From ae8869e1b62c1784992e5a7a40098ece12420abc Mon Sep 17 00:00:00 2001 From: Chen Tao <70054568+eeee0717@users.noreply.github.com> Date: Sun, 23 Mar 2025 19:22:39 +0800 Subject: [PATCH] feat(knowledge): support Voyage AI (#3810) * feat(knowledge): support Voyage AI * chore --- package.json | 1 + src/main/embeddings/Embeddings.ts | 24 + src/main/embeddings/EmbeddingsFactory.ts | 38 ++ src/main/embeddings/VoyageEmbeddings.ts | 30 ++ src/main/reranker/RerankerFactory.ts | 3 + src/main/reranker/VoyageReranker.ts | 60 +++ src/main/services/KnowledgeService.ts | 40 +- .../src/assets/images/models/voyageai.png | Bin 0 -> 14064 bytes .../src/assets/images/providers/voyageai.png | Bin 0 -> 14064 bytes src/renderer/src/config/embedings.ts | 52 ++ src/renderer/src/config/models.ts | 65 ++- src/renderer/src/config/providers.ts | 17 +- src/renderer/src/i18n/locales/en-us.json | 3 +- src/renderer/src/i18n/locales/ja-jp.json | 3 +- src/renderer/src/i18n/locales/ru-ru.json | 3 +- src/renderer/src/i18n/locales/zh-cn.json | 3 +- src/renderer/src/i18n/locales/zh-tw.json | 3 +- .../settings/ProviderSettings/ModelList.tsx | 1 + src/renderer/src/store/index.ts | 2 +- src/renderer/src/store/llm.ts | 10 + src/renderer/src/store/migrate.ts | 4 + yarn.lock | 455 +++++++++++++++++- 22 files changed, 765 insertions(+), 52 deletions(-) create mode 100644 src/main/embeddings/Embeddings.ts create mode 100644 src/main/embeddings/EmbeddingsFactory.ts create mode 100644 src/main/embeddings/VoyageEmbeddings.ts create mode 100644 src/main/reranker/VoyageReranker.ts create mode 100644 src/renderer/src/assets/images/models/voyageai.png create mode 100644 src/renderer/src/assets/images/providers/voyageai.png diff --git a/package.json b/package.json index 2b743267..b989c1ea 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@electron-toolkit/utils": "^3.0.0", "@electron/notarize": "^2.5.0", "@google/generative-ai": "^0.21.0", + "@langchain/community": "^0.3.36", "@llm-tools/embedjs": "patch:@llm-tools/embedjs@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-npm-0.1.28-8e4393fa2d.patch", "@llm-tools/embedjs-libsql": "^0.1.28", "@llm-tools/embedjs-loader-csv": "^0.1.28", diff --git a/src/main/embeddings/Embeddings.ts b/src/main/embeddings/Embeddings.ts new file mode 100644 index 00000000..1cbbce9e --- /dev/null +++ b/src/main/embeddings/Embeddings.ts @@ -0,0 +1,24 @@ +import type { BaseEmbeddings } from '@llm-tools/embedjs-interfaces' +import { KnowledgeBaseParams } from '@types' + +import EmbeddingsFactory from './EmbeddingsFactory' + +export default class Embeddings { + private sdk: BaseEmbeddings + constructor({ model, apiKey, apiVersion, baseURL, dimensions }: KnowledgeBaseParams) { + this.sdk = EmbeddingsFactory.create({ model, apiKey, apiVersion, baseURL, dimensions } as KnowledgeBaseParams) + } + public async init(): Promise { + return this.sdk.init() + } + public async getDimensions(): Promise { + return this.sdk.getDimensions() + } + public async embedDocuments(texts: string[]): Promise { + return this.sdk.embedDocuments(texts) + } + + public async embedQuery(text: string): Promise { + return this.sdk.embedQuery(text) + } +} diff --git a/src/main/embeddings/EmbeddingsFactory.ts b/src/main/embeddings/EmbeddingsFactory.ts new file mode 100644 index 00000000..6524f9b9 --- /dev/null +++ b/src/main/embeddings/EmbeddingsFactory.ts @@ -0,0 +1,38 @@ +import type { BaseEmbeddings } from '@llm-tools/embedjs-interfaces' +import { OpenAiEmbeddings } from '@llm-tools/embedjs-openai' +import { AzureOpenAiEmbeddings } from '@llm-tools/embedjs-openai/src/azure-openai-embeddings' +import { getInstanceName } from '@main/utils' +import { KnowledgeBaseParams } from '@types' + +import VoyageEmbeddings from './VoyageEmbeddings' + +export default class EmbeddingsFactory { + static create({ model, apiKey, apiVersion, baseURL, dimensions }: KnowledgeBaseParams): BaseEmbeddings { + const batchSize = 10 + if (model.includes('voyage')) { + return new VoyageEmbeddings({ + modelName: model, + apiKey, + outputDimension: dimensions, + batchSize: 8 + }) + } + if (apiVersion !== undefined) { + return new AzureOpenAiEmbeddings({ + azureOpenAIApiKey: apiKey, + azureOpenAIApiVersion: apiVersion, + azureOpenAIApiDeploymentName: model, + azureOpenAIApiInstanceName: getInstanceName(baseURL), + dimensions, + batchSize + }) + } + return new OpenAiEmbeddings({ + model, + apiKey, + dimensions, + batchSize, + configuration: { baseURL } + }) + } +} diff --git a/src/main/embeddings/VoyageEmbeddings.ts b/src/main/embeddings/VoyageEmbeddings.ts new file mode 100644 index 00000000..7635c114 --- /dev/null +++ b/src/main/embeddings/VoyageEmbeddings.ts @@ -0,0 +1,30 @@ +import { VoyageEmbeddings as _VoyageEmbeddings } from '@langchain/community/embeddings/voyage' +import { BaseEmbeddings } from '@llm-tools/embedjs-interfaces' + +export default class VoyageEmbeddings extends BaseEmbeddings { + private model: _VoyageEmbeddings + constructor(private readonly configuration?: ConstructorParameters[0]) { + super() + if (!this.configuration) this.configuration = {} + if (!this.configuration.modelName) this.configuration.modelName = 'voyage-3' + + if (!this.configuration.outputDimension) { + throw new Error('You need to pass in the optional dimensions parameter for this model') + } + this.model = new _VoyageEmbeddings(this.configuration) + } + override async getDimensions(): Promise { + if (!this.configuration?.outputDimension) { + throw new Error('You need to pass in the optional dimensions parameter for this model') + } + return this.configuration?.outputDimension + } + + override async embedDocuments(texts: string[]): Promise { + return this.model.embedDocuments(texts) + } + + override async embedQuery(text: string): Promise { + return this.model.embedQuery(text) + } +} diff --git a/src/main/reranker/RerankerFactory.ts b/src/main/reranker/RerankerFactory.ts index 0c2e8d7d..9557d58a 100644 --- a/src/main/reranker/RerankerFactory.ts +++ b/src/main/reranker/RerankerFactory.ts @@ -4,6 +4,7 @@ import BaseReranker from './BaseReranker' import DefaultReranker from './DefaultReranker' import JinaReranker from './JinaReranker' import SiliconFlowReranker from './SiliconFlowReranker' +import VoyageReranker from './VoyageReranker' export default class RerankerFactory { static create(base: KnowledgeBaseParams): BaseReranker { @@ -11,6 +12,8 @@ export default class RerankerFactory { return new SiliconFlowReranker(base) } else if (base.rerankModelProvider === 'jina') { return new JinaReranker(base) + } else if (base.rerankModelProvider === 'voyageai') { + return new VoyageReranker(base) } return new DefaultReranker(base) } diff --git a/src/main/reranker/VoyageReranker.ts b/src/main/reranker/VoyageReranker.ts new file mode 100644 index 00000000..71057882 --- /dev/null +++ b/src/main/reranker/VoyageReranker.ts @@ -0,0 +1,60 @@ +import { ExtractChunkData } from '@llm-tools/embedjs-interfaces' +import { KnowledgeBaseParams } from '@types' +import axios from 'axios' + +import BaseReranker from './BaseReranker' + +export default class VoyageReranker extends BaseReranker { + constructor(base: KnowledgeBaseParams) { + super(base) + } + + public rerank = async (query: string, searchResults: ExtractChunkData[]): Promise => { + let baseURL = this.base?.rerankBaseURL?.endsWith('/') + ? this.base.rerankBaseURL.slice(0, -1) + : this.base.rerankBaseURL + + if (baseURL && !baseURL.endsWith('/v1')) { + baseURL = `${baseURL}/v1` + } + + const url = `${baseURL}/rerank` + + const requestBody = { + model: this.base.rerankModel, + query, + documents: searchResults.map((doc) => doc.pageContent), + top_k: this.base.topN, + return_documents: false, + truncation: true + } + + try { + const { data } = await axios.post(url, requestBody, { + headers: { + ...this.defaultHeaders() + } + }) + + const rerankResults = data.data + + const resultMap = new Map(rerankResults.map((result: any) => [result.index, result.relevance_score || 0])) + + return searchResults + .map((doc: ExtractChunkData, index: number) => { + const score = resultMap.get(index) + if (score === undefined) return undefined + + return { + ...doc, + score + } + }) + .filter((doc): doc is ExtractChunkData => doc !== undefined) + .sort((a, b) => b.score - a.score) + } catch (error: any) { + console.error('Voyage Reranker API 错误:', error.message || error) + throw new Error(`${error} - BaseUrl: ${baseURL}`) + } + } +} diff --git a/src/main/services/KnowledgeService.ts b/src/main/services/KnowledgeService.ts index f9fedb78..098f3170 100644 --- a/src/main/services/KnowledgeService.ts +++ b/src/main/services/KnowledgeService.ts @@ -21,11 +21,10 @@ import type { ExtractChunkData } from '@llm-tools/embedjs-interfaces' import { LibSqlDb } from '@llm-tools/embedjs-libsql' import { SitemapLoader } from '@llm-tools/embedjs-loader-sitemap' import { WebLoader } from '@llm-tools/embedjs-loader-web' -import { AzureOpenAiEmbeddings, OpenAiEmbeddings } from '@llm-tools/embedjs-openai' +import Embeddings from '@main/embeddings/Embeddings' import { addFileLoader } from '@main/loader' import Reranker from '@main/reranker/Reranker' import { windowService } from '@main/services/WindowService' -import { getInstanceName } from '@main/utils' import { getAllFiles } from '@main/utils/file' import type { LoaderReturn } from '@shared/config/types' import { FileType, KnowledgeBaseParams, KnowledgeItem } from '@types' @@ -114,29 +113,20 @@ class KnowledgeService { baseURL, dimensions }: KnowledgeBaseParams): Promise => { - const batchSize = 10 - return new RAGApplicationBuilder() - .setModel('NO_MODEL') - .setEmbeddingModel( - apiVersion - ? new AzureOpenAiEmbeddings({ - azureOpenAIApiKey: apiKey, - azureOpenAIApiVersion: apiVersion, - azureOpenAIApiDeploymentName: model, - azureOpenAIApiInstanceName: getInstanceName(baseURL), - dimensions, - batchSize - }) - : new OpenAiEmbeddings({ - model, - apiKey, - dimensions, - batchSize, - configuration: { baseURL } - }) - ) - .setVectorDatabase(new LibSqlDb({ path: path.join(this.storageDir, id) })) - .build() + let ragApplication: RAGApplication + const embeddings = new Embeddings({ model, apiKey, apiVersion, baseURL, dimensions } as KnowledgeBaseParams) + try { + ragApplication = await new RAGApplicationBuilder() + .setModel('NO_MODEL') + .setEmbeddingModel(embeddings) + .setVectorDatabase(new LibSqlDb({ path: path.join(this.storageDir, id) })) + .build() + } catch (e) { + Logger.error(e) + throw new Error(`Failed to create RAGApplication: ${e}`) + } + + return ragApplication } public create = async (_: Electron.IpcMainInvokeEvent, base: KnowledgeBaseParams): Promise => { diff --git a/src/renderer/src/assets/images/models/voyageai.png b/src/renderer/src/assets/images/models/voyageai.png new file mode 100644 index 0000000000000000000000000000000000000000..dfdfcd36da4875bce16617d50d092340f413a5ab GIT binary patch literal 14064 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 XRa;ajTT*`8MDU*UMdr^$!s7n|d}amo literal 0 HcmV?d00001 diff --git a/src/renderer/src/assets/images/providers/voyageai.png b/src/renderer/src/assets/images/providers/voyageai.png new file mode 100644 index 0000000000000000000000000000000000000000..dfdfcd36da4875bce16617d50d092340f413a5ab GIT binary patch literal 14064 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 XRa;ajTT*`8MDU*UMdr^$!s7n|d}amo literal 0 HcmV?d00001 diff --git a/src/renderer/src/config/embedings.ts b/src/renderer/src/config/embedings.ts index 12734cc1..1530a006 100644 --- a/src/renderer/src/config/embedings.ts +++ b/src/renderer/src/config/embedings.ts @@ -242,6 +242,58 @@ export const EMBEDDING_MODELS = [ { id: 'mistral-embed', max_context: 8000 + }, + { + id: 'voyage-3-large', + max_context: 1024 + }, + { + id: 'voyage-3-large', + max_context: 256 + }, + { + id: 'voyage-3-large', + max_context: 512 + }, + { + id: 'voyage-3-large', + max_context: 2048 + }, + { + id: 'voyage-3', + max_context: 1024 + }, + { + id: 'voyage-3-lite', + max_context: 512 + }, + { + id: 'voyage-code-3', + max_context: 1024 + }, + { + id: 'voyage-code-3', + max_context: 256 + }, + { + id: 'voyage-code-3', + max_context: 512 + }, + { + id: 'voyage-code-3', + max_context: 2048 + }, + { + id: 'voyage-finance-2', + max_context: 1024 + }, + { + id: 'voyage-law-2', + max_context: 1024 + }, + { + id: 'voyage-code-2', + max_context: 1536 } ] diff --git a/src/renderer/src/config/models.ts b/src/renderer/src/config/models.ts index 597fbcbf..14f1216d 100644 --- a/src/renderer/src/config/models.ts +++ b/src/renderer/src/config/models.ts @@ -122,6 +122,7 @@ import UpstageModelLogo from '@renderer/assets/images/models/upstage.png' import UpstageModelLogoDark from '@renderer/assets/images/models/upstage_dark.png' import ViduModelLogo from '@renderer/assets/images/models/vidu.png' import ViduModelLogoDark from '@renderer/assets/images/models/vidu_dark.png' +import VoyageModelLogo from '@renderer/assets/images/models/voyageai.png' import WenxinModelLogo from '@renderer/assets/images/models/wenxin.png' import WenxinModelLogoDark from '@renderer/assets/images/models/wenxin_dark.png' import XirangModelLogo from '@renderer/assets/images/models/xirang.png' @@ -175,7 +176,8 @@ export const REASONING_REGEX = /^(o\d+(?:-[\w-]+)?|.*\b(?:reasoner|thinking)\b.*|.*-[rR]\d+.*|.*\bqwq(?:-[\w-]+)?\b.*|.*\bhunyuan-t1(?:-[\w-]+)?\b.*)$/i // Embedding models -export const EMBEDDING_REGEX = /(?:^text-|embed|bge-|e5-|LLM2Vec|retrieval|uae-|gte-|jina-clip|jina-embeddings)/i +export const EMBEDDING_REGEX = + /(?:^text-|embed|bge-|e5-|LLM2Vec|retrieval|uae-|gte-|jina-clip|jina-embeddings|voyage-)/i // Rerank models export const RERANKING_REGEX = /(?:rerank|re-rank|re-ranker|re-ranking|retrieval|retriever)/i @@ -327,7 +329,8 @@ export function getModelLogo(modelId: string) { embedding: isLight ? EmbeddingModelLogo : EmbeddingModelLogoDark, perplexity: isLight ? PerplexityModelLogo : PerplexityModelLogoDark, sonar: isLight ? PerplexityModelLogo : PerplexityModelLogoDark, - 'bge-': BgeModelLogo + 'bge-': BgeModelLogo, + 'voyage-': VoyageModelLogo } for (const key in logoMap) { @@ -1801,7 +1804,63 @@ export const SYSTEM_MODELS: Record = { group: 'DeepSeek' } ], - gpustack: [] + gpustack: [], + voyageai: [ + { + id: 'voyage-3-large', + provider: 'voyageai', + name: 'voyage-3-large', + group: 'Voyage Embeddings V3' + }, + { + id: 'voyage-3', + provider: 'voyageai', + name: 'voyage-3', + group: 'Voyage Embeddings V3' + }, + { + id: 'voyage-3-lite', + provider: 'voyageai', + name: 'voyage-3-lite', + group: 'Voyage Embeddings V3' + }, + { + id: 'voyage-code-3', + provider: 'voyageai', + name: 'voyage-code-3', + group: 'Voyage Embeddings V3' + }, + { + id: 'voyage-finance-3', + provider: 'voyageai', + name: 'voyage-finance-3', + group: 'Voyage Embeddings V2' + }, + { + id: 'voyage-law-2', + provider: 'voyageai', + name: 'voyage-law-2', + group: 'Voyage Embeddings V2' + }, + { + id: 'voyage-code-2', + provider: 'voyageai', + name: 'voyage-code-2', + group: 'Voyage Embeddings V2' + }, + { + id: 'rerank-2', + provider: 'voyageai', + name: 'rerank-2', + group: 'Voyage Rerank V2' + }, + { + id: 'rerank-2-lite', + provider: 'voyageai', + name: 'rerank-2-lite', + group: 'Voyage Rerank V2' + } + ] } export const TEXT_TO_IMAGES_MODELS = [ diff --git a/src/renderer/src/config/providers.ts b/src/renderer/src/config/providers.ts index 7e01f5f8..59a6617d 100644 --- a/src/renderer/src/config/providers.ts +++ b/src/renderer/src/config/providers.ts @@ -38,6 +38,7 @@ import StepProviderLogo from '@renderer/assets/images/providers/step.png' import TencentCloudProviderLogo from '@renderer/assets/images/providers/tencent-cloud-ti.png' import TogetherProviderLogo from '@renderer/assets/images/providers/together.png' import BytedanceProviderLogo from '@renderer/assets/images/providers/volcengine.png' +import VoyageAIProviderLogo from '@renderer/assets/images/providers/voyageai.png' import XirangProviderLogo from '@renderer/assets/images/providers/xirang.png' import ZeroOneProviderLogo from '@renderer/assets/images/providers/zero-one.png' import ZhipuProviderLogo from '@renderer/assets/images/providers/zhipu.png' @@ -86,14 +87,15 @@ const PROVIDER_LOGO_MAP = { o3: O3ProviderLogo, 'tencent-cloud-ti': TencentCloudProviderLogo, gpustack: GPUStackProviderLogo, - alayanew: AlayaNewProviderLogo + alayanew: AlayaNewProviderLogo, + voyageai: VoyageAIProviderLogo } as const export function getProviderLogo(providerId: string) { return PROVIDER_LOGO_MAP[providerId as keyof typeof PROVIDER_LOGO_MAP] } -export const SUPPORTED_REANK_PROVIDERS = ['silicon', 'jina'] +export const SUPPORTED_REANK_PROVIDERS = ['silicon', 'jina', 'voyageai'] export const PROVIDER_CONFIG = { openai: { @@ -560,5 +562,16 @@ export const PROVIDER_CONFIG = { docs: 'https://docs.gpustack.ai/latest/', models: 'https://docs.gpustack.ai/latest/overview/#supported-models' } + }, + voyageai: { + api: { + url: 'https://api.voyageai.com' + }, + websites: { + official: 'https://www.voyageai.com/', + apiKey: 'https://dashboard.voyageai.com/organization/api-keys', + docs: 'https://docs.voyageai.com/docs', + models: 'https://docs.voyageai.com/docs' + } } } diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 9952bd6f..2b653a4e 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -678,7 +678,8 @@ "xirang": "State Cloud Xirang", "yi": "Yi", "zhinao": "360AI", - "zhipu": "ZHIPU AI" + "zhipu": "ZHIPU AI", + "voyageai": "Voyage AI" }, "restore": { "confirm": "Are you sure you want to restore data?", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 94d8f964..b0d67aac 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -678,7 +678,8 @@ "xirang": "天翼クラウド 息壤", "yi": "零一万物", "zhinao": "360智脳", - "zhipu": "智譜AI" + "zhipu": "智譜AI", + "voyageai": "Voyage AI" }, "restore": { "confirm": "データを復元しますか?", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index fc7c9d68..9ee57535 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -678,7 +678,8 @@ "xirang": "State Cloud Xirang", "yi": "Yi", "zhinao": "360AI", - "zhipu": "ZHIPU AI" + "zhipu": "ZHIPU AI", + "voyageai": "Voyage AI" }, "restore": { "confirm": "Вы уверены, что хотите восстановить данные?", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 12457f23..3857d77e 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -678,7 +678,8 @@ "xirang": "天翼云息壤", "yi": "零一万物", "zhinao": "360智脑", - "zhipu": "智谱AI" + "zhipu": "智谱AI", + "voyageai":"Voyage AI" }, "restore": { "confirm": "确定要恢复数据吗?", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 27d9b5da..e5fdc1d1 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -678,7 +678,8 @@ "xirang": "天翼雲息壤", "yi": "零一萬物", "zhinao": "360 智腦", - "zhipu": "智譜 AI" + "zhipu": "智譜 AI", + "voyageai": "Voyage AI" }, "restore": { "confirm": "確定要復原資料嗎?", diff --git a/src/renderer/src/pages/settings/ProviderSettings/ModelList.tsx b/src/renderer/src/pages/settings/ProviderSettings/ModelList.tsx index 47857582..2d881bd2 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ModelList.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ModelList.tsx @@ -257,6 +257,7 @@ const ModelList: React.FC = ({ provider: _provider, modelStatuse {sortedModelGroups[group].map((model) => { const modelStatus = modelStatuses.find((status) => status.model.id === model.id) const isChecking = modelStatus?.checking === true + console.log('model', model.id, getModelLogo(model.id)) return ( diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 3eabb1e0..27f24daa 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -40,7 +40,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 83, + version: 84, blacklist: ['runtime', 'messages'], migrate }, diff --git a/src/renderer/src/store/llm.ts b/src/renderer/src/store/llm.ts index ae28ec8f..00da25f4 100644 --- a/src/renderer/src/store/llm.ts +++ b/src/renderer/src/store/llm.ts @@ -456,6 +456,16 @@ export const INITIAL_PROVIDERS: Provider[] = [ models: SYSTEM_MODELS.gpustack, isSystem: true, enabled: false + }, + { + id: 'voyageai', + name: 'VoyageAI', + type: 'openai', + apiKey: '', + apiHost: 'https://api.voyageai.com', + models: SYSTEM_MODELS.voyageai, + isSystem: true, + enabled: false } ] diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index a781101a..8156d6a6 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -795,6 +795,10 @@ const migrateConfig = { state.settings.launchToTray = false state.settings.trayOnClose = true return state + }, + '84': (state: RootState) => { + addProvider(state, 'voyageai') + return state } } diff --git a/yarn.lock b/yarn.lock index 2d9f3ed3..ef9815c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1590,6 +1590,396 @@ __metadata: languageName: node linkType: hard +"@langchain/community@npm:^0.3.36": + version: 0.3.36 + resolution: "@langchain/community@npm:0.3.36" + dependencies: + "@langchain/openai": "npm:>=0.2.0 <0.5.0" + binary-extensions: "npm:^2.2.0" + expr-eval: "npm:^2.0.2" + flat: "npm:^5.0.2" + js-yaml: "npm:^4.1.0" + langchain: "npm:>=0.2.3 <0.3.0 || >=0.3.4 <0.4.0" + langsmith: "npm:>=0.2.8 <0.4.0" + uuid: "npm:^10.0.0" + zod: "npm:^3.22.3" + zod-to-json-schema: "npm:^3.22.5" + peerDependencies: + "@arcjet/redact": ^v1.0.0-alpha.23 + "@aws-crypto/sha256-js": ^5.0.0 + "@aws-sdk/client-bedrock-agent-runtime": ^3.749.0 + "@aws-sdk/client-bedrock-runtime": ^3.749.0 + "@aws-sdk/client-dynamodb": ^3.749.0 + "@aws-sdk/client-kendra": ^3.749.0 + "@aws-sdk/client-lambda": ^3.749.0 + "@aws-sdk/client-s3": ^3.749.0 + "@aws-sdk/client-sagemaker-runtime": ^3.749.0 + "@aws-sdk/client-sfn": ^3.749.0 + "@aws-sdk/credential-provider-node": ^3.388.0 + "@azure/search-documents": ^12.0.0 + "@azure/storage-blob": ^12.15.0 + "@browserbasehq/sdk": "*" + "@browserbasehq/stagehand": ^1.0.0 + "@clickhouse/client": ^0.2.5 + "@cloudflare/ai": "*" + "@datastax/astra-db-ts": ^1.0.0 + "@elastic/elasticsearch": ^8.4.0 + "@getmetal/metal-sdk": "*" + "@getzep/zep-cloud": ^1.0.6 + "@getzep/zep-js": ^0.9.0 + "@gomomento/sdk": ^1.51.1 + "@gomomento/sdk-core": ^1.51.1 + "@google-ai/generativelanguage": "*" + "@google-cloud/storage": ^6.10.1 || ^7.7.0 + "@gradientai/nodejs-sdk": ^1.2.0 + "@huggingface/inference": ^2.6.4 + "@huggingface/transformers": ^3.2.3 + "@ibm-cloud/watsonx-ai": "*" + "@lancedb/lancedb": ^0.12.0 + "@langchain/core": ">=0.2.21 <0.4.0" + "@layerup/layerup-security": ^1.5.12 + "@libsql/client": ^0.14.0 + "@mendable/firecrawl-js": ^1.4.3 + "@mlc-ai/web-llm": "*" + "@mozilla/readability": "*" + "@neondatabase/serverless": "*" + "@notionhq/client": ^2.2.10 + "@opensearch-project/opensearch": "*" + "@pinecone-database/pinecone": "*" + "@planetscale/database": ^1.8.0 + "@premai/prem-sdk": ^0.3.25 + "@qdrant/js-client-rest": ^1.8.2 + "@raycast/api": ^1.55.2 + "@rockset/client": ^0.9.1 + "@smithy/eventstream-codec": ^2.0.5 + "@smithy/protocol-http": ^3.0.6 + "@smithy/signature-v4": ^2.0.10 + "@smithy/util-utf8": ^2.0.0 + "@spider-cloud/spider-client": ^0.0.21 + "@supabase/supabase-js": ^2.45.0 + "@tensorflow-models/universal-sentence-encoder": "*" + "@tensorflow/tfjs-converter": "*" + "@tensorflow/tfjs-core": "*" + "@upstash/ratelimit": ^1.1.3 || ^2.0.3 + "@upstash/redis": ^1.20.6 + "@upstash/vector": ^1.1.1 + "@vercel/kv": "*" + "@vercel/postgres": "*" + "@writerai/writer-sdk": ^0.40.2 + "@xata.io/client": ^0.28.0 + "@zilliz/milvus2-sdk-node": ">=2.3.5" + apify-client: ^2.7.1 + assemblyai: ^4.6.0 + better-sqlite3: ">=9.4.0 <12.0.0" + cassandra-driver: ^4.7.2 + cborg: ^4.1.1 + cheerio: ^1.0.0-rc.12 + chromadb: "*" + closevector-common: 0.1.3 + closevector-node: 0.1.6 + closevector-web: 0.1.6 + cohere-ai: "*" + convex: ^1.3.1 + crypto-js: ^4.2.0 + d3-dsv: ^2.0.0 + discord.js: ^14.14.1 + dria: ^0.0.3 + duck-duck-scrape: ^2.2.5 + epub2: ^3.0.1 + fast-xml-parser: "*" + firebase-admin: ^11.9.0 || ^12.0.0 + google-auth-library: "*" + googleapis: "*" + hnswlib-node: ^3.0.0 + html-to-text: ^9.0.5 + ibm-cloud-sdk-core: "*" + ignore: ^5.2.0 + interface-datastore: ^8.2.11 + ioredis: ^5.3.2 + it-all: ^3.0.4 + jsdom: "*" + jsonwebtoken: ^9.0.2 + llmonitor: ^0.5.9 + lodash: ^4.17.21 + lunary: ^0.7.10 + mammoth: ^1.6.0 + mariadb: ^3.4.0 + mongodb: ">=5.2.0" + mysql2: ^3.9.8 + neo4j-driver: "*" + notion-to-md: ^3.1.0 + officeparser: ^4.0.4 + openai: "*" + pdf-parse: 1.1.1 + pg: ^8.11.0 + pg-copy-streams: ^6.0.5 + pickleparser: ^0.2.1 + playwright: ^1.32.1 + portkey-ai: ^0.1.11 + puppeteer: "*" + pyodide: ">=0.24.1 <0.27.0" + redis: "*" + replicate: "*" + sonix-speech-recognition: ^2.1.1 + srt-parser-2: ^1.2.3 + typeorm: ^0.3.20 + typesense: ^1.5.3 + usearch: ^1.1.1 + voy-search: 0.6.2 + weaviate-ts-client: "*" + web-auth-library: ^1.0.3 + word-extractor: "*" + ws: ^8.14.2 + youtubei.js: "*" + peerDependenciesMeta: + "@arcjet/redact": + optional: true + "@aws-crypto/sha256-js": + optional: true + "@aws-sdk/client-bedrock-agent-runtime": + optional: true + "@aws-sdk/client-bedrock-runtime": + optional: true + "@aws-sdk/client-dynamodb": + optional: true + "@aws-sdk/client-kendra": + optional: true + "@aws-sdk/client-lambda": + optional: true + "@aws-sdk/client-s3": + optional: true + "@aws-sdk/client-sagemaker-runtime": + optional: true + "@aws-sdk/client-sfn": + optional: true + "@aws-sdk/credential-provider-node": + optional: true + "@aws-sdk/dsql-signer": + optional: true + "@azure/search-documents": + optional: true + "@azure/storage-blob": + optional: true + "@browserbasehq/sdk": + optional: true + "@clickhouse/client": + optional: true + "@cloudflare/ai": + optional: true + "@datastax/astra-db-ts": + optional: true + "@elastic/elasticsearch": + optional: true + "@getmetal/metal-sdk": + optional: true + "@getzep/zep-cloud": + optional: true + "@getzep/zep-js": + optional: true + "@gomomento/sdk": + optional: true + "@gomomento/sdk-core": + optional: true + "@google-ai/generativelanguage": + optional: true + "@google-cloud/storage": + optional: true + "@gradientai/nodejs-sdk": + optional: true + "@huggingface/inference": + optional: true + "@huggingface/transformers": + optional: true + "@lancedb/lancedb": + optional: true + "@layerup/layerup-security": + optional: true + "@libsql/client": + optional: true + "@mendable/firecrawl-js": + optional: true + "@mlc-ai/web-llm": + optional: true + "@mozilla/readability": + optional: true + "@neondatabase/serverless": + optional: true + "@notionhq/client": + optional: true + "@opensearch-project/opensearch": + optional: true + "@pinecone-database/pinecone": + optional: true + "@planetscale/database": + optional: true + "@premai/prem-sdk": + optional: true + "@qdrant/js-client-rest": + optional: true + "@raycast/api": + optional: true + "@rockset/client": + optional: true + "@smithy/eventstream-codec": + optional: true + "@smithy/protocol-http": + optional: true + "@smithy/signature-v4": + optional: true + "@smithy/util-utf8": + optional: true + "@spider-cloud/spider-client": + optional: true + "@supabase/supabase-js": + optional: true + "@tensorflow-models/universal-sentence-encoder": + optional: true + "@tensorflow/tfjs-converter": + optional: true + "@tensorflow/tfjs-core": + optional: true + "@upstash/ratelimit": + optional: true + "@upstash/redis": + optional: true + "@upstash/vector": + optional: true + "@vercel/kv": + optional: true + "@vercel/postgres": + optional: true + "@writerai/writer-sdk": + optional: true + "@xata.io/client": + optional: true + "@zilliz/milvus2-sdk-node": + optional: true + apify-client: + optional: true + assemblyai: + optional: true + better-sqlite3: + optional: true + cassandra-driver: + optional: true + cborg: + optional: true + cheerio: + optional: true + chromadb: + optional: true + closevector-common: + optional: true + closevector-node: + optional: true + closevector-web: + optional: true + cohere-ai: + optional: true + convex: + optional: true + crypto-js: + optional: true + d3-dsv: + optional: true + discord.js: + optional: true + dria: + optional: true + duck-duck-scrape: + optional: true + epub2: + optional: true + fast-xml-parser: + optional: true + firebase-admin: + optional: true + google-auth-library: + optional: true + googleapis: + optional: true + hnswlib-node: + optional: true + html-to-text: + optional: true + ignore: + optional: true + interface-datastore: + optional: true + ioredis: + optional: true + it-all: + optional: true + jsdom: + optional: true + jsonwebtoken: + optional: true + llmonitor: + optional: true + lodash: + optional: true + lunary: + optional: true + mammoth: + optional: true + mariadb: + optional: true + mongodb: + optional: true + mysql2: + optional: true + neo4j-driver: + optional: true + notion-to-md: + optional: true + officeparser: + optional: true + pdf-parse: + optional: true + pg: + optional: true + pg-copy-streams: + optional: true + pickleparser: + optional: true + playwright: + optional: true + portkey-ai: + optional: true + puppeteer: + optional: true + pyodide: + optional: true + redis: + optional: true + replicate: + optional: true + sonix-speech-recognition: + optional: true + srt-parser-2: + optional: true + typeorm: + optional: true + typesense: + optional: true + usearch: + optional: true + voy-search: + optional: true + weaviate-ts-client: + optional: true + web-auth-library: + optional: true + word-extractor: + optional: true + ws: + optional: true + youtubei.js: + optional: true + checksum: 10c0/7945ba936c1b18506ca8ca70449d41208c627cadf52782a9d41e54e395fdc86a4421c01fa4977b582f7eddf5458dd7c418f932016c558a058abea3442828b8dd + languageName: node + linkType: hard + "@langchain/core@npm:^0.3.26": version: 0.3.42 resolution: "@langchain/core@npm:0.3.42" @@ -1638,6 +2028,20 @@ __metadata: languageName: node linkType: hard +"@langchain/openai@npm:>=0.2.0 <0.5.0": + version: 0.4.7 + resolution: "@langchain/openai@npm:0.4.7" + dependencies: + js-tiktoken: "npm:^1.0.12" + openai: "npm:^4.87.3" + zod: "npm:^3.22.4" + zod-to-json-schema: "npm:^3.22.3" + peerDependencies: + "@langchain/core": ">=0.3.39 <0.4.0" + checksum: 10c0/4c809100c1e039c8c786141f097764cc399699ca9b149861396b2339147ad8b7fec5c97e5365a546bb7c123c4ec1943cfe3ef2eb5f056d6ab5a3fd1dc35940bc + languageName: node + linkType: hard + "@langchain/openai@patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch": version: 0.3.16 resolution: "@langchain/openai@patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch::version=0.3.16&hash=642f39" @@ -2798,20 +3202,6 @@ __metadata: languageName: node linkType: hard -"@types/command-line-args@npm:^5.2.3": - version: 5.2.3 - resolution: "@types/command-line-args@npm:5.2.3" - checksum: 10c0/3a9bc58fd26e546391f6369dd28c03d59349dc4ac39eada1a5c39cc3578e02e4aac222615170e0db79b198ffba2af84fdbdda46e08c6edc4da42bc17ea85200f - languageName: node - linkType: hard - -"@types/command-line-usage@npm:^5.0.4": - version: 5.0.4 - resolution: "@types/command-line-usage@npm:5.0.4" - checksum: 10c0/67840ebf4bcfee200c07d978669ad596fe2adc350fd5c19d44ec2248623575d96ec917f513d1d59453f8f57e879133861a4cc41c20045c07f6c959f1fcaac7ad - languageName: node - linkType: hard - "@types/d3-color@npm:*": version: 3.1.3 resolution: "@types/d3-color@npm:3.1.3" @@ -3421,6 +3811,7 @@ __metadata: "@google/generative-ai": "npm:^0.21.0" "@hello-pangea/dnd": "npm:^16.6.0" "@kangfenmao/keyv-storage": "npm:^0.1.0" + "@langchain/community": "npm:^0.3.36" "@llm-tools/embedjs": "patch:@llm-tools/embedjs@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-npm-0.1.28-8e4393fa2d.patch" "@llm-tools/embedjs-libsql": "npm:^0.1.28" "@llm-tools/embedjs-loader-csv": "npm:^0.1.28" @@ -4091,6 +4482,13 @@ __metadata: languageName: node linkType: hard +"binary-extensions@npm:^2.2.0": + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: 10c0/75a59cafc10fb12a11d510e77110c6c7ae3f4ca22463d52487709ca7f18f69d886aa387557cc9864fbdb10153d0bdb4caacabf11541f55e89ed6e18d12ece2b5 + languageName: node + linkType: hard + "bindings@npm:^1.5.0": version: 1.5.0 resolution: "bindings@npm:1.5.0" @@ -6742,6 +7140,13 @@ __metadata: languageName: node linkType: hard +"expr-eval@npm:^2.0.2": + version: 2.0.2 + resolution: "expr-eval@npm:2.0.2" + checksum: 10c0/642f112ff28ea34574c595c3ad73ccd8e638498879a4dd28620c4dabebab2e11987a851266ba81883dae85a5800e0c93b3d06f81718b71a215f831534646e4f2 + languageName: node + linkType: hard + "express-rate-limit@npm:^7.5.0": version: 7.5.0 resolution: "express-rate-limit@npm:7.5.0" @@ -7095,6 +7500,15 @@ __metadata: languageName: node linkType: hard +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 10c0/f178b13482f0cd80c7fede05f4d10585b1f2fdebf26e12edc138e32d3150c6ea6482b7f12813a1091143bad52bb6d3596bca51a162257a21163c0ff438baa5fe + languageName: node + linkType: hard + "flatted@npm:^3.2.9": version: 3.3.3 resolution: "flatted@npm:3.3.3" @@ -9067,7 +9481,7 @@ __metadata: languageName: node linkType: hard -"langchain@npm:^0.3.8": +"langchain@npm:>=0.2.3 <0.3.0 || >=0.3.4 <0.4.0, langchain@npm:^0.3.8": version: 0.3.19 resolution: "langchain@npm:0.3.19" dependencies: @@ -16029,6 +16443,15 @@ __metadata: languageName: node linkType: hard +"zod-to-json-schema@npm:^3.22.5": + version: 3.24.5 + resolution: "zod-to-json-schema@npm:3.24.5" + peerDependencies: + zod: ^3.24.1 + checksum: 10c0/0745b94ba53e652d39f262641cdeb2f75d24339fb6076a38ce55bcf53d82dfaea63adf524ebc5f658681005401687f8e9551c4feca7c4c882e123e66091dfb90 + languageName: node + linkType: hard + "zod-validation-error@npm:^3.4.0": version: 3.4.0 resolution: "zod-validation-error@npm:3.4.0" @@ -16038,7 +16461,7 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.22.4, zod@npm:^3.23.8": +"zod@npm:^3.22.3, zod@npm:^3.22.4, zod@npm:^3.23.8": version: 3.24.2 resolution: "zod@npm:3.24.2" checksum: 10c0/c638c7220150847f13ad90635b3e7d0321b36cce36f3fc6050ed960689594c949c326dfe2c6fa87c14b126ee5d370ccdebd6efb304f41ef5557a4aaca2824565