119 lines
3.7 KiB
TypeScript
119 lines
3.7 KiB
TypeScript
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
|