feat: add zai coding plan byok (#1434)

This commit is contained in:
Ari Webb
2026-03-18 14:35:18 -07:00
committed by GitHub
parent 3ada498f72
commit 8b8885c891
4 changed files with 58 additions and 9 deletions

View File

@@ -9,6 +9,7 @@ export type ConnectProviderCanonical =
| "anthropic"
| "openai"
| "zai"
| "zai-coding"
| "minimax"
| "gemini"
| "openrouter"
@@ -20,6 +21,7 @@ const ALIAS_TO_CANONICAL: Record<string, ConnectProviderCanonical> = {
anthropic: "anthropic",
openai: "openai",
zai: "zai",
"zai-coding": "zai-coding",
minimax: "minimax",
gemini: "gemini",
openrouter: "openrouter",
@@ -31,6 +33,7 @@ const CANONICAL_ORDER: ConnectProviderCanonical[] = [
"anthropic",
"openai",
"zai",
"zai-coding",
"minimax",
"gemini",
"openrouter",
@@ -40,7 +43,8 @@ const CANONICAL_ORDER: ConnectProviderCanonical[] = [
function canonicalToByokId(
canonical: ConnectProviderCanonical,
): ByokProviderId {
return canonical === "chatgpt" ? "codex" : canonical;
if (canonical === "chatgpt") return "codex";
return canonical;
}
export interface ResolvedConnectProvider {
@@ -113,3 +117,9 @@ export function isConnectApiKeyProvider(
!isConnectOAuthProvider(provider) && !isConnectBedrockProvider(provider)
);
}
export function isConnectZaiBaseProvider(
provider: ResolvedConnectProvider,
): boolean {
return provider.canonical === "zai";
}

View File

@@ -20,6 +20,7 @@ import {
isConnectApiKeyProvider,
isConnectBedrockProvider,
isConnectOAuthProvider,
isConnectZaiBaseProvider,
listConnectProvidersForHelp,
listConnectProviderTokens,
type ResolvedConnectProvider,
@@ -208,6 +209,18 @@ function formatApiKeyUsage(provider: ResolvedConnectProvider): string {
].join("\n");
}
function formatZaiCodingPlanPrompt(apiKey?: string): string {
const keyHint = apiKey ? ` ${apiKey}` : " <api_key>";
return [
"Connect to Z.ai",
"",
"Do you have a Z.ai Coding plan?",
"",
` • Coding plan: /connect zai-coding${keyHint}`,
` • Regular API: /connect zai${keyHint}`,
].join("\n");
}
async function handleConnectChatGPT(
ctx: ConnectCommandContext,
msg: string,
@@ -501,13 +514,23 @@ export async function handleConnect(
if (isConnectApiKeyProvider(provider)) {
const apiKey = parts.slice(2).join("");
if (!apiKey) {
addCommandResult(
ctx.buffersRef,
ctx.refreshDerived,
msg,
formatApiKeyUsage(provider),
false,
);
if (isConnectZaiBaseProvider(provider)) {
addCommandResult(
ctx.buffersRef,
ctx.refreshDerived,
msg,
formatZaiCodingPlanPrompt(),
false,
);
} else {
addCommandResult(
ctx.buffersRef,
ctx.refreshDerived,
msg,
formatApiKeyUsage(provider),
false,
);
}
return;
}
await handleConnectApiKeyProvider(ctx, msg, provider, apiKey);

View File

@@ -10,6 +10,7 @@ import {
isConnectApiKeyProvider,
isConnectBedrockProvider,
isConnectOAuthProvider,
isConnectZaiBaseProvider,
listConnectProvidersForHelp,
listConnectProviderTokens,
resolveConnectProvider,
@@ -261,6 +262,14 @@ export async function runConnectSubcommand(
if (isConnectApiKeyProvider(provider)) {
let apiKey =
readStringOption(parsed.values["api-key"]) ?? restPositionals[0] ?? "";
if (!apiKey && isConnectZaiBaseProvider(provider)) {
io.stdout(
"Do you have a Z.ai Coding plan?\n" +
" • Coding plan: letta connect zai-coding [--api-key <key>]\n" +
" • Regular API: letta connect zai [--api-key <key>]",
);
return 0;
}
if (!apiKey) {
if (!io.isTTY()) {
io.stderr(

View File

@@ -50,10 +50,17 @@ export const BYOK_PROVIDERS = [
{
id: "zai",
displayName: "zAI API",
description: "Connect a zAI key or coding plan",
description: "Connect a zAI API key",
providerType: "zai",
providerName: "lc-zai",
},
{
id: "zai-coding",
displayName: "zAI Coding Plan",
description: "Connect a zAI Coding plan key",
providerType: "zai_coding",
providerName: "lc-zai-coding",
},
{
id: "minimax",
displayName: "MiniMax API",