feat: support push chat log (#3093)
* feat: custom uid/metadata * to: custom info * fix: chat push latest * feat: add chat log envs * refactor: move timer to pushChatLog * fix: using precise log --------- Co-authored-by: Finley Ge <m13203533462@163.com>
This commit is contained in:
152
packages/service/core/chat/pushChatLog.ts
Normal file
152
packages/service/core/chat/pushChatLog.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { addLog } from '../../common/system/log';
|
||||
import { MongoChatItem } from './chatItemSchema';
|
||||
import { MongoChat } from './chatSchema';
|
||||
import axios from 'axios';
|
||||
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
|
||||
export type Metadata = {
|
||||
[key: string]: {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
};
|
||||
|
||||
export const pushChatLog = ({
|
||||
chatId,
|
||||
chatItemIdHuman,
|
||||
chatItemIdAi,
|
||||
appId,
|
||||
metadata
|
||||
}: {
|
||||
chatId: string;
|
||||
chatItemIdHuman: string;
|
||||
chatItemIdAi: string;
|
||||
appId: string;
|
||||
metadata?: Metadata;
|
||||
}) => {
|
||||
const interval = Number(process.env.CHAT_LOG_INTERVAL);
|
||||
const url = process.env.CHAT_LOG_URL;
|
||||
if (interval > 0 && url) {
|
||||
addLog.info(`[ChatLogPush] push chat log after ${interval}ms`, {
|
||||
appId,
|
||||
chatItemIdHuman,
|
||||
chatItemIdAi
|
||||
});
|
||||
setTimeout(() => {
|
||||
pushChatLogInternal({ chatId, chatItemIdHuman, chatItemIdAi, appId, url, metadata });
|
||||
}, interval);
|
||||
}
|
||||
};
|
||||
|
||||
type ChatItem = ChatItemType & {
|
||||
userGoodFeedback?: string;
|
||||
userBadFeedback?: string;
|
||||
chatId: string;
|
||||
responseData: {
|
||||
moduleType: string;
|
||||
runningTime: number; //s
|
||||
historyPreview: { obj: string; value: string }[];
|
||||
}[];
|
||||
time: Date;
|
||||
};
|
||||
|
||||
type ChatLog = {
|
||||
title: string;
|
||||
feedback: 'like' | 'dislike' | null;
|
||||
chatItemId: string;
|
||||
uid: string;
|
||||
question: string;
|
||||
answer: string;
|
||||
chatId: string;
|
||||
responseTime: number;
|
||||
metadata: string;
|
||||
sourceName: string;
|
||||
createdAt: number;
|
||||
sourceId: string;
|
||||
};
|
||||
|
||||
const pushChatLogInternal = async ({
|
||||
chatId,
|
||||
chatItemIdHuman,
|
||||
chatItemIdAi,
|
||||
appId,
|
||||
url,
|
||||
metadata
|
||||
}: {
|
||||
chatId: string;
|
||||
chatItemIdHuman: string;
|
||||
chatItemIdAi: string;
|
||||
appId: string;
|
||||
url: string;
|
||||
metadata?: Metadata;
|
||||
}) => {
|
||||
const [chatItemHuman, chatItemAi] = await Promise.all([
|
||||
MongoChatItem.findById(chatItemIdHuman).lean() as Promise<ChatItem>,
|
||||
MongoChatItem.findById(chatItemIdAi).lean() as Promise<ChatItem>
|
||||
]);
|
||||
const [chat] = (await MongoChat.find({ chatId }).lean()) as {
|
||||
title: string;
|
||||
outLinkUid: string | undefined;
|
||||
tmbId: string;
|
||||
teamId: string;
|
||||
metadata: Object;
|
||||
source: string;
|
||||
}[];
|
||||
|
||||
// addLog.warn('ChatLogDebug', chat);
|
||||
// addLog.warn('ChatLogDebug', { chatItemHuman, chatItemAi });
|
||||
|
||||
if (!chat) {
|
||||
return;
|
||||
}
|
||||
|
||||
const metadataString = JSON.stringify(metadata ?? {});
|
||||
|
||||
const uid = chat.outLinkUid || chat.tmbId;
|
||||
// Pop last two items
|
||||
const question = chatItemHuman.value[chatItemHuman.value.length - 1]?.text?.content;
|
||||
const answer = chatItemAi.value[chatItemAi.value.length - 1]?.text?.content;
|
||||
if (!question || !answer) {
|
||||
addLog.error('[ChatLogPush] question or answer is empty', {
|
||||
question: chatItemHuman.value,
|
||||
answer: chatItemAi.value
|
||||
});
|
||||
return;
|
||||
}
|
||||
const responseData = chatItemAi.responseData;
|
||||
let responseTime = 0;
|
||||
responseData.forEach((item) => {
|
||||
responseTime += item.runningTime;
|
||||
});
|
||||
|
||||
const chatLog: ChatLog = {
|
||||
title: chat.title,
|
||||
feedback: (() => {
|
||||
if (chatItemAi.userGoodFeedback) {
|
||||
return 'like';
|
||||
} else if (chatItemAi.userBadFeedback) {
|
||||
return 'dislike';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})(),
|
||||
chatItemId: `${chatItemIdHuman},${chatItemIdAi}`,
|
||||
uid,
|
||||
question,
|
||||
answer,
|
||||
chatId,
|
||||
responseTime: responseTime * 1000,
|
||||
metadata: metadataString,
|
||||
sourceName: chat.source ?? '-',
|
||||
createdAt: new Date(chatItemAi.time).getTime(),
|
||||
sourceId: `crbeer-fastgpt-${appId}`
|
||||
};
|
||||
await axios
|
||||
.post(url + '/api/chat/push', chatLog)
|
||||
.then((res) => {
|
||||
addLog.info('[ChatLogPush] push success', res.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
addLog.error('[ChatLogPush] push failed', { e, resData: e.response?.data });
|
||||
});
|
||||
};
|
||||
@@ -1,4 +1,9 @@
|
||||
import type { AIChatItemType, UserChatItemType } from '@fastgpt/global/core/chat/type.d';
|
||||
import type {
|
||||
AIChatItemType,
|
||||
ChatItemType,
|
||||
UserChatItemType
|
||||
} from '@fastgpt/global/core/chat/type.d';
|
||||
import axios from 'axios';
|
||||
import { MongoApp } from '../app/schema';
|
||||
import {
|
||||
ChatItemValueTypeEnum,
|
||||
@@ -13,6 +18,7 @@ import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
||||
import { getAppChatConfig, getGuideModule } from '@fastgpt/global/core/workflow/utils';
|
||||
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
|
||||
import { mergeChatResponseData } from '@fastgpt/global/core/chat/utils';
|
||||
import { pushChatLog } from './pushChatLog';
|
||||
|
||||
type Props = {
|
||||
chatId: string;
|
||||
@@ -67,7 +73,7 @@ export async function saveChat({
|
||||
});
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
await MongoChatItem.insertMany(
|
||||
const [{ _id: chatItemIdHuman }, { _id: chatItemIdAi }] = await MongoChatItem.insertMany(
|
||||
content.map((item) => ({
|
||||
chatId,
|
||||
teamId,
|
||||
@@ -105,6 +111,13 @@ export async function saveChat({
|
||||
upsert: true
|
||||
}
|
||||
);
|
||||
|
||||
pushChatLog({
|
||||
chatId,
|
||||
chatItemIdHuman: String(chatItemIdHuman),
|
||||
chatItemIdAi: String(chatItemIdAi),
|
||||
appId
|
||||
});
|
||||
});
|
||||
|
||||
if (isUpdateUseTime) {
|
||||
|
||||
Reference in New Issue
Block a user