Feat: save room even if llm failed to properly guess; fix prompt
This commit is contained in:
		| @@ -50,7 +50,7 @@ | ||||
|     {{template "teamlist" .Room.RedTeam}} | ||||
|   </div> | ||||
|   <hr /> | ||||
|   <div id="systembox"> | ||||
|   <div id="systembox" style="overflow-y: auto; max-height: 100px;"> | ||||
|     Server says: <br> | ||||
|     <ul> | ||||
|     {{range .Room.LogJournal}}  | ||||
|   | ||||
| @@ -248,7 +248,6 @@ func listRooms(allRooms bool) []*models.Room { | ||||
| 				log.Warn("failed to unmarshal room", "error", err) | ||||
| 				continue | ||||
| 			} | ||||
| 			log.Debug("consider room for list", "room", room, "key", key) | ||||
| 			if room.IsPublic || allRooms { | ||||
| 				publicRooms = append(publicRooms, room) | ||||
| 			} | ||||
|   | ||||
| @@ -79,11 +79,11 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | ||||
| 		return | ||||
| 	} | ||||
| 	http.SetCookie(w, cookie) | ||||
| 	tmpl, err := template.ParseGlob("components/*.html") | ||||
| 	if err != nil { | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	// tmpl, err := template.ParseGlob("components/*.html") | ||||
| 	// if err != nil { | ||||
| 	// 	abortWithError(w, err.Error()) | ||||
| 	// 	return | ||||
| 	// } | ||||
| 	// check if that user was already in db | ||||
| 	userstate, err := loadState(cleanName) | ||||
| 	if err != nil || userstate == nil { | ||||
| @@ -120,9 +120,10 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil { | ||||
| 		log.Error("failed to execute base template", "error", err) | ||||
| 	} | ||||
| 	// if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil { | ||||
| 	// 	log.Error("failed to execute base template", "error", err) | ||||
| 	// } | ||||
| 	http.Redirect(w, r, "/", 302) | ||||
| } | ||||
|  | ||||
| func makeCookie(username string, remote string) (*http.Cookie, error) { | ||||
|   | ||||
| @@ -78,7 +78,7 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) { | ||||
| 		Actor:      fi.State.Username, | ||||
| 		ActorColor: string(fi.State.Team), | ||||
| 		WordColor:  string(color), | ||||
| 		Action:     "guessed", | ||||
| 		Action:     models.ActionTypeGuess, | ||||
| 		Word:       word, | ||||
| 	} | ||||
| 	fi.Room.ActionHistory = append(fi.Room.ActionHistory, action) | ||||
| @@ -103,8 +103,8 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) { | ||||
| 		action := models.Action{ | ||||
| 			Actor:      fi.State.Username, | ||||
| 			ActorColor: string(fi.State.Team), | ||||
| 			WordColor:  "black", | ||||
| 			Action:     "game over", | ||||
| 			WordColor:  models.WordColorBlack, | ||||
| 			Action:     models.ActionTypeGameOver, | ||||
| 		} | ||||
| 		fi.Room.OpenedThisTurn = 0 | ||||
| 		fi.Room.ThisTurnLimit = 0 | ||||
| @@ -124,8 +124,8 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) { | ||||
| 			action := models.Action{ | ||||
| 				Actor:      fi.State.Username, | ||||
| 				ActorColor: string(fi.State.Team), | ||||
| 				WordColor:  "blue", | ||||
| 				Action:     "game over", | ||||
| 				WordColor:  models.WordColorBlue, | ||||
| 				Action:     models.ActionTypeGameOver, | ||||
| 			} | ||||
| 			fi.Room.OpenedThisTurn = 0 | ||||
| 			fi.Room.ThisTurnLimit = 0 | ||||
| @@ -139,8 +139,8 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) { | ||||
| 			action := models.Action{ | ||||
| 				Actor:      fi.State.Username, | ||||
| 				ActorColor: string(fi.State.Team), | ||||
| 				WordColor:  "red", | ||||
| 				Action:     "game over", | ||||
| 				WordColor:  models.WordColorRed, | ||||
| 				Action:     models.ActionTypeGameOver, | ||||
| 			} | ||||
| 			fi.Room.OpenedThisTurn = 0 | ||||
| 			fi.Room.ThisTurnLimit = 0 | ||||
|   | ||||
| @@ -153,9 +153,7 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) { | ||||
| 		Actor:      fi.State.Username, | ||||
| 		ActorColor: string(fi.State.Team), | ||||
| 		WordColor:  string(fi.State.Team), | ||||
| 		Action:     "game started", | ||||
| 		// Word:       clue, | ||||
| 		// Number:     num, | ||||
| 		Action:     models.ActionTypeGameStarted, | ||||
| 	} | ||||
| 	fi.Room.ActionHistory = append(fi.Room.ActionHistory, action) | ||||
| 	if err := saveFullInfo(fi); err != nil { | ||||
|   | ||||
| @@ -120,42 +120,44 @@ func (b *Bot) StartBot() { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-SignalChanMap[b.BotName]: | ||||
| 			botJournalName := models.NotifyJournalPrefix + b.RoomID | ||||
| 			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) | ||||
| 				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 | ||||
| 					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{} | ||||
| @@ -189,7 +191,9 @@ func (b *Bot) StartBot() { | ||||
| 						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.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"]) | ||||
| @@ -203,22 +207,13 @@ func (b *Bot) StartBot() { | ||||
| 				// 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 | ||||
| 					return | ||||
| 				} | ||||
| 				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 | ||||
| 			}() | ||||
| 		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 { | ||||
|   | ||||
| @@ -19,6 +19,15 @@ const ( | ||||
| 	WordColorUknown = "stone" // beige | ||||
| ) | ||||
|  | ||||
| type ActionType string | ||||
|  | ||||
| const ( | ||||
| 	ActionTypeClue        = "gave_clue" | ||||
| 	ActionTypeGuess       = "guessed" | ||||
| 	ActionTypeGameOver    = "game_over" | ||||
| 	ActionTypeGameStarted = "game_started" | ||||
| ) | ||||
|  | ||||
| func StrToWordColor(s string) WordColor { | ||||
| 	switch s { | ||||
| 	case "amber", "white": | ||||
| @@ -88,6 +97,15 @@ type Room struct { | ||||
| 	LogJournal []string | ||||
| } | ||||
|  | ||||
| func (r *Room) FetchLastClue() (*Action, error) { | ||||
| 	for i := len(r.ActionHistory) - 1; i >= 0; i-- { | ||||
| 		if r.ActionHistory[i].Action == string(ActionTypeClue) { | ||||
| 			return &r.ActionHistory[i], nil | ||||
| 		} | ||||
| 	} | ||||
| 	return nil, errors.New("no clue in history") | ||||
| } | ||||
|  | ||||
| func (r *Room) GetPlayerByName(name string) (role UserRole, team UserTeam, found bool) { | ||||
| 	if r.RedTeam.Mime == name { | ||||
| 		return "mime", "red", true | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder