diff --git a/README.md b/README.md index 54df114..5fb64b8 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ Diagrams are represented as XML that can be rendered in draw.io. The AI processe - Google AI - Azure OpenAI - Ollama +- OpenRouter +- DeepSeek Note that `claude-sonnet-4-5` has trained on draw.io diagrams with AWS logos, so if you want to create AWS architecture diagrams, this is the best choice. @@ -105,7 +107,7 @@ cp env.example .env.local Edit `.env.local` and configure your chosen provider: -- Set `AI_PROVIDER` to your chosen provider (bedrock, openai, anthropic, google, azure, ollama) +- Set `AI_PROVIDER` to your chosen provider (bedrock, openai, anthropic, google, azure, ollama, openrouter, deepseek) - Set `AI_MODEL` to the specific model you want to use - Add the required API keys for your provider diff --git a/env.example b/env.example index 7df2030..1921f1b 100644 --- a/env.example +++ b/env.example @@ -1,6 +1,6 @@ # AI Provider Configuration # AI_PROVIDER: Which provider to use -# Options: bedrock, openai, anthropic, google, azure, ollama, openrouter +# Options: bedrock, openai, anthropic, google, azure, ollama, openrouter, deepseek # Default: bedrock AI_PROVIDER=bedrock @@ -37,3 +37,7 @@ AI_MODEL=global.anthropic.claude-sonnet-4-5-20250929-v1:0 # OpenRouter Configuration # OPENROUTER_API_KEY=sk-or-v1-... # OPENROUTER_BASE_URL=https://openrouter.ai/api/v1 # Optional: Custom endpoint + +# DeepSeek Configuration +# DEEPSEEK_API_KEY=sk-... +# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1 # Optional: Custom endpoint diff --git a/lib/ai-providers.ts b/lib/ai-providers.ts index aeb65fd..4ed0e65 100644 --- a/lib/ai-providers.ts +++ b/lib/ai-providers.ts @@ -5,6 +5,7 @@ import { google, createGoogleGenerativeAI } from '@ai-sdk/google'; import { azure, createAzure } from '@ai-sdk/azure'; import { ollama, createOllama } from 'ollama-ai-provider-v2'; import { createOpenRouter } from '@openrouter/ai-sdk-provider'; +import { deepseek, createDeepSeek } from '@ai-sdk/deepseek'; export type ProviderName = | 'bedrock' @@ -13,7 +14,8 @@ export type ProviderName = | 'google' | 'azure' | 'ollama' - | 'openrouter'; + | 'openrouter' + | 'deepseek'; interface ModelConfig { model: any; @@ -45,6 +47,7 @@ function validateProviderCredentials(provider: ProviderName): void { azure: 'AZURE_API_KEY', ollama: null, // No credentials needed for local Ollama openrouter: 'OPENROUTER_API_KEY', + deepseek: 'DEEPSEEK_API_KEY', }; const requiredVar = requiredEnvVars[provider]; @@ -60,7 +63,7 @@ function validateProviderCredentials(provider: ProviderName): void { * Get the AI model based on environment variables * * Environment variables: - * - AI_PROVIDER: The provider to use (bedrock, openai, anthropic, google, azure, ollama, openrouter) + * - AI_PROVIDER: The provider to use (bedrock, openai, anthropic, google, azure, ollama, openrouter, deepseek) * - AI_MODEL: The model ID/name for the selected provider * * Provider-specific env vars: @@ -72,6 +75,8 @@ function validateProviderCredentials(provider: ProviderName): void { * - AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY: AWS Bedrock credentials * - OLLAMA_BASE_URL: Ollama server URL (optional, defaults to http://localhost:11434) * - OPENROUTER_API_KEY: OpenRouter API key + * - DEEPSEEK_API_KEY: DeepSeek API key + * - DEEPSEEK_BASE_URL: DeepSeek endpoint (optional) */ export function getAIModel(): ModelConfig { const provider = (process.env.AI_PROVIDER || 'bedrock') as ProviderName; @@ -168,9 +173,21 @@ export function getAIModel(): ModelConfig { model = openrouter(modelId); break; + case 'deepseek': + if (process.env.DEEPSEEK_BASE_URL) { + const customDeepSeek = createDeepSeek({ + apiKey: process.env.DEEPSEEK_API_KEY, + baseURL: process.env.DEEPSEEK_BASE_URL, + }); + model = customDeepSeek(modelId); + } else { + model = deepseek(modelId); + } + break; + default: throw new Error( - `Unknown AI provider: ${provider}. Supported providers: bedrock, openai, anthropic, google, azure, ollama, openrouter` + `Unknown AI provider: ${provider}. Supported providers: bedrock, openai, anthropic, google, azure, ollama, openrouter, deepseek` ); } diff --git a/package-lock.json b/package-lock.json index 4f43218..a382552 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@ai-sdk/amazon-bedrock": "^3.0.62", "@ai-sdk/anthropic": "^2.0.44", "@ai-sdk/azure": "^2.0.69", + "@ai-sdk/deepseek": "^1.0.30", "@ai-sdk/google": "^2.0.0", "@ai-sdk/openai": "^2.0.19", "@ai-sdk/react": "^2.0.22", @@ -155,6 +156,40 @@ "zod": "^3.25.76 || ^4.1.8" } }, + "node_modules/@ai-sdk/deepseek": { + "version": "1.0.30", + "resolved": "https://registry.npmjs.org/@ai-sdk/deepseek/-/deepseek-1.0.30.tgz", + "integrity": "sha512-pafNclW9L8Z3WimaRwlpHrGbdeaDE/UklT3rMi2aoRRyrA+s7zGcFuu1zbO2ViLNlKfaS91XZa9MFAPXbIftUA==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/openai-compatible": "1.0.28", + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.18" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/deepseek/node_modules/@ai-sdk/provider-utils": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz", + "integrity": "sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, "node_modules/@ai-sdk/gateway": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.7.tgz", @@ -231,6 +266,39 @@ "zod": "^3.25.76 || ^4.1.8" } }, + "node_modules/@ai-sdk/openai-compatible": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/@ai-sdk/openai-compatible/-/openai-compatible-1.0.28.tgz", + "integrity": "sha512-yKubDxLYtXyGUzkr9lNStf/lE/I+Okc8tmotvyABhsQHHieLKk6oV5fJeRJxhr67Ejhg+FRnwUOxAmjRoFM4dA==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.18" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/openai-compatible/node_modules/@ai-sdk/provider-utils": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz", + "integrity": "sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, "node_modules/@ai-sdk/openai/node_modules/@ai-sdk/provider-utils": { "version": "3.0.17", "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.17.tgz", diff --git a/package.json b/package.json index 41dddf2..dbf0258 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@ai-sdk/amazon-bedrock": "^3.0.62", "@ai-sdk/anthropic": "^2.0.44", "@ai-sdk/azure": "^2.0.69", + "@ai-sdk/deepseek": "^1.0.30", "@ai-sdk/google": "^2.0.0", "@ai-sdk/openai": "^2.0.19", "@ai-sdk/react": "^2.0.22",