mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-25 20:02:47 +00:00
feat: save chat
This commit is contained in:
parent
d63311d67a
commit
b458c3447c
|
|
@ -21,12 +21,13 @@ export const HelperBotChatSchema = z.object({
|
|||
type: HelperBotTypeEnum,
|
||||
userId: z.string(),
|
||||
createTime: z.date(),
|
||||
updateTime: z.date()
|
||||
updateTime: z.date(),
|
||||
metadata: z.record(z.string(), z.any()).optional()
|
||||
});
|
||||
export type HelperBotChatType = z.infer<typeof HelperBotChatSchema>;
|
||||
|
||||
// AI schema
|
||||
const AIChatItemValueItemSchema = z.union([
|
||||
export const AIChatItemValueItemSchema = z.union([
|
||||
z.object({
|
||||
text: z.object({
|
||||
content: z.string()
|
||||
|
|
@ -41,10 +42,12 @@ const AIChatItemValueItemSchema = z.union([
|
|||
tool: ToolModuleResponseItemSchema
|
||||
})
|
||||
]);
|
||||
export type AIChatItemValueItemType = z.infer<typeof AIChatItemValueItemSchema>;
|
||||
const AIChatItemSchema = z.object({
|
||||
obj: z.literal(ChatRoleEnum.AI),
|
||||
value: z.array(AIChatItemValueItemSchema)
|
||||
});
|
||||
export type AIChatItemType = z.infer<typeof AIChatItemSchema>;
|
||||
|
||||
const HelperBotChatRoleSchema = z.union([
|
||||
UserChatItemSchema,
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export type ChatWithAppSchema = Omit<ChatSchemaType, 'appId'> & {
|
|||
/* --------- chat item ---------- */
|
||||
// User
|
||||
export const UserChatItemFileItemSchema = z.object({
|
||||
type: z.enum(Object.values(ChatFileTypeEnum)),
|
||||
type: z.enum(ChatFileTypeEnum),
|
||||
name: z.string().optional(),
|
||||
key: z.string().optional(),
|
||||
url: z.string()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { PaginationPropsSchema, PaginationResponseSchema } from '../../../type';
|
||||
import {
|
||||
type HelperBotChatItemSiteType,
|
||||
HelperBotTypeEnum,
|
||||
HelperBotTypeEnumSchema,
|
||||
topAgentParamsSchema
|
||||
} from '../../../../core/chat/helperBot/type';
|
||||
import { z } from 'zod';
|
||||
import type { PaginationResponse } from '../../../../../web/common/fetch/type';
|
||||
import { ChatFileTypeEnum } from '../../../../core/chat/constants';
|
||||
|
||||
// 分页获取记录
|
||||
export const GetHelperBotChatRecordsParamsSchema = z
|
||||
|
|
@ -46,7 +48,7 @@ export const HelperBotCompletionsParamsSchema = z.object({
|
|||
query: z.string(),
|
||||
files: z.array(
|
||||
z.object({
|
||||
type: z.enum(['image', 'file']),
|
||||
type: z.enum(ChatFileTypeEnum),
|
||||
key: z.string(),
|
||||
url: z.string().optional(),
|
||||
name: z.string()
|
||||
|
|
@ -54,7 +56,7 @@ export const HelperBotCompletionsParamsSchema = z.object({
|
|||
),
|
||||
metadata: z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal('topAgent'),
|
||||
type: z.literal(HelperBotTypeEnum.topAgent),
|
||||
data: topAgentParamsSchema
|
||||
})
|
||||
])
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ const HelperBotChatSchema = new Schema({
|
|||
updateTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
}
|
||||
},
|
||||
metadata: Object
|
||||
});
|
||||
|
||||
HelperBotChatSchema.index({ type: 1, userId: 1, chatId: 1 }, { unique: true });
|
||||
|
|
|
|||
|
|
@ -1,10 +1,35 @@
|
|||
import type { HelperBotDispatchParamsType } from '../type';
|
||||
import type { HelperBotDispatchParamsType, HelperBotDispatchResponseType } from '../type';
|
||||
import { helperChats2GPTMessages } from '@fastgpt/global/core/chat/helperBot/adaptor';
|
||||
|
||||
export const dispatchTopAgent = async (props: HelperBotDispatchParamsType) => {
|
||||
export const dispatchTopAgent = async (
|
||||
props: HelperBotDispatchParamsType
|
||||
): Promise<HelperBotDispatchResponseType> => {
|
||||
const { query, files, metadata, histories } = props;
|
||||
const messages = helperChats2GPTMessages({
|
||||
messages: histories,
|
||||
reserveTool: false
|
||||
});
|
||||
// 拿工具资源参考 FastGPT/projects/app/src/pages/api/core/app/tool/getSystemToolTemplates.ts
|
||||
|
||||
/*
|
||||
流输出
|
||||
onReasoning({ text }) {
|
||||
if (!aiChatReasoning) return;
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
reasoning_content: text
|
||||
})
|
||||
});
|
||||
},
|
||||
onStreaming({ text }) {
|
||||
if (!isResponseAnswerText) return;
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
text
|
||||
})
|
||||
});
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import { z } from 'zod';
|
||||
import { HelperBotCompletionsParamsSchema } from '../../../../../global/openapi/core/chat/helperBot/api';
|
||||
import { HelperBotChatItemSchema } from '@fastgpt/global/core/chat/helperBot/type';
|
||||
import {
|
||||
AIChatItemValueItemSchema,
|
||||
HelperBotChatItemSchema
|
||||
} from '@fastgpt/global/core/chat/helperBot/type';
|
||||
import { WorkflowResponseFnSchema } from '../../../workflow/dispatch/type';
|
||||
|
||||
export const HelperBotDispatchParamsSchema = z.object({
|
||||
|
|
@ -12,5 +15,7 @@ export const HelperBotDispatchParamsSchema = z.object({
|
|||
});
|
||||
export type HelperBotDispatchParamsType = z.infer<typeof HelperBotDispatchParamsSchema>;
|
||||
|
||||
export const HelperBotDispatchResponseSchema = z.object({});
|
||||
export const HelperBotDispatchResponseSchema = z.object({
|
||||
aiResponse: z.array(AIChatItemValueItemSchema)
|
||||
});
|
||||
export type HelperBotDispatchResponseType = z.infer<typeof HelperBotDispatchResponseSchema>;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
import type { HelperBotTypeEnum } from '@fastgpt/global/core/chat/helperBot/type';
|
||||
import type { HelperBotCompletionsParamsType } from '@fastgpt/global/openapi/core/chat/helperBot/api';
|
||||
import { MongoHelperBotChat } from './chatSchema';
|
||||
import type {
|
||||
AIChatItemValueItemType,
|
||||
UserChatItemValueItemType
|
||||
} from '@fastgpt/global/core/chat/type';
|
||||
import { MongoHelperBotChatItem } from './chatItemSchema';
|
||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { mongoSessionRun } from 'common/mongo/sessionRun';
|
||||
|
||||
export const pushChatRecords = async ({
|
||||
type,
|
||||
userId,
|
||||
chatId,
|
||||
chatItemId,
|
||||
query,
|
||||
files,
|
||||
aiResponse,
|
||||
memories,
|
||||
metadata
|
||||
}: {
|
||||
type: HelperBotTypeEnum;
|
||||
userId: string;
|
||||
chatId: string;
|
||||
chatItemId: string;
|
||||
query: string;
|
||||
files: HelperBotCompletionsParamsType['files'];
|
||||
aiResponse: AIChatItemValueItemType[];
|
||||
memories?: Record<string, any>;
|
||||
metadata?: Record<string, any>;
|
||||
}) => {
|
||||
const chat = await MongoHelperBotChat.findOne(
|
||||
{
|
||||
type,
|
||||
userId,
|
||||
chatId
|
||||
},
|
||||
'_id metadata'
|
||||
).lean();
|
||||
const metadataUpdate = {
|
||||
...chat?.metadata,
|
||||
...metadata
|
||||
};
|
||||
|
||||
const userValue: UserChatItemValueItemType[] = [
|
||||
...files.map((file) => ({
|
||||
file: {
|
||||
type: file.type,
|
||||
name: file.name,
|
||||
url: '',
|
||||
key: file.key || ''
|
||||
}
|
||||
})),
|
||||
...(query
|
||||
? [
|
||||
{
|
||||
text: {
|
||||
content: query
|
||||
}
|
||||
}
|
||||
]
|
||||
: [])
|
||||
];
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
await MongoHelperBotChatItem.create(
|
||||
[
|
||||
{
|
||||
userId,
|
||||
chatId,
|
||||
dataId: chatItemId,
|
||||
obj: ChatRoleEnum.Human,
|
||||
value: userValue
|
||||
},
|
||||
{
|
||||
userId,
|
||||
chatId,
|
||||
dataId: chatItemId,
|
||||
obj: ChatRoleEnum.AI,
|
||||
value: aiResponse,
|
||||
memories
|
||||
}
|
||||
],
|
||||
{ session, ordered: true }
|
||||
);
|
||||
|
||||
await MongoHelperBotChat.updateOne(
|
||||
{
|
||||
type,
|
||||
userId,
|
||||
chatId
|
||||
},
|
||||
{
|
||||
updateTime: new Date(),
|
||||
metadata: metadataUpdate
|
||||
},
|
||||
{
|
||||
session
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
|
@ -8,6 +8,7 @@ import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
|||
import { MongoHelperBotChatItem } from '@fastgpt/service/core/chat/HelperBot/chatItemSchema';
|
||||
import { getWorkflowResponseWrite } from '@fastgpt/service/core/workflow/dispatch/utils';
|
||||
import { dispatchMap } from '@fastgpt/service/core/chat/HelperBot/dispatch/index';
|
||||
import { pushChatRecords } from '@fastgpt/service/core/chat/HelperBot/utils';
|
||||
|
||||
export type completionsBody = HelperBotCompletionsParamsType;
|
||||
|
||||
|
|
@ -37,9 +38,24 @@ async function handler(req: ApiRequestProps<completionsBody>, res: ApiResponseTy
|
|||
|
||||
// 执行不同逻辑
|
||||
const fn = dispatchMap[metadata.type];
|
||||
const result = await fn({});
|
||||
const result = await fn({
|
||||
query,
|
||||
files,
|
||||
metadata,
|
||||
histories,
|
||||
workflowResponseWrite
|
||||
});
|
||||
|
||||
// Save chat
|
||||
await pushChatRecords({
|
||||
type: metadata.type,
|
||||
userId,
|
||||
chatId,
|
||||
chatItemId,
|
||||
query,
|
||||
files,
|
||||
aiResponse: result.aiResponse
|
||||
});
|
||||
// Push usage
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue