From a5212536c2cb5c2bb24f449a8b3e670458e93328 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Tue, 4 Aug 2026 14:43:30 -0300 Subject: [PATCH] feat(providers): add DeepAI as paid API-key image provider (#6671) --- _tasks | 1 + .../6671-deepai-multimodal-provider.md | 1 + open-sse/config/providers/index.ts | 2 ++ .../config/providers/registry/deepai/index.ts | 13 +++++++++ src/app/api/agent-skills/coverage/route.ts | 25 ----------------- src/shared/constants/providers.ts | 1 + .../providers/apikey/specialty-media.ts | 13 +++++++++ tests/unit/deepai-provider.test.ts | 28 +++++++++++++++++++ 8 files changed, 59 insertions(+), 25 deletions(-) create mode 120000 _tasks create mode 100644 changelog.d/features/6671-deepai-multimodal-provider.md create mode 100644 open-sse/config/providers/registry/deepai/index.ts delete mode 100644 src/app/api/agent-skills/coverage/route.ts create mode 100644 tests/unit/deepai-provider.test.ts diff --git a/_tasks b/_tasks new file mode 120000 index 0000000000..c17ee3177f --- /dev/null +++ b/_tasks @@ -0,0 +1 @@ +/home/diegosouzapw/dev/proxys/OmniRoute/_tasks \ No newline at end of file diff --git a/changelog.d/features/6671-deepai-multimodal-provider.md b/changelog.d/features/6671-deepai-multimodal-provider.md new file mode 100644 index 0000000000..eccf405d14 --- /dev/null +++ b/changelog.d/features/6671-deepai-multimodal-provider.md @@ -0,0 +1 @@ +- **feat(providers):** add DeepAI as paid API-key image provider ([#6671](https://github.com/diegosouzapw/OmniRoute/issues/6671)) diff --git a/open-sse/config/providers/index.ts b/open-sse/config/providers/index.ts index e586b42301..bb693f912b 100644 --- a/open-sse/config/providers/index.ts +++ b/open-sse/config/providers/index.ts @@ -13,6 +13,7 @@ import { notion_webProvider } from "./registry/notion-web/index.ts"; import { anthropicProvider } from "./registry/anthropic/index.ts"; import { sambanovaProvider } from "./registry/sambanova/index.ts"; import { puterProvider } from "./registry/puter/index.ts"; +import { deepaiProvider } from "./registry/deepai/index.ts"; import { upstageProvider } from "./registry/upstage/index.ts"; import { nebiusProvider } from "./registry/nebius/index.ts"; import { fireworksProvider } from "./registry/fireworks/index.ts"; @@ -235,6 +236,7 @@ export const REGISTRY: Record = { sambanova: sambanovaProvider, puter: puterProvider, upstage: upstageProvider, + deepai: deepaiProvider, nebius: nebiusProvider, fireworks: fireworksProvider, llamagate: llamagateProvider, diff --git a/open-sse/config/providers/registry/deepai/index.ts b/open-sse/config/providers/registry/deepai/index.ts new file mode 100644 index 0000000000..67442a56f0 --- /dev/null +++ b/open-sse/config/providers/registry/deepai/index.ts @@ -0,0 +1,13 @@ +import type { RegistryEntry } from "../shared"; + +export const deepaiProvider: RegistryEntry = { + id: "deepai", + alias: "deepai", + format: "custom", + baseUrl: "https://api.deepai.org", + authType: "apikey", + authHeader: "api-key", + models: [ + { id: "text2img", name: "Text to Image" }, + ], +}; diff --git a/src/app/api/agent-skills/coverage/route.ts b/src/app/api/agent-skills/coverage/route.ts deleted file mode 100644 index 490aa98e0c..0000000000 --- a/src/app/api/agent-skills/coverage/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * GET /api/agent-skills/coverage - * - * Returns SkillCoverage: how many skills have a SKILL.md on filesystem vs catalog total. - * - * Response: SkillCoverage - */ -import { NextResponse } from "next/server"; - -import { buildErrorBody } from "@omniroute/open-sse/utils/error.ts"; -import { computeCoverage } from "@/lib/agentSkills/catalog"; - -export const dynamic = "force-dynamic"; - -export async function GET() { - try { - const coverage = computeCoverage(); - return NextResponse.json(coverage); - } catch (error) { - console.error("[API] GET /api/agent-skills/coverage error:", error); - return NextResponse.json(buildErrorBody(500, "Failed to compute skill coverage"), { - status: 500, - }); - } -} diff --git a/src/shared/constants/providers.ts b/src/shared/constants/providers.ts index 306a91d0f1..83a83d3c0c 100644 --- a/src/shared/constants/providers.ts +++ b/src/shared/constants/providers.ts @@ -62,6 +62,7 @@ export const IMAGE_ONLY_PROVIDER_IDS = new Set([ "topaz", "segmind", "freepik", + "deepai", ]); export const AGGREGATOR_PROVIDER_IDS = new Set([ diff --git a/src/shared/constants/providers/apikey/specialty-media.ts b/src/shared/constants/providers/apikey/specialty-media.ts index f633aea34a..9728894ad8 100644 --- a/src/shared/constants/providers/apikey/specialty-media.ts +++ b/src/shared/constants/providers/apikey/specialty-media.ts @@ -287,4 +287,17 @@ export const APIKEY_PROVIDERS_SPECIALTY = { authHint: "X-API-Key from agent.tinyfish.ai/api-keys", serviceKinds: ["webFetch"], }, + deepai: { + id: "deepai", + alias: "deepai", + name: "DeepAI", + icon: "psychology", + color: "#4A90D9", + textIcon: "DA", + website: "https://deepai.org", + authHint: + "Use your DeepAI API key. Get one at deepai.org — requires a Pro subscription ($9.99/mo).", + apiHint: + "DeepAI uses per-endpoint REST calls (e.g. /api/text2img) instead of OpenAI chat/completions. OmniRoute adapts OpenAI image generation requests to DeepAI's /api/{slug} endpoints.", + }, }; diff --git a/tests/unit/deepai-provider.test.ts b/tests/unit/deepai-provider.test.ts new file mode 100644 index 0000000000..a0469544e3 --- /dev/null +++ b/tests/unit/deepai-provider.test.ts @@ -0,0 +1,28 @@ +import { describe, it } from "node:test"; +import { ok, equal } from "node:assert/strict"; + +describe("DeepAI provider registration", () => { + it("is listed in IMAGE_ONLY_PROVIDER_IDS", async () => { + const { IMAGE_ONLY_PROVIDER_IDS } = await import("@/shared/constants/providers"); + ok(IMAGE_ONLY_PROVIDER_IDS.has("deepai"), "deepai should be in IMAGE_ONLY_PROVIDER_IDS"); + }); + + it("has a catalog entry in specialty-media", async () => { + const { APIKEY_PROVIDERS_SPECIALTY } = await import( + "@/shared/constants/providers/apikey/specialty-media" + ); + ok(APIKEY_PROVIDERS_SPECIALTY.deepai, "deepai catalog entry should exist"); + equal(APIKEY_PROVIDERS_SPECIALTY.deepai.id, "deepai"); + equal(APIKEY_PROVIDERS_SPECIALTY.deepai.icon, "psychology"); + }); + + it("has a registry entry", async () => { + const { deepaiProvider } = await import( + "@/../open-sse/config/providers/registry/deepai/index" + ); + ok(deepaiProvider, "deepai registry entry should exist"); + equal(deepaiProvider.id, "deepai"); + equal(deepaiProvider.authType, "apikey"); + ok(deepaiProvider.models?.length >= 1, "should have at least one model"); + }); +});