Feat: remove bot

This commit is contained in:
Grail Finder
2025-06-27 07:35:25 +03:00
parent 12fe92b261
commit 86b1ecf82e
9 changed files with 165 additions and 100 deletions

View File

@ -77,7 +77,7 @@ func (b *Bot) checkGuess(word string, room *models.Room) error {
Actor: b.BotName,
ActorColor: b.Team,
WordColor: string(color),
Action: "guessed",
Action: models.ActionTypeGuess,
Word: word,
}
room.ActionHistory = append(room.ActionHistory, action)
@ -115,105 +115,107 @@ func (b *Bot) checkGuess(word string, room *models.Room) error {
return nil
}
func (b *Bot) BotMove() {
// botJournalName := models.NotifyJournalPrefix + b.RoomID
b.log.Debug("got signal", "bot-team", b.Team, "bot-role", b.Role)
// get room cards and actions
room, err := getRoomByID(b.RoomID)
if err != nil {
b.log.Error("bot loop", "error", err)
return
}
eventName := models.NotifyBacklogPrefix + room.ID
eventPayload := ""
defer func() { // save room
if err := saveRoom(room); err != nil {
b.log.Error("failed to save room", "error", err)
return
}
broker.Notifier.Notifier <- broker.NotificationEvent{
EventName: eventName,
Payload: eventPayload,
}
}()
// form prompt
prompt := b.BuildPrompt(room)
b.log.Debug("got prompt", "prompt", prompt)
room.LogJournal = append(room.LogJournal, b.BotName+" got prompt: "+prompt)
// call llm
llmResp, err := b.CallLLM(prompt)
if err != nil {
room.LogJournal = append(room.LogJournal, b.BotName+" send call got error: "+err.Error())
b.log.Error("bot loop", "error", err)
return
}
tempMap, err := b.LLMParser.ParseBytes(llmResp)
if err != nil {
room.LogJournal = append(room.LogJournal, b.BotName+" parse resp got error: "+err.Error())
b.log.Error("bot loop", "error", err, "resp", string(llmResp))
return
}
switch b.Role {
case models.UserRoleMime:
mimeResp := MimeResp{}
b.log.Info("mime resp log", "mimeResp", tempMap)
mimeResp.Clue = tempMap["clue"].(string)
mimeResp.Number = tempMap["number"].(string)
action := models.Action{
Actor: b.BotName,
ActorColor: b.Team,
WordColor: b.Team,
Action: models.ActionTypeClue,
Word: mimeResp.Clue,
Number: mimeResp.Number,
}
room.ActionHistory = append(room.ActionHistory, action)
room.MimeDone = true
eventPayload = mimeResp.Clue + mimeResp.Number
guessLimitU64, err := strconv.ParseUint(mimeResp.Number, 10, 8)
if err != nil {
b.log.Warn("failed to parse bot given limit", "mimeResp", mimeResp, "bot_name", b.BotName)
}
room.ThisTurnLimit = uint8(guessLimitU64)
case models.UserRoleGuesser:
// // deprecated
// if err := b.checkGuesses(tempMap, room); err != nil {
// b.log.Warn("failed to check guess", "mimeResp", tempMap, "bot_name", b.BotName)
// continue
// }
guess, ok := tempMap["guess"].(string)
if !ok || guess == "" {
b.log.Warn("failed to parse guess", "mimeResp", tempMap, "bot_name", b.BotName)
}
if err := b.checkGuess(guess, room); err != nil {
b.log.Warn("failed to check guess", "mimeResp", tempMap, "bot_name", b.BotName, "guess", guess, "error", err)
msg := fmt.Sprintf("failed to check guess", "mimeResp", tempMap, "bot_name", b.BotName, "guess", guess, "error", err)
room.LogJournal = append(room.LogJournal, msg)
}
b.log.Info("mime resp log", "guesserResp", tempMap)
couldBe, err := convertToSliceOfStrings(tempMap["could_be"])
if err != nil {
b.log.Warn("failed to parse could_be", "bot_resp", tempMap, "bot_name", b.BotName)
}
room.LogJournal = append(room.LogJournal, fmt.Sprintf("%s also considered this: %v", b.BotName, couldBe))
eventName = models.NotifyRoomUpdatePrefix + room.ID
eventPayload = ""
// TODO: needs to decide if it wants to open the next cardword or end turn
// or end turn on limit
default:
b.log.Error("unexpected role", "role", b.Role, "resp-map", tempMap)
return
}
if botName := room.WhichBotToMove(); botName != "" {
b.log.Debug("notifying bot", "name", botName)
SignalChanMap[botName] <- true
}
}
// StartBot
func (b *Bot) StartBot() {
for {
select {
case <-SignalChanMap[b.BotName]:
func() {
// botJournalName := models.NotifyJournalPrefix + b.RoomID
b.log.Debug("got signal", "bot-team", b.Team, "bot-role", b.Role)
// get room cards and actions
room, err := getRoomByID(b.RoomID)
if err != nil {
b.log.Error("bot loop", "error", err)
return
}
eventName := models.NotifyBacklogPrefix + room.ID
eventPayload := ""
defer func() { // save room
if err := saveRoom(room); err != nil {
b.log.Error("failed to save room", "error", err)
return
}
broker.Notifier.Notifier <- broker.NotificationEvent{
EventName: eventName,
Payload: eventPayload,
}
}()
// form prompt
prompt := b.BuildPrompt(room)
b.log.Debug("got prompt", "prompt", prompt)
room.LogJournal = append(room.LogJournal, b.BotName+" got prompt: "+prompt)
// call llm
llmResp, err := b.CallLLM(prompt)
if err != nil {
room.LogJournal = append(room.LogJournal, b.BotName+" send call got error: "+err.Error())
b.log.Error("bot loop", "error", err)
return
}
tempMap, err := b.LLMParser.ParseBytes(llmResp)
if err != nil {
room.LogJournal = append(room.LogJournal, b.BotName+" parse resp got error: "+err.Error())
b.log.Error("bot loop", "error", err, "resp", string(llmResp))
return
}
switch b.Role {
case models.UserRoleMime:
mimeResp := MimeResp{}
b.log.Info("mime resp log", "mimeResp", tempMap)
mimeResp.Clue = tempMap["clue"].(string)
mimeResp.Number = tempMap["number"].(string)
action := models.Action{
Actor: b.BotName,
ActorColor: b.Team,
WordColor: b.Team,
Action: "gave clue",
Word: mimeResp.Clue,
Number: mimeResp.Number,
}
room.ActionHistory = append(room.ActionHistory, action)
room.MimeDone = true
eventPayload = mimeResp.Clue + mimeResp.Number
guessLimitU64, err := strconv.ParseUint(mimeResp.Number, 10, 8)
if err != nil {
b.log.Warn("failed to parse bot given limit", "mimeResp", mimeResp, "bot_name", b.BotName)
}
room.ThisTurnLimit = uint8(guessLimitU64)
case models.UserRoleGuesser:
// // deprecated
// if err := b.checkGuesses(tempMap, room); err != nil {
// b.log.Warn("failed to check guess", "mimeResp", tempMap, "bot_name", b.BotName)
// continue
// }
guess, ok := tempMap["guess"].(string)
if !ok || guess == "" {
b.log.Warn("failed to parse guess", "mimeResp", tempMap, "bot_name", b.BotName)
}
if err := b.checkGuess(guess, room); err != nil {
b.log.Warn("failed to check guess", "mimeResp", tempMap, "bot_name", b.BotName, "guess", guess, "error", err)
msg := fmt.Sprintf("failed to check guess", "mimeResp", tempMap, "bot_name", b.BotName, "guess", guess, "error", err)
room.LogJournal = append(room.LogJournal, msg)
}
b.log.Info("mime resp log", "guesserResp", tempMap)
couldBe, err := convertToSliceOfStrings(tempMap["could_be"])
if err != nil {
b.log.Warn("failed to parse could_be", "bot_resp", tempMap, "bot_name", b.BotName)
}
room.LogJournal = append(room.LogJournal, fmt.Sprintf("%s also considered this: %v", b.BotName, couldBe))
eventName = models.NotifyRoomUpdatePrefix + room.ID
eventPayload = ""
// TODO: needs to decide if it wants to open the next cardword or end turn
// or end turn on limit
default:
b.log.Error("unexpected role", "role", b.Role, "resp-map", tempMap)
return
}
if botName := room.WhichBotToMove(); botName != "" {
b.log.Debug("notifying bot", "name", botName)
SignalChanMap[botName] <- true
}
}()
b.BotMove()
case <-DoneChanMap[b.BotName]:
b.log.Debug("got done signal", "bot-name", b.BotName)
return
@ -221,6 +223,18 @@ func (b *Bot) StartBot() {
}
}
func RemoveBot(botName string, room *models.Room) error {
// channels
DoneChanMap[botName] <- true
close(DoneChanMap[botName])
close(SignalChanMap[botName])
// maps
delete(room.BotMap, botName)
delete(DoneChanMap, botName)
delete(SignalChanMap, botName)
return saveRoom(room)
}
// EndBot
func NewBot(role, team, name, roomID string, cfg *config.Config, recovery bool) (*Bot, error) {

View File

@ -160,8 +160,10 @@ func (p *openRouterParser) ParseBytes(body []byte) (map[string]any, error) {
}
func (p *openRouterParser) MakePayload(prompt string) io.Reader {
// "model": "deepseek/deepseek-chat-v3-0324:free",
// TODO: set list of models an option to pick on the frontend
strPayload := fmt.Sprintf(`{
"model": "deepseek/deepseek-chat-v3-0324:free",
"model": "google/gemini-2.0-flash-exp:free",
"messages": [
{
"role": "user",