Cole Medin
commited on
Commit
·
4f7a06f
1
Parent(s):
90a206f
Added the OpenRouter provider and a few models from OpenRouter (easily extendable to include more!)
Browse files- .env.example +5 -0
- app/lib/.server/llm/api-key.ts +2 -0
- app/lib/.server/llm/model.ts +11 -0
- app/utils/constants.ts +6 -0
- package.json +1 -0
- pnpm-lock.yaml +43 -2
- worker-configuration.d.ts +1 -0
.env.example
CHANGED
|
@@ -15,5 +15,10 @@ OPENAI_API_KEY=
|
|
| 15 |
# You only need this environment variable set if you want to use Claude models
|
| 16 |
ANTHROPIC_API_KEY=
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
# Include this environment variable if you want more logging for debugging locally
|
| 19 |
VITE_LOG_LEVEL=debug
|
|
|
|
| 15 |
# You only need this environment variable set if you want to use Claude models
|
| 16 |
ANTHROPIC_API_KEY=
|
| 17 |
|
| 18 |
+
# Get your OpenRouter API Key in your account settings -
|
| 19 |
+
# https://openrouter.ai/settings/keys
|
| 20 |
+
# You only need this environment variable set if you want to use OpenRouter models
|
| 21 |
+
OPEN_ROUTER_API_KEY=
|
| 22 |
+
|
| 23 |
# Include this environment variable if you want more logging for debugging locally
|
| 24 |
VITE_LOG_LEVEL=debug
|
app/lib/.server/llm/api-key.ts
CHANGED
|
@@ -14,6 +14,8 @@ export function getAPIKey(cloudflareEnv: Env, provider: string) {
|
|
| 14 |
return env.OPENAI_API_KEY || cloudflareEnv.OPENAI_API_KEY;
|
| 15 |
case 'Groq':
|
| 16 |
return env.GROQ_API_KEY || cloudflareEnv.GROQ_API_KEY;
|
|
|
|
|
|
|
| 17 |
default:
|
| 18 |
return "";
|
| 19 |
}
|
|
|
|
| 14 |
return env.OPENAI_API_KEY || cloudflareEnv.OPENAI_API_KEY;
|
| 15 |
case 'Groq':
|
| 16 |
return env.GROQ_API_KEY || cloudflareEnv.GROQ_API_KEY;
|
| 17 |
+
case 'OpenRouter':
|
| 18 |
+
return env.OPEN_ROUTER_API_KEY || cloudflareEnv.OPEN_ROUTER_API_KEY;
|
| 19 |
default:
|
| 20 |
return "";
|
| 21 |
}
|
app/lib/.server/llm/model.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { getAPIKey } from '~/lib/.server/llm/api-key';
|
|
| 4 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 5 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 6 |
import { ollama } from 'ollama-ai-provider';
|
|
|
|
| 7 |
|
| 8 |
export function getAnthropicModel(apiKey: string, model: string) {
|
| 9 |
const anthropic = createAnthropic({
|
|
@@ -34,6 +35,14 @@ export function getOllamaModel(model: string) {
|
|
| 34 |
return ollama(model);
|
| 35 |
}
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
export function getModel(provider: string, model: string, env: Env) {
|
| 38 |
const apiKey = getAPIKey(env, provider);
|
| 39 |
|
|
@@ -44,6 +53,8 @@ export function getModel(provider: string, model: string, env: Env) {
|
|
| 44 |
return getOpenAIModel(apiKey, model);
|
| 45 |
case 'Groq':
|
| 46 |
return getGroqModel(apiKey, model);
|
|
|
|
|
|
|
| 47 |
default:
|
| 48 |
return getOllamaModel(model);
|
| 49 |
}
|
|
|
|
| 4 |
import { createAnthropic } from '@ai-sdk/anthropic';
|
| 5 |
import { createOpenAI } from '@ai-sdk/openai';
|
| 6 |
import { ollama } from 'ollama-ai-provider';
|
| 7 |
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
| 8 |
|
| 9 |
export function getAnthropicModel(apiKey: string, model: string) {
|
| 10 |
const anthropic = createAnthropic({
|
|
|
|
| 35 |
return ollama(model);
|
| 36 |
}
|
| 37 |
|
| 38 |
+
export function getOpenRouterModel(apiKey: string, model: string) {
|
| 39 |
+
const openRouter = createOpenRouter({
|
| 40 |
+
apiKey
|
| 41 |
+
});
|
| 42 |
+
|
| 43 |
+
return openRouter.chat(model);
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
export function getModel(provider: string, model: string, env: Env) {
|
| 47 |
const apiKey = getAPIKey(env, provider);
|
| 48 |
|
|
|
|
| 53 |
return getOpenAIModel(apiKey, model);
|
| 54 |
case 'Groq':
|
| 55 |
return getGroqModel(apiKey, model);
|
| 56 |
+
case 'OpenRouter':
|
| 57 |
+
return getOpenRouterModel(apiKey, model);
|
| 58 |
default:
|
| 59 |
return getOllamaModel(model);
|
| 60 |
}
|
app/utils/constants.ts
CHANGED
|
@@ -17,6 +17,12 @@ export const MODEL_LIST = [
|
|
| 17 |
{ name: 'codellama:34b', label: 'Code Llama 34b', provider: 'Ollama' },
|
| 18 |
{ name: 'codellama:13b', label: 'Code Llama 13b', provider: 'Ollama' },
|
| 19 |
{ name: 'codellama:7b', label: 'Code Llama 7b', provider: 'Ollama' },
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
{ name: 'llama-3.1-70b-versatile', label: 'Llama 3.1 70b (Groq)', provider: 'Groq' },
|
| 21 |
{ name: 'llama-3.1-8b-instant', label: 'Llama 3.1 8b (Groq)', provider: 'Groq' },
|
| 22 |
{ name: 'llama-3.2-11b-vision-preview', label: 'Llama 3.2 11b (Groq)', provider: 'Groq' },
|
|
|
|
| 17 |
{ name: 'codellama:34b', label: 'Code Llama 34b', provider: 'Ollama' },
|
| 18 |
{ name: 'codellama:13b', label: 'Code Llama 13b', provider: 'Ollama' },
|
| 19 |
{ name: 'codellama:7b', label: 'Code Llama 7b', provider: 'Ollama' },
|
| 20 |
+
{ name: 'deepseek/deepseek-coder', label: 'Deepseek-Coder V2 236B (OpenRouter)', provider: 'OpenRouter' },
|
| 21 |
+
{ name: 'google/gemini-flash-1.5', label: 'Google Gemini Flash 1.5 (OpenRouter)', provider: 'OpenRouter' },
|
| 22 |
+
{ name: 'google/gemini-pro-1.5', label: 'Google Gemini Pro 1.5 (OpenRouter)', provider: 'OpenRouter' },
|
| 23 |
+
{ name: 'mistralai/mistral-nemo', label: 'OpenRouter Mistral Nemo (OpenRouter)', provider: 'OpenRouter' },
|
| 24 |
+
{ name: 'qwen/qwen-110b-chat', label: 'OpenRouter Qwen 110b Chat (OpenRouter)', provider: 'OpenRouter' },
|
| 25 |
+
{ name: 'cohere/command', label: 'Cohere Command (OpenRouter)', provider: 'OpenRouter' },
|
| 26 |
{ name: 'llama-3.1-70b-versatile', label: 'Llama 3.1 70b (Groq)', provider: 'Groq' },
|
| 27 |
{ name: 'llama-3.1-8b-instant', label: 'Llama 3.1 8b (Groq)', provider: 'Groq' },
|
| 28 |
{ name: 'llama-3.2-11b-vision-preview', label: 'Llama 3.2 11b (Groq)', provider: 'Groq' },
|
package.json
CHANGED
|
@@ -44,6 +44,7 @@
|
|
| 44 |
"@iconify-json/svg-spinners": "^1.1.2",
|
| 45 |
"@lezer/highlight": "^1.2.0",
|
| 46 |
"@nanostores/react": "^0.7.2",
|
|
|
|
| 47 |
"@radix-ui/react-dialog": "^1.1.1",
|
| 48 |
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
| 49 |
"@remix-run/cloudflare": "^2.10.2",
|
|
|
|
| 44 |
"@iconify-json/svg-spinners": "^1.1.2",
|
| 45 |
"@lezer/highlight": "^1.2.0",
|
| 46 |
"@nanostores/react": "^0.7.2",
|
| 47 |
+
"@openrouter/ai-sdk-provider": "^0.0.5",
|
| 48 |
"@radix-ui/react-dialog": "^1.1.1",
|
| 49 |
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
| 50 |
"@remix-run/cloudflare": "^2.10.2",
|
pnpm-lock.yaml
CHANGED
|
@@ -74,6 +74,9 @@ importers:
|
|
| 74 |
'@nanostores/react':
|
| 75 |
specifier: ^0.7.2
|
| 76 |
version: 0.7.2([email protected])([email protected])
|
|
|
|
|
|
|
|
|
|
| 77 |
'@radix-ui/react-dialog':
|
| 78 |
specifier: ^1.1.1
|
| 79 |
version: 1.1.1(@types/[email protected])(@types/[email protected])([email protected]([email protected]))([email protected])
|
|
@@ -249,6 +252,15 @@ packages:
|
|
| 249 |
peerDependencies:
|
| 250 |
zod: ^3.0.0
|
| 251 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
'@ai-sdk/[email protected]':
|
| 253 |
resolution: {integrity: sha512-ngg/RGpnA00eNOWEtXHenpX1MsM2QshQh4QJFjUfwcqHpM5kTfG7je7Rc3HcEDP+OkRVv2GF+X4fC1Vfcnl8Ow==}
|
| 254 |
engines: {node: '>=18'}
|
|
@@ -267,6 +279,10 @@ packages:
|
|
| 267 |
zod:
|
| 268 |
optional: true
|
| 269 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
'@ai-sdk/[email protected]':
|
| 271 |
resolution: {integrity: sha512-f9j+P5yYRkqKFHxvWae5FI0j6nqROPCoPnMkpc2hc2vC7vKjqzrxBJucD8rpSaUjqiBnY/QuRJ0QeV717Uz5tg==}
|
| 272 |
engines: {node: '>=18'}
|
|
@@ -1196,6 +1212,12 @@ packages:
|
|
| 1196 |
resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
|
| 1197 |
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
| 1198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1199 |
'@opentelemetry/[email protected]':
|
| 1200 |
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
| 1201 |
engines: {node: '>=8.0.0'}
|
|
@@ -5331,6 +5353,15 @@ snapshots:
|
|
| 5331 |
'@ai-sdk/provider-utils': 1.0.20([email protected])
|
| 5332 |
zod: 3.23.8
|
| 5333 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5334 |
'@ai-sdk/[email protected]([email protected])':
|
| 5335 |
dependencies:
|
| 5336 |
'@ai-sdk/provider': 0.0.24
|
|
@@ -5349,6 +5380,10 @@ snapshots:
|
|
| 5349 |
optionalDependencies:
|
| 5350 |
zod: 3.23.8
|
| 5351 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5352 |
'@ai-sdk/[email protected]':
|
| 5353 |
dependencies:
|
| 5354 |
json-schema: 0.4.0
|
|
@@ -6288,6 +6323,12 @@ snapshots:
|
|
| 6288 |
dependencies:
|
| 6289 |
which: 3.0.1
|
| 6290 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6291 |
'@opentelemetry/[email protected]': {}
|
| 6292 |
|
| 6293 |
'@pkgjs/[email protected]':
|
|
@@ -7194,7 +7235,7 @@ snapshots:
|
|
| 7194 |
'@babel/plugin-syntax-typescript': 7.24.7(@babel/[email protected])
|
| 7195 |
'@vanilla-extract/babel-plugin-debug-ids': 1.0.6
|
| 7196 |
'@vanilla-extract/css': 1.15.3
|
| 7197 |
-
esbuild: 0.17.
|
| 7198 |
eval: 0.1.8
|
| 7199 |
find-up: 5.0.0
|
| 7200 |
javascript-stringify: 2.1.0
|
|
@@ -9734,7 +9775,7 @@ snapshots:
|
|
| 9734 |
acorn: 8.12.0
|
| 9735 |
pathe: 1.1.2
|
| 9736 |
pkg-types: 1.1.1
|
| 9737 |
-
ufo: 1.5.
|
| 9738 |
|
| 9739 | |
| 9740 |
|
|
|
|
| 74 |
'@nanostores/react':
|
| 75 |
specifier: ^0.7.2
|
| 76 |
version: 0.7.2([email protected])([email protected])
|
| 77 |
+
'@openrouter/ai-sdk-provider':
|
| 78 |
+
specifier: ^0.0.5
|
| 79 |
+
version: 0.0.5([email protected])
|
| 80 |
'@radix-ui/react-dialog':
|
| 81 |
specifier: ^1.1.1
|
| 82 |
version: 1.1.1(@types/[email protected])(@types/[email protected])([email protected]([email protected]))([email protected])
|
|
|
|
| 252 |
peerDependencies:
|
| 253 |
zod: ^3.0.0
|
| 254 |
|
| 255 |
+
'@ai-sdk/[email protected]':
|
| 256 |
+
resolution: {integrity: sha512-57f6O4OFVNEpI8Z8o+K40tIB3YQiTw+VCql/qrAO9Utq7Ti1o6+X9tvm177DlZJL7ft0Rwzvgy48S9YhrEKgmA==}
|
| 257 |
+
engines: {node: '>=18'}
|
| 258 |
+
peerDependencies:
|
| 259 |
+
zod: ^3.0.0
|
| 260 |
+
peerDependenciesMeta:
|
| 261 |
+
zod:
|
| 262 |
+
optional: true
|
| 263 |
+
|
| 264 |
'@ai-sdk/[email protected]':
|
| 265 |
resolution: {integrity: sha512-ngg/RGpnA00eNOWEtXHenpX1MsM2QshQh4QJFjUfwcqHpM5kTfG7je7Rc3HcEDP+OkRVv2GF+X4fC1Vfcnl8Ow==}
|
| 266 |
engines: {node: '>=18'}
|
|
|
|
| 279 |
zod:
|
| 280 |
optional: true
|
| 281 |
|
| 282 |
+
'@ai-sdk/[email protected]':
|
| 283 |
+
resolution: {integrity: sha512-oOwPQD8i2Ynpn22cur4sk26FW3mSy6t6/X/K1Ay2yGBKYiSpRyLfObhOrZEGsXDx+3euKy4nEZ193R36NM+tpQ==}
|
| 284 |
+
engines: {node: '>=18'}
|
| 285 |
+
|
| 286 |
'@ai-sdk/[email protected]':
|
| 287 |
resolution: {integrity: sha512-f9j+P5yYRkqKFHxvWae5FI0j6nqROPCoPnMkpc2hc2vC7vKjqzrxBJucD8rpSaUjqiBnY/QuRJ0QeV717Uz5tg==}
|
| 288 |
engines: {node: '>=18'}
|
|
|
|
| 1212 |
resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
|
| 1213 |
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
| 1214 |
|
| 1215 |
+
'@openrouter/[email protected]':
|
| 1216 |
+
resolution: {integrity: sha512-AfxXQhISpxQSeUjU/4jo9waM5GRNX6eIkfTFS9l7vHkD1TKDP81Y/dXrE0ttJeN/Kap3tPF3Jwh49me0gWwjSw==}
|
| 1217 |
+
engines: {node: '>=18'}
|
| 1218 |
+
peerDependencies:
|
| 1219 |
+
zod: ^3.0.0
|
| 1220 |
+
|
| 1221 |
'@opentelemetry/[email protected]':
|
| 1222 |
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
| 1223 |
engines: {node: '>=8.0.0'}
|
|
|
|
| 5353 |
'@ai-sdk/provider-utils': 1.0.20([email protected])
|
| 5354 |
zod: 3.23.8
|
| 5355 |
|
| 5356 |
+
'@ai-sdk/[email protected]([email protected])':
|
| 5357 |
+
dependencies:
|
| 5358 |
+
'@ai-sdk/provider': 0.0.12
|
| 5359 |
+
eventsource-parser: 1.1.2
|
| 5360 |
+
nanoid: 3.3.6
|
| 5361 |
+
secure-json-parse: 2.7.0
|
| 5362 |
+
optionalDependencies:
|
| 5363 |
+
zod: 3.23.8
|
| 5364 |
+
|
| 5365 |
'@ai-sdk/[email protected]([email protected])':
|
| 5366 |
dependencies:
|
| 5367 |
'@ai-sdk/provider': 0.0.24
|
|
|
|
| 5380 |
optionalDependencies:
|
| 5381 |
zod: 3.23.8
|
| 5382 |
|
| 5383 |
+
'@ai-sdk/[email protected]':
|
| 5384 |
+
dependencies:
|
| 5385 |
+
json-schema: 0.4.0
|
| 5386 |
+
|
| 5387 |
'@ai-sdk/[email protected]':
|
| 5388 |
dependencies:
|
| 5389 |
json-schema: 0.4.0
|
|
|
|
| 6323 |
dependencies:
|
| 6324 |
which: 3.0.1
|
| 6325 |
|
| 6326 |
+
'@openrouter/[email protected]([email protected])':
|
| 6327 |
+
dependencies:
|
| 6328 |
+
'@ai-sdk/provider': 0.0.12
|
| 6329 |
+
'@ai-sdk/provider-utils': 1.0.2([email protected])
|
| 6330 |
+
zod: 3.23.8
|
| 6331 |
+
|
| 6332 |
'@opentelemetry/[email protected]': {}
|
| 6333 |
|
| 6334 |
'@pkgjs/[email protected]':
|
|
|
|
| 7235 |
'@babel/plugin-syntax-typescript': 7.24.7(@babel/[email protected])
|
| 7236 |
'@vanilla-extract/babel-plugin-debug-ids': 1.0.6
|
| 7237 |
'@vanilla-extract/css': 1.15.3
|
| 7238 |
+
esbuild: 0.17.19
|
| 7239 |
eval: 0.1.8
|
| 7240 |
find-up: 5.0.0
|
| 7241 |
javascript-stringify: 2.1.0
|
|
|
|
| 9775 |
acorn: 8.12.0
|
| 9776 |
pathe: 1.1.2
|
| 9777 |
pkg-types: 1.1.1
|
| 9778 |
+
ufo: 1.5.4
|
| 9779 |
|
| 9780 | |
| 9781 |
|
worker-configuration.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ interface Env {
|
|
| 2 |
ANTHROPIC_API_KEY: string;
|
| 3 |
OPENAI_API_KEY: string;
|
| 4 |
GROQ_API_KEY: string;
|
|
|
|
| 5 |
}
|
|
|
|
| 2 |
ANTHROPIC_API_KEY: string;
|
| 3 |
OPENAI_API_KEY: string;
|
| 4 |
GROQ_API_KEY: string;
|
| 5 |
+
OPEN_ROUTER_API_KEY: string;
|
| 6 |
}
|