@code-yeongyu/senpi-ai 2026.11.3-2 → 2026.11.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/dist/api/anthropic-messages.js +5 -5
- package/dist/api/lazy.js +3 -0
- package/dist/api/openai-completions.js +19 -4
- package/dist/api/simple-options.js +1 -0
- package/dist/auth/oauth/openai-chatgpt.d.ts +46 -2
- package/dist/auth/oauth/openai-chatgpt.js +206 -74
- package/dist/auth/oauth/openai-id-token.d.ts +16 -0
- package/dist/auth/oauth/openai-id-token.js +105 -0
- package/dist/auth/oauth-refresh.d.ts +3 -1
- package/dist/auth/oauth-refresh.js +49 -11
- package/dist/auth/types.d.ts +33 -3
- package/dist/cli.js +2 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/opengateway.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/venice.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/utils/oauth-refresh-error.d.ts +11 -0
- package/dist/utils/oauth-refresh-error.js +18 -0
- package/dist/utils/oauth-url.d.ts +7 -0
- package/dist/utils/oauth-url.js +13 -0
- package/dist/utils/provider-diagnostic-vocabulary.d.ts +4 -0
- package/dist/utils/provider-diagnostic-vocabulary.js +14 -0
- package/dist/utils/provider-failure-description.d.ts +2 -0
- package/dist/utils/provider-failure-description.js +1 -1
- package/package.json +2 -2
package/dist/types.d.ts
CHANGED
|
@@ -213,6 +213,12 @@ export interface StreamOptions extends ProviderRequestOptions<Model<Api>> {
|
|
|
213
213
|
* session-aware features. Ignored by providers that don't support it.
|
|
214
214
|
*/
|
|
215
215
|
sessionId?: string;
|
|
216
|
+
/**
|
|
217
|
+
* Opaque, non-identifying routing key for the session. When set, Anthropic Messages sends it in
|
|
218
|
+
* the session-affinity header instead of `sessionId`, so a gateway keeps the session on one
|
|
219
|
+
* upstream account without learning the session id. Other providers ignore it.
|
|
220
|
+
*/
|
|
221
|
+
sessionAffinityKey?: string;
|
|
216
222
|
/**
|
|
217
223
|
* Optional custom fields to merge into the outgoing provider request body.
|
|
218
224
|
* Applied before `onPayload` so `onPayload` can observe/override them.
|
|
@@ -10,6 +10,17 @@ export declare class OAuthTokenEndpointError extends Error {
|
|
|
10
10
|
credentialRefused?: boolean;
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
|
+
export type OAuthReauthorizationCode = "invalid_grant" | "invalid_refresh_token" | "token_expired" | "refresh_token_expired" | "refresh_token_invalidated" | "refresh_token_reused";
|
|
14
|
+
/** The renewable session is unusable; sign in again with its saved client ID. */
|
|
15
|
+
export declare class OAuthReauthorizationRequiredError extends OAuthTokenEndpointError {
|
|
16
|
+
readonly code: OAuthReauthorizationCode;
|
|
17
|
+
constructor(code: OAuthReauthorizationCode, status: number);
|
|
18
|
+
}
|
|
19
|
+
/** Repeating sign-in cannot repair an invalid client configuration. */
|
|
20
|
+
export declare class OAuthClientConfigurationError extends OAuthTokenEndpointError {
|
|
21
|
+
readonly code = "invalid_client";
|
|
22
|
+
constructor(status: number);
|
|
23
|
+
}
|
|
13
24
|
/** Closed, log-safe facts only; never inspect the message or response body. */
|
|
14
25
|
export declare function oauthRefreshFailureCause(error: unknown): string | undefined;
|
|
15
26
|
export declare function classifyOAuthRefreshFailure(error: unknown): "transient" | "permanent";
|
|
@@ -8,6 +8,24 @@ export class OAuthTokenEndpointError extends Error {
|
|
|
8
8
|
this.credentialRefused = facts.credentialRefused ?? false;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
+
/** The renewable session is unusable; sign in again with its saved client ID. */
|
|
12
|
+
export class OAuthReauthorizationRequiredError extends OAuthTokenEndpointError {
|
|
13
|
+
constructor(code, status) {
|
|
14
|
+
super(`OAuth refresh requires reauthorization (${code})`, status, { oauthError: code, credentialRefused: true });
|
|
15
|
+
this.name = "OAuthReauthorizationRequiredError";
|
|
16
|
+
this.code = code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Repeating sign-in cannot repair an invalid client configuration. */
|
|
20
|
+
export class OAuthClientConfigurationError extends OAuthTokenEndpointError {
|
|
21
|
+
constructor(status) {
|
|
22
|
+
super("OAuth refresh failed: invalid client configuration (invalid_client)", status, {
|
|
23
|
+
oauthError: "invalid_client",
|
|
24
|
+
});
|
|
25
|
+
this.code = "invalid_client";
|
|
26
|
+
this.name = "OAuthClientConfigurationError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
const TRANSPORT_CODES = new Set([
|
|
12
30
|
"ConnectionRefused",
|
|
13
31
|
"FailedToOpenSocket",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep retained ID tokens out of terminal output and notification transcripts.
|
|
3
|
+
* The hint-free URL remains usable for manual authorization (with an account
|
|
4
|
+
* selector); browser launchers should receive the original URL.
|
|
5
|
+
*/
|
|
6
|
+
export declare function redactOAuthUrl(value: string): string;
|
|
7
|
+
//# sourceMappingURL=oauth-url.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep retained ID tokens out of terminal output and notification transcripts.
|
|
3
|
+
* The hint-free URL remains usable for manual authorization (with an account
|
|
4
|
+
* selector); browser launchers should receive the original URL.
|
|
5
|
+
*/
|
|
6
|
+
export function redactOAuthUrl(value) {
|
|
7
|
+
const url = new URL(value);
|
|
8
|
+
if (!url.searchParams.has("id_token_hint"))
|
|
9
|
+
return value;
|
|
10
|
+
url.searchParams.delete("id_token_hint");
|
|
11
|
+
return url.toString();
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=oauth-url.js.map
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { ProviderDiagnostic, ProviderDiagnosticCategory, ProviderDiagnosticEvidence } from "../provider-diagnostic.ts";
|
|
2
2
|
/** Serialized UTF-8 budget for one emitted diagnostic. */
|
|
3
3
|
export declare const PROVIDER_DIAGNOSTIC_MAX_BYTES = 512;
|
|
4
|
+
/** A credential pool whose every account is limited until `resetsAt`, the soonest one is due back. */
|
|
5
|
+
export declare function credentialPoolBlockedDiagnostic(resetsAt: number): ProviderDiagnostic | undefined;
|
|
4
6
|
/**
|
|
5
7
|
* Closed allowlist of provider error tokens and the family each one proves.
|
|
6
8
|
* Exact tokens only: Anthropic `error.type` values, OpenAI-compatible
|
|
7
9
|
* `error.code` values, and the precise OpenAI-compatible `error.type` values
|
|
8
10
|
* that stand in for a missing code (`exceeded_current_quota_error`, senpi#4950).
|
|
9
11
|
* `billing_error` proves a billing failure, not quota exhaustion, so it stays `unknown`.
|
|
12
|
+
* `credential_pool_blocked` is senpi's own token for a credential pool whose every account waits on a
|
|
13
|
+
* rate or usage limit (senpi#3975).
|
|
10
14
|
*/
|
|
11
15
|
export declare function categoryForProviderCode(code: string): ProviderDiagnosticCategory | undefined;
|
|
12
16
|
export declare function isTlsChainVerificationCode(code: string): boolean;
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { siwcErrorForCode } from "./provider-diagnostic-carrier.js";
|
|
2
2
|
/** Serialized UTF-8 budget for one emitted diagnostic. */
|
|
3
3
|
export const PROVIDER_DIAGNOSTIC_MAX_BYTES = 512;
|
|
4
|
+
const CREDENTIAL_POOL_BLOCKED_CODE = "credential_pool_blocked";
|
|
5
|
+
/** A credential pool whose every account is limited until `resetsAt`, the soonest one is due back. */
|
|
6
|
+
export function credentialPoolBlockedDiagnostic(resetsAt) {
|
|
7
|
+
return buildProviderDiagnostic({
|
|
8
|
+
category: "rate_limit",
|
|
9
|
+
code: CREDENTIAL_POOL_BLOCKED_CODE,
|
|
10
|
+
evidence: "structured_code",
|
|
11
|
+
resetsAt,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
4
14
|
/**
|
|
5
15
|
* Closed allowlist of provider error tokens and the family each one proves.
|
|
6
16
|
* Exact tokens only: Anthropic `error.type` values, OpenAI-compatible
|
|
7
17
|
* `error.code` values, and the precise OpenAI-compatible `error.type` values
|
|
8
18
|
* that stand in for a missing code (`exceeded_current_quota_error`, senpi#4950).
|
|
9
19
|
* `billing_error` proves a billing failure, not quota exhaustion, so it stays `unknown`.
|
|
20
|
+
* `credential_pool_blocked` is senpi's own token for a credential pool whose every account waits on a
|
|
21
|
+
* rate or usage limit (senpi#3975).
|
|
10
22
|
*/
|
|
11
23
|
export function categoryForProviderCode(code) {
|
|
12
24
|
const siwc = siwcErrorForCode(code);
|
|
@@ -21,6 +33,7 @@ export function categoryForProviderCode(code) {
|
|
|
21
33
|
// `account_pool_blocked`: a subscription account pool that refused the request locally until its soonest reset (senpi#4672).
|
|
22
34
|
case "rate_limit_error":
|
|
23
35
|
case "rate_limit_exceeded":
|
|
36
|
+
case CREDENTIAL_POOL_BLOCKED_CODE:
|
|
24
37
|
case "account_pool_blocked":
|
|
25
38
|
return "rate_limit";
|
|
26
39
|
case "insufficient_quota":
|
|
@@ -97,6 +110,7 @@ export function isProviderCodeStatusCompatible(code, status) {
|
|
|
97
110
|
return status === 401;
|
|
98
111
|
case "rate_limit_error":
|
|
99
112
|
case "rate_limit_exceeded":
|
|
113
|
+
case CREDENTIAL_POOL_BLOCKED_CODE:
|
|
100
114
|
case "insufficient_quota":
|
|
101
115
|
case "exceeded_current_quota_error":
|
|
102
116
|
case "usage_limit_reached":
|
|
@@ -22,6 +22,8 @@ export declare function stripTurnRetrySuppressionPrefix(message: string): string
|
|
|
22
22
|
*/
|
|
23
23
|
export declare function describeProviderFailureForUser(errorMessage: string | undefined, options?: ProviderStallDescriptionOptions & {
|
|
24
24
|
usageLimit?: "account" | "model";
|
|
25
|
+
/** The account limit's reset as the caller knows it, used when the provider text names none. */
|
|
26
|
+
resetsAt?: string;
|
|
25
27
|
}): string | undefined;
|
|
26
28
|
/**
|
|
27
29
|
* The turn-ending message for a provider module that can no longer be imported because the
|
|
@@ -84,7 +84,7 @@ export function describeProviderFailureForUser(errorMessage, options = {}) {
|
|
|
84
84
|
const reset = /\bresets?\s+([^"}\n]+)/i
|
|
85
85
|
.exec(message)?.[1]
|
|
86
86
|
?.trim()
|
|
87
|
-
.replace(/[.;]+$/, "");
|
|
87
|
+
.replace(/[.;]+$/, "") ?? options.resetsAt;
|
|
88
88
|
return `The ${provider ? `${provider} ` : ""}account usage limit has been reached${reset ? ` (resets ${reset})` : ""}. Switch to another provider, or configure another provider in retry.fallbackChains.`;
|
|
89
89
|
}
|
|
90
90
|
const stall = describeProviderStallForUser(message, options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-ai",
|
|
3
|
-
"version": "2026.11.
|
|
3
|
+
"version": "2026.11.4-2",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"dependencies": {
|
|
89
89
|
"@anthropic-ai/sdk": "0.127.0",
|
|
90
90
|
"@aws-sdk/client-bedrock-runtime": "3.1136.0",
|
|
91
|
-
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.11.
|
|
91
|
+
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.11.4-2",
|
|
92
92
|
"@google/genai": "2.23.0",
|
|
93
93
|
"@smithy/node-http-handler": "4.12.1",
|
|
94
94
|
"google-auth-library": "10.6.2",
|