@code-yeongyu/senpi-ai 2026.9.21 → 2026.9.22-3
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/README.md +4 -4
- package/dist/api/azure-openai-responses.js +1 -1
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/openai-codex-responses/fallback-state.d.ts +3 -3
- package/dist/api/openai-codex-responses/fallback-state.d.ts.map +1 -1
- package/dist/api/openai-codex-responses/fallback-state.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts +5 -5
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +24 -66
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-prompt-cache.d.ts +1 -1
- package/dist/api/openai-prompt-cache.d.ts.map +1 -1
- package/dist/api/openai-prompt-cache.js +1 -1
- package/dist/api/openai-prompt-cache.js.map +1 -1
- package/dist/api/openai-responses-shared.js +1 -1
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +19 -28
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/websocket-transport-failure.d.ts +40 -0
- package/dist/api/websocket-transport-failure.d.ts.map +1 -0
- package/dist/api/websocket-transport-failure.js +102 -0
- package/dist/api/websocket-transport-failure.js.map +1 -0
- package/dist/auth/oauth/{openai-codex.d.ts → chatgpt-subscription.d.ts} +3 -3
- package/dist/auth/oauth/chatgpt-subscription.d.ts.map +1 -0
- package/dist/auth/oauth/{openai-codex.js → chatgpt-subscription.js} +35 -35
- package/dist/auth/oauth/chatgpt-subscription.js.map +1 -0
- package/dist/auth/oauth/kimi-coding.d.ts +4 -3
- package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/dist/auth/oauth/kimi-coding.js +28 -14
- package/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/dist/auth/oauth/kimi-region.d.ts +44 -0
- package/dist/auth/oauth/kimi-region.d.ts.map +1 -0
- package/dist/auth/oauth/kimi-region.js +120 -0
- package/dist/auth/oauth/kimi-region.js.map +1 -0
- package/dist/auth/oauth/load.d.ts +2 -2
- package/dist/auth/oauth/load.d.ts.map +1 -1
- package/dist/auth/oauth/load.js +4 -3
- package/dist/auth/oauth/load.js.map +1 -1
- package/dist/auth/pool/failover.d.ts +2 -2
- package/dist/auth/pool/failover.d.ts.map +1 -1
- package/dist/auth/pool/failover.js +2 -2
- package/dist/auth/pool/failover.js.map +1 -1
- package/dist/auth/pool/slots.d.ts +10 -0
- package/dist/auth/pool/slots.d.ts.map +1 -1
- package/dist/auth/pool/slots.js +41 -17
- package/dist/auth/pool/slots.js.map +1 -1
- package/dist/bun-oauth.js +2 -2
- package/dist/bun-oauth.js.map +1 -1
- package/dist/compat.d.ts +1 -0
- package/dist/compat.d.ts.map +1 -1
- package/dist/compat.js +1 -0
- package/dist/compat.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy-provider-ids.d.ts +28 -0
- package/dist/legacy-provider-ids.d.ts.map +1 -0
- package/dist/legacy-provider-ids.js +82 -0
- package/dist/legacy-provider-ids.js.map +1 -0
- package/dist/models.generated.d.ts +2 -2
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +2 -2
- package/dist/models.generated.js.map +1 -1
- package/dist/providers/all.d.ts.map +1 -1
- package/dist/providers/all.js +2 -2
- package/dist/providers/all.js.map +1 -1
- package/dist/providers/chatgpt-subscription.d.ts +3 -0
- package/dist/providers/chatgpt-subscription.d.ts.map +1 -0
- package/dist/providers/chatgpt-subscription.js +22 -0
- package/dist/providers/chatgpt-subscription.js.map +1 -0
- package/dist/providers/chatgpt-subscription.models.d.ts +4 -0
- package/dist/providers/chatgpt-subscription.models.d.ts.map +1 -0
- package/dist/providers/chatgpt-subscription.models.js +6 -0
- package/dist/providers/chatgpt-subscription.models.js.map +1 -0
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/anthropic.json +1 -1
- package/dist/providers/data/chatgpt-subscription.json +1 -0
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/venice.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.json +1 -1
- package/dist/providers/kimi-coding-auth.d.ts +9 -0
- package/dist/providers/kimi-coding-auth.d.ts.map +1 -0
- package/dist/providers/kimi-coding-auth.js +43 -0
- package/dist/providers/kimi-coding-auth.js.map +1 -0
- package/dist/providers/kimi-coding.d.ts.map +1 -1
- package/dist/providers/kimi-coding.js +3 -2
- package/dist/providers/kimi-coding.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/{openai-codex-auth.d.ts → chatgpt-subscription-auth.d.ts} +3 -3
- package/dist/utils/chatgpt-subscription-auth.d.ts.map +1 -0
- package/dist/utils/{openai-codex-auth.js → chatgpt-subscription-auth.js} +4 -4
- package/dist/utils/chatgpt-subscription-auth.js.map +1 -0
- package/dist/utils/provider-failure-description.d.ts +19 -0
- package/dist/utils/provider-failure-description.d.ts.map +1 -0
- package/dist/utils/provider-failure-description.js +63 -0
- package/dist/utils/provider-failure-description.js.map +1 -0
- package/dist/utils/retry-profile/classifiers.d.ts.map +1 -1
- package/dist/utils/retry-profile/classifiers.js +5 -1
- package/dist/utils/retry-profile/classifiers.js.map +1 -1
- package/dist/utils/retry.d.ts +17 -0
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +22 -1
- package/dist/utils/retry.js.map +1 -1
- package/package.json +3 -3
- package/dist/auth/oauth/openai-codex.d.ts.map +0 -1
- package/dist/auth/oauth/openai-codex.js.map +0 -1
- package/dist/providers/data/openai-codex.json +0 -1
- package/dist/providers/openai-codex.d.ts +0 -3
- package/dist/providers/openai-codex.d.ts.map +0 -1
- package/dist/providers/openai-codex.js +0 -22
- package/dist/providers/openai-codex.js.map +0 -1
- package/dist/providers/openai-codex.models.d.ts +0 -4
- package/dist/providers/openai-codex.models.d.ts.map +0 -1
- package/dist/providers/openai-codex.models.js +0 -6
- package/dist/providers/openai-codex.models.js.map +0 -1
- package/dist/utils/openai-codex-auth.d.ts.map +0 -1
- package/dist/utils/openai-codex-auth.js.map +0 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { getProviderEnvValue } from "../../utils/provider-env.js";
|
|
2
|
+
export const KIMI_CODE_REGION_ENV = "KIMI_CODE_REGION";
|
|
3
|
+
export const KIMI_CODE_OAUTH_HOST_ENV = "KIMI_CODE_OAUTH_HOST";
|
|
4
|
+
export const KIMI_OAUTH_HOST_ENV = "KIMI_OAUTH_HOST";
|
|
5
|
+
export const DEFAULT_KIMI_CODE_REGION = "mainland-cn";
|
|
6
|
+
export const KIMI_CODE_REGION_PROFILES = {
|
|
7
|
+
"mainland-cn": {
|
|
8
|
+
id: "mainland-cn",
|
|
9
|
+
label: "Mainland China (kimi.com)",
|
|
10
|
+
description: "Accounts created on kimi.com",
|
|
11
|
+
oauthHost: "https://auth.kimi.com",
|
|
12
|
+
apiBaseUrl: "https://api.kimi.com/coding",
|
|
13
|
+
},
|
|
14
|
+
global: {
|
|
15
|
+
id: "global",
|
|
16
|
+
label: "Outside mainland China (kimi.ai)",
|
|
17
|
+
description: "Accounts created on kimi.ai",
|
|
18
|
+
oauthHost: "https://auth.kimi.ai",
|
|
19
|
+
apiBaseUrl: "https://api.kimi.ai/coding",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export function isKimiCodeRegion(value) {
|
|
23
|
+
return value === "mainland-cn" || value === "global";
|
|
24
|
+
}
|
|
25
|
+
function normalizeHost(host) {
|
|
26
|
+
return host.trim().replace(/\/+$/, "");
|
|
27
|
+
}
|
|
28
|
+
export function kimiCodeRegionForOauthHost(host) {
|
|
29
|
+
const normalized = normalizeHost(host);
|
|
30
|
+
for (const profile of Object.values(KIMI_CODE_REGION_PROFILES)) {
|
|
31
|
+
if (profile.oauthHost === normalized)
|
|
32
|
+
return profile.id;
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
function endpointsForRegion(region) {
|
|
37
|
+
const profile = KIMI_CODE_REGION_PROFILES[region];
|
|
38
|
+
return {
|
|
39
|
+
region,
|
|
40
|
+
oauthHost: profile.oauthHost,
|
|
41
|
+
apiBaseUrl: region === DEFAULT_KIMI_CODE_REGION ? undefined : profile.apiBaseUrl,
|
|
42
|
+
env: { [KIMI_CODE_REGION_ENV]: region },
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function endpointsForHost(host) {
|
|
46
|
+
const region = kimiCodeRegionForOauthHost(host);
|
|
47
|
+
if (region !== undefined)
|
|
48
|
+
return endpointsForRegion(region);
|
|
49
|
+
return {
|
|
50
|
+
region: undefined,
|
|
51
|
+
oauthHost: normalizeHost(host),
|
|
52
|
+
apiBaseUrl: undefined,
|
|
53
|
+
env: { [KIMI_CODE_OAUTH_HOST_ENV]: normalizeHost(host) },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A credential's stored host or region owns its refresh and inference routing;
|
|
58
|
+
* the process env only decides for credentials that predate regions and for
|
|
59
|
+
* new logins.
|
|
60
|
+
*/
|
|
61
|
+
export function resolveKimiCodeEndpoints(input) {
|
|
62
|
+
if (typeof input.storedOauthHost === "string" && input.storedOauthHost.trim()) {
|
|
63
|
+
return endpointsForHost(input.storedOauthHost);
|
|
64
|
+
}
|
|
65
|
+
if (isKimiCodeRegion(input.storedRegion))
|
|
66
|
+
return endpointsForRegion(input.storedRegion);
|
|
67
|
+
if (input.envOauthHost?.trim())
|
|
68
|
+
return endpointsForHost(input.envOauthHost);
|
|
69
|
+
if (isKimiCodeRegion(input.envRegion))
|
|
70
|
+
return endpointsForRegion(input.envRegion);
|
|
71
|
+
return { ...endpointsForRegion(DEFAULT_KIMI_CODE_REGION), env: undefined };
|
|
72
|
+
}
|
|
73
|
+
export function kimiCodeCredentialEnv(credential) {
|
|
74
|
+
const value = credential.env;
|
|
75
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
76
|
+
return undefined;
|
|
77
|
+
const env = {};
|
|
78
|
+
for (const [name, entry] of Object.entries(value)) {
|
|
79
|
+
if (typeof entry === "string")
|
|
80
|
+
env[name] = entry;
|
|
81
|
+
}
|
|
82
|
+
return env;
|
|
83
|
+
}
|
|
84
|
+
export function kimiCodeEndpointsForCredential(credential) {
|
|
85
|
+
const env = kimiCodeCredentialEnv(credential);
|
|
86
|
+
return resolveKimiCodeEndpoints({
|
|
87
|
+
storedRegion: env?.[KIMI_CODE_REGION_ENV],
|
|
88
|
+
storedOauthHost: env?.[KIMI_CODE_OAUTH_HOST_ENV],
|
|
89
|
+
envOauthHost: getProviderEnvValue(KIMI_CODE_OAUTH_HOST_ENV) || getProviderEnvValue(KIMI_OAUTH_HOST_ENV),
|
|
90
|
+
envRegion: getProviderEnvValue(KIMI_CODE_REGION_ENV),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export function kimiCodeRegionPrompt() {
|
|
94
|
+
return {
|
|
95
|
+
type: "select",
|
|
96
|
+
message: "Which Kimi service hosts your account?",
|
|
97
|
+
options: Object.values(KIMI_CODE_REGION_PROFILES).map((profile) => ({
|
|
98
|
+
id: profile.id,
|
|
99
|
+
label: profile.label,
|
|
100
|
+
description: profile.description,
|
|
101
|
+
})),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** An explicit host or region in the env skips the prompt so headless logins keep working. */
|
|
105
|
+
export async function chooseKimiCodeLoginEndpoints(interaction) {
|
|
106
|
+
const fromEnv = resolveKimiCodeEndpoints({
|
|
107
|
+
envOauthHost: getProviderEnvValue(KIMI_CODE_OAUTH_HOST_ENV) || getProviderEnvValue(KIMI_OAUTH_HOST_ENV),
|
|
108
|
+
envRegion: getProviderEnvValue(KIMI_CODE_REGION_ENV),
|
|
109
|
+
});
|
|
110
|
+
if (fromEnv.env !== undefined)
|
|
111
|
+
return fromEnv;
|
|
112
|
+
interaction.signal.throwIfAborted();
|
|
113
|
+
const answer = await interaction.prompt(kimiCodeRegionPrompt());
|
|
114
|
+
interaction.signal.throwIfAborted();
|
|
115
|
+
if (!isKimiCodeRegion(answer)) {
|
|
116
|
+
throw new Error(`Unknown Kimi Code region: ${answer}`);
|
|
117
|
+
}
|
|
118
|
+
return endpointsForRegion(answer);
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=kimi-region.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kimi-region.js","sourceRoot":"","sources":["../../../src/auth/oauth/kimi-region.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProviderEnv } from \"../../types.ts\";\nimport { getProviderEnvValue } from \"../../utils/provider-env.ts\";\nimport type { AuthPrompt, ProviderAuthInteraction } from \"../types.ts\";\n\n/** Region ids match the official Kimi Code CLI's `kimi login --region` values. */\nexport type KimiCodeRegion = \"mainland-cn\" | \"global\";\n\nexport const KIMI_CODE_REGION_ENV = \"KIMI_CODE_REGION\";\nexport const KIMI_CODE_OAUTH_HOST_ENV = \"KIMI_CODE_OAUTH_HOST\";\nexport const KIMI_OAUTH_HOST_ENV = \"KIMI_OAUTH_HOST\";\nexport const DEFAULT_KIMI_CODE_REGION: KimiCodeRegion = \"mainland-cn\";\n\nexport interface KimiCodeRegionProfile {\n\treadonly id: KimiCodeRegion;\n\treadonly label: string;\n\treadonly description: string;\n\treadonly oauthHost: string;\n\treadonly apiBaseUrl: string;\n}\n\nexport const KIMI_CODE_REGION_PROFILES: Readonly<Record<KimiCodeRegion, KimiCodeRegionProfile>> = {\n\t\"mainland-cn\": {\n\t\tid: \"mainland-cn\",\n\t\tlabel: \"Mainland China (kimi.com)\",\n\t\tdescription: \"Accounts created on kimi.com\",\n\t\toauthHost: \"https://auth.kimi.com\",\n\t\tapiBaseUrl: \"https://api.kimi.com/coding\",\n\t},\n\tglobal: {\n\t\tid: \"global\",\n\t\tlabel: \"Outside mainland China (kimi.ai)\",\n\t\tdescription: \"Accounts created on kimi.ai\",\n\t\toauthHost: \"https://auth.kimi.ai\",\n\t\tapiBaseUrl: \"https://api.kimi.ai/coding\",\n\t},\n};\n\nexport interface KimiCodeEndpoints {\n\treadonly region: KimiCodeRegion | undefined;\n\treadonly oauthHost: string;\n\t/** Set only when the region moves inference off the provider's catalog base. */\n\treadonly apiBaseUrl: string | undefined;\n\t/** Credential metadata that makes refresh and inference follow this choice. */\n\treadonly env: ProviderEnv | undefined;\n}\n\nexport interface KimiCodeEndpointInput {\n\treadonly storedRegion?: unknown;\n\treadonly storedOauthHost?: unknown;\n\treadonly envOauthHost?: string | undefined;\n\treadonly envRegion?: string | undefined;\n}\n\nexport function isKimiCodeRegion(value: unknown): value is KimiCodeRegion {\n\treturn value === \"mainland-cn\" || value === \"global\";\n}\n\nfunction normalizeHost(host: string): string {\n\treturn host.trim().replace(/\\/+$/, \"\");\n}\n\nexport function kimiCodeRegionForOauthHost(host: string): KimiCodeRegion | undefined {\n\tconst normalized = normalizeHost(host);\n\tfor (const profile of Object.values(KIMI_CODE_REGION_PROFILES)) {\n\t\tif (profile.oauthHost === normalized) return profile.id;\n\t}\n\treturn undefined;\n}\n\nfunction endpointsForRegion(region: KimiCodeRegion): KimiCodeEndpoints {\n\tconst profile = KIMI_CODE_REGION_PROFILES[region];\n\treturn {\n\t\tregion,\n\t\toauthHost: profile.oauthHost,\n\t\tapiBaseUrl: region === DEFAULT_KIMI_CODE_REGION ? undefined : profile.apiBaseUrl,\n\t\tenv: { [KIMI_CODE_REGION_ENV]: region },\n\t};\n}\n\nfunction endpointsForHost(host: string): KimiCodeEndpoints {\n\tconst region = kimiCodeRegionForOauthHost(host);\n\tif (region !== undefined) return endpointsForRegion(region);\n\treturn {\n\t\tregion: undefined,\n\t\toauthHost: normalizeHost(host),\n\t\tapiBaseUrl: undefined,\n\t\tenv: { [KIMI_CODE_OAUTH_HOST_ENV]: normalizeHost(host) },\n\t};\n}\n\n/**\n * A credential's stored host or region owns its refresh and inference routing;\n * the process env only decides for credentials that predate regions and for\n * new logins.\n */\nexport function resolveKimiCodeEndpoints(input: KimiCodeEndpointInput): KimiCodeEndpoints {\n\tif (typeof input.storedOauthHost === \"string\" && input.storedOauthHost.trim()) {\n\t\treturn endpointsForHost(input.storedOauthHost);\n\t}\n\tif (isKimiCodeRegion(input.storedRegion)) return endpointsForRegion(input.storedRegion);\n\tif (input.envOauthHost?.trim()) return endpointsForHost(input.envOauthHost);\n\tif (isKimiCodeRegion(input.envRegion)) return endpointsForRegion(input.envRegion);\n\treturn { ...endpointsForRegion(DEFAULT_KIMI_CODE_REGION), env: undefined };\n}\n\nexport function kimiCodeCredentialEnv(credential: Readonly<Record<string, unknown>>): ProviderEnv | undefined {\n\tconst value = credential.env;\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n\tconst env: ProviderEnv = {};\n\tfor (const [name, entry] of Object.entries(value)) {\n\t\tif (typeof entry === \"string\") env[name] = entry;\n\t}\n\treturn env;\n}\n\nexport function kimiCodeEndpointsForCredential(credential: Readonly<Record<string, unknown>>): KimiCodeEndpoints {\n\tconst env = kimiCodeCredentialEnv(credential);\n\treturn resolveKimiCodeEndpoints({\n\t\tstoredRegion: env?.[KIMI_CODE_REGION_ENV],\n\t\tstoredOauthHost: env?.[KIMI_CODE_OAUTH_HOST_ENV],\n\t\tenvOauthHost: getProviderEnvValue(KIMI_CODE_OAUTH_HOST_ENV) || getProviderEnvValue(KIMI_OAUTH_HOST_ENV),\n\t\tenvRegion: getProviderEnvValue(KIMI_CODE_REGION_ENV),\n\t});\n}\n\nexport function kimiCodeRegionPrompt(): AuthPrompt {\n\treturn {\n\t\ttype: \"select\",\n\t\tmessage: \"Which Kimi service hosts your account?\",\n\t\toptions: Object.values(KIMI_CODE_REGION_PROFILES).map((profile) => ({\n\t\t\tid: profile.id,\n\t\t\tlabel: profile.label,\n\t\t\tdescription: profile.description,\n\t\t})),\n\t};\n}\n\n/** An explicit host or region in the env skips the prompt so headless logins keep working. */\nexport async function chooseKimiCodeLoginEndpoints(interaction: ProviderAuthInteraction): Promise<KimiCodeEndpoints> {\n\tconst fromEnv = resolveKimiCodeEndpoints({\n\t\tenvOauthHost: getProviderEnvValue(KIMI_CODE_OAUTH_HOST_ENV) || getProviderEnvValue(KIMI_OAUTH_HOST_ENV),\n\t\tenvRegion: getProviderEnvValue(KIMI_CODE_REGION_ENV),\n\t});\n\tif (fromEnv.env !== undefined) return fromEnv;\n\tinteraction.signal.throwIfAborted();\n\tconst answer = await interaction.prompt(kimiCodeRegionPrompt());\n\tinteraction.signal.throwIfAborted();\n\tif (!isKimiCodeRegion(answer)) {\n\t\tthrow new Error(`Unknown Kimi Code region: ${answer}`);\n\t}\n\treturn endpointsForRegion(answer);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { OAuthAuth } from "../types.ts";
|
|
2
2
|
type OAuthFlowLoaders = {
|
|
3
3
|
anthropic: () => OAuthAuth | Promise<OAuthAuth>;
|
|
4
|
-
|
|
4
|
+
chatgptSubscription: () => OAuthAuth | Promise<OAuthAuth>;
|
|
5
5
|
githubCopilot: () => OAuthAuth | Promise<OAuthAuth>;
|
|
6
6
|
openrouter: () => OAuthAuth | Promise<OAuthAuth>;
|
|
7
7
|
kimiCoding: () => OAuthAuth | Promise<OAuthAuth>;
|
|
@@ -16,7 +16,7 @@ type OAuthFlowLoaders = {
|
|
|
16
16
|
/** Registers statically bundled OAuth flows for standalone Bun binaries. */
|
|
17
17
|
export declare function registerBundledOAuthFlowLoaders(loaders: OAuthFlowLoaders): void;
|
|
18
18
|
export declare const loadAnthropicOAuth: () => Promise<OAuthAuth>;
|
|
19
|
-
export declare const
|
|
19
|
+
export declare const loadChatGptSubscriptionOAuth: () => Promise<OAuthAuth>;
|
|
20
20
|
export declare const loadGitHubCopilotOAuth: () => Promise<OAuthAuth>;
|
|
21
21
|
export declare const loadOpenRouterOAuth: () => Promise<OAuthAuth>;
|
|
22
22
|
export declare const loadKimiCodingOAuth: () => Promise<OAuthAuth>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAa7C,KAAK,gBAAgB,GAAG;IACvB,SAAS,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAChD,
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAa7C,KAAK,gBAAgB,GAAG;IACvB,SAAS,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAChD,mBAAmB,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1D,aAAa,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,UAAU,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,UAAU,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,GAAG,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7C,KAAK,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACvF,CAAC;AAIF,4EAA4E;AAC5E,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAE/E;AAED,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,SAAS,CAG5D,CAAC;AAEF,eAAO,MAAM,4BAA4B,QAAa,OAAO,CAAC,SAAS,CAItE,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,SAAS,CAGhE,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAa,OAAO,CAAC,SAAS,CAG7D,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAa,OAAO,CAAC,SAAS,CAG7D,CAAC;AAEF,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,SAAS,CAGtD,CAAC;AAEF,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,SAAS,CAGzD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,SAAS,CAGxD,CAAC;AAEF,eAAO,MAAM,eAAe,YAAmB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,OAAO,CAAC,SAAS,CAOnG,CAAC"}
|
package/dist/auth/oauth/load.js
CHANGED
|
@@ -26,10 +26,11 @@ export const loadAnthropicOAuth = async () => {
|
|
|
26
26
|
return bundledLoaders.anthropic();
|
|
27
27
|
return (await importOAuthModule("./anthropic.ts")).anthropicOAuth;
|
|
28
28
|
};
|
|
29
|
-
export const
|
|
29
|
+
export const loadChatGptSubscriptionOAuth = async () => {
|
|
30
30
|
if (bundledLoaders)
|
|
31
|
-
return bundledLoaders.
|
|
32
|
-
return (await importOAuthModule("./
|
|
31
|
+
return bundledLoaders.chatgptSubscription();
|
|
32
|
+
return (await importOAuthModule("./chatgpt-subscription.ts"))
|
|
33
|
+
.chatgptSubscriptionOAuth;
|
|
33
34
|
};
|
|
34
35
|
export const loadGitHubCopilotOAuth = async () => {
|
|
35
36
|
if (bundledLoaders)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/auth/oauth/load.ts"],"names":[],"mappings":";;;;;;;;AAEA;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,CAAC,SAAiB,EAAoB,EAAE;IACjE,MAAM,gBAAgB,GAAG,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzG,OAAO,MAAM,kCAAC,gBAAgB,EAAC,CAAC;AACjC,CAAC,CAAC;AAcF,IAAI,cAA4C,CAAC;AAEjD,4EAA4E;AAC5E,MAAM,UAAU,+BAA+B,CAAC,OAAyB;IACxE,cAAc,GAAG,OAAO,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAwB,EAAE;IAChE,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC,SAAS,EAAE,CAAC;IACtD,OAAQ,CAAC,MAAM,iBAAiB,CAAC,gBAAgB,CAAC,CAAmC,CAAC,cAAc,CAAC;AACtG,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/auth/oauth/load.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OAuthAuth } from \"../types.ts\";\n\n/**\n * Loads an OAuth flow module through a variable specifier so bundlers cannot\n * follow the import into Node-only flow code (`node:http` callback servers,\n * `node:crypto` PKCE). The `.ts`/`.js` rewrite keeps the trick working from\n * both source and built output.\n */\nconst importOAuthModule = (specifier: string): Promise<unknown> => {\n\tconst runtimeSpecifier = import.meta.url.endsWith(\".js\") ? specifier.replace(/\\.ts$/, \".js\") : specifier;\n\treturn import(runtimeSpecifier);\n};\n\ntype OAuthFlowLoaders = {\n\tanthropic: () => OAuthAuth | Promise<OAuthAuth>;\n\tchatgptSubscription: () => OAuthAuth | Promise<OAuthAuth>;\n\tgithubCopilot: () => OAuthAuth | Promise<OAuthAuth>;\n\topenrouter: () => OAuthAuth | Promise<OAuthAuth>;\n\tkimiCoding: () => OAuthAuth | Promise<OAuthAuth>;\n\txai: () => OAuthAuth | Promise<OAuthAuth>;\n\tcursor: () => OAuthAuth | Promise<OAuthAuth>;\n\tdevin: () => OAuthAuth | Promise<OAuthAuth>;\n\tradius: (options: { name: string; gateway: string }) => OAuthAuth | Promise<OAuthAuth>;\n};\n\nlet bundledLoaders: OAuthFlowLoaders | undefined;\n\n/** Registers statically bundled OAuth flows for standalone Bun binaries. */\nexport function registerBundledOAuthFlowLoaders(loaders: OAuthFlowLoaders): void {\n\tbundledLoaders = loaders;\n}\n\nexport const loadAnthropicOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.anthropic();\n\treturn ((await importOAuthModule(\"./anthropic.ts\")) as { anthropicOAuth: OAuthAuth }).anthropicOAuth;\n};\n\nexport const loadChatGptSubscriptionOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.chatgptSubscription();\n\treturn ((await importOAuthModule(\"./chatgpt-subscription.ts\")) as { chatgptSubscriptionOAuth: OAuthAuth })\n\t\t.chatgptSubscriptionOAuth;\n};\n\nexport const loadGitHubCopilotOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.githubCopilot();\n\treturn ((await importOAuthModule(\"./github-copilot.ts\")) as { githubCopilotOAuth: OAuthAuth }).githubCopilotOAuth;\n};\n\nexport const loadOpenRouterOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.openrouter();\n\treturn ((await importOAuthModule(\"./openrouter.ts\")) as { openRouterOAuth: OAuthAuth }).openRouterOAuth;\n};\n\nexport const loadKimiCodingOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.kimiCoding();\n\treturn ((await importOAuthModule(\"./kimi-coding.ts\")) as { kimiCodingOAuth: OAuthAuth }).kimiCodingOAuth;\n};\n\nexport const loadXaiOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.xai();\n\treturn ((await importOAuthModule(\"./xai.ts\")) as { xaiOAuth: OAuthAuth }).xaiOAuth;\n};\n\nexport const loadCursorOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.cursor();\n\treturn ((await importOAuthModule(\"./cursor.ts\")) as { cursorOAuth: OAuthAuth }).cursorOAuth;\n};\n\nexport const loadDevinOAuth = async (): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.devin();\n\treturn ((await importOAuthModule(\"./devin.ts\")) as { devinOAuth: OAuthAuth }).devinOAuth;\n};\n\nexport const loadRadiusOAuth = async (options: { name: string; gateway: string }): Promise<OAuthAuth> => {\n\tif (bundledLoaders) return bundledLoaders.radius(options);\n\treturn (\n\t\t(await importOAuthModule(\"./radius.ts\")) as {\n\t\t\tcreateRadiusOAuth: (input: { name: string; gateway: string }) => OAuthAuth;\n\t\t}\n\t).createRadiusOAuth(options);\n};\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { TURN_RETRY_SUPPRESSION_PREFIX } from "../../utils/provider-failure-description.ts";
|
|
1
2
|
import { type PoolFailureClassification } from "./classify.ts";
|
|
2
3
|
import type { SelectableSlot } from "./select.ts";
|
|
3
|
-
|
|
4
|
-
export declare const TURN_RETRY_SUPPRESSION_PREFIX = "senpi:no-turn-retry:";
|
|
4
|
+
export { TURN_RETRY_SUPPRESSION_PREFIX };
|
|
5
5
|
export declare const DEFAULT_SLOT_BLOCK_MS = 60000;
|
|
6
6
|
export declare const MAX_SLOT_BLOCK_MS: number;
|
|
7
7
|
export type PoolFailoverEvent<TSlot extends SelectableSlot> = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failover.d.ts","sourceRoot":"","sources":["../../../src/auth/pool/failover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,
|
|
1
|
+
{"version":3,"file":"failover.d.ts","sourceRoot":"","sources":["../../../src/auth/pool/failover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAC5F,OAAO,EAAuB,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,6BAA6B,EAAE,CAAC;AACzC,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,eAAO,MAAM,iBAAiB,QAAuB,CAAC;AAEtD,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,cAAc,IAAI;IAC7D,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,cAAc,EAAE,yBAAyB,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,MAAM,EAAE,KAAK,SAAS,cAAc,IAAI;IACvE,KAAK,EAAE,SAAS,KAAK,EAAE,CAAC;IACxB,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,KAAK,KAAK,CAAC;IAC3C,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IACpF,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,yBAAyB,CAAC;IACzD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,cAAc,EAAE,yBAAyB,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IAEpC,YAAY,cAAc,EAAE,yBAAyB,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAOnG;CACD;AAoBD;;;;;;GAMG;AACH,wBAAuB,eAAe,CAAC,MAAM,EAAE,KAAK,SAAS,cAAc,EAC1E,OAAO,EAAE,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,GACzC,cAAc,CAAC,MAAM,CAAC,CA4CxB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { TURN_RETRY_SUPPRESSION_PREFIX } from "../../utils/provider-failure-description.js";
|
|
1
2
|
import { classifyPoolFailure } from "./classify.js";
|
|
2
|
-
|
|
3
|
-
export const TURN_RETRY_SUPPRESSION_PREFIX = "senpi:no-turn-retry:";
|
|
3
|
+
export { TURN_RETRY_SUPPRESSION_PREFIX };
|
|
4
4
|
export const DEFAULT_SLOT_BLOCK_MS = 60_000;
|
|
5
5
|
export const MAX_SLOT_BLOCK_MS = 48 * 60 * 60 * 1_000;
|
|
6
6
|
export class PoolFailoverError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failover.js","sourceRoot":"","sources":["../../../src/auth/pool/failover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAkC,MAAM,eAAe,CAAC;AAGpF,
|
|
1
|
+
{"version":3,"file":"failover.js","sourceRoot":"","sources":["../../../src/auth/pool/failover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAkC,MAAM,eAAe,CAAC;AAGpF,OAAO,EAAE,6BAA6B,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AA4BtD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAK3C,YAAY,cAAyC,EAAE,QAAiB,EAAE,iBAA0B;QACnG,MAAM,MAAM,GAAG,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/E,KAAK,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC5C,CAAC;CACD;AAED,SAAS,WAAW,CACnB,IAAW,EACX,cAAyC,EACzC,GAAW,EACX,OAAe,EACf,WAAmB;IAEnB,IAAI,cAAc,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;QACjD,kEAAkE;QAClE,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC,YAAY,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAC,YAAY,IAAI,QAAQ,CAAC,CAAC;IACtF,OAAO,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,GAAG,GAAG,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAC7E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,eAAe,CACrC,OAA2C;IAE3C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,mBAAmB,CAAC;IACzD,MAAM,SAAS,GAAG,OAAO,CAAC,iBAAiB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,qBAAqB,CAAC;IACjE,IAAI,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,SAAwC,CAAC;IAE7C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;QACjE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACrD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;gBACzC,eAAe,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC;gBACrC,MAAM,KAAK,CAAC;YACb,CAAC;YACD,OAAO;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,cAAc,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;YAC9E,SAAS,GAAG,OAAO,CAAC;YACpB,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ;gBAAE,MAAM,OAAO,CAAC;YAEtD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YAC/E,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YAC1F,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;YACtC,MAAM,QAAQ,GAA6B;gBAC1C,IAAI,EAAE,OAAO;gBACb,cAAc;gBACd,OAAO,EAAE,OAAO,GAAG,CAAC;gBACpB,eAAe;aACf,CAAC;YACF,IAAI,CAAC;gBACJ,IAAI,CAAC,eAAe,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;oBACpD,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3C,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;YACpC,CAAC;YACD,IAAI,eAAe;gBAAE,MAAM,OAAO,CAAC;QACpC,CAAC;IACF,CAAC;IACD,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;AACvF,CAAC","sourcesContent":["import { TURN_RETRY_SUPPRESSION_PREFIX } from \"../../utils/provider-failure-description.ts\";\nimport { classifyPoolFailure, type PoolFailureClassification } from \"./classify.ts\";\nimport type { SelectableSlot } from \"./select.ts\";\n\nexport { TURN_RETRY_SUPPRESSION_PREFIX };\nexport const DEFAULT_SLOT_BLOCK_MS = 60_000;\nexport const MAX_SLOT_BLOCK_MS = 48 * 60 * 60 * 1_000;\n\nexport type PoolFailoverEvent<TSlot extends SelectableSlot> = {\n\tslot: TSlot;\n\tnextSlot?: TSlot;\n\tclassification: PoolFailureClassification;\n\tattempt: number;\n\tcommittedOutput: boolean;\n};\n\nexport type PoolFailoverOptions<TEvent, TSlot extends SelectableSlot> = {\n\tslots: readonly TSlot[];\n\tselect: (slots: readonly TSlot[]) => TSlot;\n\trunAttempt: (slot: TSlot) => AsyncIterable<TEvent> | Promise<AsyncIterable<TEvent>>;\n\tclassify?: (error: unknown) => PoolFailureClassification;\n\t/**\n\t * Rotation is transparent only before committed output. Absent, every yielded\n\t * event counts as committed (default-DENY), so silent mid-stream rotation\n\t * requires an explicit opt-in from a caller that knows which events are\n\t * bookkeeping rather than user-visible output.\n\t */\n\tisCommittedOutput?: (event: TEvent) => boolean;\n\tpersistBlock?: (slot: TSlot) => void | Promise<void>;\n\tonRotate?: (event: PoolFailoverEvent<TSlot>) => void | Promise<void>;\n\tnow?: () => number;\n\tbaseBlockMs?: number;\n};\n\nexport class PoolFailoverError extends Error {\n\treadonly classification: PoolFailureClassification;\n\treadonly original: unknown;\n\treadonly suppressTurnRetry: boolean;\n\n\tconstructor(classification: PoolFailureClassification, original: unknown, suppressTurnRetry: boolean) {\n\t\tconst detail = original instanceof Error ? original.message : String(original);\n\t\tsuper(`${suppressTurnRetry ? TURN_RETRY_SUPPRESSION_PREFIX : \"\"}${detail}`);\n\t\tthis.name = \"PoolFailoverError\";\n\t\tthis.classification = classification;\n\t\tthis.original = original;\n\t\tthis.suppressTurnRetry = suppressTurnRetry;\n\t}\n}\n\nfunction blockedSlot<TSlot extends SelectableSlot>(\n\tslot: TSlot,\n\tclassification: PoolFailureClassification,\n\tnow: number,\n\tattempt: number,\n\tbaseBlockMs: number,\n): TSlot {\n\tif (classification.blockReason === \"auth_error\") {\n\t\t// An auth block has no expiry: only a re-login rewrites the slot.\n\t\tconst next = { ...slot, blockReason: \"auth_error\" };\n\t\tdelete next.blockedUntil;\n\t\treturn next;\n\t}\n\tconst fallback = Math.min(MAX_SLOT_BLOCK_MS, baseBlockMs * 2 ** attempt);\n\tconst duration = Math.min(MAX_SLOT_BLOCK_MS, classification.retryAfterMs ?? fallback);\n\treturn { ...slot, blockedUntil: now + duration, blockReason: \"rate_limit\" };\n}\n\n/**\n * Runs at most one attempt per slot. A rotation is transparent only while no\n * committed output has reached the caller; afterwards the classified error is\n * thrown with the turn-retry suppression marker so the session layer never\n * replays a partially delivered turn. Non-rotate classes throw immediately and\n * compose with the retry/model-fallback machinery above this engine.\n */\nexport async function* runSlotFailover<TEvent, TSlot extends SelectableSlot>(\n\toptions: PoolFailoverOptions<TEvent, TSlot>,\n): AsyncGenerator<TEvent> {\n\tconst now = options.now ?? Date.now;\n\tconst classify = options.classify ?? classifyPoolFailure;\n\tconst committed = options.isCommittedOutput ?? (() => true);\n\tconst baseBlockMs = options.baseBlockMs ?? DEFAULT_SLOT_BLOCK_MS;\n\tlet slots = [...options.slots];\n\tlet lastError: PoolFailoverError | undefined;\n\n\tfor (let attempt = 0; attempt < options.slots.length; attempt++) {\n\t\tconst slot = options.select(slots);\n\t\tlet committedOutput = false;\n\t\ttry {\n\t\t\tconst attemptStream = await options.runAttempt(slot);\n\t\t\tfor await (const event of attemptStream) {\n\t\t\t\tcommittedOutput ||= committed(event);\n\t\t\t\tyield event;\n\t\t\t}\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tconst classification = classify(error);\n\t\t\tconst failure = new PoolFailoverError(classification, error, committedOutput);\n\t\t\tlastError = failure;\n\t\t\tif (classification.action !== \"rotate\") throw failure;\n\n\t\t\tconst blocked = blockedSlot(slot, classification, now(), attempt, baseBlockMs);\n\t\t\tslots = slots.map((candidate) => (candidate.name === blocked.name ? blocked : candidate));\n\t\t\tawait options.persistBlock?.(blocked);\n\t\t\tconst rotation: PoolFailoverEvent<TSlot> = {\n\t\t\t\tslot: blocked,\n\t\t\t\tclassification,\n\t\t\t\tattempt: attempt + 1,\n\t\t\t\tcommittedOutput,\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tif (!committedOutput && attempt + 1 < slots.length) {\n\t\t\t\t\trotation.nextSlot = options.select(slots);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait options.onRotate?.(rotation);\n\t\t\t}\n\t\t\tif (committedOutput) throw failure;\n\t\t}\n\t}\n\tthrow lastError ?? new Error(\"Credential pool failover exhausted without an attempt\");\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProviderEnv } from "../../types.ts";
|
|
1
2
|
import type { Credential } from "../types.ts";
|
|
2
3
|
export type { Credential };
|
|
3
4
|
export declare const DEFAULT_SLOT_NAME = "default";
|
|
@@ -12,6 +13,8 @@ export type CredentialSlot = {
|
|
|
12
13
|
access?: string;
|
|
13
14
|
refresh?: string;
|
|
14
15
|
expires?: number;
|
|
16
|
+
/** Provider-scoped values this account carries (a Kimi region, a Cloudflare account id). */
|
|
17
|
+
env?: ProviderEnv;
|
|
15
18
|
};
|
|
16
19
|
export type PooledCredential = Credential & {
|
|
17
20
|
accounts?: CredentialSlot[];
|
|
@@ -91,6 +94,13 @@ export declare function appendLoginSlot(current: PooledCredential | undefined, f
|
|
|
91
94
|
* `<providerId>-managed` in both OAuth fields. It is a marker, never a token.
|
|
92
95
|
*/
|
|
93
96
|
export declare function managedSentinelMaterial(providerId: string): string;
|
|
97
|
+
/**
|
|
98
|
+
* Every sentinel material a stored credential may legitimately carry for this
|
|
99
|
+
* provider: the canonical `<providerId>-managed` plus the legacy material of
|
|
100
|
+
* any renamed ancestor id, because credentials written before a rename keep
|
|
101
|
+
* the old literal verbatim.
|
|
102
|
+
*/
|
|
103
|
+
export declare function managedSentinelMaterials(providerId: string): string[];
|
|
94
104
|
/**
|
|
95
105
|
* A POOL SLOT carrying that marker can never authenticate: `projectSlot` hands
|
|
96
106
|
* it to the provider's `check`, which rejects it, and the request dies with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/auth/pool/slots.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/auth/pool/slots.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/pool/slots.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LEGACY_PROVIDER_IDS } from "../../legacy-provider-ids.js";
|
|
1
2
|
export const DEFAULT_SLOT_NAME = "default";
|
|
2
3
|
const SLOT_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
|
|
3
4
|
export function assertValidSlotName(name) {
|
|
@@ -119,17 +120,20 @@ export function renameSlotDisplayName(credential, name, value) {
|
|
|
119
120
|
function storedSlots(credential) {
|
|
120
121
|
return Array.isArray(credential.accounts) ? credential.accounts : [];
|
|
121
122
|
}
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
function credentialSlotEnv(credential) {
|
|
124
|
+
const value = credential.env;
|
|
125
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
126
|
+
return {};
|
|
127
|
+
const env = {};
|
|
128
|
+
for (const [name, entry] of Object.entries(value)) {
|
|
129
|
+
if (typeof entry !== "string")
|
|
130
|
+
return {};
|
|
131
|
+
env[name] = entry;
|
|
131
132
|
}
|
|
132
|
-
return {
|
|
133
|
+
return { env };
|
|
134
|
+
}
|
|
135
|
+
function slotFromFlatCredential(credential) {
|
|
136
|
+
return slotFromFlatCredentialNamed(credential, DEFAULT_SLOT_NAME);
|
|
133
137
|
}
|
|
134
138
|
/**
|
|
135
139
|
* A flat credential written by a build predating pools is read as a one-slot pool
|
|
@@ -170,12 +174,13 @@ function slotMirrorsFlat(credential, slot) {
|
|
|
170
174
|
}
|
|
171
175
|
/** Rewrites the flat top-level projection to carry the given slot's material. */
|
|
172
176
|
function projectFlatFields(credential, slot) {
|
|
177
|
+
const env = slot.env === undefined ? {} : { env: slot.env };
|
|
173
178
|
if (credential.type === "oauth") {
|
|
174
179
|
if (slot.access === undefined || slot.refresh === undefined || slot.expires === undefined)
|
|
175
180
|
return credential;
|
|
176
|
-
return { ...credential, access: slot.access, refresh: slot.refresh, expires: slot.expires };
|
|
181
|
+
return { ...credential, access: slot.access, refresh: slot.refresh, expires: slot.expires, ...env };
|
|
177
182
|
}
|
|
178
|
-
return { ...credential, key: slot.key };
|
|
183
|
+
return { ...credential, key: slot.key, ...env };
|
|
179
184
|
}
|
|
180
185
|
/**
|
|
181
186
|
* Removes one slot. The credential is dropped entirely once its last slot is gone,
|
|
@@ -219,12 +224,13 @@ export function projectSlot(credential, name) {
|
|
|
219
224
|
if (!slot)
|
|
220
225
|
return undefined;
|
|
221
226
|
const { accounts: _accounts, pinned: _pinned, ...flat } = credential;
|
|
227
|
+
const env = slot.env === undefined ? {} : { env: slot.env };
|
|
222
228
|
if (flat.type === "oauth") {
|
|
223
229
|
if (slot.access === undefined || slot.refresh === undefined || slot.expires === undefined)
|
|
224
230
|
return undefined;
|
|
225
|
-
return { ...flat, access: slot.access, refresh: slot.refresh, expires: slot.expires };
|
|
231
|
+
return { ...flat, access: slot.access, refresh: slot.refresh, expires: slot.expires, ...env };
|
|
226
232
|
}
|
|
227
|
-
return { ...flat, key: slot.key };
|
|
233
|
+
return { ...flat, key: slot.key, ...env };
|
|
228
234
|
}
|
|
229
235
|
function slotFromFlatCredentialNamed(credential, name) {
|
|
230
236
|
if (credential.type === "oauth") {
|
|
@@ -234,9 +240,10 @@ function slotFromFlatCredentialNamed(credential, name) {
|
|
|
234
240
|
access: credential.access,
|
|
235
241
|
refresh: credential.refresh,
|
|
236
242
|
expires: credential.expires,
|
|
243
|
+
...credentialSlotEnv(credential),
|
|
237
244
|
};
|
|
238
245
|
}
|
|
239
|
-
return { name, source: "login", key: credential.key };
|
|
246
|
+
return { name, source: "login", key: credential.key, ...credentialSlotEnv(credential) };
|
|
240
247
|
}
|
|
241
248
|
function nextLoginSlotName(credential) {
|
|
242
249
|
const taken = new Set(listSlots(credential).map((slot) => slot.name));
|
|
@@ -316,6 +323,23 @@ export function appendLoginSlot(current, flat, onAllocated) {
|
|
|
316
323
|
export function managedSentinelMaterial(providerId) {
|
|
317
324
|
return `${providerId}-managed`;
|
|
318
325
|
}
|
|
326
|
+
const LEGACY_SENTINEL_MATERIALS = new Map(Object.entries(LEGACY_PROVIDER_IDS).map(([legacyId, canonicalId]) => [
|
|
327
|
+
canonicalId,
|
|
328
|
+
managedSentinelMaterial(legacyId),
|
|
329
|
+
]));
|
|
330
|
+
/**
|
|
331
|
+
* Every sentinel material a stored credential may legitimately carry for this
|
|
332
|
+
* provider: the canonical `<providerId>-managed` plus the legacy material of
|
|
333
|
+
* any renamed ancestor id, because credentials written before a rename keep
|
|
334
|
+
* the old literal verbatim.
|
|
335
|
+
*/
|
|
336
|
+
export function managedSentinelMaterials(providerId) {
|
|
337
|
+
const materials = [managedSentinelMaterial(providerId)];
|
|
338
|
+
const legacy = LEGACY_SENTINEL_MATERIALS.get(providerId);
|
|
339
|
+
if (legacy !== undefined && !materials.includes(legacy))
|
|
340
|
+
materials.push(legacy);
|
|
341
|
+
return materials;
|
|
342
|
+
}
|
|
319
343
|
/**
|
|
320
344
|
* A POOL SLOT carrying that marker can never authenticate: `projectSlot` hands
|
|
321
345
|
* it to the provider's `check`, which rejects it, and the request dies with
|
|
@@ -324,8 +348,8 @@ export function managedSentinelMaterial(providerId) {
|
|
|
324
348
|
* slot.
|
|
325
349
|
*/
|
|
326
350
|
export function isManagedSentinelSlot(providerId, slot) {
|
|
327
|
-
const
|
|
328
|
-
return slot.access
|
|
351
|
+
const materials = managedSentinelMaterials(providerId);
|
|
352
|
+
return materials.includes(slot.access ?? "") && slot.refresh === slot.access;
|
|
329
353
|
}
|
|
330
354
|
/**
|
|
331
355
|
* Drops those poisoned slots from a stored credential, clearing a pin that
|