feat: add alibaba-coding-plan provider support (#295)
This commit is contained in:
parent
6a39f7226b
commit
c3ceb077d9
5 changed files with 155 additions and 6 deletions
|
|
@ -122,6 +122,7 @@ export function getEnvApiKey(provider: any): string | undefined {
|
|||
opencode: "OPENCODE_API_KEY",
|
||||
"opencode-go": "OPENCODE_API_KEY",
|
||||
"kimi-coding": "KIMI_API_KEY",
|
||||
"alibaba-coding-plan": "ALIBABA_API_KEY",
|
||||
};
|
||||
|
||||
const envVar = envMap[provider];
|
||||
|
|
|
|||
|
|
@ -13384,4 +13384,142 @@ export const MODELS = {
|
|||
maxTokens: 131072,
|
||||
} satisfies Model<"openai-completions">,
|
||||
},
|
||||
"alibaba-coding-plan": {
|
||||
"qwen3.5-plus": {
|
||||
id: "qwen3.5-plus",
|
||||
name: "Qwen3.5 Plus",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 1000000,
|
||||
maxTokens: 65536,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"qwen3-max-2026-01-23": {
|
||||
id: "qwen3-max-2026-01-23",
|
||||
name: "Qwen3 Max 2026-01-23",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 262144,
|
||||
maxTokens: 32768,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"qwen3-coder-next": {
|
||||
id: "qwen3-coder-next",
|
||||
name: "Qwen3 Coder Next",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 262144,
|
||||
maxTokens: 65536,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"qwen3-coder-plus": {
|
||||
id: "qwen3-coder-plus",
|
||||
name: "Qwen3 Coder Plus",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 1000000,
|
||||
maxTokens: 65536,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"MiniMax-M2.5": {
|
||||
id: "MiniMax-M2.5",
|
||||
name: "MiniMax M2.5",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 196608,
|
||||
maxTokens: 24576,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"glm-5": {
|
||||
id: "glm-5",
|
||||
name: "GLM-5",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 202752,
|
||||
maxTokens: 16384,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"glm-4.7": {
|
||||
id: "glm-4.7",
|
||||
name: "GLM-4.7",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 202752,
|
||||
maxTokens: 16384,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
"kimi-k2.5": {
|
||||
id: "kimi-k2.5",
|
||||
name: "Kimi K2.5",
|
||||
api: "anthropic-messages",
|
||||
provider: "alibaba-coding-plan",
|
||||
baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 262144,
|
||||
maxTokens: 32768,
|
||||
} satisfies Model<"anthropic-messages">,
|
||||
},
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -452,6 +452,9 @@ export const streamAnthropic: StreamFunction<"anthropic-messages", AnthropicOpti
|
|||
for (const block of output.content) delete (block as any).index;
|
||||
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
||||
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
||||
if (model.provider === "alibaba-coding-plan") {
|
||||
output.errorMessage = `[alibaba-coding-plan] ${output.errorMessage}`;
|
||||
}
|
||||
if (error instanceof Anthropic.APIError && error.headers) {
|
||||
const retryAfterMs = extractRetryAfterMs(error.headers, error.message);
|
||||
if (retryAfterMs !== undefined) {
|
||||
|
|
@ -583,8 +586,10 @@ function createClient(
|
|||
return { client, isOAuthToken: false };
|
||||
}
|
||||
|
||||
const betaFeatures = ["fine-grained-tool-streaming-2025-05-14"];
|
||||
if (needsInterleavedBeta) {
|
||||
// Skip beta headers for providers that don't support them (e.g., Alibaba Coding Plan)
|
||||
const skipBetaHeaders = model.provider === "alibaba-coding-plan";
|
||||
const betaFeatures = skipBetaHeaders ? [] : ["fine-grained-tool-streaming-2025-05-14"];
|
||||
if (needsInterleavedBeta && !skipBetaHeaders) {
|
||||
betaFeatures.push("interleaved-thinking-2025-05-14");
|
||||
}
|
||||
|
||||
|
|
@ -599,7 +604,7 @@ function createClient(
|
|||
{
|
||||
accept: "application/json",
|
||||
"anthropic-dangerous-direct-browser-access": "true",
|
||||
"anthropic-beta": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(",")}`,
|
||||
...(betaFeatures.length > 0 ? { "anthropic-beta": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(",")}` } : {}),
|
||||
"user-agent": `claude-cli/${claudeCodeVersion}`,
|
||||
"x-app": "cli",
|
||||
},
|
||||
|
|
@ -612,15 +617,18 @@ function createClient(
|
|||
}
|
||||
|
||||
// API key auth
|
||||
// Alibaba Coding Plan uses Bearer token auth instead of x-api-key
|
||||
const isAlibabaProvider = model.provider === "alibaba-coding-plan";
|
||||
const client = new Anthropic({
|
||||
apiKey,
|
||||
apiKey: isAlibabaProvider ? null : apiKey,
|
||||
authToken: isAlibabaProvider ? apiKey : undefined,
|
||||
baseURL: model.baseUrl,
|
||||
dangerouslyAllowBrowser: true,
|
||||
defaultHeaders: mergeHeaders(
|
||||
{
|
||||
accept: "application/json",
|
||||
"anthropic-dangerous-direct-browser-access": "true",
|
||||
"anthropic-beta": betaFeatures.join(","),
|
||||
...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
|
||||
},
|
||||
model.headers,
|
||||
optionsHeaders,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ export type KnownProvider =
|
|||
| "huggingface"
|
||||
| "opencode"
|
||||
| "opencode-go"
|
||||
| "kimi-coding";
|
||||
| "kimi-coding"
|
||||
| "alibaba-coding-plan";
|
||||
export type Provider = KnownProvider | string;
|
||||
|
||||
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export const defaultModelPerProvider: Record<KnownProvider, string> = {
|
|||
opencode: "claude-opus-4-6",
|
||||
"opencode-go": "kimi-k2.5",
|
||||
"kimi-coding": "kimi-k2-thinking",
|
||||
"alibaba-coding-plan": "qwen3.5-plus",
|
||||
};
|
||||
|
||||
export interface ScopedModel {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue