@oh-my-pi/pi-ai 18.1.10 → 18.1.12
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 +15 -0
- package/dist/types/auth-storage.d.ts +36 -0
- package/dist/types/error/oauth.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/providers/openai-shared.d.ts +6 -5
- package/dist/types/registry/muse-code.d.ts +3 -0
- package/dist/types/registry/oauth/index.d.ts +1 -0
- package/dist/types/registry/oauth/muse-code.d.ts +67 -0
- package/dist/types/usage/muse-code.d.ts +2 -0
- package/dist/types/usage.d.ts +2 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +2 -0
- package/package.json +6 -6
- package/src/auth-gateway/server.ts +1 -0
- package/src/auth-storage.ts +198 -11
- package/src/error/flags.ts +1 -1
- package/src/error/oauth.ts +2 -0
- package/src/index.ts +1 -0
- package/src/providers/openai-shared.ts +10 -6
- package/src/providers/pi-native-client.ts +10 -6
- package/src/registry/engine/common.ts +13 -9
- package/src/registry/hooks/device-code.ts +3 -1
- package/src/registry/muse-code.ts +23 -0
- package/src/registry/oauth/github-copilot.ts +1 -1
- package/src/registry/oauth/index.ts +13 -21
- package/src/registry/oauth/muse-code.ts +174 -0
- package/src/registry/registry.ts +2 -0
- package/src/usage/muse-code.ts +158 -0
- package/src/usage/opencode-go.ts +8 -0
- package/src/usage.ts +2 -0
- package/src/utils/schema/json-schema-validator.ts +120 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.1.12] - 2026-09-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added Muse Code subscription sign-in, credential refresh, inference, and quota reporting in `/usage`, with durable rate-limit backoff so quota refresh recovers instead of repeatedly retrying.
|
|
10
|
+
|
|
11
|
+
## [18.1.11] - 2026-09-05
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Fixed OpenCode Go usage polls (`GET /zen/go/v1/usage`) missing `x-opencode-session` and omp's `User-Agent`: background polls now attribute with the stable install id so the requests OpenCode flags as `Bun fetch` carry the required session header.
|
|
16
|
+
- GitHub Copilot sign-in now requests only basic profile access, restoring login for Enterprise organizations that reject repository, gist, and Codespaces permissions ([#10656](https://github.com/can1357/oh-my-pi/issues/10656)).
|
|
17
|
+
|
|
5
18
|
## [18.1.9] - 2026-09-04
|
|
6
19
|
|
|
7
20
|
### Added
|
|
@@ -27,6 +40,7 @@
|
|
|
27
40
|
### Fixed
|
|
28
41
|
|
|
29
42
|
- Fixed DeepSeek-family Responses replay (e.g. opencode-go) rejecting a resumed thinking-mode turn with `400 The reasoning_text in the thinking mode must be passed back to the API` when compaction dropped the turn's reasoning; a non-empty placeholder is now synthesized instead of an empty `reasoning_text` ([#10690](https://github.com/can1357/oh-my-pi/issues/10690)).
|
|
43
|
+
- Fixed pi-native streams treating a connection that closed before its terminal event as a successful empty response; incomplete streams and namespaced gateway 5xx failures now remain retryable.
|
|
30
44
|
|
|
31
45
|
## [18.1.6] - 2026-09-03
|
|
32
46
|
|
|
@@ -50,6 +64,7 @@
|
|
|
50
64
|
- Anthropic and OpenRouter credit-exhaustion errors now automatically switch to a sibling account instead of stopping the turn with a retry hint.
|
|
51
65
|
- Fixed OpenCode Go and Zen requests by including the required stable per-conversation session identification.
|
|
52
66
|
- Improved Anthropic prompt caching so explicit cache breakpoints preserve reusable tools and system prompts when the message tail changes.
|
|
67
|
+
- Anthropic and OpenRouter 402 credit-exhaustion errors ("would exceed your available credits", "Insufficient credits") now switch to a sibling account instead of stopping the turn with a retry hint.
|
|
53
68
|
|
|
54
69
|
## [18.1.5] - 2026-09-03
|
|
55
70
|
|
|
@@ -496,10 +496,40 @@ export { isDefinitiveOAuthFailure } from "./error/auth-classify.js";
|
|
|
496
496
|
* multi-hour) retry-after when it is sooner. `retryAtMs` is `undefined` when
|
|
497
497
|
* no sibling credentials exist at all, or when the session has no tracked
|
|
498
498
|
* credential to rotate away from.
|
|
499
|
+
*
|
|
500
|
+
* `blockedUntilMs` (epoch ms) is the just-blocked credential's own unblock
|
|
501
|
+
* deadline — the later of the caller's retry-after and any exhausted window
|
|
502
|
+
* the usage report reveals. Callers that wait the account out (instead of
|
|
503
|
+
* rotating) must sleep until this, not the error-text hint alone.
|
|
504
|
+
*
|
|
505
|
+
* `priorBlockedUntilMs` (epoch ms) is the live block deadline the map already
|
|
506
|
+
* stored for this credential before this call. The merged `blockedUntilMs`
|
|
507
|
+
* masks a pre-existing block shorter than this call's own heuristic
|
|
508
|
+
* fallback (`Math.max` in the mark), so callers that replace that heuristic
|
|
509
|
+
* with an authoritative report window must consult the prior deadline to
|
|
510
|
+
* keep honoring the earlier response's provider-stated block.
|
|
511
|
+
*
|
|
512
|
+
* `priorBlockedUntilTimed` is `true` when that prior deadline came from
|
|
513
|
+
* provider-stated timing (a parsed hint or usage-report reset) rather than
|
|
514
|
+
* another session's heuristic guess — only timed priors may extend a wait
|
|
515
|
+
* past an authoritative report window. Persisted blocks carry no provenance
|
|
516
|
+
* and count as untimed: a stale persisted heuristic must not outrank a
|
|
517
|
+
* fresh complete report (longer persisted deadlines still win through the
|
|
518
|
+
* merged `blockedUntilMs`).
|
|
519
|
+
*
|
|
520
|
+
* `reportResetAtMs` (epoch ms) is present only when the usage report is a
|
|
521
|
+
* complete authority for the wait: every exhausted window carries a future
|
|
522
|
+
* reset, so sleeping until the latest one can actually clear the account. A
|
|
523
|
+
* permanent cap alongside a timed window (or no report at all) leaves it
|
|
524
|
+
* unset, and the heuristic fallback alone must never authorize a wait.
|
|
499
525
|
*/
|
|
500
526
|
export interface UsageLimitMarkResult {
|
|
501
527
|
switched: boolean;
|
|
502
528
|
retryAtMs?: number;
|
|
529
|
+
blockedUntilMs?: number;
|
|
530
|
+
priorBlockedUntilMs?: number;
|
|
531
|
+
priorBlockedUntilTimed?: boolean;
|
|
532
|
+
reportResetAtMs?: number;
|
|
503
533
|
}
|
|
504
534
|
export type ModelUsageHealthState = "healthy" | "reserve" | "depleted" | "unknown";
|
|
505
535
|
export interface ModelUsageAccountHealth {
|
|
@@ -1013,6 +1043,12 @@ export declare class AuthStorage {
|
|
|
1013
1043
|
*/
|
|
1014
1044
|
markUsageLimitReached(provider: string, sessionId: string | undefined, options?: {
|
|
1015
1045
|
retryAfterMs?: number;
|
|
1046
|
+
/**
|
|
1047
|
+
* Whether `retryAfterMs` came from provider-stated timing (a parsed
|
|
1048
|
+
* retry hint) rather than a heuristic/default guess. A report reset
|
|
1049
|
+
* extending the block counts as provider timing regardless.
|
|
1050
|
+
*/
|
|
1051
|
+
providerTimed?: boolean;
|
|
1016
1052
|
baseUrl?: string;
|
|
1017
1053
|
modelId?: string;
|
|
1018
1054
|
apiKey?: string;
|
|
@@ -22,6 +22,8 @@ export type OAuthErrorKind =
|
|
|
22
22
|
| "configuration"
|
|
23
23
|
/** Cloud project provisioning / onboarding (loadCodeAssist, onboardUser). */
|
|
24
24
|
| "provisioning"
|
|
25
|
+
/** Subscription/payment gate: plan required or purchase action needed. */
|
|
26
|
+
| "entitlement"
|
|
25
27
|
/** OIDC / endpoint discovery failed. */
|
|
26
28
|
| "discovery";
|
|
27
29
|
export interface OAuthErrorOptions {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export * from "./usage/github-copilot.js";
|
|
|
35
35
|
export * from "./usage/google-antigravity.js";
|
|
36
36
|
export * from "./usage/kimi.js";
|
|
37
37
|
export * from "./usage/minimax-code.js";
|
|
38
|
+
export * from "./usage/muse-code.js";
|
|
38
39
|
export * from "./usage/ollama.js";
|
|
39
40
|
export * from "./usage/openai-codex.js";
|
|
40
41
|
export * from "./usage/openai-codex-reset.js";
|
|
@@ -357,11 +357,12 @@ export declare function resolveOpenAICompletionsOutputClamp(model: Model<"openai
|
|
|
357
357
|
/**
|
|
358
358
|
* Provider-specific Responses API output clamp.
|
|
359
359
|
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
* conservative 64k OpenAI-compatible default.
|
|
360
|
+
* Models whose compiled provider policy opts in may use their full advertised
|
|
361
|
+
* output cap instead of the conservative 64k OpenAI-compatible default.
|
|
363
362
|
*/
|
|
364
|
-
export declare function resolveOpenAIResponsesOutputClamp(model: Pick<Model, "
|
|
363
|
+
export declare function resolveOpenAIResponsesOutputClamp(model: Pick<Model, "maxTokens"> & {
|
|
364
|
+
compat: Pick<ResolvedOpenAISharedCompat, "clampOutputToModelMax">;
|
|
365
|
+
}): number | undefined;
|
|
365
366
|
/**
|
|
366
367
|
* Enable `tool_stream` for Z.AI/GLM-5.2 reasoning models when tools are present
|
|
367
368
|
* (GLM-5.2 streams tool-call arguments incrementally and needs the flag to do so).
|
|
@@ -659,7 +660,7 @@ type CommonSamplingOptions = Pick<StreamOptions, "temperature" | "topP" | "topK"
|
|
|
659
660
|
* reflect the model's context window rather than the upstream output limit.
|
|
660
661
|
*/
|
|
661
662
|
export declare function applyCommonResponsesSamplingParams<P extends CommonResponsesParams>(params: P, options: CommonSamplingOptions | undefined, model: Pick<Model, "provider" | "api" | "id" | "omitMaxOutputTokens" | "maxTokens" | "identity"> & {
|
|
662
|
-
compat: Pick<ResolvedOpenAISharedCompat, "supportsSamplingParams" | "supportsPenaltyAndStopParams">;
|
|
663
|
+
compat: Pick<ResolvedOpenAISharedCompat, "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "clampOutputToModelMax">;
|
|
663
664
|
}): void;
|
|
664
665
|
type ReasoningOptions = {
|
|
665
666
|
reasoning?: string;
|
|
@@ -22,6 +22,7 @@ export declare function unregisterOAuthProviders(sourceId: string): void;
|
|
|
22
22
|
* Refresh a built-in OAuth grant, cancelling provider work when refresh ownership ends.
|
|
23
23
|
*/
|
|
24
24
|
export declare function refreshOAuthToken(provider: OAuthProvider, credentials: OAuthCredentials, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
25
|
+
export declare function normalizeOAuthCredentialExpiry<T extends OAuthCredentials>(provider: string, credentials: T): T;
|
|
25
26
|
/**
|
|
26
27
|
* Build API-key bytes for a provider from an already-fresh OAuth credential.
|
|
27
28
|
*
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { AfterExchangeHook } from "../hooks/types.js";
|
|
2
|
+
import type { FetchImpl } from "../../types.js";
|
|
3
|
+
declare const museCodeKeyResponseSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
4
|
+
action_url?: string | null | undefined;
|
|
5
|
+
api_key?: string | undefined;
|
|
6
|
+
is_subs_active?: boolean | undefined;
|
|
7
|
+
require_payment?: boolean | undefined;
|
|
8
|
+
require_payment_action_url?: string | undefined;
|
|
9
|
+
subs_tier_id?: string | undefined;
|
|
10
|
+
subs_tier_name?: string | undefined;
|
|
11
|
+
subs_usage?: {
|
|
12
|
+
weekly?: {
|
|
13
|
+
resets_at?: string | number | undefined;
|
|
14
|
+
used_percent?: number | undefined;
|
|
15
|
+
window_duration_mins?: number | undefined;
|
|
16
|
+
} | null | undefined;
|
|
17
|
+
window?: {
|
|
18
|
+
resets_at?: string | number | undefined;
|
|
19
|
+
used_percent?: number | undefined;
|
|
20
|
+
window_duration_mins?: number | undefined;
|
|
21
|
+
} | null | undefined;
|
|
22
|
+
} | null | undefined;
|
|
23
|
+
user_email?: string | undefined;
|
|
24
|
+
user_id?: string | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
action_url?: string | null | undefined;
|
|
27
|
+
api_key?: string | undefined;
|
|
28
|
+
is_subs_active?: boolean | undefined;
|
|
29
|
+
require_payment?: boolean | undefined;
|
|
30
|
+
require_payment_action_url?: string | undefined;
|
|
31
|
+
subs_tier_id?: string | undefined;
|
|
32
|
+
subs_tier_name?: string | undefined;
|
|
33
|
+
subs_usage?: {
|
|
34
|
+
weekly?: {
|
|
35
|
+
resets_at?: string | number | undefined;
|
|
36
|
+
used_percent?: number | undefined;
|
|
37
|
+
window_duration_mins?: number | undefined;
|
|
38
|
+
} | null | undefined;
|
|
39
|
+
window?: {
|
|
40
|
+
resets_at?: string | number | undefined;
|
|
41
|
+
used_percent?: number | undefined;
|
|
42
|
+
window_duration_mins?: number | undefined;
|
|
43
|
+
} | null | undefined;
|
|
44
|
+
} | null | undefined;
|
|
45
|
+
user_email?: string | undefined;
|
|
46
|
+
user_id?: string | undefined;
|
|
47
|
+
}>;
|
|
48
|
+
export type MuseCodeKeyResponse = typeof museCodeKeyResponseSchema.infer;
|
|
49
|
+
declare const museCodeCredentialSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
50
|
+
apiKey: string;
|
|
51
|
+
oauthAccessToken: string;
|
|
52
|
+
}, {
|
|
53
|
+
apiKey: string;
|
|
54
|
+
oauthAccessToken: string;
|
|
55
|
+
}>;
|
|
56
|
+
export type MuseCodeCredential = typeof museCodeCredentialSchema.infer;
|
|
57
|
+
export interface MuseCodeKeyRequestOptions {
|
|
58
|
+
fetch?: FetchImpl;
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
/** Ask Meta to onboard the account during an interactive login exchange. */
|
|
61
|
+
onboard?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export declare function parseMuseCodeCredential(value: string): MuseCodeCredential;
|
|
64
|
+
export declare function requestMuseCodeKey(accessToken: string, options?: MuseCodeKeyRequestOptions): Promise<MuseCodeKeyResponse>;
|
|
65
|
+
/** Exchange Meta account access for the Model API key authorized by a Muse subscription. */
|
|
66
|
+
export declare const attachMuseCodeApiKey: AfterExchangeHook;
|
|
67
|
+
export {};
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -478,6 +478,8 @@ export interface UsageProvider {
|
|
|
478
478
|
validatesCredentials?: boolean;
|
|
479
479
|
/** Whether a failed refresh may serve the previous successful report. Defaults to true. */
|
|
480
480
|
retainLastGoodOnFailure?: boolean;
|
|
481
|
+
/** Provider-specific cool-down after a failed refresh. Defaults to the shared short backoff. */
|
|
482
|
+
failureBackoffMs?: number;
|
|
481
483
|
}
|
|
482
484
|
/** Request context used when ranking usage for a specific model. */
|
|
483
485
|
export interface CredentialRankingContext {
|
|
@@ -16,5 +16,7 @@ export interface JsonSchemaValidationResult {
|
|
|
16
16
|
success: boolean;
|
|
17
17
|
issues: JsonSchemaValidationIssue[];
|
|
18
18
|
}
|
|
19
|
+
/** Whether any same-instance schema declaration or constraint owns this property name. */
|
|
20
|
+
export declare function schemaDefinesProperty(schema: unknown, key: string): boolean;
|
|
19
21
|
export declare function validateJsonSchemaValue(schema: unknown, value: unknown): JsonSchemaValidationResult;
|
|
20
22
|
export declare function isJsonSchemaValueValid(schema: unknown, value: unknown): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-ai",
|
|
3
|
-
"version": "18.1.
|
|
3
|
+
"version": "18.1.12",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -124,11 +124,11 @@
|
|
|
124
124
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
125
125
|
},
|
|
126
126
|
"dependencies": {
|
|
127
|
-
"@oh-my-pi/omptype": "18.1.
|
|
128
|
-
"@oh-my-pi/pi-catalog": "18.1.
|
|
129
|
-
"@oh-my-pi/pi-natives": "18.1.
|
|
130
|
-
"@oh-my-pi/pi-utils": "18.1.
|
|
131
|
-
"@oh-my-pi/pi-wire": "18.1.
|
|
127
|
+
"@oh-my-pi/omptype": "18.1.12",
|
|
128
|
+
"@oh-my-pi/pi-catalog": "18.1.12",
|
|
129
|
+
"@oh-my-pi/pi-natives": "18.1.12",
|
|
130
|
+
"@oh-my-pi/pi-utils": "18.1.12",
|
|
131
|
+
"@oh-my-pi/pi-wire": "18.1.12"
|
|
132
132
|
},
|
|
133
133
|
"devDependencies": {
|
|
134
134
|
"@types/bun": "^1.3.14"
|
|
@@ -251,6 +251,7 @@ async function refreshGatewayApiKeyAfterAuthError(
|
|
|
251
251
|
const retryAfterMs = extractRetryHint(undefined, message);
|
|
252
252
|
const { switched, retryAtMs } = await storage.markUsageLimitReached(provider, sessionId, {
|
|
253
253
|
retryAfterMs,
|
|
254
|
+
providerTimed: retryAfterMs !== undefined,
|
|
254
255
|
baseUrl: model.baseUrl,
|
|
255
256
|
modelId: model.id,
|
|
256
257
|
apiKey: oldKey,
|