Update providers

This commit is contained in:
Arjun Komath
2026-03-25 20:53:17 +11:00
parent 57162df213
commit 5bed4c5053
2 changed files with 306 additions and 58 deletions
+43
View File
@@ -21,6 +21,11 @@
authChoices: [],
selectedAuth: '',
authSecret: '',
customBaseUrl: '',
customModelId: '',
customCompatibility: 'openai',
cloudflareAccountId: '',
cloudflareGatewayId: '',
telegramToken: '',
discordToken: '',
slackBotToken: '',
@@ -103,6 +108,11 @@
authChoice: this.selectedAuth,
authSecret: this.authSecret,
model: this.model,
customBaseUrl: this.customBaseUrl,
customModelId: this.customModelId,
customCompatibility: this.customCompatibility,
cloudflareAccountId: this.cloudflareAccountId,
cloudflareGatewayId: this.cloudflareGatewayId,
telegramToken: this.telegramToken,
discordToken: this.discordToken,
slackBotToken: this.slackBotToken,
@@ -521,6 +531,39 @@
<input x-model="authSecret" type="password" placeholder="Paste your API key or token" class="input" />
</div>
<template x-if="selectedAuth === 'custom-api-key'">
<div>
<div class="form-group">
<label class="label">Base URL</label>
<input x-model="customBaseUrl" type="text" placeholder="e.g. https://api.example.com/v1" class="input" />
</div>
<div class="form-group">
<label class="label">Model ID</label>
<input x-model="customModelId" type="text" placeholder="e.g. my-model-id" class="input" />
</div>
<div class="form-group">
<label class="label">API Compatibility</label>
<select x-model="customCompatibility" class="select">
<option value="openai">OpenAI-compatible</option>
<option value="anthropic">Anthropic-compatible</option>
</select>
</div>
</div>
</template>
<template x-if="selectedAuth === 'cloudflare-ai-gateway-api-key'">
<div>
<div class="form-group">
<label class="label">Account ID</label>
<input x-model="cloudflareAccountId" type="text" placeholder="Cloudflare Account ID" class="input" />
</div>
<div class="form-group">
<label class="label">Gateway ID</label>
<input x-model="cloudflareGatewayId" type="text" placeholder="Cloudflare AI Gateway ID" class="input" />
</div>
</div>
</template>
<div class="form-group">
<label class="label">Model</label>
<input x-model="model" type="text" placeholder="e.g. openai/gpt-4.1, anthropic/claude-sonnet-4" class="input" />
+263 -58
View File
@@ -419,14 +419,6 @@ app.get("/setup/api/status", requireSetupAuth, async (_req, res) => {
const { version, channelsHelp } = await getOpenclawInfo();
const authGroups = [
{
value: "openai",
label: "OpenAI",
hint: "API key",
options: [
{ value: "openai-api-key", label: "OpenAI API key" },
],
},
{
value: "anthropic",
label: "Anthropic",
@@ -435,12 +427,30 @@ app.get("/setup/api/status", requireSetupAuth, async (_req, res) => {
{ value: "apiKey", label: "Anthropic API key" },
],
},
{
value: "openai",
label: "OpenAI",
hint: "API key / Codex",
options: [
{ value: "openai-api-key", label: "OpenAI API key" },
{ value: "openai-codex", label: "OpenAI Codex (ChatGPT OAuth)" },
],
},
{
value: "google",
label: "Google",
hint: "API key",
hint: "API key / CLI",
options: [
{ value: "gemini-api-key", label: "Google Gemini API key" },
{ value: "google-gemini-cli", label: "Google Gemini CLI (OAuth)" },
],
},
{
value: "deepseek",
label: "DeepSeek",
hint: "API key",
options: [
{ value: "deepseek-api-key", label: "DeepSeek API key" },
],
},
{
@@ -450,42 +460,28 @@ app.get("/setup/api/status", requireSetupAuth, async (_req, res) => {
options: [{ value: "openrouter-api-key", label: "OpenRouter API key" }],
},
{
value: "ai-gateway",
label: "Vercel AI Gateway",
value: "xai",
label: "xAI (Grok)",
hint: "API key",
options: [
{ value: "ai-gateway-api-key", label: "Vercel AI Gateway API key" },
],
options: [{ value: "xai-api-key", label: "xAI API key" }],
},
{
value: "moonshot",
label: "Moonshot AI",
hint: "Kimi K2 + Kimi Code",
options: [
{ value: "moonshot-api-key", label: "Moonshot AI API key" },
{ value: "kimi-code-api-key", label: "Kimi Code API key" },
],
},
{
value: "zai",
label: "Z.AI (GLM 4.7)",
value: "mistral",
label: "Mistral AI",
hint: "API key",
options: [{ value: "zai-api-key", label: "Z.AI (GLM 4.7) API key" }],
options: [{ value: "mistral-api-key", label: "Mistral API key" }],
},
{
value: "minimax",
label: "MiniMax",
hint: "M2.1 (recommended)",
options: [
{ value: "minimax-global-api", label: "MiniMax M2.1" },
{ value: "minimax-global-api-lightning", label: "MiniMax M2.1 Lightning" },
],
value: "together",
label: "Together AI",
hint: "API key",
options: [{ value: "together-api-key", label: "Together AI API key" }],
},
{
value: "qwen",
label: "Qwen",
hint: "OAuth",
options: [{ value: "qwen-portal", label: "Qwen OAuth" }],
value: "huggingface",
label: "Hugging Face",
hint: "API key",
options: [{ value: "huggingface-api-key", label: "Hugging Face API key" }],
},
{
value: "copilot",
@@ -499,6 +495,132 @@ app.get("/setup/api/status", requireSetupAuth, async (_req, res) => {
{ value: "copilot-proxy", label: "Copilot Proxy (local)" },
],
},
{
value: "moonshot",
label: "Moonshot AI",
hint: "Kimi K2 + Kimi Code",
options: [
{ value: "moonshot-api-key", label: "Moonshot AI API key" },
{ value: "moonshot-api-key-cn", label: "Moonshot AI API key (CN)" },
{ value: "kimi-code-api-key", label: "Kimi Code API key" },
],
},
{
value: "minimax",
label: "MiniMax",
hint: "API key / OAuth",
options: [
{ value: "minimax-global-api", label: "MiniMax API key (Global)" },
{ value: "minimax-global-oauth", label: "MiniMax OAuth (Global)" },
{ value: "minimax-cn-api", label: "MiniMax API key (CN)" },
{ value: "minimax-cn-oauth", label: "MiniMax OAuth (CN)" },
],
},
{
value: "zai",
label: "Z.AI (GLM 4.7)",
hint: "API key / OAuth",
options: [
{ value: "zai-api-key", label: "Z.AI API key" },
{ value: "zai-coding-global", label: "Z.AI Coding (Global)" },
{ value: "zai-coding-cn", label: "Z.AI Coding (CN)" },
{ value: "zai-global", label: "Z.AI (Global)" },
{ value: "zai-cn", label: "Z.AI (CN)" },
],
},
{
value: "qwen",
label: "Qwen",
hint: "OAuth",
options: [{ value: "qwen-portal", label: "Qwen OAuth" }],
},
{
value: "modelstudio",
label: "Alibaba Model Studio",
hint: "Qwen via Alibaba Cloud",
options: [
{ value: "modelstudio-api-key", label: "Coding Plan (Global)" },
{ value: "modelstudio-api-key-cn", label: "Coding Plan (CN)" },
{ value: "modelstudio-standard-api-key", label: "Standard Plan (Global)" },
{ value: "modelstudio-standard-api-key-cn", label: "Standard Plan (CN)" },
],
},
{
value: "venice",
label: "Venice AI",
hint: "API key",
options: [{ value: "venice-api-key", label: "Venice AI API key" }],
},
{
value: "chutes",
label: "Chutes",
hint: "OAuth / API key",
options: [
{ value: "chutes", label: "Chutes OAuth" },
{ value: "chutes-api-key", label: "Chutes API key" },
],
},
{
value: "kilocode",
label: "Kilocode",
hint: "API key",
options: [{ value: "kilocode-api-key", label: "Kilocode API key" }],
},
{
value: "xiaomi",
label: "Xiaomi",
hint: "API key",
options: [{ value: "xiaomi-api-key", label: "Xiaomi API key" }],
},
{
value: "volcengine",
label: "Volcano Engine (Doubao)",
hint: "API key",
options: [{ value: "volcengine-api-key", label: "Volcano Engine API key" }],
},
{
value: "byteplus",
label: "BytePlus",
hint: "API key",
options: [{ value: "byteplus-api-key", label: "BytePlus API key" }],
},
{
value: "qianfan",
label: "Qianfan (Baidu)",
hint: "API key",
options: [{ value: "qianfan-api-key", label: "Qianfan API key" }],
},
{
value: "ai-gateway",
label: "Vercel AI Gateway",
hint: "API key",
options: [
{ value: "ai-gateway-api-key", label: "Vercel AI Gateway API key" },
],
},
{
value: "cloudflare-ai-gateway",
label: "Cloudflare AI Gateway",
hint: "API key",
options: [
{ value: "cloudflare-ai-gateway-api-key", label: "Cloudflare AI Gateway API key" },
],
},
{
value: "litellm",
label: "LiteLLM",
hint: "Unified gateway",
options: [{ value: "litellm-api-key", label: "LiteLLM API key" }],
},
{
value: "opencode",
label: "OpenCode",
hint: "Zen / Go",
options: [
{ value: "opencode-zen", label: "OpenCode Zen (multi-model proxy)" },
{ value: "opencode-go", label: "OpenCode Go" },
],
},
{
value: "synthetic",
label: "Synthetic",
@@ -506,13 +628,21 @@ app.get("/setup/api/status", requireSetupAuth, async (_req, res) => {
options: [{ value: "synthetic-api-key", label: "Synthetic API key" }],
},
{
value: "opencode-zen",
label: "OpenCode Zen",
hint: "API key",
value: "self-hosted",
label: "Self-hosted",
hint: "Ollama / vLLM / SGLang",
options: [
{ value: "opencode-zen", label: "OpenCode Zen (multi-model proxy)" },
{ value: "ollama", label: "Ollama (local)" },
{ value: "vllm", label: "vLLM" },
{ value: "sglang", label: "SGLang" },
],
},
{
value: "custom",
label: "Custom endpoint",
hint: "OpenAI / Anthropic compatible",
options: [{ value: "custom-api-key", label: "Custom provider" }],
},
];
res.json({
@@ -552,24 +682,61 @@ function buildOnboardArgs(payload) {
const secret = (payload.authSecret || "").trim();
const map = {
"openai-api-key": "--openai-api-key",
apiKey: "--anthropic-api-key",
"openrouter-api-key": "--openrouter-api-key",
"ai-gateway-api-key": "--ai-gateway-api-key",
"moonshot-api-key": "--moonshot-api-key",
"kimi-code-api-key": "--kimi-code-api-key",
"openai-api-key": "--openai-api-key",
"gemini-api-key": "--gemini-api-key",
"zai-api-key": "--zai-api-key",
"deepseek-api-key": "--deepseek-api-key",
"openrouter-api-key": "--openrouter-api-key",
"xai-api-key": "--xai-api-key",
"mistral-api-key": "--mistral-api-key",
"together-api-key": "--together-api-key",
"huggingface-api-key": "--huggingface-api-key",
"moonshot-api-key": "--moonshot-api-key",
"moonshot-api-key-cn": "--moonshot-api-key",
"kimi-code-api-key": "--kimi-code-api-key",
"minimax-global-api": "--minimax-api-key",
"minimax-global-api-lightning": "--minimax-api-key",
"synthetic-api-key": "--synthetic-api-key",
"minimax-cn-api": "--minimax-api-key",
"zai-api-key": "--zai-api-key",
"modelstudio-api-key": "--modelstudio-api-key",
"modelstudio-api-key-cn": "--modelstudio-api-key-cn",
"modelstudio-standard-api-key": "--modelstudio-standard-api-key",
"modelstudio-standard-api-key-cn": "--modelstudio-standard-api-key-cn",
"venice-api-key": "--venice-api-key",
"chutes-api-key": "--chutes-api-key",
"kilocode-api-key": "--kilocode-api-key",
"xiaomi-api-key": "--xiaomi-api-key",
"volcengine-api-key": "--volcengine-api-key",
"byteplus-api-key": "--byteplus-api-key",
"qianfan-api-key": "--qianfan-api-key",
"ai-gateway-api-key": "--ai-gateway-api-key",
"cloudflare-ai-gateway-api-key": "--cloudflare-ai-gateway-api-key",
"litellm-api-key": "--litellm-api-key",
"opencode-zen": "--opencode-zen-api-key",
"opencode-go": "--opencode-go-api-key",
"synthetic-api-key": "--synthetic-api-key",
"custom-api-key": "--custom-api-key",
};
const flag = map[payload.authChoice];
if (flag && secret) {
args.push(flag, secret);
}
if (payload.authChoice === "custom-api-key") {
const baseUrl = (payload.customBaseUrl || "").trim();
const modelId = (payload.customModelId || "").trim();
const compat = (payload.customCompatibility || "").trim();
if (baseUrl) args.push("--custom-base-url", baseUrl);
if (modelId) args.push("--custom-model-id", modelId);
if (compat) args.push("--custom-compatibility", compat);
}
if (payload.authChoice === "cloudflare-ai-gateway-api-key") {
const accountId = (payload.cloudflareAccountId || "").trim();
const gatewayId = (payload.cloudflareGatewayId || "").trim();
if (accountId) args.push("--cloudflare-ai-gateway-account-id", accountId);
if (gatewayId) args.push("--cloudflare-ai-gateway-gateway-id", gatewayId);
}
}
return args;
@@ -600,21 +767,54 @@ function runCmd(cmd, args, opts = {}) {
}
const VALID_AUTH_CHOICES = [
"openai-api-key",
"apiKey",
"openai-api-key",
"openai-codex",
"gemini-api-key",
"google-gemini-cli",
"deepseek-api-key",
"openrouter-api-key",
"ai-gateway-api-key",
"moonshot-api-key",
"kimi-code-api-key",
"zai-api-key",
"minimax-global-api",
"minimax-global-api-lightning",
"qwen-portal",
"xai-api-key",
"mistral-api-key",
"together-api-key",
"huggingface-api-key",
"github-copilot",
"copilot-proxy",
"synthetic-api-key",
"moonshot-api-key",
"moonshot-api-key-cn",
"kimi-code-api-key",
"minimax-global-api",
"minimax-global-oauth",
"minimax-cn-api",
"minimax-cn-oauth",
"zai-api-key",
"zai-coding-global",
"zai-coding-cn",
"zai-global",
"zai-cn",
"qwen-portal",
"modelstudio-api-key",
"modelstudio-api-key-cn",
"modelstudio-standard-api-key",
"modelstudio-standard-api-key-cn",
"venice-api-key",
"chutes",
"chutes-api-key",
"kilocode-api-key",
"xiaomi-api-key",
"volcengine-api-key",
"byteplus-api-key",
"qianfan-api-key",
"ai-gateway-api-key",
"cloudflare-ai-gateway-api-key",
"litellm-api-key",
"opencode-zen",
"opencode-go",
"synthetic-api-key",
"ollama",
"vllm",
"sglang",
"custom-api-key",
];
function validatePayload(payload) {
@@ -628,6 +828,11 @@ if (payload.authChoice && !VALID_AUTH_CHOICES.includes(payload.authChoice)) {
"slackAppToken",
"authSecret",
"model",
"customBaseUrl",
"customModelId",
"customCompatibility",
"cloudflareAccountId",
"cloudflareGatewayId",
];
for (const field of stringFields) {
if (payload[field] !== undefined && typeof payload[field] !== "string") {