diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index 08c8eef6dd..9ca49f5dd2 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -641,6 +641,25 @@ export const REGISTRY: Record = { ], }, + blackbox: { + id: "blackbox", + alias: "bb", + format: "openai", + executor: "default", + baseUrl: "https://api.blackbox.ai/v1/chat/completions", + modelsUrl: "https://api.blackbox.ai/v1/models", + authType: "apikey", + authHeader: "bearer", + models: [ + { id: "gpt-4o", name: "GPT-4o" }, + { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash" }, + { id: "claude-sonnet-4", name: "Claude Sonnet 4" }, + { id: "deepseek-v3", name: "DeepSeek V3" }, + { id: "blackboxai", name: "Blackbox AI" }, + { id: "blackboxai-pro", name: "Blackbox AI Pro" }, + ], + }, + xai: { id: "xai", alias: "xai", diff --git a/open-sse/executors/antigravity.ts b/open-sse/executors/antigravity.ts index 3f38ba184e..ad5fdaae67 100644 --- a/open-sse/executors/antigravity.ts +++ b/open-sse/executors/antigravity.ts @@ -36,7 +36,18 @@ export class AntigravityExecutor extends BaseExecutor { } transformRequest(model, body, stream, credentials) { - const projectId = credentials?.projectId || this.generateProjectId(); + const bodyProjectId = body?.project; + const credentialsProjectId = credentials?.projectId; + const hasExplicitProject = !!(bodyProjectId || credentialsProjectId); + const projectId = bodyProjectId || credentialsProjectId || this.generateProjectId(); + + if (!hasExplicitProject) { + console.warn( + `[Antigravity] ⚠️ No projectId provided via body or credentials — using generated fallback "${projectId}". ` + + `This may cause 404 errors if the account has no active GCP project. ` + + `Ensure the OAuth token includes a valid project or the request includes a project field.` + ); + } // Fix contents for Claude models via Antigravity const normalizedContents = diff --git a/open-sse/translator/request/openai-to-gemini.ts b/open-sse/translator/request/openai-to-gemini.ts index 6f3ca2ab65..6f5a0365c7 100644 --- a/open-sse/translator/request/openai-to-gemini.ts +++ b/open-sse/translator/request/openai-to-gemini.ts @@ -271,8 +271,16 @@ export function openaiToGeminiCLIRequest(model, body, stream) { // Wrap Gemini CLI format in Cloud Code wrapper function wrapInCloudCodeEnvelope(model, geminiCLI, credentials = null, isAntigravity = false) { + const hasRealProject = !!credentials?.projectId; const projectId = credentials?.projectId || generateProjectId(); + if (!hasRealProject) { + console.warn( + `[${isAntigravity ? "Antigravity" : "GeminiCLI"}] ⚠️ No projectId in credentials — using generated fallback "${projectId}". ` + + `This may cause 404 errors. Ensure the OAuth token includes a valid GCP project.` + ); + } + const cleanModel = model.includes("/") ? model.split("/").pop()! : model; const envelope: Record = { @@ -315,10 +323,17 @@ function wrapInCloudCodeEnvelope(model, geminiCLI, credentials = null, isAntigra return envelope; } -// Wrap Claude format in Cloud Code envelope for Antigravity function wrapInCloudCodeEnvelopeForClaude(model, claudeRequest, credentials = null) { + const hasRealProject = !!credentials?.projectId; const projectId = credentials?.projectId || generateProjectId(); + if (!hasRealProject) { + console.warn( + `[Antigravity/Claude] ⚠️ No projectId in credentials — using generated fallback "${projectId}". ` + + `This may cause 404 errors. Ensure the OAuth token includes a valid GCP project.` + ); + } + const cleanModel = model.includes("/") ? model.split("/").pop()! : model; const envelope: Record = { diff --git a/public/providers/blackbox.png b/public/providers/blackbox.png new file mode 100644 index 0000000000..5c836c9669 Binary files /dev/null and b/public/providers/blackbox.png differ