import { SoupGameMessage } from "../../constant/message" import { SoupGame } from "../../db/soupGame" import { Context } from "../../types" /** * 开启或者停止游戏 * @param ctx * @param value */ const startOrStopGame = async ( ctx: Context, value: boolean, which: "auto" | "manual" = "manual" ) => { const { db, logger, larkBody: { chatId }, attachService, larkCard, larkService: { message }, } = ctx const cardGender = larkCard.child("soupAgent") if (!chatId) { logger.error("chatId is required") return } // 获取正在进行中的游戏 const activeGame = await db.soupGame.getActiveOneByChatId(chatId) if (!activeGame) { logger.info(`chatId: ${chatId} has no active game`) } // 停止游戏 if (!value) { // 没有进行中的游戏 if (!activeGame) { await message.updateOrReply( cardGender.genSuccessCard(SoupGameMessage.hasStopped) ) return } // 有进行中的游戏,关闭游戏 logger.info(`chatId: ${chatId} is closing the game`) const res = await db.soupGame.close(activeGame.id) if (!res) { logger.error(`chatId: ${chatId} failed to close the game`) await message.updateOrReply( cardGender.genErrorCard(SoupGameMessage.startFailed) ) } // 手动结束 if (which === "manual") { await message.updateOrReply( cardGender.genCard("markdownSuccessCard", { content: ` 游戏结束! **汤面:**${activeGame?.query} **汤底:**${activeGame?.answer}`, }) ) } else { // 自动结束 await message.updateOrReply( cardGender.genCard("markdownSuccessCard", { llmRes: ` 恭喜您回答正确!游戏结束! **汤面:**${activeGame?.query} **汤底:**${activeGame?.answer}`, }) ) } return } // 开始游戏,有进行中的游戏 if (activeGame) { logger.info(`chatId: ${chatId} has an active game`) await message.updateOrReply( cardGender.genSuccessCard(SoupGameMessage.hasStarted) ) return } logger.info(`chatId: ${chatId} is starting a new game`) // 没有进行中的游戏,开始新游戏 const game = await attachService.startSoup() if (!game) { logger.error(`chatId: ${chatId} failed to start a new game`) await message.updateOrReply( cardGender.genErrorCard(SoupGameMessage.startFailed) ) return } // 写到数据库 const newSoupGame: SoupGame = { ...game, chatId, history: [], active: true, } const res = await db.soupGame.create(newSoupGame) if (!res) { logger.error(`chatId: ${chatId} failed to create a new game`) await message.updateOrReply( cardGender.genErrorCard(SoupGameMessage.startFailed) ) return } logger.info(`chatId: ${chatId} created a new game`) // 回复用户模型的消息 await message.updateOrReply( cardGender.genCard("markdownSuccessCard", { content: ` 游戏开始啦! **题目:**${game.title} **汤面:**${game.query} 艾特机器人说“结束游戏”即可结束游戏 `, }) ) } const chat2Soup = async (ctx: Context) => { const { db, larkBody: { msgText, chatId, messageId }, logger, attachService, larkService: { message }, } = ctx message.setReplyMessage(messageId, "text") const activeGame = await db.soupGame.getActiveOneByChatId(chatId) if (!activeGame) { logger.info(`chatId: ${chatId} has no active game`) return } await message.updateOrReply("模型生成中...") const res = await attachService.chat2Soup({ user_query: msgText, soup_id: activeGame.title, history: "", }) if (!res) { logger.error(`chatId: ${chatId} failed to get soup result`) await message.updateOrReply(SoupGameMessage.chatFailed) return } // 用户答对了 if (res.type === "END") { await startOrStopGame(ctx, false, "auto") return } // 继续游戏,更新历史记录 await db.soupGame.overrideHistory(activeGame.id, [ ...activeGame.history, msgText, ]) // 回复用户模型的消息 await message.updateOrReply(res.content) } /** * 海龟汤游戏 * @param ctx */ const agent = async (ctx: Context) => { const { larkBody: { chatId, msgText }, db, } = ctx if (!chatId) return const activeGame = await db.soupGame.getActiveOneByChatId(chatId) if (!activeGame) return false if (msgText === "结束游戏" || msgText === "停止游戏") { startOrStopGame(ctx, false) return true } chat2Soup(ctx) return true } const soupAgent = { startOrStopGame, agent, } export default soupAgent