Merge branch 'pr-203'
This commit is contained in:
@@ -223,6 +223,11 @@ export const PROVIDERS = {
|
|||||||
"Anthropic-Beta": "claude-code-20250219,interleaved-thinking-2025-05-14"
|
"Anthropic-Beta": "claude-code-20250219,interleaved-thinking-2025-05-14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
alicode: {
|
||||||
|
baseUrl: "https://coding.dashscope.aliyuncs.com/v1/chat/completions",
|
||||||
|
format: "openai",
|
||||||
|
headers: {}
|
||||||
|
},
|
||||||
github: {
|
github: {
|
||||||
baseUrl: "https://api.githubcopilot.com/chat/completions", // GitHub Copilot API endpoint for chat
|
baseUrl: "https://api.githubcopilot.com/chat/completions", // GitHub Copilot API endpoint for chat
|
||||||
responsesUrl: "https://api.githubcopilot.com/responses",
|
responsesUrl: "https://api.githubcopilot.com/responses",
|
||||||
|
|||||||
@@ -186,6 +186,16 @@ export const PROVIDER_MODELS = {
|
|||||||
{ id: "MiniMax-M2.5", name: "MiniMax M2.5" },
|
{ id: "MiniMax-M2.5", name: "MiniMax M2.5" },
|
||||||
{ id: "MiniMax-M2.1", name: "MiniMax M2.1" },
|
{ id: "MiniMax-M2.1", name: "MiniMax M2.1" },
|
||||||
],
|
],
|
||||||
|
alicode: [
|
||||||
|
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus" },
|
||||||
|
{ id: "kimi-k2.5", name: "Kimi K2.5" },
|
||||||
|
{ id: "glm-5", name: "GLM 5" },
|
||||||
|
{ id: "MiniMax-M2.5", name: "MiniMax M2.5" },
|
||||||
|
{ id: "qwen3-max-2026-01-23", name: "Qwen3 Max" },
|
||||||
|
{ id: "qwen3-coder-next", name: "Qwen3 Coder Next" },
|
||||||
|
{ id: "qwen3-coder-plus", name: "Qwen3 Coder Plus" },
|
||||||
|
{ id: "glm-4.7", name: "GLM 4.7" },
|
||||||
|
],
|
||||||
deepseek: [
|
deepseek: [
|
||||||
{ id: "deepseek-chat", name: "DeepSeek V3.2 Chat" },
|
{ id: "deepseek-chat", name: "DeepSeek V3.2 Chat" },
|
||||||
{ id: "deepseek-reasoner", name: "DeepSeek V3.2 Reasoner" },
|
{ id: "deepseek-reasoner", name: "DeepSeek V3.2 Reasoner" },
|
||||||
@@ -324,6 +334,7 @@ export const PROVIDER_ID_TO_ALIAS = {
|
|||||||
kimi: "kimi",
|
kimi: "kimi",
|
||||||
minimax: "minimax",
|
minimax: "minimax",
|
||||||
"minimax-cn": "minimax-cn",
|
"minimax-cn": "minimax-cn",
|
||||||
|
alicode: "alicode",
|
||||||
deepseek: "deepseek",
|
deepseek: "deepseek",
|
||||||
groq: "groq",
|
groq: "groq",
|
||||||
xai: "xai",
|
xai: "xai",
|
||||||
|
|||||||
@@ -120,6 +120,15 @@ const PROVIDER_MODELS_CONFIG = {
|
|||||||
parseResponse: (data) => data.data || []
|
parseResponse: (data) => data.data || []
|
||||||
},
|
},
|
||||||
|
|
||||||
|
alicode: {
|
||||||
|
url: "https://coding.dashscope.aliyuncs.com/v1/models",
|
||||||
|
method: "GET",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
authHeader: "Authorization",
|
||||||
|
authPrefix: "Bearer ",
|
||||||
|
parseResponse: (data) => data.data || []
|
||||||
|
},
|
||||||
|
|
||||||
// OpenAI-compatible API key providers
|
// OpenAI-compatible API key providers
|
||||||
deepseek: createOpenAIModelsConfig("https://api.deepseek.com/models"),
|
deepseek: createOpenAIModelsConfig("https://api.deepseek.com/models"),
|
||||||
groq: createOpenAIModelsConfig("https://api.groq.com/openai/v1/models"),
|
groq: createOpenAIModelsConfig("https://api.groq.com/openai/v1/models"),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { getProviderConnectionById, updateProviderConnection } from "@/lib/localDb";
|
import { getProviderConnectionById, updateProviderConnection } from "@/lib/localDb";
|
||||||
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
||||||
|
import { getDefaultModel } from "open-sse/config/providerModels.js";
|
||||||
import {
|
import {
|
||||||
GEMINI_CONFIG,
|
GEMINI_CONFIG,
|
||||||
ANTIGRAVITY_CONFIG,
|
ANTIGRAVITY_CONFIG,
|
||||||
@@ -308,6 +309,16 @@ async function testApiKeyConnection(connection) {
|
|||||||
const valid = res.status !== 401 && res.status !== 403;
|
const valid = res.status !== 401 && res.status !== 403;
|
||||||
return { valid, error: valid ? null : "Invalid API key" };
|
return { valid, error: valid ? null : "Invalid API key" };
|
||||||
}
|
}
|
||||||
|
case "alicode": {
|
||||||
|
// Aliyun Coding Plan uses OpenAI-compatible API
|
||||||
|
const res = await fetch("https://coding.dashscope.aliyuncs.com/v1/chat/completions", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Authorization": `Bearer ${connection.apiKey}`, "content-type": "application/json" },
|
||||||
|
body: JSON.stringify({ model: getDefaultModel("alicode"), max_tokens: 1, messages: [{ role: "user", content: "test" }] }),
|
||||||
|
});
|
||||||
|
const valid = res.status !== 401 && res.status !== 403;
|
||||||
|
return { valid, error: valid ? null : "Invalid API key" };
|
||||||
|
}
|
||||||
case "deepseek": {
|
case "deepseek": {
|
||||||
const res = await fetch("https://api.deepseek.com/models", { headers: { Authorization: `Bearer ${connection.apiKey}` } });
|
const res = await fetch("https://api.deepseek.com/models", { headers: { Authorization: `Bearer ${connection.apiKey}` } });
|
||||||
return { valid: res.ok, error: res.ok ? null : "Invalid API key" };
|
return { valid: res.ok, error: res.ok ? null : "Invalid API key" };
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { getProviderNodeById } from "@/models";
|
import { getProviderNodeById } from "@/models";
|
||||||
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
import { isOpenAICompatibleProvider, isAnthropicCompatibleProvider } from "@/shared/constants/providers";
|
||||||
|
import { getDefaultModel } from "open-sse/config/providerModels.js";
|
||||||
|
|
||||||
// POST /api/providers/validate - Validate API key with provider
|
// POST /api/providers/validate - Validate API key with provider
|
||||||
export async function POST(request) {
|
export async function POST(request) {
|
||||||
@@ -102,17 +103,20 @@ export async function POST(request) {
|
|||||||
case "glm-cn":
|
case "glm-cn":
|
||||||
case "kimi":
|
case "kimi":
|
||||||
case "minimax":
|
case "minimax":
|
||||||
case "minimax-cn": {
|
case "minimax-cn":
|
||||||
|
case "alicode": {
|
||||||
const claudeBaseUrls = {
|
const claudeBaseUrls = {
|
||||||
glm: "https://api.z.ai/api/anthropic/v1/messages",
|
glm: "https://api.z.ai/api/anthropic/v1/messages",
|
||||||
"glm-cn": "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
|
"glm-cn": "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",
|
||||||
kimi: "https://api.kimi.com/coding/v1/messages",
|
kimi: "https://api.kimi.com/coding/v1/messages",
|
||||||
minimax: "https://api.minimax.io/anthropic/v1/messages",
|
minimax: "https://api.minimax.io/anthropic/v1/messages",
|
||||||
"minimax-cn": "https://api.minimaxi.com/anthropic/v1/messages",
|
"minimax-cn": "https://api.minimaxi.com/anthropic/v1/messages",
|
||||||
|
alicode: "https://coding.dashscope.aliyuncs.com/v1/chat/completions",
|
||||||
};
|
};
|
||||||
|
|
||||||
// glm-cn uses OpenAI format
|
// glm-cn and alicode use OpenAI format
|
||||||
if (provider === "glm-cn") {
|
if (provider === "glm-cn" || provider === "alicode") {
|
||||||
|
const testModel = getDefaultModel(provider);
|
||||||
const glmCnRes = await fetch(claudeBaseUrls[provider], {
|
const glmCnRes = await fetch(claudeBaseUrls[provider], {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
@@ -120,7 +124,7 @@ export async function POST(request) {
|
|||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
model: "glm-4.7",
|
model: testModel,
|
||||||
max_tokens: 1,
|
max_tokens: 1,
|
||||||
messages: [{ role: "user", content: "test" }],
|
messages: [{ role: "user", content: "test" }],
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export const PROVIDER_ENDPOINTS = {
|
|||||||
kimi: "https://api.kimi.com/coding/v1/messages",
|
kimi: "https://api.kimi.com/coding/v1/messages",
|
||||||
minimax: "https://api.minimax.io/anthropic/v1/messages",
|
minimax: "https://api.minimax.io/anthropic/v1/messages",
|
||||||
"minimax-cn": "https://api.minimaxi.com/anthropic/v1/messages",
|
"minimax-cn": "https://api.minimaxi.com/anthropic/v1/messages",
|
||||||
|
alicode: "https://coding.dashscope.aliyuncs.com/v1/chat/completions",
|
||||||
openai: "https://api.openai.com/v1/chat/completions",
|
openai: "https://api.openai.com/v1/chat/completions",
|
||||||
anthropic: "https://api.anthropic.com/v1/messages",
|
anthropic: "https://api.anthropic.com/v1/messages",
|
||||||
gemini: "https://generativelanguage.googleapis.com/v1beta/models",
|
gemini: "https://generativelanguage.googleapis.com/v1beta/models",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export const APIKEY_PROVIDERS = {
|
|||||||
kimi: { id: "kimi", alias: "kimi", name: "Kimi", icon: "psychology", color: "#1E3A8A", textIcon: "KM", website: "https://kimi.moonshot.cn" },
|
kimi: { id: "kimi", alias: "kimi", name: "Kimi", icon: "psychology", color: "#1E3A8A", textIcon: "KM", website: "https://kimi.moonshot.cn" },
|
||||||
minimax: { id: "minimax", alias: "minimax", name: "Minimax Coding", icon: "memory", color: "#7C3AED", textIcon: "MM", website: "https://www.minimaxi.com" },
|
minimax: { id: "minimax", alias: "minimax", name: "Minimax Coding", icon: "memory", color: "#7C3AED", textIcon: "MM", website: "https://www.minimaxi.com" },
|
||||||
"minimax-cn": { id: "minimax-cn", alias: "minimax-cn", name: "Minimax (China)", icon: "memory", color: "#DC2626", textIcon: "MC", website: "https://www.minimaxi.com" },
|
"minimax-cn": { id: "minimax-cn", alias: "minimax-cn", name: "Minimax (China)", icon: "memory", color: "#DC2626", textIcon: "MC", website: "https://www.minimaxi.com" },
|
||||||
|
alicode: { id: "alicode", alias: "alicode", name: "Aliyun Bailian Coding Plan", icon: "cloud", color: "#FF6A00", textIcon: "ALi" },
|
||||||
openai: { id: "openai", alias: "openai", name: "OpenAI", icon: "auto_awesome", color: "#10A37F", textIcon: "OA", website: "https://platform.openai.com" },
|
openai: { id: "openai", alias: "openai", name: "OpenAI", icon: "auto_awesome", color: "#10A37F", textIcon: "OA", website: "https://platform.openai.com" },
|
||||||
anthropic: { id: "anthropic", alias: "anthropic", name: "Anthropic", icon: "smart_toy", color: "#D97757", textIcon: "AN", website: "https://console.anthropic.com" },
|
anthropic: { id: "anthropic", alias: "anthropic", name: "Anthropic", icon: "smart_toy", color: "#D97757", textIcon: "AN", website: "https://console.anthropic.com" },
|
||||||
gemini: { id: "gemini", alias: "gemini", name: "Gemini", icon: "diamond", color: "#4285F4", textIcon: "GE", website: "https://ai.google.dev" },
|
gemini: { id: "gemini", alias: "gemini", name: "Gemini", icon: "diamond", color: "#4285F4", textIcon: "GE", website: "https://ai.google.dev" },
|
||||||
|
|||||||
Reference in New Issue
Block a user