mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
chore(providers): refresh provider metadata and ordering (#2318)
Integrated into release/v3.8.0 — refreshes provider model metadata, sorts dashboard provider entries by display name, and fixes docs generator relative links.
This commit is contained in:
@@ -52,7 +52,7 @@ export const EMBEDDING_PROVIDERS: Record<string, EmbeddingProvider> = {
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
models: [
|
||||
{ id: "embed-v4.0", name: "Embed v4.0 Pro" },
|
||||
{ id: "embed-v4.0", name: "Embed v4.0" },
|
||||
{ id: "embed-multilingual-v3.0", name: "Embed Multilingual v3.0" },
|
||||
{ id: "embed-multilingual-v3.0-images", name: "Embed Multilingual v3.0 Image" },
|
||||
{ id: "embed-multilingual-light-v3.0", name: "Embed Multilingual Light v3.0" },
|
||||
@@ -189,19 +189,11 @@ export const EMBEDDING_PROVIDERS: Record<string, EmbeddingProvider> = {
|
||||
{ id: "voyage-4-large", name: "Voyage 4 Large", dimensions: 1024 },
|
||||
{ id: "voyage-4", name: "Voyage 4", dimensions: 1024 },
|
||||
{ id: "voyage-4-lite", name: "Voyage 4 Lite", dimensions: 1024 },
|
||||
{ id: "voyage-multilingual-3.5", name: "Voyage Multilingual 3.5", dimensions: 1024 },
|
||||
{ id: "voyage-code-3", name: "Voyage Code 3", dimensions: 1024 },
|
||||
{ id: "voyage-code-2", name: "Voyage Code 2", dimensions: 1536 },
|
||||
{ id: "voyage-finance-2", name: "Voyage Finance 2", dimensions: 1024 },
|
||||
{ id: "voyage-law-2", name: "Voyage Law 2", dimensions: 1024 },
|
||||
{ id: "voyage-code-2", name: "Voyage Code 2", dimensions: 1536 },
|
||||
{ id: "voyage-3-large", name: "Voyage 3 Large", dimensions: 1024 },
|
||||
{ id: "voyage-3.5", name: "Voyage 3.5", dimensions: 1024 },
|
||||
{ id: "voyage-3.5-lite", name: "Voyage 3.5 Lite", dimensions: 1024 },
|
||||
{ id: "voyage-3", name: "Voyage 3", dimensions: 1024 },
|
||||
{ id: "voyage-3-lite", name: "Voyage 3 Lite", dimensions: 512 },
|
||||
{ id: "voyage-multilingual-2", name: "Voyage Multilingual 2", dimensions: 1024 },
|
||||
{ id: "voyage-large-2-instruct", name: "Voyage Large 2 Instruct", dimensions: 1024 },
|
||||
{ id: "voyage-large-2", name: "Voyage Large 2", dimensions: 1536 },
|
||||
{ id: "voyage-2", name: "Voyage 2", dimensions: 1024 },
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -157,135 +157,6 @@ const KIMI_CODING_SHARED = {
|
||||
const buildModels = (ids: readonly string[]): RegistryModel[] =>
|
||||
ids.map((id) => ({ id, name: id }));
|
||||
|
||||
const COMMAND_CODE_MODELS: RegistryModel[] = [
|
||||
{
|
||||
id: "claude-opus-4-7",
|
||||
name: "Claude Opus 4.7 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 32000,
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-6",
|
||||
name: "Claude Opus 4.6 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 32000,
|
||||
},
|
||||
{
|
||||
id: "claude-sonnet-4-6",
|
||||
name: "Claude Sonnet 4.6 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 16384,
|
||||
},
|
||||
{
|
||||
id: "claude-haiku-4-5-20251001",
|
||||
name: "Claude Haiku 4.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 8192,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.5",
|
||||
name: "GPT-5.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.4",
|
||||
name: "GPT-5.4 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.3-codex",
|
||||
name: "GPT-5.3 Codex (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.4-mini",
|
||||
name: "GPT-5.4 Mini (CC)",
|
||||
supportsReasoning: false,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "deepseek/deepseek-v4-pro",
|
||||
name: "DeepSeek V4 Pro (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 384000,
|
||||
},
|
||||
{
|
||||
id: "deepseek/deepseek-v4-flash",
|
||||
name: "DeepSeek V4 Flash (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 384000,
|
||||
},
|
||||
{
|
||||
id: "moonshotai/Kimi-K2.6",
|
||||
name: "Kimi K2.6 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 262144,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "moonshotai/Kimi-K2.5",
|
||||
name: "Kimi K2.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 262144,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "zai-org/GLM-5.1",
|
||||
name: "GLM-5.1 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "zai-org/GLM-5",
|
||||
name: "GLM-5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "MiniMaxAI/MiniMax-M2.7",
|
||||
name: "MiniMax M2.7 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1048576,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "MiniMaxAI/MiniMax-M2.5",
|
||||
name: "MiniMax M2.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1048576,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "Qwen/Qwen3.6-Max-Preview",
|
||||
name: "Qwen 3.6 Max (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "Qwen/Qwen3.6-Plus",
|
||||
name: "Qwen 3.6 Plus (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
];
|
||||
|
||||
const GPT_5_5_CONTEXT_LENGTH = 1050000;
|
||||
const GPT_5_5_CODEX_CAPABILITIES = {
|
||||
targetFormat: "openai-responses",
|
||||
@@ -1143,7 +1014,134 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
authHeader: "Authorization",
|
||||
authPrefix: "Bearer ",
|
||||
defaultContextLength: 200000,
|
||||
models: COMMAND_CODE_MODELS,
|
||||
models: [
|
||||
{
|
||||
id: "claude-opus-4-7",
|
||||
name: "Claude Opus 4.7 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 32000,
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-6",
|
||||
name: "Claude Opus 4.6 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 32000,
|
||||
},
|
||||
{
|
||||
id: "claude-sonnet-4-6",
|
||||
name: "Claude Sonnet 4.6 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 16384,
|
||||
},
|
||||
{
|
||||
id: "claude-haiku-4-5-20251001",
|
||||
name: "Claude Haiku 4.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 8192,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.5",
|
||||
name: "GPT-5.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.4",
|
||||
name: "GPT-5.4 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.3-codex",
|
||||
name: "GPT-5.3 Codex (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "gpt-5.4-mini",
|
||||
name: "GPT-5.4 Mini (CC)",
|
||||
supportsReasoning: false,
|
||||
contextLength: 256000,
|
||||
maxOutputTokens: 128000,
|
||||
},
|
||||
{
|
||||
id: "deepseek/deepseek-v4-pro",
|
||||
name: "DeepSeek V4 Pro (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 384000,
|
||||
},
|
||||
{
|
||||
id: "deepseek/deepseek-v4-flash",
|
||||
name: "DeepSeek V4 Flash (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 384000,
|
||||
},
|
||||
{
|
||||
id: "moonshotai/Kimi-K2.6",
|
||||
name: "Kimi K2.6 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 262144,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "moonshotai/Kimi-K2.5",
|
||||
name: "Kimi K2.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 262144,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "zai-org/GLM-5.1",
|
||||
name: "GLM-5.1 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "zai-org/GLM-5",
|
||||
name: "GLM-5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 200000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "MiniMaxAI/MiniMax-M2.7",
|
||||
name: "MiniMax M2.7 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1048576,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "MiniMaxAI/MiniMax-M2.5",
|
||||
name: "MiniMax M2.5 (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1048576,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "Qwen/Qwen3.6-Max-Preview",
|
||||
name: "Qwen 3.6 Max (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
{
|
||||
id: "Qwen/Qwen3.6-Plus",
|
||||
name: "Qwen 3.6 Plus (CC)",
|
||||
supportsReasoning: true,
|
||||
contextLength: 1000000,
|
||||
maxOutputTokens: 131072,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
openrouter: {
|
||||
@@ -1604,25 +1602,31 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
// Seed list — runtime /v1/models discovery keeps this fresh.
|
||||
// Source: GET https://crof.ai/v1/models (2026-04-25).
|
||||
// Source: GET https://crof.ai/v1/models (2026-05-17).
|
||||
models: [
|
||||
{
|
||||
id: "deepseek-v4-pro-precision",
|
||||
name: "DeepSeek V4 Pro (Precision)",
|
||||
supportsReasoning: true,
|
||||
},
|
||||
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
|
||||
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
|
||||
{ id: "deepseek-v3.2", name: "DeepSeek V3.2" },
|
||||
{ id: "kimi-k2.6", name: "Kimi K2.6" },
|
||||
{ id: "kimi-k2.6-precision", name: "Kimi K2.6 (Precision)" },
|
||||
{ id: "kimi-k2.5", name: "Kimi K2.5" },
|
||||
{ id: "kimi-k2.5-lightning", name: "Kimi K2.5 (Lightning)" },
|
||||
{ id: "glm-5.1", name: "GLM 5.1" },
|
||||
{ id: "glm-5.1-precision", name: "GLM 5.1 (Precision)" },
|
||||
{ id: "glm-5", name: "GLM 5" },
|
||||
{ id: "kimi-k2.6-precision", name: "Kimi K2.6 (Precision)", supportsReasoning: true },
|
||||
{ id: "kimi-k2.6", name: "Kimi K2.6", supportsReasoning: true },
|
||||
{ id: "kimi-k2.5-lightning", name: "Kimi K2.5 (Lightning)", supportsReasoning: true },
|
||||
{ id: "kimi-k2.5", name: "Kimi K2.5", supportsReasoning: true },
|
||||
{ id: "glm-5.1-precision", name: "GLM 5.1 (Precision)", supportsReasoning: true },
|
||||
{ id: "glm-5.1", name: "GLM 5.1", supportsReasoning: true },
|
||||
{ id: "glm-4.7", name: "GLM 4.7" },
|
||||
{ id: "glm-4.7-flash", name: "GLM 4.7 Flash" },
|
||||
{ id: "gemma-4-31b-it", name: "Gemma 4 31B" },
|
||||
{ id: "mimo-v2.5-pro-precision", name: "Mimo 2.5 Pro (Precision)", supportsReasoning: true },
|
||||
{ id: "mimo-v2.5-pro", name: "Mimo 2.5 Pro", supportsReasoning: true },
|
||||
{ id: "gemma-4-31b-it", name: "Gemma 4 31B", supportsReasoning: true },
|
||||
{ id: "minimax-m2.5", name: "MiniMax M2.5" },
|
||||
{ id: "qwen3.6-27b", name: "Qwen3.6 27B" },
|
||||
{ id: "qwen3.5-397b-a17b", name: "Qwen3.5 397B A17B" },
|
||||
{ id: "qwen3.5-9b", name: "Qwen3.5 9B" },
|
||||
{ id: "qwen3.5-9b-chat", name: "Qwen3.5 9B (Chat)" },
|
||||
{ id: "qwen3.6-27b", name: "Qwen3.6 27B", supportsReasoning: true },
|
||||
{ id: "qwen3.5-397b-a17b", name: "Qwen3.5 397B A17B", supportsReasoning: true },
|
||||
{ id: "qwen3.5-9b", name: "Qwen3.5 9B", supportsReasoning: true },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1675,8 +1679,8 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
models: [
|
||||
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
|
||||
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
|
||||
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1689,10 +1693,11 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
models: [
|
||||
{ id: "meta-llama/llama-4-scout-17b-16e-instruct", name: "Llama 4 Scout" },
|
||||
{ id: "llama-3.3-70b-versatile", name: "Llama 3.3 70B" },
|
||||
{ id: "meta-llama/llama-4-maverick-17b-128e-instruct", name: "Llama 4 Maverick" },
|
||||
{ id: "qwen/qwen3-32b", name: "Qwen3 32B" },
|
||||
{ id: "openai/gpt-oss-120b", name: "GPT-OSS 120B" },
|
||||
{ id: "openai/gpt-oss-20b", name: "GPT-OSS 20B" },
|
||||
{ id: "qwen/qwen3-32b", name: "Qwen3 32B" },
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -55,10 +55,6 @@ export const RERANK_PROVIDERS = {
|
||||
models: [
|
||||
{ id: "rerank-2.5", name: "Rerank 2.5" },
|
||||
{ id: "rerank-2.5-lite", name: "Rerank 2.5 Lite" },
|
||||
{ id: "rerank-2", name: "Rerank 2" },
|
||||
{ id: "rerank-2-lite", name: "Rerank 2 Lite" },
|
||||
{ id: "rerank-1", name: "Rerank 1" },
|
||||
{ id: "rerank-lite-1", name: "Rerank Lite 1" },
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -94,7 +94,16 @@ function buildSection(title: string, rows: ProviderRecord[], category: string):
|
||||
|
||||
function buildHeader(total: number): string {
|
||||
const date = new Date().toISOString().slice(0, 10);
|
||||
const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8")) as {
|
||||
version?: string;
|
||||
};
|
||||
return [
|
||||
"---",
|
||||
'title: "Provider Reference"',
|
||||
`version: ${pkg.version || "unknown"}`,
|
||||
`lastUpdated: ${date}`,
|
||||
"---",
|
||||
"",
|
||||
"# Provider Reference",
|
||||
"",
|
||||
`> **Auto-generated** from \`src/shared/constants/providers.ts\` — do not edit by hand.`,
|
||||
@@ -166,16 +175,16 @@ function main() {
|
||||
const footer = [
|
||||
"## Sources of truth",
|
||||
"",
|
||||
"- Catalog: [`src/shared/constants/providers.ts`](../src/shared/constants/providers.ts)",
|
||||
"- Registry (per-model details): [`open-sse/config/providerRegistry.ts`](../open-sse/config/providerRegistry.ts)",
|
||||
"- Executors: [`open-sse/executors/`](../open-sse/executors/) (31 files)",
|
||||
"- Translators: [`open-sse/translator/`](../open-sse/translator/)",
|
||||
"- Catalog: [`src/shared/constants/providers.ts`](../../src/shared/constants/providers.ts)",
|
||||
"- Registry (per-model details): [`open-sse/config/providerRegistry.ts`](../../open-sse/config/providerRegistry.ts)",
|
||||
"- Executors: [`open-sse/executors/`](../../open-sse/executors/) (31 files)",
|
||||
"- Translators: [`open-sse/translator/`](../../open-sse/translator/)",
|
||||
"",
|
||||
"## See Also",
|
||||
"",
|
||||
"- [FREE_TIERS.md](./FREE_TIERS.md) — curated free-tier guide",
|
||||
"- [USER_GUIDE.md](./USER_GUIDE.md) — provider setup walkthrough",
|
||||
"- [ARCHITECTURE.md](./ARCHITECTURE.md) — overall architecture",
|
||||
"- [USER_GUIDE.md](../guides/USER_GUIDE.md) — provider setup walkthrough",
|
||||
"- [ARCHITECTURE.md](../architecture/ARCHITECTURE.md) — overall architecture",
|
||||
"",
|
||||
].join("\n");
|
||||
|
||||
|
||||
@@ -28,6 +28,22 @@ type GetProviderStats = (
|
||||
authType: "oauth" | "free" | "apikey"
|
||||
) => ProviderStatsSnapshot;
|
||||
|
||||
function getProviderSortLabel<TProvider>(entry: ProviderEntry<TProvider>): string {
|
||||
const provider = entry.provider as Record<string, unknown>;
|
||||
const name = typeof provider.name === "string" ? provider.name : "";
|
||||
return (name || entry.providerId).toLowerCase();
|
||||
}
|
||||
|
||||
export function sortProviderEntriesByName<TProvider>(
|
||||
entries: ProviderEntry<TProvider>[]
|
||||
): ProviderEntry<TProvider>[] {
|
||||
return [...entries].sort((a, b) => {
|
||||
const nameCompare = getProviderSortLabel(a).localeCompare(getProviderSortLabel(b));
|
||||
if (nameCompare !== 0) return nameCompare;
|
||||
return a.providerId.localeCompare(b.providerId);
|
||||
});
|
||||
}
|
||||
|
||||
export function buildProviderEntries<TProvider = Record<string, unknown>>(
|
||||
providers: ProviderRecord<TProvider>,
|
||||
displayAuthType: ProviderEntry["displayAuthType"],
|
||||
@@ -88,7 +104,7 @@ export function filterConfiguredProviderEntries<TProvider>(
|
||||
});
|
||||
}
|
||||
|
||||
return filtered;
|
||||
return sortProviderEntriesByName(filtered);
|
||||
}
|
||||
|
||||
export function resolveDashboardProviderInfo(
|
||||
|
||||
@@ -291,6 +291,7 @@ const LOBE_PROVIDER_ALIASES = {
|
||||
"cloudflare-ai": "WorkersAI",
|
||||
codestral: "Mistral",
|
||||
codex: "Codex",
|
||||
"codex-cloud": "Codex",
|
||||
cohere: "Cohere",
|
||||
comfyui: "ComfyUI",
|
||||
copilot: "GithubCopilot",
|
||||
@@ -298,6 +299,7 @@ const LOBE_PROVIDER_ALIASES = {
|
||||
databricks: "Dbrx",
|
||||
deepinfra: "DeepInfra",
|
||||
deepseek: "DeepSeek",
|
||||
"deepseek-web": "DeepSeek",
|
||||
elevenlabs: "ElevenLabs",
|
||||
exa: "Exa",
|
||||
"exa-search": "Exa",
|
||||
@@ -352,6 +354,7 @@ const LOBE_PROVIDER_ALIASES = {
|
||||
nvidia: "Nvidia",
|
||||
ollama: "Ollama",
|
||||
"ollama-cloud": "Ollama",
|
||||
"ollama-search": "Ollama",
|
||||
openai: "OpenAI",
|
||||
openclaw: "OpenClaw",
|
||||
opencode: "OpenCode",
|
||||
|
||||
Reference in New Issue
Block a user