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:
a.e.
2024-11-08 15:35:27 +08:00
committed by archer
parent 8ede7add01
commit 0a238845ab
5 changed files with 223 additions and 36 deletions

View File

@@ -46,4 +46,9 @@ STORE_LOG_LEVEL=warn
# 工作流最大运行次数,避免极端的死循环情况
WORKFLOW_MAX_RUN_TIMES=500
# 循环最大运行次数,避免极端的死循环情况
WORKFLOW_MAX_LOOP_TIMES=50
WORKFLOW_MAX_LOOP_TIMES=50
# 对话日志推送服务
# URL/INTERVAL 为空时不推送
CHAT_LOG_URL=http://localhost:8080
CHAT_LOG_INTERVAL=10000

View File

@@ -63,6 +63,8 @@ import { getPluginInputsFromStoreNodes } from '@fastgpt/global/core/app/plugin/u
type FastGptWebChatProps = {
chatId?: string; // undefined: get histories from messages, '': new chat, 'xxxxx': get histories from db
appId?: string;
customUid?: string; // non-undefined: will be the priority provider for the logger.
metadata?: Record<string, any>;
};
export type Props = ChatCompletionCreateParams &
@@ -99,6 +101,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
let {
chatId,
appId,
customUid,
// share chat
shareId,
outLinkUid,
@@ -110,7 +113,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
detail = false,
messages = [],
variables = {},
responseChatItemId = getNanoid()
responseChatItemId = getNanoid(),
metadata
} = req.body as Props;
const originIp = requestIp.getClientIp(req);
@@ -122,7 +126,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
throw new Error('messages is not array');
}
/*
/*
Web params: chatId + [Human]
API params: chatId + [Human]
API params: [histories, Human]
@@ -139,41 +143,50 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return JSON.stringify(variables);
})();
/*
/*
1. auth app permission
2. auth balance
3. get app
4. parse outLink token
*/
const { teamId, tmbId, user, app, responseDetail, authType, apikey, canWrite, outLinkUserId } =
await (async () => {
// share chat
if (shareId && outLinkUid) {
return authShareChat({
shareId,
outLinkUid,
chatId,
ip: originIp,
question: startHookText
});
}
// team space chat
if (spaceTeamId && appId && teamToken) {
return authTeamSpaceChat({
teamId: spaceTeamId,
teamToken,
appId,
chatId
});
}
/* parse req: api or token */
return authHeaderRequest({
req,
const {
teamId,
tmbId,
user,
app,
responseDetail,
authType,
apikey,
canWrite,
outLinkUserId = customUid
} = await (async () => {
// share chat
if (shareId && outLinkUid) {
return authShareChat({
shareId,
outLinkUid,
chatId,
ip: originIp,
question: startHookText
});
}
// team space chat
if (spaceTeamId && appId && teamToken) {
return authTeamSpaceChat({
teamId: spaceTeamId,
teamToken,
appId,
chatId
});
})();
}
/* parse req: api or token */
return authHeaderRequest({
req,
appId,
chatId
});
})();
const isPlugin = app.type === AppTypeEnum.plugin;
// Check message type
@@ -333,7 +346,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
source,
content: [userQuestion, aiResponse],
metadata: {
originIp
originIp,
...metadata
}
});
}

View File

@@ -41,6 +41,7 @@ type Props = {
appAvatar: string;
shareId: string;
authToken: string;
customUid: string;
};
const OutLink = ({
@@ -371,13 +372,13 @@ const OutLink = ({
};
const Render = (props: Props) => {
const { shareId, authToken } = props;
const { shareId, authToken, customUid } = props;
const { localUId, loaded } = useShareChatStore();
const [isLoaded, setIsLoaded] = useState(false);
const contextParams = useMemo(() => {
return { shareId, outLinkUid: authToken || localUId };
}, [authToken, localUId, shareId]);
return { shareId, outLinkUid: authToken || customUid || localUId };
}, [authToken, customUid, localUId, shareId]);
useMount(() => {
setIsLoaded(true);
@@ -401,6 +402,7 @@ export default React.memo(Render);
export async function getServerSideProps(context: any) {
const shareId = context?.query?.shareId || '';
const authToken = context?.query?.authToken || '';
const customUid = context?.query?.customUid || '';
const app = await (async () => {
try {
@@ -427,6 +429,7 @@ export async function getServerSideProps(context: any) {
appIntro: app?.appId?.intro ?? 'intro',
shareId: shareId ?? '',
authToken: authToken ?? '',
customUid,
...(await serviceSideProps(context, ['file', 'app', 'chat', 'workflow']))
}
};