mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
refactor(open-sse): D1a/D1b — URL quirks → schema urlSuffix + clean debug logs
buildUrl: switch provider-name → config-driven. ?beta=true thành
urlSuffix per registry (claude/glm/kimi/minimax/minimax-cn/kimi-coding);
gemini path dùng format==="gemini"; accountId substitution giữ generic.
Xóa console.log('[DEBUG]') trong refreshCline.
Golden url-header 142 pass (byte-for-byte URL).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -55,17 +55,14 @@ export class DefaultExecutor extends BaseExecutor {
|
|||||||
const normalized = baseUrl.replace(/\/$/, "");
|
const normalized = baseUrl.replace(/\/$/, "");
|
||||||
return `${normalized}/messages`;
|
return `${normalized}/messages`;
|
||||||
}
|
}
|
||||||
switch (this.provider) {
|
// gemini-format: build :streamGenerateContent / :generateContent path
|
||||||
case "claude":
|
if (this.config.format === "gemini") {
|
||||||
case "glm":
|
|
||||||
case "kimi":
|
|
||||||
case "minimax":
|
|
||||||
case "minimax-cn":
|
|
||||||
case "kimi-coding":
|
|
||||||
return `${this.config.baseUrl}?beta=true`;
|
|
||||||
case "gemini":
|
|
||||||
return `${this.config.baseUrl}/${model}:${stream ? "streamGenerateContent?alt=sse" : "generateContent"}`;
|
return `${this.config.baseUrl}/${model}:${stream ? "streamGenerateContent?alt=sse" : "generateContent"}`;
|
||||||
default: {
|
}
|
||||||
|
// urlSuffix (e.g. ?beta=true) declared per-provider in registry
|
||||||
|
if (this.config.urlSuffix) {
|
||||||
|
return `${this.config.baseUrl}${this.config.urlSuffix}`;
|
||||||
|
}
|
||||||
const url = this.config.baseUrl;
|
const url = this.config.baseUrl;
|
||||||
if (url?.includes("{accountId}")) {
|
if (url?.includes("{accountId}")) {
|
||||||
const accountId = credentials?.providerSpecificData?.accountId;
|
const accountId = credentials?.providerSpecificData?.accountId;
|
||||||
@@ -74,8 +71,6 @@ export class DefaultExecutor extends BaseExecutor {
|
|||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildHeaders(credentials, stream = true) {
|
buildHeaders(credentials, stream = true) {
|
||||||
const headers = { "Content-Type": "application/json", ...this.config.headers };
|
const headers = { "Content-Type": "application/json", ...this.config.headers };
|
||||||
@@ -280,24 +275,16 @@ export class DefaultExecutor extends BaseExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async refreshCline(refreshToken, proxyOptions = null) {
|
async refreshCline(refreshToken, proxyOptions = null) {
|
||||||
console.log('[DEBUG] Refreshing Cline token, refreshToken length:', refreshToken?.length);
|
|
||||||
const response = await proxyAwareFetch(PROVIDERS.cline.refreshUrl, {
|
const response = await proxyAwareFetch(PROVIDERS.cline.refreshUrl, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json", "Accept": "application/json" },
|
headers: { "Content-Type": "application/json", "Accept": "application/json" },
|
||||||
body: JSON.stringify({ refreshToken, grantType: "refresh_token", clientType: "extension" })
|
body: JSON.stringify({ refreshToken, grantType: "refresh_token", clientType: "extension" })
|
||||||
}, proxyOptions);
|
}, proxyOptions);
|
||||||
console.log('[DEBUG] Cline refresh response status:', response.status);
|
if (!response.ok) return null;
|
||||||
if (!response.ok) {
|
|
||||||
const errorText = await response.text();
|
|
||||||
console.log('[DEBUG] Cline refresh error:', errorText);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const payload = await response.json();
|
const payload = await response.json();
|
||||||
console.log('[DEBUG] Cline refresh payload:', JSON.stringify(payload).substring(0, 200));
|
|
||||||
const data = payload?.data || payload;
|
const data = payload?.data || payload;
|
||||||
const expiresAtIso = data?.expiresAt;
|
const expiresAtIso = data?.expiresAt;
|
||||||
const expiresIn = expiresAtIso ? Math.max(1, Math.floor((new Date(expiresAtIso).getTime() - Date.now()) / 1000)) : undefined;
|
const expiresIn = expiresAtIso ? Math.max(1, Math.floor((new Date(expiresAtIso).getTime() - Date.now()) / 1000)) : undefined;
|
||||||
console.log('[DEBUG] Cline refresh success, expiresIn:', expiresIn);
|
|
||||||
return { accessToken: data?.accessToken, refreshToken: data?.refreshToken || refreshToken, expiresIn };
|
return { accessToken: data?.accessToken, refreshToken: data?.refreshToken || refreshToken, expiresIn };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: "https://api.anthropic.com/v1/messages",
|
baseUrl: "https://api.anthropic.com/v1/messages",
|
||||||
format: "claude",
|
format: "claude",
|
||||||
|
urlSuffix: "?beta=true",
|
||||||
headers: { ...CLAUDE_CLI_SPOOF_HEADERS },
|
headers: { ...CLAUDE_CLI_SPOOF_HEADERS },
|
||||||
clientId: "9d1c250a-e61b-44d9-88ed-5944d1962f5e",
|
clientId: "9d1c250a-e61b-44d9-88ed-5944d1962f5e",
|
||||||
tokenUrl: "https://api.anthropic.com/v1/oauth/token"
|
tokenUrl: "https://api.anthropic.com/v1/oauth/token"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: "https://api.z.ai/api/anthropic/v1/messages",
|
baseUrl: "https://api.z.ai/api/anthropic/v1/messages",
|
||||||
format: "claude",
|
format: "claude",
|
||||||
|
urlSuffix: "?beta=true",
|
||||||
headers: { ...CLAUDE_API_HEADERS }
|
headers: { ...CLAUDE_API_HEADERS }
|
||||||
},
|
},
|
||||||
models: [
|
models: [
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: KIMI_CODING_BASE_URL,
|
baseUrl: KIMI_CODING_BASE_URL,
|
||||||
format: "claude",
|
format: "claude",
|
||||||
|
urlSuffix: "?beta=true",
|
||||||
headers: { ...CLAUDE_API_HEADERS },
|
headers: { ...CLAUDE_API_HEADERS },
|
||||||
clientId: "17e5f671-d194-4dfb-9706-5516cb48c098",
|
clientId: "17e5f671-d194-4dfb-9706-5516cb48c098",
|
||||||
tokenUrl: "https://auth.kimi.com/api/oauth/token",
|
tokenUrl: "https://auth.kimi.com/api/oauth/token",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: KIMI_CODING_BASE_URL,
|
baseUrl: KIMI_CODING_BASE_URL,
|
||||||
format: "claude",
|
format: "claude",
|
||||||
|
urlSuffix: "?beta=true",
|
||||||
headers: { ...CLAUDE_API_HEADERS }
|
headers: { ...CLAUDE_API_HEADERS }
|
||||||
},
|
},
|
||||||
models: [
|
models: [
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: "https://api.minimaxi.com/anthropic/v1/messages",
|
baseUrl: "https://api.minimaxi.com/anthropic/v1/messages",
|
||||||
format: "claude",
|
format: "claude",
|
||||||
|
urlSuffix: "?beta=true",
|
||||||
headers: { ...CLAUDE_API_HEADERS }
|
headers: { ...CLAUDE_API_HEADERS }
|
||||||
},
|
},
|
||||||
models: [
|
models: [
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: "https://api.minimax.io/anthropic/v1/messages",
|
baseUrl: "https://api.minimax.io/anthropic/v1/messages",
|
||||||
format: "claude",
|
format: "claude",
|
||||||
|
urlSuffix: "?beta=true",
|
||||||
headers: { ...CLAUDE_API_HEADERS }
|
headers: { ...CLAUDE_API_HEADERS }
|
||||||
},
|
},
|
||||||
models: [
|
models: [
|
||||||
|
|||||||
Reference in New Issue
Block a user