feat(providers): add Venice AI provider

OpenAI-compatible apikey provider (chat/embedding/image) with dynamic
model discovery via modelsFetcher + passthroughModels. No executor needed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Brokenc0de
2026-06-26 11:37:44 +07:00
committed by decolua
co-authored by Cursor
parent eb9728d084
commit ab5ec52f28
3 changed files with 124 additions and 25 deletions
+27 -25
View File
@@ -1,6 +1,6 @@
// Auto-generated: static imports of all registry entries
import p0 from "./alicode.js";
import p1 from "./alicode-intl.js";
import p0 from "./alicode-intl.js";
import p1 from "./alicode.js";
import p2 from "./anthropic.js";
import p3 from "./antigravity.js";
import p4 from "./assemblyai.js";
@@ -31,12 +31,12 @@ import p28 from "./exa.js";
import p29 from "./fal-ai.js";
import p30 from "./firecrawl.js";
import p31 from "./fireworks.js";
import p32 from "./gemini.js";
import p33 from "./gemini-cli.js";
import p32 from "./gemini-cli.js";
import p33 from "./gemini.js";
import p34 from "./github.js";
import p35 from "./gitlab.js";
import p36 from "./glm.js";
import p37 from "./glm-cn.js";
import p36 from "./glm-cn.js";
import p37 from "./glm.js";
import p38 from "./google-pse.js";
import p39 from "./google-tts.js";
import p40 from "./grok-web.js";
@@ -48,27 +48,27 @@ import p45 from "./inworld.js";
import p46 from "./jina-ai.js";
import p47 from "./jina-reader.js";
import p48 from "./kilocode.js";
import p49 from "./kimi.js";
import p50 from "./kimi-coding.js";
import p49 from "./kimi-coding.js";
import p50 from "./kimi.js";
import p51 from "./kiro.js";
import p52 from "./linkup.js";
import p53 from "./local-device.js";
import p54 from "./mimo-free.js";
import p55 from "./minimax.js";
import p56 from "./minimax-cn.js";
import p55 from "./minimax-cn.js";
import p56 from "./minimax.js";
import p57 from "./mistral.js";
import p58 from "./mmf.js";
import p59 from "./nanobanana.js";
import p60 from "./nebius.js";
import p61 from "./nvidia.js";
import p62 from "./ollama.js";
import p63 from "./ollama-local.js";
import p62 from "./ollama-local.js";
import p63 from "./ollama.js";
import p64 from "./openai.js";
import p65 from "./opencode.js";
import p66 from "./opencode-go.js";
import p65 from "./opencode-go.js";
import p66 from "./opencode.js";
import p67 from "./openrouter.js";
import p68 from "./perplexity.js";
import p69 from "./perplexity-web.js";
import p68 from "./perplexity-web.js";
import p69 from "./perplexity.js";
import p70 from "./playht.js";
import p71 from "./qoder.js";
import p72 from "./qwen.js";
@@ -84,15 +84,16 @@ import p81 from "./tavily.js";
import p82 from "./together.js";
import p83 from "./topaz.js";
import p84 from "./tortoise.js";
import p85 from "./vercel-ai-gateway.js";
import p86 from "./vertex.js";
import p85 from "./venice.js";
import p86 from "./vercel-ai-gateway.js";
import p87 from "./vertex-partner.js";
import p88 from "./volcengine-ark.js";
import p89 from "./voyage-ai.js";
import p90 from "./xai.js";
import p91 from "./xiaomi-mimo.js";
import p92 from "./xiaomi-tokenplan.js";
import p93 from "./youcom.js";
import p88 from "./vertex.js";
import p89 from "./volcengine-ark.js";
import p90 from "./voyage-ai.js";
import p91 from "./xai.js";
import p92 from "./xiaomi-mimo.js";
import p93 from "./xiaomi-tokenplan.js";
import p94 from "./youcom.js";
export default [
p0,
@@ -188,5 +189,6 @@ export default [
p90,
p91,
p92,
p93
p93,
p94
];
+56
View File
@@ -0,0 +1,56 @@
export default {
id: "venice",
priority: 115,
alias: "venice",
aliases: [
"vn",
],
uiAlias: "venice",
display: {
name: "Venice AI",
icon: "shield",
color: "#DC2626",
textIcon: "VE",
website: "https://venice.ai",
notice: {
text: "OpenAI-compatible. Private inference + uncensored models (Venice Uncensored, GLM, Qwen, DeepSeek, Llama).",
apiKeyUrl: "https://venice.ai/settings/api",
},
},
category: "apikey",
transport: {
baseUrl: "https://api.venice.ai/api/v1/chat/completions",
validateUrl: "https://api.venice.ai/api/v1/models",
thinkingFormat: "openai",
},
// Curated seed; the full live catalogue (90+ text models) is fetched via
// modelsFetcher and any other id is accepted via passthroughModels.
models: [
{ id: "venice-uncensored-1-2", name: "Venice Uncensored 1.2" },
{ id: "zai-org-glm-5", name: "GLM-5" },
{ id: "qwen3-235b-a22b-instruct-2507", name: "Qwen3 235B A22B Instruct" },
{ id: "qwen3-coder-480b-a35b-instruct-turbo", name: "Qwen3 Coder 480B A35B Turbo" },
{ id: "qwen3-vl-235b-a22b", name: "Qwen3 VL 235B A22B" },
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro" },
{ id: "llama-3.3-70b", name: "Llama 3.3 70B" },
{ id: "hermes-3-llama-3.1-405b", name: "Hermes 3 Llama 3.1 405B" },
{ id: "mistral-small-3-2-24b-instruct", name: "Mistral Small 3.2 24B" },
{ id: "text-embedding-3-large", name: "Text Embedding 3 Large", kind: "embedding" },
{ id: "text-embedding-bge-m3", name: "BGE-M3 Embedding", kind: "embedding" },
{ id: "text-embedding-qwen3-8b", name: "Qwen3 8B Embedding", kind: "embedding" },
{ id: "venice-sd35", name: "Venice SD3.5", params: ["n", "size"], kind: "image" },
{ id: "flux-2-pro", name: "FLUX.2 Pro", params: ["n", "size"], kind: "image" },
{ id: "gpt-image-2", name: "GPT Image 2 (via Venice)", params: ["n", "size", "quality"], kind: "image" },
],
serviceKinds: ["llm", "embedding", "image"],
embeddingConfig: {
baseUrl: "https://api.venice.ai/api/v1/embeddings",
authType: "apikey",
authHeader: "bearer",
},
imageConfig: {
baseUrl: "https://api.venice.ai/api/v1/images/generations",
},
modelsFetcher: { url: "https://api.venice.ai/api/v1/models", type: "openai" },
passthroughModels: true,
};
+41
View File
@@ -0,0 +1,41 @@
import { describe, expect, it } from "vitest";
import REGISTRY from "../../open-sse/providers/registry/index.js";
import { PROVIDERS, PROVIDER_MODELS } from "../../open-sse/providers/index.js";
describe("Venice AI provider", () => {
const venice = REGISTRY.find((e) => e.id === "venice");
it("is registered as an OpenAI-compatible apikey provider", () => {
expect(venice).toBeDefined();
expect(venice.category).toBe("apikey");
expect(venice.transport.baseUrl).toBe("https://api.venice.ai/api/v1/chat/completions");
expect(venice.alias).toBe("venice");
expect(venice.aliases).toContain("vn");
});
it("enables dynamic model discovery and passthrough", () => {
expect(venice.passthroughModels).toBe(true);
expect(venice.modelsFetcher).toMatchObject({
url: "https://api.venice.ai/api/v1/models",
type: "openai",
});
});
it("builds into the runtime PROVIDERS map with the openai format default", () => {
expect(PROVIDERS.venice).toBeDefined();
expect(PROVIDERS.venice.format).toBe("openai");
expect(PROVIDERS.venice.baseUrl).toBe("https://api.venice.ai/api/v1/chat/completions");
});
it("exposes its seed models (incl. the signature uncensored model)", () => {
const ids = (PROVIDER_MODELS.venice || []).map((m) => m.id);
expect(ids.length).toBeGreaterThan(0);
expect(ids).toContain("venice-uncensored-1-2");
});
it("keeps every registry id unique after adding venice", () => {
const ids = REGISTRY.map((e) => e.id);
expect(new Set(ids).size).toBe(ids.length);
});
});