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