@oh-my-pi/pi-ai 15.11.4 → 15.11.7
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 +40 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +3 -0
- package/dist/types/auth-storage.d.ts +87 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/providers/anthropic.d.ts +5 -0
- package/dist/types/providers/google-gemini-cli.d.ts +16 -0
- package/dist/types/usage/openai-codex-reset.d.ts +79 -0
- package/dist/types/usage/openai-codex.d.ts +1 -0
- package/dist/types/usage.d.ts +56 -0
- package/dist/types/utils/request-debug.d.ts +3 -0
- package/package.json +3 -3
- package/src/auth-storage.ts +373 -0
- package/src/index.ts +1 -0
- package/src/providers/anthropic.ts +6 -1
- package/src/providers/aws-credentials.ts +0 -1
- package/src/providers/google-gemini-cli.ts +24 -1
- package/src/providers/openai-completions.ts +11 -7
- package/src/providers/openai-responses.ts +44 -10
- package/src/stream.ts +81 -41
- package/src/usage/openai-codex-reset.ts +174 -0
- package/src/usage/openai-codex.ts +18 -1
- package/src/usage.ts +68 -0
- package/src/utils/request-debug.ts +55 -12
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.11.7] - 2026-06-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `requestModelId` and `thinking.suppress` options to `google-gemini-cli` so collapsed effort-tier variants serialize their per-effort upstream wire id, and thinking-off requests on models with `thinking.suppressWhenOff` send an explicit `thinkingConfig` (`includeThoughts: false` with `thinkingLevel: "MINIMAL"` or `thinkingBudget: 0`) — Cloud Code Assist re-applies the per-id baked server default when the config is omitted, silently thinking and billing the tokens
|
|
10
|
+
- Added mandatory-reasoning clamping: models baked with `thinking.requiresEffort` floor omitted or disabled reasoning to the lowest supported effort in every api mapping, and `disableReasoning` no longer emits OpenRouter `reasoning: { enabled: false }` for them — fixes `omp bench` and utility requests 400ing with "Reasoning is mandatory for this endpoint and cannot be disabled" on OpenRouter Gemini 3.x
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Changed `google-gemini-cli` request mapping to route per-request wire ids via `resolveWireModelId`: the session effort picks the backing variant id (collapsed `gemini-3.5-flash` at high → `gemini-3.5-flash-low`; claude pairs route off → bare id, efforts → `-thinking`) while `AssistantMessage.model` and usage attribution stay on the logical id. A thinking budget clamped to zero now falls through to the thinking-off path (off routing plus suppression) instead of only disabling thinking
|
|
15
|
+
- Changed `openai-completions` and `anthropic-messages` to serialize per-request wire ids via `resolveWireModelId`, so collapsed `X`/`X-thinking` pairs on aggregators and custom providers switch to the thinking SKU when reasoning is enabled (previously only `google-gemini-cli` routed effort-tier variants)
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed `google-gemini-cli` ignoring `Model.requestModelId` when serializing the request model id
|
|
20
|
+
|
|
21
|
+
## [15.11.5] - 2026-06-12
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Added `AuthStorage.listUsageHistory` to retrieve historical usage snapshots with optional `provider` and `sinceMs` filtering
|
|
26
|
+
- Added durable usage-history persistence in the sqlite auth store so successful usage reports are recorded as time-series snapshots of limit utilization for later trend inspection
|
|
27
|
+
- Added `AuthStorage.redeemResetCredit` to redeem stored OpenAI Codex saved rate-limit reset credits for a target account by `credentialId`, `accountId`, or `email`
|
|
28
|
+
- Added `listCodexResetCredits` and `consumeCodexResetCredit` exports for OpenAI Codex saved reset-credit listing and redemption
|
|
29
|
+
- Added `resetCredits` with `availableCount` to `UsageReport` so OpenAI Codex usage data now exposes redeemable rate-limit resets
|
|
30
|
+
- Added `openai-codex-reset` exports via package barrel for out-of-band tooling usage
|
|
31
|
+
- Added a one-shot request-debug target that writes the next provider HTTP request JSON to an explicit path.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Changed `AuthStorage.redeemResetCredit` to invalidate cached usage data after a successful redemption so the next usage report reflects the reset immediately
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- Fixed temporary credential block state so redeemed reset credits immediately make the affected account selectable again after `redeemResetCredit` succeeds
|
|
40
|
+
- Fixed one-shot request-debug path handling so an explicit request log target is consumed after the next request and no longer affects subsequent calls
|
|
41
|
+
- Fixed explicit request-debug path mode to create missing parent directories before writing request logs
|
|
42
|
+
- Fixed explicit request-debug mode to overwrite existing `.res.log` files for the requested path instead of failing when they already exist
|
|
43
|
+
- Fixed OpenAI Responses `previous_response_id` chaining on Zero Data Retention orgs: the in-provider retry classifier missed the ZDR-specific 400 ("Previous response cannot be used for this organization due to Zero Data Retention"), so chained turns kept failing every other request after a brief recovery — the chain was reset but not disabled, so the next successful full-replay turn re-armed it. The ZDR phrasing is now classified categorically: one strike disables chaining for the session (skipping the three-strike circuit breaker) and the in-call retry drops `store: true`/`previous_response_id` and replays the full transcript instead ([#2341](https://github.com/can1357/oh-my-pi/issues/2341)).
|
|
44
|
+
|
|
5
45
|
## [15.11.4] - 2026-06-12
|
|
6
46
|
|
|
7
47
|
### Added
|
|
@@ -344,6 +344,9 @@ export declare const usageResponseSchema: z.ZodObject<{
|
|
|
344
344
|
}>>;
|
|
345
345
|
notes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
346
346
|
}, z.core.$strip>>;
|
|
347
|
+
resetCredits: z.ZodOptional<z.ZodObject<{
|
|
348
|
+
availableCount: z.ZodNumber;
|
|
349
|
+
}, z.core.$strip>>;
|
|
347
350
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
348
351
|
raw: z.ZodOptional<z.ZodUnknown>;
|
|
349
352
|
}, z.core.$strip>>;
|
|
@@ -11,7 +11,8 @@ import { Database } from "bun:sqlite";
|
|
|
11
11
|
import type { ApiKeyResolver } from "./auth-retry";
|
|
12
12
|
import type { OAuthController, OAuthCredentials, OAuthProviderId } from "./registry/oauth/types";
|
|
13
13
|
import type { Provider } from "./types";
|
|
14
|
-
import type { CredentialRankingStrategy, UsageLogger, UsageProvider, UsageReport } from "./usage";
|
|
14
|
+
import type { CredentialRankingStrategy, UsageHistoryEntry, UsageHistoryQuery, UsageLogger, UsageProvider, UsageReport } from "./usage";
|
|
15
|
+
import { type CodexResetConsumeCode, type CodexResetCredit } from "./usage/openai-codex-reset";
|
|
15
16
|
export type ApiKeyCredential = {
|
|
16
17
|
type: "api_key";
|
|
17
18
|
key: string;
|
|
@@ -225,6 +226,14 @@ export interface AuthCredentialStore {
|
|
|
225
226
|
}): string | null;
|
|
226
227
|
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
227
228
|
cleanExpiredCache(): void;
|
|
229
|
+
/**
|
|
230
|
+
* Append usage-limit snapshots for trend history. Optional: stores without
|
|
231
|
+
* durable storage (e.g. the broker remote store) omit it and recording is
|
|
232
|
+
* skipped — the broker host records into its own database instead.
|
|
233
|
+
*/
|
|
234
|
+
recordUsageSnapshots?(entries: UsageHistoryEntry[]): void;
|
|
235
|
+
/** Read recorded usage-limit snapshots, oldest first. */
|
|
236
|
+
listUsageHistory?(query?: UsageHistoryQuery): UsageHistoryEntry[];
|
|
228
237
|
/**
|
|
229
238
|
* Optional store-supplied OAuth refresh. When present, `AuthStorage` uses
|
|
230
239
|
* it before the per-provider local refresh path. `RemoteAuthCredentialStore`
|
|
@@ -450,6 +459,44 @@ export interface InvalidateCredentialMatchingOptions {
|
|
|
450
459
|
signal?: AbortSignal;
|
|
451
460
|
sessionId?: string;
|
|
452
461
|
}
|
|
462
|
+
/**
|
|
463
|
+
* Identifies which stored account to redeem a saved rate-limit reset for.
|
|
464
|
+
* Any one field is enough; `credentialId` is the most precise.
|
|
465
|
+
*/
|
|
466
|
+
export interface ResetCreditTarget {
|
|
467
|
+
credentialId?: number;
|
|
468
|
+
accountId?: string;
|
|
469
|
+
email?: string;
|
|
470
|
+
}
|
|
471
|
+
/** Outcome of {@link AuthStorage.redeemResetCredit}. */
|
|
472
|
+
export interface ResetCreditRedeemOutcome {
|
|
473
|
+
/** `true` only when a reset was actually applied (`code === "reset"`). */
|
|
474
|
+
ok: boolean;
|
|
475
|
+
/**
|
|
476
|
+
* Result code. Backend codes: `reset` (success), `already_redeemed`,
|
|
477
|
+
* `no_credit`, `nothing_to_reset`. Locally-synthesized: `no_account`
|
|
478
|
+
* (target not found), `account_unavailable` (token refresh failed),
|
|
479
|
+
* `http_<status>` (unexpected HTTP).
|
|
480
|
+
*/
|
|
481
|
+
code: CodexResetConsumeCode;
|
|
482
|
+
accountId?: string;
|
|
483
|
+
email?: string;
|
|
484
|
+
/** The credit that was spent (when one was). */
|
|
485
|
+
creditId?: string;
|
|
486
|
+
}
|
|
487
|
+
/** One stored account's live saved-reset status, from {@link AuthStorage.listResetCredits}. */
|
|
488
|
+
export interface ResetCreditAccountStatus {
|
|
489
|
+
credentialId?: number;
|
|
490
|
+
accountId?: string;
|
|
491
|
+
email?: string;
|
|
492
|
+
/** Resets redeemable for this account right now (live, not cached). */
|
|
493
|
+
availableCount: number;
|
|
494
|
+
credits: CodexResetCredit[];
|
|
495
|
+
/** Whether this is the given session's active account. */
|
|
496
|
+
active: boolean;
|
|
497
|
+
/** Set when the account's token refresh or list call failed. */
|
|
498
|
+
error?: string;
|
|
499
|
+
}
|
|
453
500
|
/**
|
|
454
501
|
* Credential storage backed by an AuthCredentialStore.
|
|
455
502
|
* Reads from storage on reload(), manages round-robin credential selection,
|
|
@@ -621,6 +668,11 @@ export declare class AuthStorage {
|
|
|
621
668
|
* Logout from a provider.
|
|
622
669
|
*/
|
|
623
670
|
logout(provider: string): Promise<void>;
|
|
671
|
+
/**
|
|
672
|
+
* Recorded usage-limit snapshots, oldest first. Empty when the underlying
|
|
673
|
+
* store has no durable history (e.g. a broker-backed remote store).
|
|
674
|
+
*/
|
|
675
|
+
listUsageHistory(query?: UsageHistoryQuery): UsageHistoryEntry[];
|
|
624
676
|
ingestUsageHeaders(provider: Provider, headers: Record<string, string>, options?: {
|
|
625
677
|
sessionId?: string;
|
|
626
678
|
baseUrl?: string;
|
|
@@ -713,6 +765,38 @@ export declare class AuthStorage {
|
|
|
713
765
|
* exercise each stored account exactly once.
|
|
714
766
|
*/
|
|
715
767
|
getOAuthAccesses(provider: string, options?: AuthApiKeyOptions): Promise<OAuthAccessResolution[]>;
|
|
768
|
+
/**
|
|
769
|
+
* List saved rate-limit resets for every stored OAuth account of `provider`
|
|
770
|
+
* (Codex), fetched LIVE from the dedicated `rate-limit-reset-credits` route.
|
|
771
|
+
*
|
|
772
|
+
* This deliberately bypasses the usage-report cache: `/wham/usage` is
|
|
773
|
+
* IP-rate-limited and may serve stale (or pre-feature) snapshots when many
|
|
774
|
+
* accounts are polled, which would hide redeemable credits. One entry per
|
|
775
|
+
* account, with the session's active account flagged and unreachable
|
|
776
|
+
* accounts carrying an `error`.
|
|
777
|
+
*/
|
|
778
|
+
listResetCredits(options?: {
|
|
779
|
+
provider?: string;
|
|
780
|
+
sessionId?: string;
|
|
781
|
+
baseUrlResolver?: (provider: string) => string | undefined;
|
|
782
|
+
signal?: AbortSignal;
|
|
783
|
+
}): Promise<ResetCreditAccountStatus[]>;
|
|
784
|
+
/**
|
|
785
|
+
* Redeem one saved rate-limit reset (OpenAI Codex "saved resets") for a
|
|
786
|
+
* specific stored account.
|
|
787
|
+
*
|
|
788
|
+
* Resolves a fresh access token for the target account, picks an available
|
|
789
|
+
* credit (the given `creditId`, else the first redeemable one), spends it,
|
|
790
|
+
* and invalidates the cached usage report so the next `/usage` reflects the
|
|
791
|
+
* reset. Never throws for business outcomes — inspect the returned `code`.
|
|
792
|
+
*/
|
|
793
|
+
redeemResetCredit(options: {
|
|
794
|
+
target: ResetCreditTarget;
|
|
795
|
+
provider?: string;
|
|
796
|
+
creditId?: string;
|
|
797
|
+
baseUrlResolver?: (provider: string) => string | undefined;
|
|
798
|
+
signal?: AbortSignal;
|
|
799
|
+
}): Promise<ResetCreditRedeemOutcome>;
|
|
716
800
|
invalidateCredentialMatching(provider: string, apiKey: string, options?: InvalidateCredentialMatchingOptions): Promise<boolean>;
|
|
717
801
|
invalidateCredentialMatching(provider: string, apiKey: string, signal?: AbortSignal): Promise<boolean>;
|
|
718
802
|
/**
|
|
@@ -836,6 +920,8 @@ export declare class SqliteAuthCredentialStore implements AuthCredentialStore {
|
|
|
836
920
|
}): string | null;
|
|
837
921
|
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
838
922
|
cleanExpiredCache(): void;
|
|
923
|
+
recordUsageSnapshots(entries: UsageHistoryEntry[]): void;
|
|
924
|
+
listUsageHistory(query?: UsageHistoryQuery): UsageHistoryEntry[];
|
|
839
925
|
/**
|
|
840
926
|
* Save OAuth credentials for a provider.
|
|
841
927
|
* Preserves unrelated identities and replaces only the matching credential.
|
package/dist/types/index.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export * from "./usage/google-antigravity";
|
|
|
34
34
|
export * from "./usage/kimi";
|
|
35
35
|
export * from "./usage/minimax-code";
|
|
36
36
|
export * from "./usage/openai-codex";
|
|
37
|
+
export * from "./usage/openai-codex-reset";
|
|
37
38
|
export * from "./usage/zai";
|
|
38
39
|
export * from "./utils/anthropic-auth";
|
|
39
40
|
export * from "./utils/event-stream";
|
|
@@ -83,6 +83,11 @@ export interface AnthropicOptions extends StreamOptions {
|
|
|
83
83
|
* Ignored for adaptive-capable models.
|
|
84
84
|
*/
|
|
85
85
|
thinkingBudgetTokens?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Upstream wire model id override for collapsed effort-tier variants.
|
|
88
|
+
* Serialized as `requestModelId ?? model.requestModelId ?? model.id`.
|
|
89
|
+
*/
|
|
90
|
+
requestModelId?: string;
|
|
86
91
|
/**
|
|
87
92
|
* Effort level for adaptive thinking.
|
|
88
93
|
* Controls how much thinking Claude allocates:
|
|
@@ -34,7 +34,23 @@ export interface GoogleGeminiCliOptions extends StreamOptions {
|
|
|
34
34
|
budgetTokens?: number;
|
|
35
35
|
/** Thinking level. Use for Gemini 3 models (LOW/HIGH for Pro, MINIMAL/LOW/MEDIUM/HIGH for Flash). */
|
|
36
36
|
level?: GoogleThinkingLevel;
|
|
37
|
+
/**
|
|
38
|
+
* Explicit wire suppression when `enabled` is false. Cloud Code Assist
|
|
39
|
+
* re-applies the per-id baked server default when thinkingConfig is
|
|
40
|
+
* omitted, so models with `thinking.suppressWhenOff` must send
|
|
41
|
+
* `includeThoughts: false` plus a MINIMAL level (or zero budget).
|
|
42
|
+
*/
|
|
43
|
+
suppress?: {
|
|
44
|
+
level: GoogleThinkingLevel;
|
|
45
|
+
} | {
|
|
46
|
+
budget: number;
|
|
47
|
+
};
|
|
37
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Upstream wire model id override for collapsed effort-tier variants.
|
|
51
|
+
* Serialized as `requestModelId ?? model.requestModelId ?? model.id`.
|
|
52
|
+
*/
|
|
53
|
+
requestModelId?: string;
|
|
38
54
|
projectId?: string;
|
|
39
55
|
}
|
|
40
56
|
export { ANTIGRAVITY_SYSTEM_INSTRUCTION, getAntigravityUserAgent, getGeminiCliHeaders, getGeminiCliUserAgent, } from "@oh-my-pi/pi-catalog/wire/gemini-headers";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Codex "saved rate limit reset" redemption client.
|
|
3
|
+
*
|
|
4
|
+
* OpenAI lets paid Codex accounts bank a usage-window reset and spend it on
|
|
5
|
+
* demand (announced 2026-06-11). The count is surfaced on `/wham/usage` as
|
|
6
|
+
* `rate_limit_reset_credits.available_count` (see `./openai-codex.ts`), but the
|
|
7
|
+
* actual credit objects and the redeem action live on two dedicated routes:
|
|
8
|
+
*
|
|
9
|
+
* GET /wham/rate-limit-reset-credits → list redeemable credits
|
|
10
|
+
* POST /wham/rate-limit-reset-credits/consume → spend one credit
|
|
11
|
+
* body: { credit_id, redeem_request_id }
|
|
12
|
+
*
|
|
13
|
+
* `redeem_request_id` is a client-generated idempotency key (UUID). The consume
|
|
14
|
+
* response carries a `code`: `"reset"` on success, otherwise a business reason
|
|
15
|
+
* (`already_redeemed`, `no_credit`, `nothing_to_reset`).
|
|
16
|
+
*
|
|
17
|
+
* These are thin, dependency-light functions so both the interactive session
|
|
18
|
+
* (the `/usage reset` command + auto-redeem) and any out-of-band tooling can
|
|
19
|
+
* share one wire contract.
|
|
20
|
+
*/
|
|
21
|
+
import type { FetchImpl } from "../types";
|
|
22
|
+
/** A single redeemable (or already-spent) saved reset. */
|
|
23
|
+
export interface CodexResetCredit {
|
|
24
|
+
/** Opaque credit id, e.g. `RateLimitResetCredit_…`. Pass to {@link consumeCodexResetCredit}. */
|
|
25
|
+
id: string;
|
|
26
|
+
/** Backend reset family, e.g. `codex_rate_limits`. */
|
|
27
|
+
resetType?: string;
|
|
28
|
+
/** `available`, `redeemed`, … */
|
|
29
|
+
status?: string;
|
|
30
|
+
grantedAt?: string;
|
|
31
|
+
expiresAt?: string;
|
|
32
|
+
redeemStartedAt?: string | null;
|
|
33
|
+
redeemedAt?: string | null;
|
|
34
|
+
/** Human-facing card title, e.g. "One free rate limit reset". */
|
|
35
|
+
title?: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Result of listing an account's saved resets. */
|
|
39
|
+
export interface CodexResetCreditList {
|
|
40
|
+
credits: CodexResetCredit[];
|
|
41
|
+
/** Backend-reported count of credits redeemable right now. */
|
|
42
|
+
availableCount: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Consume outcome `code`. `reset` means a window was actually reset; the others
|
|
46
|
+
* are no-op business outcomes the caller should surface verbatim-ish to the user.
|
|
47
|
+
*/
|
|
48
|
+
export type CodexResetConsumeCode = "reset" | "already_redeemed" | "no_credit" | "nothing_to_reset" | (string & {});
|
|
49
|
+
export interface CodexResetConsumeResult {
|
|
50
|
+
/** `true` only when `code === "reset"` (a reset was applied). */
|
|
51
|
+
ok: boolean;
|
|
52
|
+
code: CodexResetConsumeCode;
|
|
53
|
+
/** HTTP status of the consume call (for diagnostics). */
|
|
54
|
+
status: number;
|
|
55
|
+
raw?: unknown;
|
|
56
|
+
}
|
|
57
|
+
interface CodexResetAuth {
|
|
58
|
+
accessToken: string;
|
|
59
|
+
accountId?: string;
|
|
60
|
+
/** Provider base URL override; defaults to the Codex backend. */
|
|
61
|
+
baseUrl?: string;
|
|
62
|
+
fetch: FetchImpl;
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* List the account's saved rate-limit resets. Returns `null` on transport/auth
|
|
67
|
+
* failure (non-2xx or thrown), letting callers treat it the same as "no data".
|
|
68
|
+
*/
|
|
69
|
+
export declare function listCodexResetCredits(auth: CodexResetAuth): Promise<CodexResetCreditList | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Spend one saved reset. `redeemRequestId` is the idempotency key; one is
|
|
72
|
+
* generated when omitted, so retrying with the SAME id is safe and won't
|
|
73
|
+
* double-spend. The returned `code` is `"reset"` on success.
|
|
74
|
+
*/
|
|
75
|
+
export declare function consumeCodexResetCredit(auth: CodexResetAuth & {
|
|
76
|
+
creditId: string;
|
|
77
|
+
redeemRequestId?: string;
|
|
78
|
+
}): Promise<CodexResetConsumeResult>;
|
|
79
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { CredentialRankingStrategy, UsageProvider } from "../usage";
|
|
2
|
+
export declare function normalizeCodexBaseUrl(baseUrl?: string): string;
|
|
2
3
|
export declare const openaiCodexUsageProvider: UsageProvider;
|
|
3
4
|
export declare const codexRankingStrategy: CredentialRankingStrategy;
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -57,14 +57,64 @@ export interface UsageLimit {
|
|
|
57
57
|
status?: UsageStatus;
|
|
58
58
|
notes?: string[];
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Saved/banked rate-limit resets an account can redeem on demand.
|
|
62
|
+
*
|
|
63
|
+
* Surfaced by providers that let users defer a usage-window reset and spend it
|
|
64
|
+
* later (OpenAI Codex "saved rate limit resets"). The redeem itself is a
|
|
65
|
+
* separate, provider-specific action; this is the read-only count for display.
|
|
66
|
+
*/
|
|
67
|
+
export interface UsageResetCredits {
|
|
68
|
+
/** Number of resets available to redeem right now. */
|
|
69
|
+
availableCount: number;
|
|
70
|
+
}
|
|
60
71
|
/** Aggregated usage report for a provider. */
|
|
61
72
|
export interface UsageReport {
|
|
62
73
|
provider: Provider;
|
|
63
74
|
fetchedAt: number;
|
|
64
75
|
limits: UsageLimit[];
|
|
76
|
+
/** Saved rate-limit resets the account can redeem, when the provider reports them. */
|
|
77
|
+
resetCredits?: UsageResetCredits;
|
|
65
78
|
metadata?: Record<string, unknown>;
|
|
66
79
|
raw?: unknown;
|
|
67
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolve a limit's used fraction (0..1; >1 means overage) from whichever
|
|
83
|
+
* amount fields the provider populated. Precedence mirrors the usage UIs:
|
|
84
|
+
* explicit fraction > used/limit > percent-unit used > inverted remaining.
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveUsedFraction(limit: UsageLimit): number | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* One recorded usage-limit snapshot: a single limit window of one account at
|
|
89
|
+
* a point in time. The usage cache itself is latest-snapshot-only; history
|
|
90
|
+
* rows are appended by the auth storage layer whenever a fresh report is
|
|
91
|
+
* fetched, so limit utilization stays inspectable over time.
|
|
92
|
+
*/
|
|
93
|
+
export interface UsageHistoryEntry {
|
|
94
|
+
/** Epoch ms the report was fetched. */
|
|
95
|
+
recordedAt: number;
|
|
96
|
+
provider: Provider;
|
|
97
|
+
/** Stable credential identity key (account/email/project derived). */
|
|
98
|
+
accountKey: string;
|
|
99
|
+
email?: string;
|
|
100
|
+
accountId?: string;
|
|
101
|
+
/** {@link UsageLimit.id} of the recorded window. */
|
|
102
|
+
limitId: string;
|
|
103
|
+
/** Human label of the limit. */
|
|
104
|
+
label: string;
|
|
105
|
+
windowLabel?: string;
|
|
106
|
+
/** Used fraction (0..1) when resolvable. */
|
|
107
|
+
usedFraction?: number;
|
|
108
|
+
status?: UsageStatus;
|
|
109
|
+
/** Epoch ms the window resets, when known. */
|
|
110
|
+
resetsAt?: number;
|
|
111
|
+
}
|
|
112
|
+
/** Filter for reading recorded usage history. */
|
|
113
|
+
export interface UsageHistoryQuery {
|
|
114
|
+
provider?: string;
|
|
115
|
+
/** Inclusive lower bound on {@link UsageHistoryEntry.recordedAt} (epoch ms). */
|
|
116
|
+
sinceMs?: number;
|
|
117
|
+
}
|
|
68
118
|
export declare const usageUnitSchema: z.ZodEnum<{
|
|
69
119
|
bytes: "bytes";
|
|
70
120
|
minutes: "minutes";
|
|
@@ -155,6 +205,9 @@ export declare const usageLimitSchema: z.ZodObject<{
|
|
|
155
205
|
}>>;
|
|
156
206
|
notes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
157
207
|
}, z.core.$strip>;
|
|
208
|
+
export declare const usageResetCreditsSchema: z.ZodObject<{
|
|
209
|
+
availableCount: z.ZodNumber;
|
|
210
|
+
}, z.core.$strip>;
|
|
158
211
|
export declare const usageReportSchema: z.ZodObject<{
|
|
159
212
|
provider: z.ZodString;
|
|
160
213
|
fetchedAt: z.ZodNumber;
|
|
@@ -201,6 +254,9 @@ export declare const usageReportSchema: z.ZodObject<{
|
|
|
201
254
|
}>>;
|
|
202
255
|
notes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
203
256
|
}, z.core.$strip>>;
|
|
257
|
+
resetCredits: z.ZodOptional<z.ZodObject<{
|
|
258
|
+
availableCount: z.ZodNumber;
|
|
259
|
+
}, z.core.$strip>>;
|
|
204
260
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
205
261
|
raw: z.ZodOptional<z.ZodUnknown>;
|
|
206
262
|
}, z.core.$strip>;
|
|
@@ -22,6 +22,9 @@ export interface RequestDebugSession {
|
|
|
22
22
|
wrapResponse(response: Response): Promise<Response>;
|
|
23
23
|
}
|
|
24
24
|
export declare function isRequestDebugEnabled(): boolean;
|
|
25
|
+
export declare function setNextRequestDebugPath(requestPath: string): void;
|
|
26
|
+
export declare function clearNextRequestDebugPath(): void;
|
|
27
|
+
export declare function getNextRequestDebugPath(): string | undefined;
|
|
25
28
|
export declare function wrapFetchForRequestDebug(fetchImpl: FetchImpl): FetchImpl;
|
|
26
29
|
export declare function withRequestDebugFetch<T extends {
|
|
27
30
|
fetch?: FetchImpl;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "15.11.
|
|
4
|
+
"version": "15.11.7",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@bufbuild/protobuf": "^2.12.0",
|
|
41
|
-
"@oh-my-pi/pi-catalog": "15.11.
|
|
42
|
-
"@oh-my-pi/pi-utils": "15.11.
|
|
41
|
+
"@oh-my-pi/pi-catalog": "15.11.7",
|
|
42
|
+
"@oh-my-pi/pi-utils": "15.11.7",
|
|
43
43
|
"openai": "^6.39.0",
|
|
44
44
|
"partial-json": "^0.1.7",
|
|
45
45
|
"zod": "4.4.3"
|