chore: remove unused files and update CNBChat model name in constructor
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run clean && bun bun.config.mjs",
|
"build": "npm run clean && bun bun.config.mjs",
|
||||||
"dev": "bun run --watch bun.config.mjs",
|
"dev": "bun run --watch bun.config.mjs",
|
||||||
"test": "tsx test/**/*.ts",
|
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"pub": "envision pack -p -u"
|
"pub": "envision pack -p -u"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
onlyBuiltDependencies:
|
|
||||||
- esbuild
|
|
||||||
@@ -6,7 +6,7 @@ export class CNBChat extends BaseChat {
|
|||||||
repo: string;
|
repo: string;
|
||||||
constructor(options: CNBOptions & { repo: string }) {
|
constructor(options: CNBOptions & { repo: string }) {
|
||||||
const baseURL = CNBChat.BASE_URL.replace('{repo}', options.repo);
|
const baseURL = CNBChat.BASE_URL.replace('{repo}', options.repo);
|
||||||
super({ model: "hunyuan-a13b", ...(options as BaseChatOptions), baseURL: baseURL });
|
super({ model: "CNB-Models", ...(options as BaseChatOptions), baseURL: baseURL });
|
||||||
}
|
}
|
||||||
async query(params: CNBQueryParam): Promise<Result<QueryRag[]>> {
|
async query(params: CNBQueryParam): Promise<Result<QueryRag[]>> {
|
||||||
const url = this.baseURL.replace('/ai', '/knowledge/base/query');
|
const url = this.baseURL.replace('/ai', '/knowledge/base/query');
|
||||||
|
|||||||
@@ -2,6 +2,4 @@ export * from './chat.ts';
|
|||||||
|
|
||||||
export * from './knowledge.ts';
|
export * from './knowledge.ts';
|
||||||
|
|
||||||
export * from './utils/index.ts';
|
|
||||||
|
|
||||||
export { AIUtils } from './core/utils/index.ts';
|
export { AIUtils } from './core/utils/index.ts';
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
import type { Permission } from '@kevisual/permission';
|
|
||||||
|
|
||||||
export type AIModel = {
|
|
||||||
/**
|
|
||||||
* 提供商
|
|
||||||
*/
|
|
||||||
provider: string;
|
|
||||||
/**
|
|
||||||
* 模型名称
|
|
||||||
*/
|
|
||||||
model: string;
|
|
||||||
/**
|
|
||||||
* 模型组
|
|
||||||
*/
|
|
||||||
group: string;
|
|
||||||
/**
|
|
||||||
* 每日请求频率限制
|
|
||||||
*/
|
|
||||||
dayLimit?: number;
|
|
||||||
/**
|
|
||||||
* 总的token限制
|
|
||||||
*/
|
|
||||||
tokenLimit?: number;
|
|
||||||
};
|
|
||||||
export type SecretKey = {
|
|
||||||
/**
|
|
||||||
* 组
|
|
||||||
*/
|
|
||||||
group: string;
|
|
||||||
/**
|
|
||||||
* API密钥
|
|
||||||
*/
|
|
||||||
apiKey: string;
|
|
||||||
/**
|
|
||||||
* 解密密钥
|
|
||||||
*/
|
|
||||||
decryptKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AIConfig = {
|
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
models: AIModel[];
|
|
||||||
secretKeys: SecretKey[];
|
|
||||||
permission?: Permission;
|
|
||||||
filter?: {
|
|
||||||
objectKey: string;
|
|
||||||
type: 'array' | 'object';
|
|
||||||
operate: 'removeAttribute' | 'remove';
|
|
||||||
attribute: string[];
|
|
||||||
}[];
|
|
||||||
};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export * from './ai-config-type.ts';
|
|
||||||
export * from './parse-config.ts';
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
import AES from 'crypto-js/aes.js';
|
|
||||||
import Utf8 from 'crypto-js/enc-utf8.js';
|
|
||||||
import type { AIConfig } from './ai-config-type.js';
|
|
||||||
const CryptoJS = { AES, enc: { Utf8 } };
|
|
||||||
// 加密函数
|
|
||||||
export function encryptAES(plainText: string, secretKey: string) {
|
|
||||||
return CryptoJS.AES.encrypt(plainText, secretKey).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解密函数
|
|
||||||
export function decryptAES(cipherText: string, secretKey: string) {
|
|
||||||
const bytes = CryptoJS.AES.decrypt(cipherText, secretKey);
|
|
||||||
return bytes.toString(CryptoJS.enc.Utf8);
|
|
||||||
}
|
|
||||||
|
|
||||||
type AIModel = {
|
|
||||||
/**
|
|
||||||
* 提供商
|
|
||||||
*/
|
|
||||||
provider: string;
|
|
||||||
/**
|
|
||||||
* 模型名称
|
|
||||||
*/
|
|
||||||
model: string;
|
|
||||||
/**
|
|
||||||
* 模型组
|
|
||||||
*/
|
|
||||||
group: string;
|
|
||||||
/**
|
|
||||||
* 每日请求频率限制
|
|
||||||
*/
|
|
||||||
dayLimit?: number;
|
|
||||||
/**
|
|
||||||
* 总的token限制
|
|
||||||
*/
|
|
||||||
tokenLimit?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SecretKey = {
|
|
||||||
/**
|
|
||||||
* 组
|
|
||||||
*/
|
|
||||||
group: string;
|
|
||||||
/**
|
|
||||||
* API密钥
|
|
||||||
*/
|
|
||||||
apiKey: string;
|
|
||||||
/**
|
|
||||||
* 解密密钥
|
|
||||||
*/
|
|
||||||
decryptKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GetProviderOpts = {
|
|
||||||
model: string;
|
|
||||||
group: string;
|
|
||||||
decryptKey?: string;
|
|
||||||
};
|
|
||||||
export type ProviderResult = {
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
group: string;
|
|
||||||
apiKey: string;
|
|
||||||
dayLimit?: number;
|
|
||||||
tokenLimit?: number;
|
|
||||||
baseURL?: string;
|
|
||||||
/**
|
|
||||||
* 解密密钥
|
|
||||||
*/
|
|
||||||
decryptKey?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class AIConfigParser {
|
|
||||||
private config: AIConfig;
|
|
||||||
result: ProviderResult;
|
|
||||||
constructor(config: AIConfig) {
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 获取模型配置
|
|
||||||
* @param opts
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
getProvider(opts: GetProviderOpts): ProviderResult {
|
|
||||||
const { model, group, decryptKey } = opts;
|
|
||||||
const modelConfig = this.config.models.find((m) => m.model === model && m.group === group);
|
|
||||||
const groupConfig = this.config.secretKeys.find((m) => m.group === group);
|
|
||||||
if (!modelConfig) {
|
|
||||||
throw new Error(`在模型组 ${group} 中未找到模型 ${model}`);
|
|
||||||
}
|
|
||||||
const mergeConfig = {
|
|
||||||
...modelConfig,
|
|
||||||
...groupConfig,
|
|
||||||
decryptKey: decryptKey || groupConfig?.decryptKey,
|
|
||||||
};
|
|
||||||
// 验证模型配置
|
|
||||||
if (!mergeConfig.provider) {
|
|
||||||
throw new Error(`模型 ${model} 未配置提供商`);
|
|
||||||
}
|
|
||||||
if (!mergeConfig.model) {
|
|
||||||
throw new Error(`模型 ${model} 未配置模型名称`);
|
|
||||||
}
|
|
||||||
if (!mergeConfig.apiKey) {
|
|
||||||
throw new Error(`组 ${group} 未配置 API 密钥`);
|
|
||||||
}
|
|
||||||
if (!mergeConfig.group) {
|
|
||||||
throw new Error(`组 ${group} 未配置`);
|
|
||||||
}
|
|
||||||
this.result = mergeConfig;
|
|
||||||
return mergeConfig;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 获取解密密钥
|
|
||||||
* @param opts
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
async getSecretKey(opts?: {
|
|
||||||
getCache?: (key: string) => Promise<string>;
|
|
||||||
setCache?: (key: string, value: string) => Promise<void>;
|
|
||||||
providerResult?: ProviderResult;
|
|
||||||
}) {
|
|
||||||
const { getCache, setCache, providerResult } = opts || {};
|
|
||||||
const { apiKey, decryptKey, group = '', model } = providerResult || this.result;
|
|
||||||
const cacheKey = `${group}--${model}`;
|
|
||||||
if (!decryptKey) {
|
|
||||||
return apiKey;
|
|
||||||
}
|
|
||||||
if (getCache) {
|
|
||||||
const cache = await getCache(cacheKey);
|
|
||||||
if (cache) {
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const secretKey = decryptAES(apiKey, decryptKey);
|
|
||||||
if (setCache) {
|
|
||||||
await setCache(cacheKey, secretKey);
|
|
||||||
}
|
|
||||||
return secretKey;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 加密
|
|
||||||
* @param plainText
|
|
||||||
* @param secretKey
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
encrypt(plainText: string, secretKey: string) {
|
|
||||||
return encryptAES(plainText, secretKey);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 解密
|
|
||||||
* @param cipherText
|
|
||||||
* @param secretKey
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
decrypt(cipherText: string, secretKey: string) {
|
|
||||||
return decryptAES(cipherText, secretKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模型配置
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
getSelectOpts() {
|
|
||||||
const { models, secretKeys = [] } = this.config;
|
|
||||||
|
|
||||||
return models.map((model) => {
|
|
||||||
const selectOpts = secretKeys.find((m) => m.group === model.group);
|
|
||||||
return {
|
|
||||||
...model,
|
|
||||||
...selectOpts,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getConfig(keepSecret?: boolean, config?: AIConfig) {
|
|
||||||
const chatConfig = config ?? this.config;
|
|
||||||
if (keepSecret) {
|
|
||||||
return chatConfig;
|
|
||||||
}
|
|
||||||
// 过滤掉secret中的所有apiKey,移除掉并返回chatConfig
|
|
||||||
const { secretKeys = [], ...rest } = chatConfig || {};
|
|
||||||
return {
|
|
||||||
...rest,
|
|
||||||
secretKeys: secretKeys.map((item) => {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
apiKey: undefined,
|
|
||||||
decryptKey: undefined,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user