Feat: save room even if llm failed to properly guess; fix prompt
This commit is contained in:
		
							
								
								
									
										195
									
								
								llmapi/main.go
									
									
									
									
									
								
							
							
						
						
									
										195
									
								
								llmapi/main.go
									
									
									
									
									
								
							| @@ -120,105 +120,100 @@ func (b *Bot) StartBot() { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-SignalChanMap[b.BotName]: | ||||
| 			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) | ||||
| 				continue | ||||
| 			} | ||||
| 			// form prompt | ||||
| 			prompt := b.BuildPrompt(room) | ||||
| 			b.log.Debug("got prompt", "prompt", prompt) | ||||
| 			broker.Notifier.Notifier <- broker.NotificationEvent{ | ||||
| 				EventName: botJournalName, | ||||
| 				Payload:   prompt, | ||||
| 			} | ||||
| 			// call llm | ||||
| 			llmResp, err := b.CallLLM(prompt) | ||||
| 			if err != nil { | ||||
| 				broker.Notifier.Notifier <- broker.NotificationEvent{ | ||||
| 					EventName: botJournalName, | ||||
| 					Payload:   "failed to get bot resp", | ||||
| 				} | ||||
| 				b.log.Error("bot loop", "error", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			tempMap, err := b.LLMParser.ParseBytes(llmResp) | ||||
| 			if err != nil { | ||||
| 				broker.Notifier.Notifier <- broker.NotificationEvent{ | ||||
| 					EventName: botJournalName, | ||||
| 					Payload:   "failed to parse bot resp", | ||||
| 				} | ||||
| 				b.log.Error("bot loop", "error", err, "resp", string(llmResp)) | ||||
| 				continue | ||||
| 			} | ||||
| 			eventName := models.NotifyBacklogPrefix + room.ID | ||||
| 			eventPayload := "" | ||||
| 			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) | ||||
| 			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.Warn("failed to parse bot given limit", "mimeResp", mimeResp, "bot_name", b.BotName) | ||||
| 					b.log.Error("bot loop", "error", err) | ||||
| 					return | ||||
| 				} | ||||
| 				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) | ||||
| 				} | ||||
| 				b.log.Info("mime resp log", "guesserResp", tempMap) | ||||
| 				couldBe, err := convertToSliceOfStrings(tempMap["could_be"]) | ||||
| 				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 { | ||||
| 					b.log.Warn("failed to parse could_be", "bot_resp", tempMap, "bot_name", b.BotName) | ||||
| 					room.LogJournal = append(room.LogJournal, b.BotName+" send call got error: "+err.Error()) | ||||
| 					b.log.Error("bot loop", "error", err) | ||||
| 					return | ||||
| 				} | ||||
| 				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) | ||||
| 				continue | ||||
| 			} | ||||
| 			// save room | ||||
| 			if err := saveRoom(room); err != nil { | ||||
| 				b.log.Error("failed to save room", "error", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			if botName := room.WhichBotToMove(); botName != "" { | ||||
| 				b.log.Debug("notifying bot", "name", botName) | ||||
| 				SignalChanMap[botName] <- true | ||||
| 			} | ||||
| 			broker.Notifier.Notifier <- broker.NotificationEvent{ | ||||
| 				EventName: eventName, | ||||
| 				Payload:   eventPayload, | ||||
| 			} | ||||
| 			continue | ||||
| 				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 | ||||
| 				} | ||||
| 			}() | ||||
| 		case <-DoneChanMap[b.BotName]: | ||||
| 			b.log.Debug("got done signal", "bot-name", b.BotName) | ||||
| 			return | ||||
| @@ -335,13 +330,19 @@ func saveRoom(room *models.Room) error { | ||||
| } | ||||
|  | ||||
| func (b *Bot) BuildSimpleGuesserPrompt(room *models.Room) string { | ||||
| 	clue := room.ActionHistory[len(room.ActionHistory)-1].Word | ||||
| 	// find not last action, but the clue | ||||
| 	// clue := room.ActionHistory[len(room.ActionHistory)-1].Word | ||||
| 	clueAction, err := room.FetchLastClue() | ||||
| 	if err != nil { | ||||
| 		b.log.Error("failed to fetch last clue", "error", err, "room", room, "bot_name", b.BotName) | ||||
| 		return "" | ||||
| 	} | ||||
| 	// number := room.ActionHistory[len(room.ActionHistory)-1].Number | ||||
| 	words := make([]string, len(room.Cards)) | ||||
| 	for i, card := range room.Cards { | ||||
| 		words[i] = card.Word | ||||
| 	} | ||||
| 	return fmt.Sprintf(GuesserSimplePrompt, clue, words) | ||||
| 	return fmt.Sprintf(GuesserSimplePrompt, clueAction.Word, words) | ||||
| } | ||||
|  | ||||
| func (b *Bot) BuildPrompt(room *models.Room) string { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder