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 |
}
|