diff --git a/components/room.html b/components/room.html
index e49d4b8..588e436 100644
--- a/components/room.html
+++ b/components/room.html
@@ -50,7 +50,7 @@
{{template "teamlist" .Room.RedTeam}}
-
+
Server says:
{{range .Room.LogJournal}}
diff --git a/handlers/actions.go b/handlers/actions.go
index 755fa10..6fec1bf 100644
--- a/handlers/actions.go
+++ b/handlers/actions.go
@@ -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)
}
diff --git a/handlers/auth.go b/handlers/auth.go
index cc41031..b487a05 100644
--- a/handlers/auth.go
+++ b/handlers/auth.go
@@ -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) {
diff --git a/handlers/elements.go b/handlers/elements.go
index 824bda7..9d9a3e9 100644
--- a/handlers/elements.go
+++ b/handlers/elements.go
@@ -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
diff --git a/handlers/game.go b/handlers/game.go
index 2f1c261..7002638 100644
--- a/handlers/game.go
+++ b/handlers/game.go
@@ -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 {
diff --git a/llmapi/main.go b/llmapi/main.go
index 637670b..480f349 100644
--- a/llmapi/main.go
+++ b/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 {
diff --git a/models/main.go b/models/main.go
index 1357906..88c4b03 100644
--- a/models/main.go
+++ b/models/main.go
@@ -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