From 297cb9c8f2f0ecbcb9410455a9626231a9c76a8b Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Fri, 7 Aug 2026 12:25:29 -0400 Subject: [PATCH] set provider default capabilities --- server/lib/aiCapabilities.ts | 37 -------------- server/lib/aiProviderDefaults.ts | 51 ++++++++++++++++--- server/routers/aiProvider/createAiProvider.ts | 12 ++--- src/lib/aiProviderFormSchema.ts | 7 +-- 4 files changed, 51 insertions(+), 56 deletions(-) diff --git a/server/lib/aiCapabilities.ts b/server/lib/aiCapabilities.ts index 356122e7f..2b3691493 100644 --- a/server/lib/aiCapabilities.ts +++ b/server/lib/aiCapabilities.ts @@ -1,5 +1,4 @@ import type { Request } from "express"; -import type { AiProviderType } from "@server/lib/aiProviderDefaults"; export const AI_CAPABILITIES = [ "openai_chat", @@ -188,20 +187,6 @@ export const AI_CAPABILITY_DEFS: Record = } }; -export const AI_PROVIDER_CAPABILITY_DEFAULTS: Record< - Exclude, - readonly AiCapability[] -> = { - openai: ["openai_chat"], - anthropic: ["anthropic_messages"], - googleGemini: ["gemini_generate_content"], - vertexAi: ["google_generate_content"], - bedrock: ["bedrock_converse"], - microsoftFoundry: ["openai_chat"], - openRouter: ["openai_chat"], - vercelAiGateway: ["openai_chat"] -}; - export function isAiCapability(value: unknown): value is AiCapability { return ( typeof value === "string" && @@ -256,25 +241,3 @@ export function providerHasCapability( : capabilities; return list.includes(capability); } - -export function resolveCapabilitiesForCreate(input: { - type: AiProviderType; - capabilities?: AiCapability[] | null; -}): AiCapability[] { - if (input.capabilities != null) { - return parseCapabilities(input.capabilities); - } - if (input.type === "custom") { - return []; - } - return [...AI_PROVIDER_CAPABILITY_DEFAULTS[input.type]]; -} - -export function defaultsForProviderType( - type: AiProviderType -): readonly AiCapability[] { - if (type === "custom") { - return []; - } - return AI_PROVIDER_CAPABILITY_DEFAULTS[type]; -} diff --git a/server/lib/aiProviderDefaults.ts b/server/lib/aiProviderDefaults.ts index f24330ec8..a8b3a0ca0 100644 --- a/server/lib/aiProviderDefaults.ts +++ b/server/lib/aiProviderDefaults.ts @@ -1,4 +1,8 @@ import { decrypt, encrypt } from "@server/lib/crypto"; +import { + parseCapabilities, + type AiCapability +} from "@server/lib/aiCapabilities"; export type AiProviderType = | "openai" @@ -28,6 +32,7 @@ export type AiProviderRoutingMode = "url" | "target"; type AiProviderDefaults = { upstreamUrl: string | null; authType: AiProviderAuthType; + capabilities: readonly AiCapability[]; }; export const AI_PROVIDER_DEFAULTS: Record< @@ -36,35 +41,43 @@ export const AI_PROVIDER_DEFAULTS: Record< > = { openai: { upstreamUrl: "https://api.openai.com/v1", - authType: "bearer" + authType: "bearer", + capabilities: ["openai_chat", "openai_responses"] }, anthropic: { upstreamUrl: "https://api.anthropic.com", - authType: "x-api-key" + authType: "x-api-key", + capabilities: ["anthropic_messages"] }, googleGemini: { upstreamUrl: "https://generativelanguage.googleapis.com", - authType: "x-goog-api-key" + authType: "x-goog-api-key", + capabilities: ["gemini_generate_content"] }, vertexAi: { upstreamUrl: null, - authType: "bearer" + authType: "bearer", + capabilities: ["google_generate_content", "google_raw_predict"] }, bedrock: { upstreamUrl: "https://bedrock-runtime.us-east-1.amazonaws.com", - authType: "bearer" + authType: "bearer", + capabilities: ["bedrock_converse"] }, microsoftFoundry: { upstreamUrl: null, - authType: "bearer" + authType: "bearer", + capabilities: ["openai_chat", "openai_responses", "anthropic_messages"] }, openRouter: { upstreamUrl: "https://openrouter.ai/api/v1", - authType: "bearer" + authType: "bearer", + capabilities: ["openai_chat"] }, vercelAiGateway: { upstreamUrl: "https://ai-gateway.vercel.sh/v1", - authType: "bearer" + authType: "bearer", + capabilities: ["openai_chat", "openai_responses"] } }; @@ -225,3 +238,25 @@ export function applyAiProviderAuthHeaders( break; } } + +export function resolveCapabilitiesForCreate(input: { + type: AiProviderType; + capabilities?: AiCapability[] | null; +}): AiCapability[] { + if (input.capabilities != null) { + return parseCapabilities(input.capabilities); + } + if (input.type === "custom") { + return []; + } + return [...AI_PROVIDER_DEFAULTS[input.type].capabilities]; +} + +export function defaultsForProviderType( + type: AiProviderType +): readonly AiCapability[] { + if (type === "custom") { + return []; + } + return AI_PROVIDER_DEFAULTS[type].capabilities; +} diff --git a/server/routers/aiProvider/createAiProvider.ts b/server/routers/aiProvider/createAiProvider.ts index 195c8040e..f115d674a 100644 --- a/server/routers/aiProvider/createAiProvider.ts +++ b/server/routers/aiProvider/createAiProvider.ts @@ -9,7 +9,11 @@ import { fromError } from "zod-validation-error"; import { OpenAPITags, registry } from "@server/openApi"; import { encrypt } from "@server/lib/crypto"; import config from "@server/lib/config"; -import { resolveAiProviderCreateFields } from "@server/lib/aiProviderDefaults"; +import { + resolveAiProviderCreateFields, + resolveCapabilitiesForCreate, + serializeAiProviderHeaders +} from "@server/lib/aiProviderDefaults"; import type { CreateOrEditAiProviderResponse } from "@server/routers/aiProvider/types"; import { toPublicAiProvider } from "@server/routers/aiProvider/types"; import { @@ -20,11 +24,7 @@ import { aiRoutingModeSchema, refineProviderUpstreamFields } from "@server/routers/aiProvider/validation"; -import { serializeAiProviderHeaders } from "@server/lib/aiProviderDefaults"; -import { - resolveCapabilitiesForCreate, - serializeCapabilities -} from "@server/lib/aiCapabilities"; +import { serializeCapabilities } from "@server/lib/aiCapabilities"; const paramsSchema = z.strictObject({ orgId: z.string().nonempty() diff --git a/src/lib/aiProviderFormSchema.ts b/src/lib/aiProviderFormSchema.ts index 04e38a71a..2f75c92ec 100644 --- a/src/lib/aiProviderFormSchema.ts +++ b/src/lib/aiProviderFormSchema.ts @@ -3,15 +3,12 @@ import { AI_PROVIDER_AUTH_TYPES, AI_PROVIDER_DEFAULTS, authTypeRequiresApiKey, + defaultsForProviderType, providerRequiresUpstreamUrl, type AiProviderAuthType, type AiProviderType } from "@server/lib/aiProviderDefaults"; -import { - AI_CAPABILITIES, - defaultsForProviderType, - type AiCapability -} from "@server/lib/aiCapabilities"; +import { AI_CAPABILITIES, type AiCapability } from "@server/lib/aiCapabilities"; type TranslateFn = (key: string) => string;