Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ LLM_AZURE_API_KEY=your_azure_key_here
# DeepInfra
LLM_DEEPINFRA_API_KEY=your_deepinfra_key_here

# deAPI
LLM_DEAPI_API_KEY=your_deapi_key_here

# Azure AI Foundry (third-party models like Grok, Llama, Mistral)
LLM_AZURE_AI_FOUNDRY_API_KEY=your_azure_ai_foundry_key_here
LLM_AZURE_AI_FOUNDRY_RESOURCE=your_azure_ai_foundry_resource_here
Expand Down
1 change: 1 addition & 0 deletions apps/gateway/src/embeddings/embeddings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ embeddings.openapi(createEmbeddings, async (c): Promise<any> => {
openai: "https://api.openai.com",
"google-ai-studio": "https://generativelanguage.googleapis.com",
"google-vertex": "https://aiplatform.googleapis.com",
deapi: "https://oai.deapi.ai",
};

interface EmbeddingAttempt {
Expand Down
1 change: 1 addition & 0 deletions apps/ui/src/components/provider-keys/provider-logo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const providerLogoUrls: Partial<
xiaomi: ProviderIcons.xiaomi,
embercloud: ProviderIcons.embercloud,
deepinfra: ProviderIcons.deepinfra,
deapi: ProviderIcons.deapi,
};

export const getProviderLogoDarkModeClasses = () => {
Expand Down
6 changes: 6 additions & 0 deletions packages/actions/src/get-provider-endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ export function getProviderEndpoint(
case "deepinfra":
url = "https://api.deepinfra.com/v1/openai";
break;
// deAPI is currently wired for embeddings only (the embeddings route
// resolves its own URL). This base-URL case keeps the provider
// resolvable for forward-compatibility with image/audio endpoints.
case "deapi":
url = "https://oai.deapi.ai";
break;
case "custom":
if (!baseUrl) {
throw new Error(`Custom provider requires a baseUrl`);
Expand Down
1 change: 1 addition & 0 deletions packages/actions/src/get-provider-headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export function getProviderHeaders(
case "canopywave":
case "embercloud":
case "deepinfra":
case "deapi":
case "custom":
default:
return {
Expand Down
16 changes: 16 additions & 0 deletions packages/actions/src/validate-provider-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ export async function validateProviderKey(
validationModel =
getValidationModel(provider, providerKeyOptions) ?? undefined;
if (!validationModel) {
// Embeddings-only providers (e.g. deAPI) expose no chat/completions
// model, and getValidationModel deliberately excludes embeddings
// models. There is nothing to validate via a chat request, so skip
// live validation for them (mirroring the `custom` provider) instead
// of failing key creation. This only fires when EVERY model for the
// provider is embeddings-only, so chat-capable providers are never
// affected even if their chat models are temporarily unavailable.
const providerMappings = models.flatMap((model) =>
model.providers.filter((p) => p.providerId === provider),
) as ProviderModelMapping[];
const isEmbeddingsOnlyProvider =
providerMappings.length > 0 &&
providerMappings.every((p) => p.embeddings === true);
if (isEmbeddingsOnlyProvider) {
return { valid: true };
}
throw new Error(
`No suitable validation model found for provider ${provider}`,
);
Expand Down
2 changes: 2 additions & 0 deletions packages/models/src/models.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { alibabaModels } from "./models/alibaba.js";
import { anthropicModels } from "./models/anthropic.js";
import { bytedanceModels } from "./models/bytedance.js";
import { deapiModels } from "./models/deapi.js";
import { deepseekModels } from "./models/deepseek.js";
import { googleModels } from "./models/google.js";
import { llmgatewayModels } from "./models/llmgateway.js";
Expand Down Expand Up @@ -529,6 +530,7 @@ export const models = [
...moonshotModels,
...alibabaModels,
...bytedanceModels,
...deapiModels,
...nousresearchModels,
...zaiModels,
] as const satisfies ModelDefinition[];
27 changes: 27 additions & 0 deletions packages/models/src/models/deapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { ModelDefinition } from "@/models.js";

export const deapiModels = [
{
id: "bge-m3",
name: "BGE-M3",
description:
"Multilingual BGE-M3 embedding model from BAAI (1024-dimensional output, 8192-token context). Served through deAPI's OpenAI-compatible /v1/embeddings endpoint.",
family: "deapi",
output: ["embedding"],
releasedAt: new Date("2024-01-30"),
providers: [
{
providerId: "deapi",
externalId: "Bge_M3_FP16",
inputPrice: "0.068e-6",
outputPrice: "0",
requestPrice: "0",
contextSize: 8192,
streaming: false,
tools: false,
jsonOutput: false,
embeddings: true,
},
],
},
] as const satisfies ModelDefinition[];
29 changes: 29 additions & 0 deletions packages/models/src/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,35 @@ export const providers: ProviderDefinition[] = [
gdpr: true,
},
},
{
id: "deapi",
name: "deAPI",
description:
"deAPI is an OpenAI-compatible inference platform for open-source models, operated by CoinAxe Ltd (Malta). This integration currently exposes deAPI's embedding models.",
env: {
required: {
apiKey: "LLM_DEAPI_API_KEY",
},
optional: {
baseUrl: "LLM_DEAPI_BASE_URL",
},
},
streaming: false,
cancellation: false,
color: "#FFBA00",
website: "https://deapi.ai",
announcement: null,
termsUrl: "https://deapi.ai/terms-of-service",
privacyPolicyUrl: "https://deapi.ai/privacy-policy",
headquarters: "MT",
dataPolicy: {
apiTraining: null,
consumerTraining: null,
promptLogging: true,
retentionPeriod: "90 days",
gdpr: true,
},
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
] as const satisfies ProviderDefinition[];

export type ProviderId = (typeof providers)[number]["id"];
Expand Down
18 changes: 18 additions & 0 deletions packages/shared/src/components/provider-icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,22 @@ export const DeepInfraIcon: React.FC<React.SVGProps<SVGSVGElement>> = (
</svg>
);

// deAPI Icon
export const DeAPIIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 29.095 32"
>
<path
fill="currentColor"
fillRule="nonzero"
d="M 23.899 26.311 L 25.051 25.18 L 25.051 22.246 L 29.095 22.246 L 29.095 19.984 L 25.051 19.984 L 25.051 17.131 L 29.095 17.131 L 29.095 14.87 L 25.051 14.87 L 25.051 12.017 L 29.095 12.017 L 29.095 9.755 L 25.051 9.755 L 25.051 6.821 L 23.899 5.69 L 20.91 5.69 L 20.91 3.116 L 18.606 1.81 L 18.606 5.689 L 15.699 5.689 L 15.699 0.163 L 15.412 0 L 13.684 0 L 13.396 0.163 L 13.396 5.689 L 10.489 5.689 L 10.489 1.81 L 8.186 3.116 L 8.186 5.69 L 5.196 5.69 L 4.044 6.821 L 4.044 9.755 L 0 9.755 L 0 12.017 L 4.044 12.017 L 4.044 14.87 L 0 14.87 L 0 17.131 L 4.044 17.131 L 4.044 19.984 L 0 19.984 L 0 22.246 L 4.044 22.246 L 4.044 25.18 L 5.196 26.311 L 8.186 26.311 L 8.186 28.884 L 10.489 30.19 L 10.489 26.311 L 13.396 26.311 L 13.396 31.837 L 13.684 32 L 15.412 32 L 15.699 31.837 L 15.699 26.311 L 18.606 26.311 L 18.606 30.19 L 20.91 28.884 L 20.91 26.311 L 23.899 26.311 Z M 6.348 24.049 L 6.348 7.951 L 22.747 7.951 L 22.747 24.048 L 6.348 24.049 Z M 17.986 9.729 L 20.889 9.729 L 11.105 22.27 L 8.202 22.27 L 17.986 9.729 Z"
/>
</svg>
);

export const ProviderIcons = {
anthropic: AnthropicIcon,
bytedance: BytedanceIcon,
Expand Down Expand Up @@ -1317,6 +1333,7 @@ export const ProviderIcons = {
xiaomi: XiaomiIcon,
embercloud: EmberCloudIcon,
deepinfra: DeepInfraIcon,
deapi: DeAPIIcon,
} as const;

// Type for provider icon keys
Expand Down Expand Up @@ -1356,6 +1373,7 @@ export const providerLogoUrls: Partial<
xiaomi: ProviderIcons.xiaomi,
embercloud: ProviderIcons.embercloud,
deepinfra: ProviderIcons.deepinfra,
deapi: ProviderIcons.deapi,
};

export const getProviderLogoDarkModeClasses = () => {
Expand Down
Loading