generated from tailored/app-template
	add permission check
This commit is contained in:
		@@ -27,6 +27,8 @@
 | 
			
		||||
  "packageManager": "pnpm@10.7.1",
 | 
			
		||||
  "type": "module",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@kevisual/cache": "^0.0.2",
 | 
			
		||||
    "@kevisual/permission": "^0.0.1",
 | 
			
		||||
    "@kevisual/router": "0.0.10"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										31
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -8,6 +8,12 @@ importers:
 | 
			
		||||
 | 
			
		||||
  .:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@kevisual/cache':
 | 
			
		||||
        specifier: ^0.0.2
 | 
			
		||||
        version: 0.0.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.2)
 | 
			
		||||
      '@kevisual/permission':
 | 
			
		||||
        specifier: ^0.0.1
 | 
			
		||||
        version: 0.0.1
 | 
			
		||||
      '@kevisual/router':
 | 
			
		||||
        specifier: 0.0.10
 | 
			
		||||
        version: 0.0.10
 | 
			
		||||
@@ -398,6 +404,9 @@ packages:
 | 
			
		||||
  '@kevisual/auth@1.0.5':
 | 
			
		||||
    resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==}
 | 
			
		||||
 | 
			
		||||
  '@kevisual/cache@0.0.2':
 | 
			
		||||
    resolution: {integrity: sha512-2Cl5KF2Gi27uLfhO6CdTMFnRzx9vYnqevAo7d9ab3rOaqTgF8tLeAXglXyRbaWW3WUbHU2XaOb4r98uUsqIQQw==}
 | 
			
		||||
 | 
			
		||||
  '@kevisual/code-center-module@0.0.18':
 | 
			
		||||
    resolution: {integrity: sha512-BfANmxLEO1AwVmqpa6VDgxk//YN8asf1r5jIPpyKDQm12kyyrYgHND9AgGCDRH8lvq6rYVe0svCZXD5b06UPWQ==}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
@@ -414,6 +423,9 @@ packages:
 | 
			
		||||
  '@kevisual/mark@0.0.7':
 | 
			
		||||
    resolution: {integrity: sha512-PiEEy4yvWEpixw76PzgrIWeNelzm+FrhtzFmqJU92o5GkgawaFwighcvIxqcVZRKeEFF4uvlTjFrGeQvXw6F4A==}
 | 
			
		||||
 | 
			
		||||
  '@kevisual/permission@0.0.1':
 | 
			
		||||
    resolution: {integrity: sha512-nSX2LzbPkU3YAMegbUFGU8tfmtFb7dcF5edqzm+gI6crcyCL1JzIB9HAYNEeEVIljLxuREwM/vVg9aFmF4cz9Q==}
 | 
			
		||||
 | 
			
		||||
  '@kevisual/query@0.0.13':
 | 
			
		||||
    resolution: {integrity: sha512-gSEIDiCvwSaLLAFZv4vam4wSrMsaCuQ3VGjE3kwRwZ8urlVH1TOA+NUO908A22p9m1Iij7Y1Q/JlfSJi2QzuKQ==}
 | 
			
		||||
 | 
			
		||||
@@ -1747,6 +1759,9 @@ packages:
 | 
			
		||||
    resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
 | 
			
		||||
    engines: {node: '>=0.10.0'}
 | 
			
		||||
 | 
			
		||||
  idb-keyval@6.2.1:
 | 
			
		||||
    resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==}
 | 
			
		||||
 | 
			
		||||
  ignore-by-default@1.0.1:
 | 
			
		||||
    resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
 | 
			
		||||
 | 
			
		||||
@@ -3347,6 +3362,18 @@ snapshots:
 | 
			
		||||
 | 
			
		||||
  '@kevisual/auth@1.0.5': {}
 | 
			
		||||
 | 
			
		||||
  '@kevisual/cache@0.0.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.2)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@rollup/plugin-commonjs': 28.0.3(rollup@4.39.0)
 | 
			
		||||
      '@rollup/plugin-node-resolve': 16.0.1(rollup@4.39.0)
 | 
			
		||||
      '@rollup/plugin-typescript': 12.1.2(rollup@4.39.0)(tslib@2.8.1)(typescript@5.8.2)
 | 
			
		||||
      idb-keyval: 6.2.1
 | 
			
		||||
      rollup-plugin-dts: 6.2.1(rollup@4.39.0)(typescript@5.8.2)
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - rollup
 | 
			
		||||
      - tslib
 | 
			
		||||
      - typescript
 | 
			
		||||
 | 
			
		||||
  '@kevisual/code-center-module@0.0.18(@kevisual/auth@1.0.5)(@kevisual/router@0.0.10)(@kevisual/use-config@1.0.10(dotenv@16.4.7))(ioredis@5.6.0)(pg@8.14.1)(sequelize@6.37.7(pg-hstore@2.3.4)(pg@8.14.1))':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      '@kevisual/auth': 1.0.5
 | 
			
		||||
@@ -3393,6 +3420,8 @@ snapshots:
 | 
			
		||||
      - tedious
 | 
			
		||||
      - utf-8-validate
 | 
			
		||||
 | 
			
		||||
  '@kevisual/permission@0.0.1': {}
 | 
			
		||||
 | 
			
		||||
  '@kevisual/query@0.0.13(ws@8.18.1)(zod@3.24.2)':
 | 
			
		||||
    dependencies:
 | 
			
		||||
      openai: 4.91.1(ws@8.18.1)(zod@3.24.2)
 | 
			
		||||
@@ -4882,6 +4911,8 @@ snapshots:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      safer-buffer: 2.1.2
 | 
			
		||||
 | 
			
		||||
  idb-keyval@6.2.1: {}
 | 
			
		||||
 | 
			
		||||
  ignore-by-default@1.0.1: {}
 | 
			
		||||
 | 
			
		||||
  ignore@5.3.2: {}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
import { Permission } from '@kevisual/permission';
 | 
			
		||||
import CryptoJS from 'crypto-js';
 | 
			
		||||
 | 
			
		||||
// 加密函数
 | 
			
		||||
@@ -73,6 +74,7 @@ export type AIConfig = {
 | 
			
		||||
  description?: string;
 | 
			
		||||
  models: AIModel[];
 | 
			
		||||
  secretKeys: SecretKey[];
 | 
			
		||||
  permission?: Permission;
 | 
			
		||||
  filter?: {
 | 
			
		||||
    objectKey: string;
 | 
			
		||||
    type: 'array' | 'object';
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ import { app } from '@/app.ts';
 | 
			
		||||
import { ChatServices } from './services/chat-services.ts';
 | 
			
		||||
import { ChatConfigServices } from './services/chat-config-srevices.ts';
 | 
			
		||||
import { AiChatHistoryModel } from './models/ai-chat-history.ts';
 | 
			
		||||
 | 
			
		||||
import { UserPermission } from '@kevisual/permission';
 | 
			
		||||
app
 | 
			
		||||
  .route({
 | 
			
		||||
    path: 'ai',
 | 
			
		||||
@@ -21,19 +21,20 @@ app
 | 
			
		||||
      if (!aiChatHistory) {
 | 
			
		||||
        ctx.throw(400, 'aiChatHistory not found');
 | 
			
		||||
      }
 | 
			
		||||
      if (aiChatHistory.uid !== tokenUser.uid) {
 | 
			
		||||
      if (aiChatHistory.uid !== tokenUser.id) {
 | 
			
		||||
        ctx.throw(403, 'not permission');
 | 
			
		||||
      }
 | 
			
		||||
      username = username || aiChatHistory.username;
 | 
			
		||||
      username = username || aiChatHistory.username || tokenUsername;
 | 
			
		||||
      model = model || aiChatHistory.model;
 | 
			
		||||
      group = group || aiChatHistory.group;
 | 
			
		||||
    } else {
 | 
			
		||||
      username = username || tokenUsername;
 | 
			
		||||
    }
 | 
			
		||||
    const isSelf = username === tokenUsername;
 | 
			
		||||
 | 
			
		||||
    if (!Array.isArray(messages)) {
 | 
			
		||||
      ctx.throw(400, 'chat messages is not array');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 初始化服务
 | 
			
		||||
    const chatServices = await ChatServices.createServices({
 | 
			
		||||
      owner: username,
 | 
			
		||||
@@ -41,6 +42,15 @@ app
 | 
			
		||||
      group,
 | 
			
		||||
      username: tokenUsername,
 | 
			
		||||
    });
 | 
			
		||||
    if (!isSelf && username !== 'root') {
 | 
			
		||||
      const aiConfig = chatServices.aiConfig;
 | 
			
		||||
      const permission = new UserPermission({ permission: aiConfig.permission, owner: username });
 | 
			
		||||
      const checkPermission = permission.checkPermissionSuccess({ username: tokenUsername, password: options.password });
 | 
			
		||||
      if (!checkPermission.success) {
 | 
			
		||||
        ctx.throw(403, checkPermission.message);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const chatConfigServices = new ChatConfigServices(username, tokenUsername);
 | 
			
		||||
    await chatConfigServices.checkUserCanChat(tokenUsername);
 | 
			
		||||
    await chatServices.checkCanChat();
 | 
			
		||||
@@ -72,6 +82,10 @@ app
 | 
			
		||||
      prompt_tokens: aiChatHistory.prompt_tokens + usage.prompt_tokens,
 | 
			
		||||
      completion_tokens: aiChatHistory.completion_tokens + usage.completion_tokens,
 | 
			
		||||
      total_tokens: aiChatHistory.total_tokens + usage.total_tokens,
 | 
			
		||||
      version: aiChatHistory.version + 1,
 | 
			
		||||
      model: model,
 | 
			
		||||
      group: group,
 | 
			
		||||
      username: username,
 | 
			
		||||
    };
 | 
			
		||||
    if (hook) {
 | 
			
		||||
      needUpdateData.data = {
 | 
			
		||||
@@ -126,19 +140,46 @@ app
 | 
			
		||||
  .define(async (ctx) => {
 | 
			
		||||
    const username = ctx.query.username || 'root';
 | 
			
		||||
    const tokenUser = ctx.state.tokenUser;
 | 
			
		||||
    const usernames = ctx.query.data?.usernames || [];
 | 
			
		||||
    const tokenUsername = tokenUser.username;
 | 
			
		||||
    const isSameUser = username === tokenUser.username;
 | 
			
		||||
    const configObject: Record<string, any> = {};
 | 
			
		||||
    const configArray: any[] = [];
 | 
			
		||||
    const services = new ChatConfigServices(username, tokenUser.username);
 | 
			
		||||
    const res = await services.getChatConfig(true, ctx.query.token);
 | 
			
		||||
    configObject[username] = res;
 | 
			
		||||
    configArray.push({
 | 
			
		||||
      username,
 | 
			
		||||
      config: res,
 | 
			
		||||
    });
 | 
			
		||||
    if (!isSameUser) {
 | 
			
		||||
      const selfServices = new ChatConfigServices(tokenUser.username, tokenUser.username);
 | 
			
		||||
      const selfRes = await selfServices.getChatConfig(true, ctx.query.token);
 | 
			
		||||
      configObject['self'] = selfRes;
 | 
			
		||||
    } else {
 | 
			
		||||
      configObject['self'] = res;
 | 
			
		||||
      configArray.push({
 | 
			
		||||
        username: tokenUser.username,
 | 
			
		||||
        self: true,
 | 
			
		||||
        config: selfRes,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    ctx.body = configObject;
 | 
			
		||||
    for (const username of usernames) {
 | 
			
		||||
      const services = new ChatConfigServices(username, tokenUser.username);
 | 
			
		||||
      const res = await services.getChatConfig(true, ctx.query.token);
 | 
			
		||||
      const aiConfig = services.aiConfig;
 | 
			
		||||
      const permission = new UserPermission({ permission: aiConfig.permission, owner: username });
 | 
			
		||||
      const checkPermission = permission.checkPermissionSuccess({ username: tokenUsername, password: '-----------------' });
 | 
			
		||||
      if (!checkPermission.success) {
 | 
			
		||||
        // ctx.throw(403, `[${username}] ${checkPermission.message}`);
 | 
			
		||||
        configArray.push({
 | 
			
		||||
          username,
 | 
			
		||||
          config: null,
 | 
			
		||||
          error: checkPermission.message,
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        configArray.push({
 | 
			
		||||
          username,
 | 
			
		||||
          config: res,
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ctx.body = configArray;
 | 
			
		||||
  })
 | 
			
		||||
  .addTo(app);
 | 
			
		||||
 | 
			
		||||
@@ -146,7 +187,7 @@ app
 | 
			
		||||
  .route({
 | 
			
		||||
    path: 'ai',
 | 
			
		||||
    key: 'get-chat-usage',
 | 
			
		||||
    description: '获取chat使用情况',
 | 
			
		||||
    description: '获取chat使用情况, 只获取root的使用情况',
 | 
			
		||||
    middleware: ['auth'],
 | 
			
		||||
  })
 | 
			
		||||
  .define(async (ctx) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,12 +12,121 @@ app
 | 
			
		||||
    const tokenUser = ctx.state.tokenUser;
 | 
			
		||||
    const aiChatList = await AiChatHistoryModel.findAll({
 | 
			
		||||
      where: {
 | 
			
		||||
        uid: tokenUser.uid,
 | 
			
		||||
        uid: tokenUser.id,
 | 
			
		||||
      },
 | 
			
		||||
      order: [['createdAt', 'DESC']],
 | 
			
		||||
      order: [['updatedAt', 'DESC']],
 | 
			
		||||
    });
 | 
			
		||||
    ctx.body = {
 | 
			
		||||
      list: aiChatList,
 | 
			
		||||
    };
 | 
			
		||||
  })
 | 
			
		||||
  .addTo(app);
 | 
			
		||||
 | 
			
		||||
app
 | 
			
		||||
  .route({
 | 
			
		||||
    path: 'ai',
 | 
			
		||||
    key: 'update-chat',
 | 
			
		||||
    description: '更新chat',
 | 
			
		||||
    middleware: ['auth'],
 | 
			
		||||
  })
 | 
			
		||||
  .define(async (ctx) => {
 | 
			
		||||
    const tokenUser = ctx.state.tokenUser;
 | 
			
		||||
    const uid = tokenUser.id;
 | 
			
		||||
    const { id, data, prompt_tokens, total_tokens, completion_tokens, createdAt, updatedAt, ...rest } = ctx.query.data || {};
 | 
			
		||||
    let aiChat: AiChatHistoryModel | null = null;
 | 
			
		||||
    if (id) {
 | 
			
		||||
      aiChat = await AiChatHistoryModel.findByPk(id);
 | 
			
		||||
      if (!aiChat) {
 | 
			
		||||
        ctx.throw(404, 'chat not found');
 | 
			
		||||
      }
 | 
			
		||||
      if (aiChat.uid !== uid) {
 | 
			
		||||
        ctx.throw(403, 'no permission');
 | 
			
		||||
      }
 | 
			
		||||
      await aiChat.update({ data: { ...aiChat.data, ...data }, ...rest, version: aiChat.version + 1 });
 | 
			
		||||
    } else {
 | 
			
		||||
      aiChat = await AiChatHistoryModel.create({
 | 
			
		||||
        ...rest,
 | 
			
		||||
        uid: uid,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    ctx.body = aiChat;
 | 
			
		||||
  })
 | 
			
		||||
  .addTo(app);
 | 
			
		||||
 | 
			
		||||
app
 | 
			
		||||
  .route({
 | 
			
		||||
    path: 'ai',
 | 
			
		||||
    key: 'get-chat',
 | 
			
		||||
    description: '获取chat',
 | 
			
		||||
    middleware: ['auth'],
 | 
			
		||||
  })
 | 
			
		||||
  .define(async (ctx) => {
 | 
			
		||||
    const tokenUser = ctx.state.tokenUser;
 | 
			
		||||
    const { id } = ctx.query.data || {};
 | 
			
		||||
    if (!id) {
 | 
			
		||||
      ctx.throw(400, 'id is required');
 | 
			
		||||
    }
 | 
			
		||||
    const aiChat = await AiChatHistoryModel.findByPk(id);
 | 
			
		||||
    if (!aiChat) {
 | 
			
		||||
      ctx.throw(404, 'chat not found');
 | 
			
		||||
    }
 | 
			
		||||
    if (aiChat.uid !== tokenUser.id) {
 | 
			
		||||
      ctx.throw(403, 'no permission');
 | 
			
		||||
    }
 | 
			
		||||
    ctx.body = aiChat;
 | 
			
		||||
  })
 | 
			
		||||
  .addTo(app);
 | 
			
		||||
app
 | 
			
		||||
  .route({
 | 
			
		||||
    path: 'ai',
 | 
			
		||||
    key: 'get-chat-version',
 | 
			
		||||
    description: '获取chat版本',
 | 
			
		||||
    middleware: ['auth'],
 | 
			
		||||
  })
 | 
			
		||||
  .define(async (ctx) => {
 | 
			
		||||
    const tokenUser = ctx.state.tokenUser;
 | 
			
		||||
    const { id } = ctx.query.data || {};
 | 
			
		||||
    if (!id) {
 | 
			
		||||
      ctx.throw(400, 'id is required');
 | 
			
		||||
    }
 | 
			
		||||
    const aiChat = await AiChatHistoryModel.findByPk(id);
 | 
			
		||||
    if (!aiChat) {
 | 
			
		||||
      ctx.throw(404, 'chat not found');
 | 
			
		||||
    }
 | 
			
		||||
    if (aiChat.uid !== tokenUser.id) {
 | 
			
		||||
      ctx.throw(403, 'no permission');
 | 
			
		||||
    }
 | 
			
		||||
    ctx.body = {
 | 
			
		||||
      id: aiChat.id,
 | 
			
		||||
      version: aiChat.version,
 | 
			
		||||
    };
 | 
			
		||||
  })
 | 
			
		||||
  .addTo(app);
 | 
			
		||||
 | 
			
		||||
app
 | 
			
		||||
  .route({
 | 
			
		||||
    path: 'ai',
 | 
			
		||||
    key: 'delete-chat',
 | 
			
		||||
    description: '删除chat',
 | 
			
		||||
    middleware: ['auth'],
 | 
			
		||||
  })
 | 
			
		||||
  .define(async (ctx) => {
 | 
			
		||||
    const tokenUser = ctx.state.tokenUser;
 | 
			
		||||
    const { id } = ctx.query.data || {};
 | 
			
		||||
    if (!id) {
 | 
			
		||||
      ctx.throw(400, 'id is required');
 | 
			
		||||
    }
 | 
			
		||||
    const aiChat = await AiChatHistoryModel.findByPk(id);
 | 
			
		||||
    if (!aiChat) {
 | 
			
		||||
      ctx.throw(404, 'chat not found');
 | 
			
		||||
    }
 | 
			
		||||
    if (aiChat.uid !== tokenUser.id) {
 | 
			
		||||
      ctx.throw(403, 'no permission');
 | 
			
		||||
    }
 | 
			
		||||
    await aiChat.destroy();
 | 
			
		||||
 | 
			
		||||
    ctx.body = {
 | 
			
		||||
      success: true,
 | 
			
		||||
    };
 | 
			
		||||
  })
 | 
			
		||||
  .addTo(app);
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,8 @@ export class AiChatHistoryModel extends Model {
 | 
			
		||||
  declare total_tokens: number;
 | 
			
		||||
  declare completion_tokens: number;
 | 
			
		||||
 | 
			
		||||
  declare version: number;
 | 
			
		||||
 | 
			
		||||
  declare createdAt: Date;
 | 
			
		||||
  declare updatedAt: Date;
 | 
			
		||||
}
 | 
			
		||||
@@ -47,14 +49,17 @@ AiChatHistoryModel.init(
 | 
			
		||||
    username: {
 | 
			
		||||
      type: DataTypes.STRING,
 | 
			
		||||
      allowNull: false,
 | 
			
		||||
      defaultValue: '',
 | 
			
		||||
    },
 | 
			
		||||
    model: {
 | 
			
		||||
      type: DataTypes.STRING,
 | 
			
		||||
      allowNull: false,
 | 
			
		||||
      defaultValue: '',
 | 
			
		||||
    },
 | 
			
		||||
    group: {
 | 
			
		||||
      type: DataTypes.STRING,
 | 
			
		||||
      allowNull: false,
 | 
			
		||||
      defaultValue: '',
 | 
			
		||||
    },
 | 
			
		||||
    title: {
 | 
			
		||||
      type: DataTypes.STRING,
 | 
			
		||||
@@ -82,6 +87,10 @@ AiChatHistoryModel.init(
 | 
			
		||||
      type: DataTypes.JSONB,
 | 
			
		||||
      defaultValue: {},
 | 
			
		||||
    },
 | 
			
		||||
    version: {
 | 
			
		||||
      type: DataTypes.INTEGER,
 | 
			
		||||
      defaultValue: 0,
 | 
			
		||||
    },
 | 
			
		||||
    uid: {
 | 
			
		||||
      type: DataTypes.UUID,
 | 
			
		||||
      allowNull: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,8 @@ export class ChatConfigServices {
 | 
			
		||||
  owner: string;
 | 
			
		||||
  // 使用者
 | 
			
		||||
  username: string;
 | 
			
		||||
  aiConfig?: AIConfig;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * username 是使用的模型的用户名,使用谁的模型
 | 
			
		||||
   * @param username
 | 
			
		||||
@@ -50,6 +52,7 @@ export class ChatConfigServices {
 | 
			
		||||
      const cacheTime = 60 * 60 * 24 * 40; // 1天
 | 
			
		||||
      await redis.set(key, JSON.stringify(modelConfig), 'EX', cacheTime);
 | 
			
		||||
    }
 | 
			
		||||
    this.aiConfig = modelConfig;
 | 
			
		||||
    if (needClearSecret) {
 | 
			
		||||
      modelConfig = this.filterApiKey(modelConfig);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { AIConfigParser, ProviderResult } from '@/provider/utils/parse-config.ts';
 | 
			
		||||
import { AIConfig, AIConfigParser, ProviderResult } from '@/provider/utils/parse-config.ts';
 | 
			
		||||
import { ProviderManager, ChatMessage, BaseChat, ChatMessageOptions } from '@/provider/index.ts';
 | 
			
		||||
import { redis } from '@/modules/db.ts';
 | 
			
		||||
import { CustomError } from '@kevisual/router';
 | 
			
		||||
@@ -36,6 +36,7 @@ export class ChatServices {
 | 
			
		||||
   * 模型配置
 | 
			
		||||
   */
 | 
			
		||||
  modelConfig?: ProviderResult;
 | 
			
		||||
  aiConfig?: AIConfig;
 | 
			
		||||
  chatProvider?: BaseChat;
 | 
			
		||||
  constructor(opts: ChatServicesConfig) {
 | 
			
		||||
    this.owner = opts.owner;
 | 
			
		||||
@@ -65,6 +66,7 @@ export class ChatServices {
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
    that.modelConfig = { ...providerResult, apiKey };
 | 
			
		||||
    that.aiConfig = config;
 | 
			
		||||
    return that.modelConfig;
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
@@ -108,7 +110,7 @@ export class ChatServices {
 | 
			
		||||
  async createNewMessage(messages: ChastHistoryMessage[]) {
 | 
			
		||||
    return messages.map((item) => {
 | 
			
		||||
      if (!item.id) {
 | 
			
		||||
        item.id = 'chat' + nanoid();
 | 
			
		||||
        item.id = 'chat-' + nanoid();
 | 
			
		||||
        item.createdAt = Date.now();
 | 
			
		||||
        item.updatedAt = Date.now();
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user