diff --git a/package.json b/package.json index 806c5aa..5303436 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ } }, "devDependencies": { - "@kevisual/code-center-module": "0.0.19", + "@kevisual/code-center-module": "0.0.20", "@kevisual/mark": "0.0.7", "@kevisual/router": "0.0.21", "@kevisual/types": "^0.0.10", @@ -63,7 +63,7 @@ "openai": "4.103.0", "pm2": "^6.0.6", "rimraf": "^6.0.1", - "rollup": "^4.41.0", + "rollup": "^4.41.1", "rollup-plugin-dts": "^6.2.1", "sequelize": "^6.37.7", "tape": "^5.9.0", diff --git a/src/provider/chat.ts b/src/provider/chat.ts new file mode 100644 index 0000000..040a420 --- /dev/null +++ b/src/provider/chat.ts @@ -0,0 +1,63 @@ +export * from './core/index.ts'; +import { BaseChat } from './core/chat.ts'; + +import { Ollama } from './chat-adapter/ollama.ts'; +import { SiliconFlow } from './chat-adapter/siliconflow.ts'; +import { Custom } from './chat-adapter/custom.ts'; +import { Volces } from './chat-adapter/volces.ts'; +import { DeepSeek } from './chat-adapter/deepseek.ts'; +import { ModelScope } from './chat-adapter/model-scope.ts'; +import { ChatMessage } from './core/type.ts'; + +export const OllamaProvider = Ollama; +export const SiliconFlowProvider = SiliconFlow; +export const CustomProvider = Custom; +export const VolcesProvider = Volces; +export const DeepSeekProvider = DeepSeek; +export const ModelScopeProvider = ModelScope; + +export const ChatProviderMap = { + Ollama: OllamaProvider, + SiliconFlow: SiliconFlowProvider, + Custom: CustomProvider, + Volces: VolcesProvider, + DeepSeek: DeepSeekProvider, + ModelScope: ModelScopeProvider, + BaseChat: BaseChat, +}; + +type ProviderManagerConfig = { + provider: string; + model: string; + apiKey: string; + baseURL?: string; +}; +export class ProviderManager { + provider: BaseChat; + constructor(config: ProviderManagerConfig) { + const { provider, model, apiKey, baseURL } = config; + const Provider = ChatProviderMap[provider] as typeof BaseChat; + if (!Provider) { + throw new Error(`Provider ${provider} not found`); + } + const providerConfig = { + model, + apiKey, + baseURL, + }; + if (!providerConfig.baseURL) { + delete providerConfig.baseURL; + } + this.provider = new Provider(providerConfig); + } + static async createProvider(config: ProviderManagerConfig) { + if (!config.baseURL) { + delete config.baseURL; + } + const pm = new ProviderManager(config); + return pm.provider; + } + async chat(messages: ChatMessage[]) { + return this.provider.chat(messages); + } +} diff --git a/src/provider/index.ts b/src/provider/index.ts index 5d265c5..7873f1f 100644 --- a/src/provider/index.ts +++ b/src/provider/index.ts @@ -1,63 +1,3 @@ -export * from './core/index.ts'; -import { BaseChat } from './core/chat.ts'; +export * from './chat.ts'; -import { Ollama } from './chat-adapter/ollama.ts'; -import { SiliconFlow } from './chat-adapter/siliconflow.ts'; -import { Custom } from './chat-adapter/custom.ts'; -import { Volces } from './chat-adapter/volces.ts'; -import { DeepSeek } from './chat-adapter/deepseek.ts'; -import { ModelScope } from './chat-adapter/model-scope.ts'; -import { ChatMessage } from './core/type.ts'; - -export const OllamaProvider = Ollama; -export const SiliconFlowProvider = SiliconFlow; -export const CustomProvider = Custom; -export const VolcesProvider = Volces; -export const DeepSeekProvider = DeepSeek; -export const ModelScopeProvider = ModelScope; - -export const ProviderMap = { - Ollama: OllamaProvider, - SiliconFlow: SiliconFlowProvider, - Custom: CustomProvider, - Volces: VolcesProvider, - DeepSeek: DeepSeekProvider, - ModelScope: ModelScopeProvider, - BaseChat: BaseChat, -}; - -type ProviderManagerConfig = { - provider: string; - model: string; - apiKey: string; - baseURL?: string; -}; -export class ProviderManager { - provider: BaseChat; - constructor(config: ProviderManagerConfig) { - const { provider, model, apiKey, baseURL } = config; - const Provider = ProviderMap[provider] as typeof BaseChat; - if (!Provider) { - throw new Error(`Provider ${provider} not found`); - } - const providerConfig = { - model, - apiKey, - baseURL, - }; - if (!providerConfig.baseURL) { - delete providerConfig.baseURL; - } - this.provider = new Provider(providerConfig); - } - static async createProvider(config: ProviderManagerConfig) { - if (!config.baseURL) { - delete config.baseURL; - } - const pm = new ProviderManager(config); - return pm.provider; - } - async chat(messages: ChatMessage[]) { - return this.provider.chat(messages); - } -} +export * from './knowledge.ts'; \ No newline at end of file diff --git a/src/provider/knowledge/knowledge-base.ts b/src/provider/knowledge-adapter/knowledge-base.ts similarity index 96% rename from src/provider/knowledge/knowledge-base.ts rename to src/provider/knowledge-adapter/knowledge-base.ts index e12829d..0cd87de 100644 --- a/src/provider/knowledge/knowledge-base.ts +++ b/src/provider/knowledge-adapter/knowledge-base.ts @@ -1,9 +1,9 @@ import { BaseChat, BaseChatOptions } from '../core/chat.ts'; import { EmbeddingMessage } from '../core/type.ts'; -export type KnowledgeOptions> = BaseChatOptions< +export type KnowledgeOptions> = BaseChatOptions< { - embeddingModel: string; + embeddingModel?: string; splitSize?: number; // 分块大小 默认 2000 splitOverlap?: number; // 分块重叠 默认 200 batchSize?: number; // 批量大小 默认 4, 4*2000=8000 diff --git a/src/provider/knowledge/knowledge.ts b/src/provider/knowledge-adapter/knowledge.ts similarity index 100% rename from src/provider/knowledge/knowledge.ts rename to src/provider/knowledge-adapter/knowledge.ts diff --git a/src/provider/knowledge-adapter/siliconflow.ts b/src/provider/knowledge-adapter/siliconflow.ts new file mode 100644 index 0000000..dfa567e --- /dev/null +++ b/src/provider/knowledge-adapter/siliconflow.ts @@ -0,0 +1,24 @@ +import { KnowledgeBase, KnowledgeOptions } from './knowledge-base.ts'; + +export class SiliconFlowKnowledge extends KnowledgeBase { + static BASE_URL = 'https://api.siliconflow.com/v1'; + constructor(options: KnowledgeOptions) { + super({ ...options, baseURL: options?.baseURL ?? SiliconFlowKnowledge.BASE_URL }); + } + + async rerank(data: RerankOptions) { + return this.openai.post('/rerank', { + body: data, + }); + } +} + +export type RerankOptions = { + model: string; + query: string; + documents: string[]; + top_n?: number; + return_documents?: boolean; + max_chunks_per_doc?: number; + overlap_tokens?: number; +}; diff --git a/src/provider/knowledge.ts b/src/provider/knowledge.ts new file mode 100644 index 0000000..02f5bdc --- /dev/null +++ b/src/provider/knowledge.ts @@ -0,0 +1,6 @@ +import { SiliconFlowKnowledge } from './knowledge-adapter/siliconflow.ts'; +import { KnowledgeBase, KnowledgeOptions } from './knowledge-adapter/knowledge-base.ts'; +import { RerankOptions } from './knowledge-adapter/siliconflow.ts'; +export { KnowledgeBase, KnowledgeOptions, RerankOptions }; + +export { SiliconFlowKnowledge }; diff --git a/src/test/chunks/01-get.ts b/src/test/chunks/01-get.ts index 2c00f8d..65e0128 100644 --- a/src/test/chunks/01-get.ts +++ b/src/test/chunks/01-get.ts @@ -1,4 +1,4 @@ -import { getChunks } from '../../../../../src/provider/utils/chunk.ts'; +import { getChunks } from '../../provider/utils/chunk.ts'; const str = 'Hello world this is a test 你好沙盒 very big'; diff --git a/src/test/encrypt/index.ts b/src/test/encrypt/index.ts index c922ea3..99b3f84 100644 --- a/src/test/encrypt/index.ts +++ b/src/test/encrypt/index.ts @@ -1,4 +1,4 @@ -import { encryptAES, decryptAES } from '../../../../../src/provider/utils/parse-config.ts'; +import { encryptAES, decryptAES } from '../..//provider/utils/parse-config.ts'; const plainx = process.env.API_KEY; const decryptKey = process.env.DECRYPT_KEY; diff --git a/src/test/func-call/demo.ts b/src/test/func-call/demo.ts index 0cf3f77..583f49e 100644 --- a/src/test/func-call/demo.ts +++ b/src/test/func-call/demo.ts @@ -1,5 +1,5 @@ -import { SiliconFlow } from '../../../../../src/provider/chat-adapter/siliconflow.ts'; -import { Ollama } from '../../../../../src/provider/chat-adapter/ollama.ts'; +import { SiliconFlow } from '../..//provider/chat-adapter/siliconflow.ts'; +import { Ollama } from '../..//provider/chat-adapter/ollama.ts'; import dotenv from 'dotenv'; dotenv.config(); diff --git a/src/test/model-scope/index.ts b/src/test/model-scope/index.ts index ac33319..54f8aba 100644 --- a/src/test/model-scope/index.ts +++ b/src/test/model-scope/index.ts @@ -1,5 +1,5 @@ -import { ModelScope } from '../../../../../src/provider/chat-adapter/model-scope.ts'; -import { log } from '../../../../../src/logger/index.ts'; +import { ModelScope } from '../..//provider/chat-adapter/model-scope.ts'; +import { log } from '../..//logger/index.ts'; import util from 'util'; import { config } from 'dotenv'; config(); diff --git a/src/test/provider/index.ts b/src/test/provider/index.ts index 872c7b7..e099a87 100644 --- a/src/test/provider/index.ts +++ b/src/test/provider/index.ts @@ -1,4 +1,4 @@ -import { ProviderManager } from '../../../../../src/provider/index.ts'; +import { ProviderManager } from '../..//provider/index.ts'; import { config } from 'dotenv'; config(); const providerConfig = { provider: 'ModelScope', model: 'Qwen/Qwen2.5-Coder-32B-Instruct', apiKey: process.env.MODEL_SCOPE_API_KEY }; diff --git a/src/test/siliconflow/common.ts b/src/test/siliconflow/common.ts index 7c5d817..85df4ca 100644 --- a/src/test/siliconflow/common.ts +++ b/src/test/siliconflow/common.ts @@ -1,11 +1,11 @@ -import { SiliconFlow } from '../../../../../src/provider/chat-adapter/siliconflow.ts'; -import { KnowledgeBase } from '../../../../../src/provider/knowledge/knowledge-base.ts'; +import { SiliconFlow } from '../../../src/provider/chat-adapter/siliconflow.ts'; +import { SiliconFlowKnowledge } from '../../provider/knowledge-adapter/siliconflow.ts'; export const siliconflow = new SiliconFlow({ apiKey: process.env.SILICONFLOW_API_KEY, model: 'Qwen/Qwen2-7B-Instruct', }); -export const knowledge = new KnowledgeBase({ +export const knowledge = new SiliconFlowKnowledge({ apiKey: process.env.SILICONFLOW_API_KEY, baseURL: SiliconFlow.BASE_URL, model: 'Qwen/Qwen2-7B-Instruct', diff --git a/src/test/siliconflow/get.ts b/src/test/siliconflow/get.ts index 727d0c7..dfb9978 100644 --- a/src/test/siliconflow/get.ts +++ b/src/test/siliconflow/get.ts @@ -1,4 +1,4 @@ -import { SiliconFlow } from '../../../../../src/provider/chat-adapter/siliconflow.ts'; +import { SiliconFlow } from '../..//provider/chat-adapter/siliconflow.ts'; import dotenv from 'dotenv'; dotenv.config(); diff --git a/src/test/siliconflow/rerank/index.ts b/src/test/siliconflow/rerank/index.ts new file mode 100644 index 0000000..707d2f8 --- /dev/null +++ b/src/test/siliconflow/rerank/index.ts @@ -0,0 +1,34 @@ +import { knowledge } from '../common.ts'; + +const install = [ + { + title: 'Git', + description: '分布式版本控制系统,用于跟踪代码变更和协作开发', + 'install-way': + '可通过操作系统的包管理器安装(如 macOS 使用 Homebrew `brew install git`,Ubuntu 使用 `sudo apt-get install git`),或从官网 https://git-scm.com/ 下载安装', + }, + { + title: 'Node.js', + description: '基于 Chrome V8 引擎的 JavaScript 运行时,用于构建服务端和命令行工具', + 'install-way': '可通过操作系统的包管理器安装,或使用 Node 版本管理工具 nvm 安装;官网 https://nodejs.org 提供 LTS 和最新版本的安装包', + }, + { + title: 'nvm (Node Version Manager)', + description: '用于管理多个 Node.js 版本的命令行工具', + 'install-way': + '在 Unix/Linux 系统中可通过脚本安装:`curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash`,安装后需重启终端或执行 source 命令加载配置', + }, +]; +const main = async () => { + const res = await knowledge.rerank({ + model: 'BAAI/bge-reranker-v2-m3', + query: '安装nvm的办法和安装node的办法', + documents: install.map((item) => { + return `${item.title}:${item.description},安装方式:${item['install-way']}`; + }), + }); + console.log(res); + // 8000 tokens 大概1w个字 2万个字符 +}; + +main(); diff --git a/src/test/siliconflow/videos/index.ts b/src/test/siliconflow/videos/index.ts index d06a9c6..76a4acf 100644 --- a/src/test/siliconflow/videos/index.ts +++ b/src/test/siliconflow/videos/index.ts @@ -1,5 +1,5 @@ -import { SiliconFlow } from '../../../../../../src/provider/chat-adapter/siliconflow.ts'; -import { VideoSiliconFlow } from '../../../../../../src/provider/media/video/siliconflow.ts'; +import { SiliconFlow } from '../../..//provider/chat-adapter/siliconflow.ts'; +import { VideoSiliconFlow } from '../../..//provider/media/video/siliconflow.ts'; import dotenv from 'dotenv'; import fs from 'fs'; import path from 'path'; diff --git a/vite.config.mjs b/vite.config.mjs new file mode 100644 index 0000000..e2cfd44 --- /dev/null +++ b/vite.config.mjs @@ -0,0 +1,9 @@ +import { defineConfig } from 'vite'; +import basicSsl from '@vitejs/plugin-basic-ssl'; + +export default defineConfig({ + plugins: [basicSsl()], + server: { + port: 3000, + }, +});