merge(master): sync master into dev

This commit is contained in:
2026-08-04 17:58:24 +07:00
174 changed files with 14405 additions and 3136 deletions
+52 -3
View File
@@ -93,7 +93,30 @@
"polly": "aws-polly",
"aws-polly": "aws-polly",
"bb": "blackbox",
"blackbox": "blackbox"
"blackbox": "blackbox",
"af": "api-airforce",
"airforce": "api-airforce",
"api-airforce": "api-airforce",
"llm7": "llm7",
"llm-7": "llm7",
"samba": "sambanova",
"sambanova": "sambanova",
"bm": "bluesminds",
"bluesminds": "bluesminds",
"bzl": "bazaarlink",
"bazaarlink": "bazaarlink",
"kgw": "kilo-gateway",
"kilo-gateway": "kilo-gateway",
"hunyuan": "tencent",
"tencent": "tencent",
"qianfan": "baidu",
"baidu": "baidu",
"ernie": "baidu",
"dv": "dv",
"devin": "devin",
"devin-cli": "devin-cli",
"morph": "morph",
"morphllm": "morph"
},
"idToAlias": {
"alicode": "alicode",
@@ -101,9 +124,13 @@
"alims-intl": "alims-intl",
"anthropic": "anthropic",
"antigravity": "ag",
"api-airforce": "af",
"assemblyai": "assemblyai",
"azure": "azure",
"baidu": "qianfan",
"bazaarlink": "bzl",
"blackbox": "blackbox",
"bluesminds": "bm",
"byteplus": "byteplus",
"cerebras": "cerebras",
"chutes": "chutes",
@@ -112,6 +139,7 @@
"clinepass": "clinepass",
"cloudflare-ai": "cloudflare-ai",
"codebuddy-cn": "cbcn",
"codebuddy-intl": "cbai",
"codex": "cx",
"cohere": "cohere",
"commandcode": "commandcode",
@@ -131,15 +159,18 @@
"groq": "groq",
"hyperbolic": "hyperbolic",
"iflow": "if",
"kilo-gateway": "kgw",
"kilocode": "kc",
"kimchi": "kimchi",
"kimi": "kimi",
"kiro": "kr",
"llm7": "llm7",
"mimo-free": "mmf",
"minimax": "minimax",
"minimax-cn": "minimax-cn",
"mistral": "mistral",
"mmf": "mmf",
"morph": "morph",
"nanobanana": "nanobanana",
"nebius": "nebius",
"nvidia": "nvidia",
@@ -149,12 +180,16 @@
"opencode": "oc",
"opencode-go": "opencode-go",
"openrouter": "openrouter",
"orbit-provider": "orbit",
"perplexity": "perplexity",
"perplexity-agent": "perplexity-agent",
"perplexity-web": "perplexity-web",
"poolside": "poolside",
"qoder": "qd",
"qwen": "qw",
"sambanova": "samba",
"siliconflow": "siliconflow",
"tencent": "hunyuan",
"together": "together",
"venice": "venice",
"vercel-ai-gateway": "vercel-ai-gateway",
@@ -163,9 +198,11 @@
"volcengine-ark": "volcengine-ark",
"xai": "xai",
"xiaomi-mimo": "xiaomi-mimo",
"xiaomi-tokenplan": "xiaomi-tokenplan"
"xiaomi-tokenplan": "xiaomi-tokenplan",
"zed": "zd"
},
"modelKeys": [
"af",
"ag",
"alicode",
"alicode-intl",
@@ -174,7 +211,10 @@
"assemblyai",
"black-forest-labs",
"blackbox",
"bm",
"byteplus",
"bzl",
"cbai",
"cbcn",
"cc",
"cerebras",
@@ -205,17 +245,21 @@
"grok-web",
"groq",
"huggingface",
"hunyuan",
"hyperbolic",
"if",
"kc",
"kgw",
"kimchi",
"kimi",
"kr",
"llm7",
"local-device",
"minimax",
"minimax-cn",
"mistral",
"mmf",
"morph",
"nanobanana",
"nebius",
"nvidia",
@@ -228,13 +272,17 @@
"openrouter",
"openrouter-tts-models",
"openrouter-tts-voices",
"orbit",
"perplexity",
"perplexity-agent",
"perplexity-web",
"poolside",
"qd",
"qianfan",
"qw",
"recraft",
"runwayml",
"samba",
"sdwebui",
"siliconflow",
"stability-ai",
@@ -246,6 +294,7 @@
"voyage-ai",
"xai",
"xiaomi-mimo",
"xiaomi-tokenplan"
"xiaomi-tokenplan",
"zd"
]
}
-1
View File
@@ -1,4 +1,3 @@
tests/unit/antigravity-mitm.test.js :: Antigravity MITM model handling flags the out-of-box agent/Default model mandatory
tests/unit/claude-header-forwarding.test.js :: proxyAwareFetch — api.anthropic.com routing routes api.anthropic.com to gotScraping (non-streaming) and returns ok response
tests/unit/oauth-cursor-auto-import.test.js :: GET /api/oauth/cursor/auto-import extracts tokens using exact keys
tests/unit/oauth-cursor-auto-import.test.js :: GET /api/oauth/cursor/auto-import falls back to fuzzy key matching on macOS when exact keys are missing
+201 -101
View File
@@ -1,14 +1,22 @@
{
"alicode-intl": {
"baseUrl": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
"alicode": {
"baseUrl": "https://coding.dashscope.aliyuncs.com/v1/chat/completions",
"headers": {},
"quirks": {
"preserveCacheControl": true
},
"format": "openai"
},
"alicode": {
"baseUrl": "https://coding.dashscope.aliyuncs.com/v1/chat/completions",
"alicode-intl": {
"baseUrl": "https://coding-intl.dashscope.aliyuncs.com/v1/chat/completions",
"headers": {},
"quirks": {
"preserveCacheControl": true
},
"format": "openai"
},
"alims-intl": {
"baseUrl": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
"headers": {},
"quirks": {
"preserveCacheControl": true
@@ -25,7 +33,7 @@
},
"antigravity": {
"baseUrls": [
"https://cloudcode-pa.googleapis.com"
"https://daily-cloudcode-pa.googleapis.com"
],
"format": "antigravity",
"headers": {
@@ -51,6 +59,15 @@
"clientSecret": "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",
"tokenUrl": "https://oauth2.googleapis.com/token"
},
"api-airforce": {
"baseUrl": "https://api.airforce/v1/chat/completions",
"validateUrl": "https://api.airforce/v1/models",
"headers": {
"HTTP-Referer": "https://endpoint-proxy.local",
"X-Title": "Endpoint Proxy"
},
"format": "openai"
},
"assemblyai": {
"baseUrl": "https://api.assemblyai.com/v1/audio/transcriptions",
"validateUrl": "https://api.assemblyai.com/v1/account",
@@ -61,11 +78,26 @@
"headers": {},
"format": "openai"
},
"baidu": {
"baseUrl": "https://qianfan.baidubce.com/v2/chat/completions",
"validateUrl": "https://qianfan.baidubce.com/v2/models",
"format": "openai"
},
"bazaarlink": {
"baseUrl": "https://bazaarlink.ai/api/v1/chat/completions",
"validateUrl": "https://bazaarlink.ai/api/v1/models",
"format": "openai"
},
"blackbox": {
"baseUrl": "https://api.blackbox.ai/v1/chat/completions",
"thinkingFormat": "openai",
"format": "openai"
},
"bluesminds": {
"baseUrl": "https://api.bluesminds.com/v1/chat/completions",
"validateUrl": "https://api.bluesminds.com/v1/models",
"format": "openai"
},
"byteplus": {
"baseUrl": "https://ark.ap-southeast.bytepluses.com/api/coding/v3/chat/completions",
"headers": {},
@@ -191,6 +223,26 @@
"format": "openai",
"tokenUrl": "https://copilot.tencent.com/v2/plugin/auth/token"
},
"codebuddy-intl": {
"baseUrl": "https://www.codebuddy.ai/v2/chat/completions",
"forceStream": true,
"thinkingFormat": "openai",
"headers": {
"User-Agent": "IDE/2.108.1 CodeBuddy/2.108.1",
"X-Product": "SaaS",
"X-IDE-Type": "IDE",
"X-IDE-Name": "IDE",
"x-requested-with": "XMLHttpRequest",
"x-codebuddy-request": "1"
},
"auth": {
"combined": true,
"header": "Authorization",
"scheme": "bearer"
},
"format": "openai",
"tokenUrl": "https://www.codebuddy.ai/v2/plugin/auth/token"
},
"codex": {
"baseUrl": "https://chatgpt.com/backend-api/codex/responses",
"format": "openai-responses",
@@ -279,19 +331,6 @@
"validateUrl": "https://api.fireworks.ai/inference/v1/models",
"format": "openai"
},
"gemini-cli": {
"baseUrl": "https://cloudcode-pa.googleapis.com/v1internal",
"format": "gemini-cli",
"cliVersion": "0.34.0",
"apiClient": "google-genai-sdk/1.41.0 gl-node/v22.19.0",
"usage": {
"quotaUrl": "https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota",
"loadCodeAssistUrl": "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist"
},
"clientId": "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",
"clientSecret": "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",
"tokenUrl": "https://oauth2.googleapis.com/token"
},
"gemini": {
"baseUrl": "https://generativelanguage.googleapis.com/v1beta/models",
"format": "gemini",
@@ -308,6 +347,19 @@
}
}
},
"gemini-cli": {
"baseUrl": "https://cloudcode-pa.googleapis.com/v1internal",
"format": "gemini-cli",
"cliVersion": "0.34.0",
"apiClient": "google-genai-sdk/1.41.0 gl-node/v22.19.0",
"usage": {
"quotaUrl": "https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota",
"loadCodeAssistUrl": "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist"
},
"clientId": "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",
"clientSecret": "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",
"tokenUrl": "https://oauth2.googleapis.com/token"
},
"github": {
"baseUrl": "https://api.githubcopilot.com/chat/completions",
"responsesUrl": "https://api.githubcopilot.com/responses",
@@ -346,14 +398,6 @@
},
"format": "openai"
},
"glm-cn": {
"baseUrl": "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
"headers": {},
"usage": {
"url": "https://open.bigmodel.cn/api/monitor/usage/quota/limit"
},
"format": "openai"
},
"glm": {
"baseUrl": "https://api.z.ai/api/anthropic/v1/messages",
"format": "claude",
@@ -396,6 +440,14 @@
}
]
},
"glm-cn": {
"baseUrl": "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
"headers": {},
"usage": {
"url": "https://open.bigmodel.cn/api/monitor/usage/quota/limit"
},
"format": "openai"
},
"grok-cli": {
"baseUrl": "https://cli-chat-proxy.grok.com/v1/responses",
"format": "openai-responses",
@@ -458,6 +510,11 @@
"clientSecret": "4Z3YjXycVsQvyGF1etiNlIBB4RsqSDtW",
"tokenUrl": "https://iflow.cn/oauth/token"
},
"kilo-gateway": {
"baseUrl": "https://api.kilo.ai/api/gateway/chat/completions",
"validateUrl": "https://api.kilo.ai/api/gateway/models",
"format": "openai"
},
"kilocode": {
"baseUrl": "https://api.kilo.ai/api/openrouter/chat/completions",
"headers": {},
@@ -548,7 +605,6 @@
"headers": {
"Content-Type": "application/json",
"Accept": "application/vnd.amazon.eventstream",
"X-Amz-Target": "AmazonCodeWhispererStreamingService.GenerateAssistantResponse",
"User-Agent": "AWS-SDK-JS/3.0.0 kiro-ide/1.0.0",
"X-Amz-User-Agent": "aws-sdk-js/3.0.0 kiro-ide/1.0.0"
},
@@ -560,62 +616,16 @@
"limitsPath": "/getUsageLimits"
}
},
"llm7": {
"baseUrl": "https://api.llm7.io/v1/chat/completions",
"validateUrl": "https://api.llm7.io/v1/models",
"format": "openai"
},
"mimo-free": {
"baseUrl": "https://api.xiaomimimo.com/api/free-ai/openai/chat",
"noAuth": true,
"format": "openai"
},
"minimax-cn": {
"baseUrl": "https://api.minimaxi.com/anthropic/v1/messages",
"format": "claude",
"urlSuffix": "?beta=true",
"headers": {
"Anthropic-Version": "2023-06-01",
"Anthropic-Beta": "claude-code-20250219,interleaved-thinking-2025-05-14"
},
"quirks": {
"dropOutputConfig": true
},
"reasoningInject": {
"scope": "all"
},
"auth": {
"combined": true,
"header": "x-api-key",
"scheme": "raw"
},
"usage": {
"urls": [
"https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains",
"https://api.minimaxi.com/v1/api/openplatform/coding_plan/remains"
]
},
"transports": [
{
"format": "openai",
"baseUrl": "https://api.minimaxi.com/v1/chat/completions",
"auth": {
"combined": true,
"header": "Authorization",
"scheme": "bearer"
}
},
{
"format": "claude",
"baseUrl": "https://api.minimaxi.com/anthropic/v1/messages",
"urlSuffix": "?beta=true",
"headers": {
"Anthropic-Version": "2023-06-01",
"Anthropic-Beta": "claude-code-20250219,interleaved-thinking-2025-05-14"
},
"auth": {
"combined": true,
"header": "x-api-key",
"scheme": "raw"
}
}
]
},
"minimax": {
"baseUrl": "https://api.minimax.io/anthropic/v1/messages",
"format": "claude",
@@ -667,6 +677,57 @@
}
]
},
"minimax-cn": {
"baseUrl": "https://api.minimaxi.com/anthropic/v1/messages",
"format": "claude",
"urlSuffix": "?beta=true",
"headers": {
"Anthropic-Version": "2023-06-01",
"Anthropic-Beta": "claude-code-20250219,interleaved-thinking-2025-05-14"
},
"quirks": {
"dropOutputConfig": true
},
"reasoningInject": {
"scope": "all"
},
"auth": {
"combined": true,
"header": "x-api-key",
"scheme": "raw"
},
"usage": {
"urls": [
"https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains",
"https://api.minimaxi.com/v1/api/openplatform/coding_plan/remains"
]
},
"transports": [
{
"format": "openai",
"baseUrl": "https://api.minimaxi.com/v1/chat/completions",
"auth": {
"combined": true,
"header": "Authorization",
"scheme": "bearer"
}
},
{
"format": "claude",
"baseUrl": "https://api.minimaxi.com/anthropic/v1/messages",
"urlSuffix": "?beta=true",
"headers": {
"Anthropic-Version": "2023-06-01",
"Anthropic-Beta": "claude-code-20250219,interleaved-thinking-2025-05-14"
},
"auth": {
"combined": true,
"header": "x-api-key",
"scheme": "raw"
}
}
]
},
"mistral": {
"baseUrl": "https://api.mistral.ai/v1/chat/completions",
"validateUrl": "https://api.mistral.ai/v1/models",
@@ -680,6 +741,11 @@
"noAuth": true,
"format": "openai"
},
"morph": {
"baseUrl": "https://api.morphllm.com/v1/chat/completions",
"validateUrl": "https://api.morphllm.com/v1/models",
"format": "openai"
},
"nanobanana": {
"baseUrl": "https://api.nanobananaapi.ai/v1/chat/completions",
"validateUrl": "https://api.nanobananaapi.ai/v1/models",
@@ -695,25 +761,20 @@
"validateUrl": "https://integrate.api.nvidia.com/v1/models",
"format": "openai"
},
"ollama-local": {
"baseUrl": "http://localhost:11434/api/chat",
"format": "ollama"
},
"ollama": {
"baseUrl": "https://ollama.com/api/chat",
"validateUrl": "https://ollama.com/api/tags",
"format": "ollama"
},
"ollama-local": {
"baseUrl": "http://localhost:11434/api/chat",
"format": "ollama"
},
"openai": {
"baseUrl": "https://api.openai.com/v1/chat/completions",
"forceStream": true,
"format": "openai"
},
"opencode-go": {
"baseUrl": "https://opencode.ai/zen/go/v1/chat/completions",
"headers": {},
"format": "openai"
},
"opencode": {
"baseUrl": "https://opencode.ai",
"headers": {
@@ -722,6 +783,11 @@
"noAuth": true,
"format": "openai"
},
"opencode-go": {
"baseUrl": "https://opencode.ai/zen/go/v1/chat/completions",
"headers": {},
"format": "openai"
},
"openrouter": {
"baseUrl": "https://openrouter.ai/api/v1/chat/completions",
"thinkingFormat": "openai",
@@ -731,10 +797,15 @@
},
"format": "openai"
},
"perplexity-web": {
"baseUrl": "https://www.perplexity.ai/rest/sse/perplexity_ask",
"format": "perplexity-web",
"authType": "cookie"
"orbit-provider": {
"baseUrl": "https://api.orbit-provider.com/anthropic/v1/messages",
"format": "claude",
"headers": {
"anthropic-version": "2023-06-01"
},
"usage": {
"url": "https://api.orbit-provider.com/v1/usage"
}
},
"perplexity": {
"baseUrl": "https://api.perplexity.ai/chat/completions",
@@ -746,6 +817,16 @@
"validateUrl": "https://api.perplexity.ai/v1/models",
"format": "openai-responses"
},
"perplexity-web": {
"baseUrl": "https://www.perplexity.ai/rest/sse/perplexity_ask",
"format": "perplexity-web",
"authType": "cookie"
},
"poolside": {
"baseUrl": "https://inference.poolside.ai/v1/chat/completions",
"validateUrl": "https://inference.poolside.ai/v1/models",
"format": "openai"
},
"qoder": {
"baseUrl": "https://api3.qoder.sh/algo/api/v2/service/pro/sse/agent_chat_generation",
"headers": {},
@@ -762,12 +843,22 @@
"clientId": "f0304373b74a44d2b584a3fb70ca9e56",
"tokenUrl": "https://chat.qwen.ai/api/v1/oauth2/token"
},
"sambanova": {
"baseUrl": "https://api.sambanova.ai/v1/chat/completions",
"validateUrl": "https://api.sambanova.ai/v1/models",
"format": "openai"
},
"siliconflow": {
"baseUrl": "https://api.siliconflow.com/v1/chat/completions",
"validateUrl": "https://api.siliconflow.com/v1/models",
"thinkingFormat": "openai",
"format": "openai"
},
"tencent": {
"baseUrl": "https://api.hunyuan.cloud.tencent.com/v1/chat/completions",
"validateUrl": "https://api.hunyuan.cloud.tencent.com/v1/models",
"format": "openai"
},
"together": {
"baseUrl": "https://api.together.xyz/v1/chat/completions",
"validateUrl": "https://api.together.xyz/v1/models",
@@ -790,14 +881,14 @@
},
"format": "openai"
},
"vertex-partner": {
"baseUrl": "https://aiplatform.googleapis.com",
"format": "openai"
},
"vertex": {
"baseUrl": "https://aiplatform.googleapis.com",
"format": "vertex"
},
"vertex-partner": {
"baseUrl": "https://aiplatform.googleapis.com",
"format": "openai"
},
"volcengine-ark": {
"baseUrl": "https://ark.cn-beijing.volces.com/api/coding/v3/chat/completions",
"headers": {},
@@ -873,12 +964,21 @@
}
]
},
"alims-intl": {
"baseUrl": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
"headers": {},
"quirks": {
"preserveCacheControl": true
"zed": {
"baseUrl": "https://cloud.zed.dev/completions",
"format": "openai",
"forceStream": true,
"headers": {
"content-type": "application/json"
},
"format": "openai"
"auth": {
"combined": true,
"header": "Authorization",
"scheme": "<user_id> <access_token>"
},
"usage": {
"url": "https://cloud.zed.dev/client/users/me"
},
"modelsUrl": "https://cloud.zed.dev/models"
}
}
+3
View File
@@ -20,6 +20,9 @@ const ALIAS_TOKENS = [
"xmtp","xiaomi-tokenplan","cf",
"cloudflare-ai","fal","fal-ai","stability","stability-ai","bfl","black-forest-labs","recraft",
"topaz","runway","runwayml","jina","jina-ai","polly","aws-polly","bb","blackbox",
"af","airforce","api-airforce","llm7","llm-7","samba","sambanova","bm","bluesminds",
"bzl","bazaarlink","kgw","kilo-gateway","hunyuan","tencent","qianfan","baidu","ernie",
"dv","devin","devin-cli","morph","morphllm",
];
// Sort idToAlias by key — runtime accesses by key, order is irrelevant (content-based)
+16 -10
View File
@@ -1,28 +1,34 @@
// Gate: so kết quả test hiện tại với baseline known-fails.
// Gate: so kết quả test hiện tại với baseline kết quả đã commit.
// PASS nếu KHÔNG có test nào pass(baseline) → fail(now). Test mới được phép.
// Usage: node tests/__baseline__/verify-no-regression.mjs <current-results.json>
import { readFileSync } from "fs";
const knownFails = new Set(
readFileSync(new URL("./known-fails.txt", import.meta.url), "utf8")
.split("\n").map(s => s.trim()).filter(Boolean)
);
const resultsPath = process.argv[2];
if (!resultsPath) { console.error("Missing results.json path"); process.exit(2); }
const r = JSON.parse(readFileSync(resultsPath, "utf8"));
const normalizeTestPath = (filePath) => {
const normalized = String(filePath || "").replaceAll("\\", "/");
const testsIndex = normalized.lastIndexOf("/tests/");
return testsIndex >= 0 ? normalized.slice(testsIndex + 1) : normalized;
};
const assertionStatuses = (results) => new Map(results.testResults.flatMap(f =>
f.assertionResults.map(a => [normalizeTestPath(f.name) + " :: " + a.fullName, a.status])
));
const baseline = JSON.parse(readFileSync(new URL("./baseline-results.json", import.meta.url), "utf8"));
const baselineStatuses = assertionStatuses(baseline);
const nowFails = r.testResults.flatMap(f =>
f.assertionResults.filter(a => a.status === "failed")
.map(a => f.name.split("/app/")[1] + " :: " + a.fullName)
.map(a => normalizeTestPath(f.name) + " :: " + a.fullName)
);
// Regression = fail bây giờ NHƯNG không có trong baseline known-fails
const regressions = nowFails.filter(f => !knownFails.has(f));
// Regression = test từng pass trong baseline nhưng fail bây giờ.
const regressions = nowFails.filter(name => baselineStatuses.get(name) === "passed");
if (regressions.length) {
console.error(`\n❌ REGRESSION: ${regressions.length} test pass→fail:\n`);
regressions.forEach(f => console.error(" - " + f));
process.exit(1);
}
console.log(`✅ No regression. (now fails=${nowFails.length}, baseline known=${knownFails.size}, all known)`);
console.log(`✅ No regression. (now fails=${nowFails.length}, baseline assertions=${baselineStatuses.size})`);