feat: add百炼

This commit is contained in:
熊潇 2025-06-21 14:01:33 +08:00
parent 3cd3be6024
commit 00a23af998
10 changed files with 113 additions and 8 deletions

View File

@ -17,9 +17,29 @@ await Bun.build({
define: { define: {
ENVISION_VERSION: JSON.stringify(pkg.version), ENVISION_VERSION: JSON.stringify(pkg.version),
IS_BROWSER: JSON.stringify(false),
}, },
env: 'ENVISION_*', env: 'ENVISION_*',
}); });
const cmd = 'dts -i src/provider/index.ts -o ai-provider.d.ts'; const cmd = 'dts -i src/provider/index.ts -o ai-provider.d.ts';
execSync(cmd, { stdio: 'inherit' }); execSync(cmd, { stdio: 'inherit' });
execSync('cp dist/ai-provider.d.ts dist/ai-provider-browser.d.ts', { stdio: 'inherit' });
// bun run src/index.ts --
await Bun.build({
target: 'browser',
format: 'esm',
entrypoints: [resolvePath('./src/provider/index.ts')],
outdir: resolvePath('./dist'),
naming: {
entry: 'ai-provider-browser.js',
},
define: {
ENVISION_VERSION: JSON.stringify(pkg.version),
IS_BROWSER: JSON.stringify(true),
},
env: 'ENVISION_*',
});

View File

@ -1,6 +1,6 @@
{ {
"name": "@kevisual/ai", "name": "@kevisual/ai",
"version": "0.0.5", "version": "0.0.8",
"description": "后面需要把ai-center的provider模块提取出去", "description": "后面需要把ai-center的provider模块提取出去",
"main": "index.js", "main": "index.js",
"basename": "/root/ai-center-services", "basename": "/root/ai-center-services",
@ -11,6 +11,7 @@
}, },
"files": [ "files": [
"dist", "dist",
"src",
"types" "types"
], ],
"scripts": { "scripts": {
@ -20,7 +21,11 @@
"clean": "rm -rf dist", "clean": "rm -rf dist",
"pub": "envision pack -p -u" "pub": "envision pack -p -u"
}, },
"keywords": [], "keywords": [
"kevisual",
"ai",
"tools"
],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)", "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
"license": "MIT", "license": "MIT",
"packageManager": "pnpm@10.11.0", "packageManager": "pnpm@10.11.0",
@ -32,11 +37,20 @@
"exports": { "exports": {
".": { ".": {
"import": "./dist/ai-provider.js", "import": "./dist/ai-provider.js",
"node": "./dist/ai-provider.js",
"browser": "./dist/ai-provider-browser.js",
"types": "./dist/ai-provider.d.ts" "types": "./dist/ai-provider.d.ts"
}, },
"./ai-provider": { "./ai-provider": {
"import": "./dist/ai-provider.js", "import": "./dist/ai-provider.js",
"types": "./dist/ai-provider.d.ts" "types": "./dist/ai-provider.d.ts"
},
"./browser": {
"import": "./dist/ai-provider-browser.js",
"types": "./dist/ai-provider-browser.d.ts"
},
"./src/**/*": {
"import": "./src/**/*"
} }
}, },
"devDependencies": { "devDependencies": {

View File

@ -0,0 +1,10 @@
import { BaseChat, BaseChatOptions } from '../core/chat.ts';
export type BailianOptions = Partial<BaseChatOptions>;
export class BailianChat extends BaseChat {
static BASE_URL = 'https://bailian.aliyuncs.com/compatible-mode/v1/';
constructor(options: BailianOptions) {
const baseURL = options.baseURL || BailianChat.BASE_URL;
super({ ...(options as BaseChatOptions), baseURL: baseURL });
}
}

View File

@ -7,6 +7,8 @@ import { Custom } from './chat-adapter/custom.ts';
import { Volces } from './chat-adapter/volces.ts'; import { Volces } from './chat-adapter/volces.ts';
import { DeepSeek } from './chat-adapter/deepseek.ts'; import { DeepSeek } from './chat-adapter/deepseek.ts';
import { ModelScope } from './chat-adapter/model-scope.ts'; import { ModelScope } from './chat-adapter/model-scope.ts';
import { BailianChat } from './chat-adapter/dashscope.ts';
import { ChatMessage } from './core/type.ts'; import { ChatMessage } from './core/type.ts';
export const OllamaProvider = Ollama; export const OllamaProvider = Ollama;
@ -15,6 +17,7 @@ export const CustomProvider = Custom;
export const VolcesProvider = Volces; export const VolcesProvider = Volces;
export const DeepSeekProvider = DeepSeek; export const DeepSeekProvider = DeepSeek;
export const ModelScopeProvider = ModelScope; export const ModelScopeProvider = ModelScope;
export const BailianProvider = BailianChat;
export const ChatProviderMap = { export const ChatProviderMap = {
Ollama: OllamaProvider, Ollama: OllamaProvider,
@ -24,6 +27,7 @@ export const ChatProviderMap = {
DeepSeek: DeepSeekProvider, DeepSeek: DeepSeekProvider,
ModelScope: ModelScopeProvider, ModelScope: ModelScopeProvider,
BaseChat: BaseChat, BaseChat: BaseChat,
Bailian: BailianProvider,
}; };
type ProviderManagerConfig = { type ProviderManagerConfig = {

View File

@ -14,7 +14,7 @@ export type BaseChatOptions<T = Record<string, any>> = {
/** /**
* baseURL * baseURL
*/ */
baseURL: string; baseURL?: string;
/** /**
* *
*/ */
@ -32,7 +32,14 @@ export type BaseChatOptions<T = Record<string, any>> = {
*/ */
stream?: boolean; stream?: boolean;
} & T; } & T;
export const getIsBrowser = () => {
try {
// @ts-ignore
return IS_BROWSER;
} catch (e) {
return false;
}
};
export class BaseChat implements BaseChatInterface, BaseChatUsageInterface { export class BaseChat implements BaseChatInterface, BaseChatUsageInterface {
/** /**
* baseURL * baseURL
@ -63,7 +70,9 @@ export class BaseChat implements BaseChatInterface, BaseChatUsageInterface {
this.baseURL = options.baseURL; this.baseURL = options.baseURL;
this.model = options.model; this.model = options.model;
this.apiKey = options.apiKey; this.apiKey = options.apiKey;
this.isBrowser = options.isBrowser ?? false; // @ts-ignore
const DEFAULT_IS_BROWSER = getIsBrowser();
this.isBrowser = options.isBrowser ?? DEFAULT_IS_BROWSER;
this.openai = new OpenAI({ this.openai = new OpenAI({
apiKey: this.apiKey, apiKey: this.apiKey,
baseURL: this.baseURL, baseURL: this.baseURL,

View File

@ -1,7 +1,13 @@
import OpenAI from 'openai'; import OpenAI from 'openai';
export type ChatMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam; export type ChatMessage = OpenAI.Chat.Completions.ChatCompletionMessageParam;
export type ChatMessageOptions = Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams>; export type ChatMessageOptions = Partial<OpenAI.Chat.Completions.ChatCompletionCreateParams> & {
/**
*
* true
*/
enable_thinking?: boolean;
};
export type ChatMessageComplete = OpenAI.Chat.Completions.ChatCompletion; export type ChatMessageComplete = OpenAI.Chat.Completions.ChatCompletion;
export type ChatMessageStream = OpenAI.Chat.Completions.ChatCompletion; export type ChatMessageStream = OpenAI.Chat.Completions.ChatCompletion;

View File

@ -1,7 +1,7 @@
import { KnowledgeBase, KnowledgeOptions } from './knowledge-base.ts'; import { KnowledgeBase, KnowledgeOptions } from './knowledge-base.ts';
export class SiliconFlowKnowledge extends KnowledgeBase { export class SiliconFlowKnowledge extends KnowledgeBase {
static BASE_URL = 'https://api.siliconflow.com/v1'; static BASE_URL = 'https://api.siliconflow.cn/v1';
constructor(options: KnowledgeOptions) { constructor(options: KnowledgeOptions) {
super({ ...options, baseURL: options?.baseURL ?? SiliconFlowKnowledge.BASE_URL }); super({ ...options, baseURL: options?.baseURL ?? SiliconFlowKnowledge.BASE_URL });
} }

View File

@ -1,5 +1,8 @@
import { SiliconFlow } from '../../../src/provider/chat-adapter/siliconflow.ts'; import { SiliconFlow } from '../../../src/provider/chat-adapter/siliconflow.ts';
import { SiliconFlowKnowledge } from '../../provider/knowledge-adapter/siliconflow.ts'; import { SiliconFlowKnowledge } from '../../provider/knowledge-adapter/siliconflow.ts';
import dotenv from 'dotenv';
dotenv.config();
export const siliconflow = new SiliconFlow({ export const siliconflow = new SiliconFlow({
apiKey: process.env.SILICONFLOW_API_KEY, apiKey: process.env.SILICONFLOW_API_KEY,
model: 'Qwen/Qwen2-7B-Instruct', model: 'Qwen/Qwen2-7B-Instruct',
@ -7,7 +10,6 @@ export const siliconflow = new SiliconFlow({
export const knowledge = new SiliconFlowKnowledge({ export const knowledge = new SiliconFlowKnowledge({
apiKey: process.env.SILICONFLOW_API_KEY, apiKey: process.env.SILICONFLOW_API_KEY,
baseURL: SiliconFlow.BASE_URL,
model: 'Qwen/Qwen2-7B-Instruct', model: 'Qwen/Qwen2-7B-Instruct',
embeddingModel: 'Pro/BAAI/bge-m3', embeddingModel: 'Pro/BAAI/bge-m3',
}); });

View File

@ -0,0 +1,28 @@
import { knowledge } from '../common.ts';
import util from 'node:util';
const fc = [
{
title: '根据描述查询对应的网页的地址',
description: '根据描述查询对应的网页的地址,并返回网页的标题和链接',
},
{
title: '查询我的 draw 应用中的内容 ',
description: '根据搜索内容,查询我的 draw 应用中的内容,并返回对应的数据',
},
];
const main = async () => {
const res = await knowledge.rerank({
model: 'BAAI/bge-reranker-v2-m3',
query: '查询网页',
// query: '网页code-center的地址',
documents: fc.map((item) => {
return `${item.title}${item.description}`;
}),
});
console.log(util.inspect(res, { depth: 10, colors: true }));
// 8000 tokens 大概1w个字 2万个字符
};
main();

12
src/utils/json.ts Normal file
View File

@ -0,0 +1,12 @@
/**
* JSON对象
*/
export const getJsonFromString = (str: string) => {
try {
const jsonMatch = str.match(/```json\s*([\s\S]*?)\s*```/);
if (jsonMatch && jsonMatch[1]) {
return JSON.parse(jsonMatch[1]);
}
} catch (error) {}
return null;
};