From 6e3b31f36d5dbff787d64823511174b3430f0e7b Mon Sep 17 00:00:00 2001 From: Ahmed Rahil Date: Sun, 29 Dec 2024 14:24:14 +0530 Subject: [PATCH 1/4] Added Hyperbolic Models --- .env.example | 6 +++ app/lib/modules/llm/providers/hyperbolic.ts | 58 +++++++++++++++++++++ app/lib/modules/llm/registry.ts | 2 + 3 files changed, 66 insertions(+) create mode 100644 app/lib/modules/llm/providers/hyperbolic.ts diff --git a/.env.example b/.env.example index 4e4b4f336..6f2f5f5af 100644 --- a/.env.example +++ b/.env.example @@ -51,6 +51,12 @@ OPENAI_LIKE_API_KEY= # Get your Together API Key TOGETHER_API_KEY= +# You only need this environment variable set if you want to use Hyperbolic models +#Get your Hyperbolics API Key at https://app.hyperbolic.xyz/settings +#baseURL="https://api.hyperbolic.xyz/v1/chat/completions" +HYPERBOLIC_API_KEY= +HYPERBOLIC_API_BASE_URL= + # Get your Mistral API Key by following these instructions - # https://console.mistral.ai/api-keys/ # You only need this environment variable set if you want to use Mistral models diff --git a/app/lib/modules/llm/providers/hyperbolic.ts b/app/lib/modules/llm/providers/hyperbolic.ts new file mode 100644 index 000000000..e89b24d18 --- /dev/null +++ b/app/lib/modules/llm/providers/hyperbolic.ts @@ -0,0 +1,58 @@ +import { BaseProvider, getOpenAILikeModel } from '~/lib/modules/llm/base-provider'; +import type { ModelInfo } from '~/lib/modules/llm/types'; +import type { IProviderSetting } from '~/types/model'; +import type { LanguageModelV1 } from 'ai'; + +export default class HyperbolicProvider extends BaseProvider { + name = 'Hyperbolic'; + getApiKeyLink = 'https://hyperbolic.xyz/settings'; + + config = { + apiTokenKey: 'HYPERBOLIC_API_KEY', + baseUrlKey: 'HYPERBOLIC_API_BASE_URL', + }; + + staticModels: ModelInfo[] = [ + { + name: 'Qwen/Qwen2.5-Coder-32B-Instruct', + label: 'Qwen 2.5 Coder 32B Instruct', + provider: 'Hyperbolic', + maxTokenAllowed: 8192, + }, + { + name: 'Qwen/Qwen2.5-72B-Instruct', + label: 'Qwen2.5-72B-Instruct', + provider: 'Hyperbolic', + maxTokenAllowed: 8192, + }, + { + name: 'deepseek-ai/DeepSeek-V2.5', + label: 'DeepSeek-V2.5', + provider: 'Hyperbolic', + maxTokenAllowed: 8192, + }, + ]; + + getModelInstance(options: { + model: string; + serverEnv: Env; + apiKeys?: Record; + providerSettings?: Record; + }): LanguageModelV1 { + const { model, serverEnv, apiKeys, providerSettings } = options; + + const { baseUrl, apiKey } = this.getProviderBaseUrlAndKey({ + apiKeys, + providerSettings: providerSettings?.[this.name], + serverEnv: serverEnv as any, + defaultBaseUrlKey: 'HYPERBOLIC_API_BASE_URL', + defaultApiTokenKey: 'HYPERBOLIC_API_KEY', + }); + + if (!baseUrl || !apiKey) { + throw new Error(`Missing configuration for ${this.name} provider`); + } + + return getOpenAILikeModel(baseUrl, apiKey, model); + } +} diff --git a/app/lib/modules/llm/registry.ts b/app/lib/modules/llm/registry.ts index fb5a31f93..c002eb88d 100644 --- a/app/lib/modules/llm/registry.ts +++ b/app/lib/modules/llm/registry.ts @@ -13,6 +13,7 @@ import OpenAIProvider from './providers/openai'; import PerplexityProvider from './providers/perplexity'; import TogetherProvider from './providers/together'; import XAIProvider from './providers/xai'; +import HyperbolicProvider from './providers/hyperbolic'; export { AnthropicProvider, @@ -21,6 +22,7 @@ export { GoogleProvider, GroqProvider, HuggingFaceProvider, + HyperbolicProvider, MistralProvider, OllamaProvider, OpenAIProvider, From 58236cbccc3536ea7ab5cbad58f68bfb139fb02b Mon Sep 17 00:00:00 2001 From: Ahmed Rahil Date: Sun, 29 Dec 2024 21:10:53 +0530 Subject: [PATCH 2/4] Fix: Fixed problem in connecting with hyperbolic models --- app/lib/modules/llm/providers/hyperbolic.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/app/lib/modules/llm/providers/hyperbolic.ts b/app/lib/modules/llm/providers/hyperbolic.ts index e89b24d18..0b62e863e 100644 --- a/app/lib/modules/llm/providers/hyperbolic.ts +++ b/app/lib/modules/llm/providers/hyperbolic.ts @@ -1,7 +1,8 @@ -import { BaseProvider, getOpenAILikeModel } from '~/lib/modules/llm/base-provider'; +import { BaseProvider } from '~/lib/modules/llm/base-provider'; import type { ModelInfo } from '~/lib/modules/llm/types'; import type { IProviderSetting } from '~/types/model'; import type { LanguageModelV1 } from 'ai'; +import { createOpenAI } from '@ai-sdk/openai'; export default class HyperbolicProvider extends BaseProvider { name = 'Hyperbolic'; @@ -9,7 +10,7 @@ export default class HyperbolicProvider extends BaseProvider { config = { apiTokenKey: 'HYPERBOLIC_API_KEY', - baseUrlKey: 'HYPERBOLIC_API_BASE_URL', + //baseUrlKey: 'HYPERBOLIC_API_BASE_URL', }; staticModels: ModelInfo[] = [ @@ -41,18 +42,24 @@ export default class HyperbolicProvider extends BaseProvider { }): LanguageModelV1 { const { model, serverEnv, apiKeys, providerSettings } = options; - const { baseUrl, apiKey } = this.getProviderBaseUrlAndKey({ + const { apiKey } = this.getProviderBaseUrlAndKey({ apiKeys, providerSettings: providerSettings?.[this.name], serverEnv: serverEnv as any, - defaultBaseUrlKey: 'HYPERBOLIC_API_BASE_URL', + defaultBaseUrlKey: '', defaultApiTokenKey: 'HYPERBOLIC_API_KEY', }); - if (!baseUrl || !apiKey) { + if (!apiKey) { + console.log(`Missing configuration for ${this.name} provider`); throw new Error(`Missing configuration for ${this.name} provider`); } - return getOpenAILikeModel(baseUrl, apiKey, model); + const openai = createOpenAI({ + baseURL: 'https://api.hyperbolic.xyz/v1/', + apiKey, + }); + + return openai(model); } } From 4918ce9bf0d02e9ce38ab983edb91831a5178bbe Mon Sep 17 00:00:00 2001 From: Ahmed Rahil Date: Mon, 30 Dec 2024 21:55:15 +0530 Subject: [PATCH 3/4] added dynamic models for hyperbolic --- app/lib/modules/llm/providers/hyperbolic.ts | 70 +++++++++++++++++++++ package.json | 1 + pnpm-lock.yaml | 13 ++-- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/app/lib/modules/llm/providers/hyperbolic.ts b/app/lib/modules/llm/providers/hyperbolic.ts index 0b62e863e..cf6c0c024 100644 --- a/app/lib/modules/llm/providers/hyperbolic.ts +++ b/app/lib/modules/llm/providers/hyperbolic.ts @@ -10,6 +10,7 @@ export default class HyperbolicProvider extends BaseProvider { config = { apiTokenKey: 'HYPERBOLIC_API_KEY', + //baseUrlKey: 'HYPERBOLIC_API_BASE_URL', }; @@ -32,8 +33,77 @@ export default class HyperbolicProvider extends BaseProvider { provider: 'Hyperbolic', maxTokenAllowed: 8192, }, + { + name: 'Qwen/QwQ-32B-Preview', + label: 'QwQ-32B-Preview', + provider: 'Hyperbolic', + maxTokenAllowed: 8192, + }, + { + name: 'Qwen/Qwen2-VL-72B-Instruct', + label: 'Qwen2-VL-72B-Instruct', + provider: 'Hyperbolic', + maxTokenAllowed: 8192, + }, ]; + async getDynamicModels( + apiKeys?: Record, + settings?: IProviderSetting, + serverEnv: Record = {}, + ): Promise { + try { + const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey({ + apiKeys, + providerSettings: settings, + serverEnv, + defaultBaseUrlKey: '', + defaultApiTokenKey: 'HYPERBOLIC_API_KEY', + }); + const baseUrl = fetchBaseUrl || 'https://api.hyperbolic.xyz/v1'; + + if (!baseUrl || !apiKey) { + return []; + } + + //console.log({ baseUrl, apiKey }); + + const response = await fetch(`${baseUrl}/models`, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const res = (await response.json()) as any; + //console.log('API response:', res); + + // if (!res || !Array.isArray(res.data)) { + // throw new Error('API response is not in the expected format'); + // } + + const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); + //console.log('Filtered data:', data); + console.log( + data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })), + ); + + return data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })); + } catch (error: any) { + console.error('Error getting Hyperbolic models:', error.message); + return []; + } + } + getModelInstance(options: { model: string; serverEnv: Env; diff --git a/package.json b/package.json index 05d483b91..19c83531f 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "ai": "^4.0.13", "date-fns": "^3.6.0", "diff": "^5.2.0", + "dotenv": "^16.4.7", "file-saver": "^2.0.5", "framer-motion": "^11.12.0", "ignore": "^6.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index da73295af..a78cfef32 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -149,6 +149,9 @@ importers: diff: specifier: ^5.2.0 version: 5.2.0 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 file-saver: specifier: ^2.0.5 version: 2.0.5 @@ -2901,8 +2904,8 @@ packages: resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} engines: {node: '>=10'} - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} duplexer@0.1.2: @@ -7246,7 +7249,7 @@ snapshots: chalk: 4.1.2 chokidar: 3.6.0 cross-spawn: 7.0.6 - dotenv: 16.4.5 + dotenv: 16.4.7 es-module-lexer: 1.5.4 esbuild: 0.17.6 esbuild-plugins-node-modules-polyfill: 1.6.8(esbuild@0.17.6) @@ -8450,7 +8453,7 @@ snapshots: domain-browser@4.22.0: {} - dotenv@16.4.5: {} + dotenv@16.4.7: {} duplexer@0.1.2: {} @@ -11957,4 +11960,4 @@ snapshots: zod@3.23.8: {} - zwitch@2.0.4: {} \ No newline at end of file + zwitch@2.0.4: {} From f77cef8a57b3993bcdadf7c52fe5c4a728691255 Mon Sep 17 00:00:00 2001 From: Ahmed Rahil Date: Mon, 30 Dec 2024 23:06:57 +0530 Subject: [PATCH 4/4] removed logs --- app/lib/modules/llm/providers/hyperbolic.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/app/lib/modules/llm/providers/hyperbolic.ts b/app/lib/modules/llm/providers/hyperbolic.ts index cf6c0c024..88c943ca6 100644 --- a/app/lib/modules/llm/providers/hyperbolic.ts +++ b/app/lib/modules/llm/providers/hyperbolic.ts @@ -10,8 +10,6 @@ export default class HyperbolicProvider extends BaseProvider { config = { apiTokenKey: 'HYPERBOLIC_API_KEY', - - //baseUrlKey: 'HYPERBOLIC_API_BASE_URL', }; staticModels: ModelInfo[] = [ @@ -66,8 +64,6 @@ export default class HyperbolicProvider extends BaseProvider { return []; } - //console.log({ baseUrl, apiKey }); - const response = await fetch(`${baseUrl}/models`, { headers: { Authorization: `Bearer ${apiKey}`, @@ -75,22 +71,8 @@ export default class HyperbolicProvider extends BaseProvider { }); const res = (await response.json()) as any; - //console.log('API response:', res); - - // if (!res || !Array.isArray(res.data)) { - // throw new Error('API response is not in the expected format'); - // } const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); - //console.log('Filtered data:', data); - console.log( - data.map((m: any) => ({ - name: m.id, - label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, - provider: this.name, - maxTokenAllowed: m.context_length || 8000, - })), - ); return data.map((m: any) => ({ name: m.id,