zhaoyingbo b992ee0b21
Some checks failed
Egg Server MIflow / build-image (push) Failing after 5m7s
feat(group-agent): 新增支持群组问答
2024-09-25 09:14:10 +00:00

119 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getChatId, getMsgText, LarkEvent } from "@egg/lark-msg-tool"
import db from "../../../db"
import { Context } from "../../../types"
import {
genGroupAgentErrorMsg,
genGroupAgentSuccessMsg,
} from "../../../utils/genMsg"
import llm from "../../../utils/llm"
import groupManager from "./groupManager"
/**
* 根据聊天历史回答用户的问题
* @param ctx - 上下文数据
* @param userInput - 用户输入
* @param targetChatId - 目标群组ID
* @param loadingMsgId - loading消息ID
*/
const chat2llm = async (
ctx: Context.Data,
userInput: string,
targetChatId: string,
loadingMsgId?: string
) => {
const { logger, body } = ctx
// 发送消息给Deepseek模型解析时间返回格式为 YYYY-MM-DD HH:mm:ss
const { startTime, endTime } = await llm.parseTime(userInput)
logger.info(`Parsed result: startTime = ${startTime}, endTime = ${endTime}`)
// 获取服务器的时区偏移量(以分钟为单位)
const serverTimezoneOffset = new Date().getTimezoneOffset()
// 上海时区的偏移量UTC+8以分钟为单位
const shanghaiTimezoneOffset = -8 * 60
// 计算时间戳,调整为上海时区
const startTimeTimestamp =
Math.round(new Date(startTime).getTime() / 1000) +
(shanghaiTimezoneOffset - serverTimezoneOffset) * 60
const endTimeTimestamp =
Math.round(new Date(endTime).getTime() / 1000) +
(shanghaiTimezoneOffset - serverTimezoneOffset) * 60
// 获取群聊中的历史记录
const { data: chatHistory } = await ctx.larkService.message.getHistory(
targetChatId,
String(startTimeTimestamp),
String(endTimeTimestamp)
)
// 如果没有历史记录则返回错误消息
if (chatHistory.length === 0) {
logger.error("Chat history is empty")
const content = genGroupAgentErrorMsg("未找到聊天记录")
if (loadingMsgId) {
await ctx.larkService.message.update(loadingMsgId, content)
} else {
await ctx.larkService.message.sendInteractive2Chat(
getChatId(body),
content
)
}
return
}
logger.debug(`Chat history: ${JSON.stringify(chatHistory)}`)
const llmRes = await llm.queryWithChatHistory(
userInput,
JSON.stringify(chatHistory)
)
logger.info(`LLM result: ${llmRes.content}`)
const successMsg = genGroupAgentSuccessMsg(llmRes.content as string)
// 发送LLM结果
if (loadingMsgId) {
await ctx.larkService.message.update(loadingMsgId, successMsg)
} else {
await ctx.larkService.message.sendInteractive2Chat(
getChatId(body),
successMsg
)
}
}
/**
* 群组代理处理消息
* @param ctx - 上下文数据
*/
const manageGroupMsg = async (ctx: Context.Data) => {
const { logger } = ctx
logger.info("Start to manage group message")
const body = ctx.body as LarkEvent.Data
// 获取用户输入
const userInput = getMsgText(body)
// 先获取当前对话的目标群组ID
const group = await groupManager.getCurrentGroup(ctx, false)
// 没有目标群组ID则发送群组选择器并保存当前问题在选择后立即处理
if (!group || !group.chat_id) {
logger.info("No group found, send group selector")
groupManager.sendGroupSelector(ctx)
db.groupAgentConfig.upsert({
user_id: body.event.sender.sender_id.user_id,
pre_query: userInput,
})
return
}
// 发送一个loading的消息
const loadingRes = await ctx.larkService.message.sendInteractive2Chat(
getChatId(body),
genGroupAgentSuccessMsg("小煎蛋正在爬楼中,请稍等...")
)
if (loadingRes.code !== 0) {
logger.error("Failed to send loading message")
}
const { message_id } = loadingRes.data
await chat2llm(ctx, userInput, group.chat_id, message_id)
}
const groupAgent = {
...groupManager,
manageGroupMsg,
}
export default groupAgent