Merge branch 'master' into enha/sse-try
This commit is contained in:
@ -1,7 +1,6 @@
|
|||||||
body{
|
body{
|
||||||
background-color: #0C1616FF;
|
background-color: #0C1616FF;
|
||||||
color: #8896b2;
|
color: #8896b2;
|
||||||
max-width: 1000px;
|
|
||||||
min-width: 0px;
|
min-width: 0px;
|
||||||
margin: 2em auto !important;
|
margin: 2em auto !important;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
Binary file not shown.
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// the amount of time to wait when pushing a message to
|
// the amount of time to wait when pushing a message to
|
||||||
// a slow client or a client that closed after `range clients` started.
|
// a slow client or a client that closed after `range clients` started.
|
||||||
const patience time.Duration = time.Second * 1
|
// const patience time.Duration = time.Second * 1
|
||||||
|
|
||||||
type (
|
type (
|
||||||
NotificationEvent struct {
|
NotificationEvent struct {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
if (!window.actionHistoryScrollSet) {
|
if (!window.actionHistoryScrollSet) {
|
||||||
htmx.onLoad(function(target) {
|
htmx.onLoad(function(target) {
|
||||||
if (target.id === 'actionHistoryContainer') {
|
if (target.id === 'actionHistoryContainer') {
|
||||||
target.scrollTop = target.scrollHeight;
|
target.scrollToBottom();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
window.actionHistoryScrollSet = true;
|
window.actionHistoryScrollSet = true;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{{define "room"}}
|
{{define "room"}}
|
||||||
<div id="room-interier" class=space-y-2>
|
<div id="room-interier" class=space-y-2>
|
||||||
<div id="meta">
|
<div id="headwrapper" class="grid grid-cols-1 md:grid-cols-5 md:gap-4">
|
||||||
|
<div id="meta" class="md:col-span-1 border-2 rounded-lg text-center space-y-2">
|
||||||
<p>Hello {{.State.Username}};</p>
|
<p>Hello {{.State.Username}};</p>
|
||||||
<p>Room created by {{.Room.CreatorName}};</p>
|
<p>Room created by {{.Room.CreatorName}};</p>
|
||||||
<p>Room link:</p>
|
<p>Room link:</p>
|
||||||
@ -16,13 +17,13 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
<p>
|
<p>
|
||||||
{{if eq .State.Team ""}}
|
{{if eq .State.Team ""}}
|
||||||
join the team!
|
you don't have a role! join the team ->
|
||||||
{{else}}
|
{{else}}
|
||||||
you're on the team <span class="text-{{.State.Team}}-500">{{.State.Team}}</span>!
|
you're on the team <span class="text-{{.State.Team}}-500">{{.State.Team}}</span>!
|
||||||
{{end}}
|
{{end}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<div id="infopatch" class="md:col-span-3">
|
||||||
{{if .Room.IsRunning}}
|
{{if .Room.IsRunning}}
|
||||||
<p>Turn of the <span class="text-{{.Room.TeamTurn}}-500">{{.Room.TeamTurn}}</span> team</p>
|
<p>Turn of the <span class="text-{{.Room.TeamTurn}}-500">{{.Room.TeamTurn}}</span> team</p>
|
||||||
{{template "turntimer" .Room}}
|
{{template "turntimer" .Room}}
|
||||||
@ -48,7 +49,18 @@
|
|||||||
<!-- Right Panel -->
|
<!-- Right Panel -->
|
||||||
{{template "teamlist" .Room.RedTeam}}
|
{{template "teamlist" .Room.RedTeam}}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-5 md:gap-4">
|
||||||
|
<div hx-get="/actionhistory" hx-trigger="sse:backlog_{{.Room.ID}}" class="md:col-span-1">
|
||||||
|
{{template "actionhistory" .Room.ActionHistory}}
|
||||||
|
</div>
|
||||||
|
<div id="cardtable" class="md:col-span-3">
|
||||||
|
{{template "cardtable" .Room}}
|
||||||
|
</div>
|
||||||
|
<div class="hidden md:block md:col-span-1"></div> <!-- Spacer -->
|
||||||
|
</div>
|
||||||
<div id="systembox" class="overflow-y-auto max-h-96 border-2 border-gray-300 p-4 rounded-lg space-y-2">
|
<div id="systembox" class="overflow-y-auto max-h-96 border-2 border-gray-300 p-4 rounded-lg space-y-2">
|
||||||
bot thought: <br>
|
bot thought: <br>
|
||||||
<ul>
|
<ul>
|
||||||
@ -57,13 +69,6 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div hx-get="/actionhistory" hx-trigger="sse:backlog_{{.Room.ID}}">
|
|
||||||
{{template "actionhistory" .Room.ActionHistory}}
|
|
||||||
</div>
|
|
||||||
<hr/>
|
|
||||||
<div id="cardtable">
|
|
||||||
{{template "cardtable" .Room}}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
{{if .Room.IsRunning}}
|
{{if .Room.IsRunning}}
|
||||||
{{if and (eq .State.Role "guesser") (eq .State.Team .Room.TeamTurn)}}
|
{{if and (eq .State.Role "guesser") (eq .State.Team .Room.TeamTurn)}}
|
||||||
@ -74,7 +79,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{if and (eq .State.Username .Room.CreatorName) (.Room.IsRunning)}}
|
{{if and (eq .State.Username .Room.CreatorName) (.Room.BotFailed)}}
|
||||||
<button hx-get="/renotify-bot" hx-swap="none" class="bg-gray-100 text-black px-1 py-1 rounded">Btn in case llm call failed</button>
|
<button hx-get="/renotify-bot" hx-swap="none" class="bg-gray-100 text-black px-1 py-1 rounded">Btn in case llm call failed</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,8 +42,9 @@ func HandleShowColor(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fi, err := getFullInfoByCtx(ctx)
|
fi, err := getFullInfoByCtx(ctx)
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := validateMove(fi, models.UserRoleGuesser); err != nil {
|
if err := validateMove(fi, models.UserRoleGuesser); err != nil {
|
||||||
@ -206,8 +207,9 @@ func HandleMarkCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fi, err := getFullInfoByCtx(ctx)
|
fi, err := getFullInfoByCtx(ctx)
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := validateMove(fi, models.UserRoleGuesser); err != nil {
|
if err := validateMove(fi, models.UserRoleGuesser); err != nil {
|
||||||
@ -274,8 +276,9 @@ func HandleMarkCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func HandleActionHistory(w http.ResponseWriter, r *http.Request) {
|
func HandleActionHistory(w http.ResponseWriter, r *http.Request) {
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tmpl, err := template.ParseGlob("components/*.html")
|
tmpl, err := template.ParseGlob("components/*.html")
|
||||||
@ -293,8 +296,9 @@ func HandleAddBot(w http.ResponseWriter, r *http.Request) {
|
|||||||
team := r.URL.Query().Get("team")
|
team := r.URL.Query().Get("team")
|
||||||
role := r.URL.Query().Get("role")
|
role := r.URL.Query().Get("role")
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var botname string
|
var botname string
|
||||||
@ -319,8 +323,9 @@ func HandleRemoveBot(w http.ResponseWriter, r *http.Request) {
|
|||||||
botName := r.URL.Query().Get("bot")
|
botName := r.URL.Query().Get("bot")
|
||||||
log.Debug("got remove-bot request", "bot_name", botName)
|
log.Debug("got remove-bot request", "bot_name", botName)
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := llmapi.RemoveBot(botName, fi.Room); err != nil {
|
if err := llmapi.RemoveBot(botName, fi.Room); err != nil {
|
||||||
|
@ -72,8 +72,9 @@ func HandleJoinTeam(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
// get username
|
// get username
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if fi.Room == nil {
|
if fi.Room == nil {
|
||||||
@ -111,8 +112,9 @@ func HandleJoinTeam(w http.ResponseWriter, r *http.Request) {
|
|||||||
func HandleEndTurn(w http.ResponseWriter, r *http.Request) {
|
func HandleEndTurn(w http.ResponseWriter, r *http.Request) {
|
||||||
// get username
|
// get username
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// check if one who pressed it is from the team who has the turn
|
// check if one who pressed it is from the team who has the turn
|
||||||
@ -143,8 +145,9 @@ func HandleEndTurn(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func HandleStartGame(w http.ResponseWriter, r *http.Request) {
|
func HandleStartGame(w http.ResponseWriter, r *http.Request) {
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// check if enough players
|
// check if enough players
|
||||||
@ -293,8 +296,9 @@ func HandleGiveClue(w http.ResponseWriter, r *http.Request) {
|
|||||||
clue := r.PostFormValue("clue")
|
clue := r.PostFormValue("clue")
|
||||||
num := r.PostFormValue("number")
|
num := r.PostFormValue("number")
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guessLimitU64, err := strconv.ParseUint(num, 10, 8)
|
guessLimitU64, err := strconv.ParseUint(num, 10, 8)
|
||||||
@ -360,8 +364,9 @@ func HandleGiveClue(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func HandleRenotifyBot(w http.ResponseWriter, r *http.Request) {
|
func HandleRenotifyBot(w http.ResponseWriter, r *http.Request) {
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
notifyBotIfNeeded(fi.Room)
|
notifyBotIfNeeded(fi.Room)
|
||||||
|
@ -75,8 +75,9 @@ func HandleExit(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fi, err := getFullInfoByCtx(r.Context())
|
fi, err := getFullInfoByCtx(r.Context())
|
||||||
if err != nil {
|
if err != nil || fi == nil {
|
||||||
abortWithError(w, err.Error())
|
log.Error("failed to fetch fi", "error", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if fi.Room.IsRunning {
|
if fi.Room.IsRunning {
|
||||||
|
@ -25,10 +25,10 @@ var (
|
|||||||
DoneChanMap = make(map[string]chan bool)
|
DoneChanMap = make(map[string]chan bool)
|
||||||
mapMutex = &sync.RWMutex{}
|
mapMutex = &sync.RWMutex{}
|
||||||
// got prompt: control character (\\u0000-\\u001F) found while parsing a string at line 4 column 0
|
// got prompt: control character (\\u0000-\\u001F) found while parsing a string at line 4 column 0
|
||||||
// MimePrompt = `we are playing alias;\nyou are a mime (player who gives a clue of one noun word and number of cards you expect them to open) of the %s team (people who would guess by your clue want open the %s cards);\nplease return your clue, number of cards to open and what words you mean them to find using that clue in json like:\n{\n\"clue\": \"one-word-noun\",\n\"number\": \"number-from-0-to-9\",\n\"words_I_mean_my_team_to_open\": [\"this\", \"that\", ...]\n}\nthe team who openes all their cards first wins.\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;\nhere is the game info in json:\n%s`
|
|
||||||
// GuesserPrompt = `we are playing alias;\nyou are to guess words of the %s team (you want open %s cards) by given clue and a number of meant guesses;\nplease return your guesses and words that could be meant by the clue, but you do not wish to open yet, in json like:\n{\n\"guesses\": [\"word1\", \"word2\", ...],\n\"could_be\": [\"this\", \"that\", ...]\n}\nthe team who openes all their cards first wins.\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;\nhere is the cards (and other info), you need to choose revealed==false words:\n%s`
|
|
||||||
GuesserSimplePrompt = `we are playing game of alias;\n you were given a clue: \"%s\";\nplease return your guess and words that could be meant by the clue, but you do not wish to open yet, in json like:\n{\n\"guess\": \"most_relevant_word_to_the_clue\",\n\"could_be\": [\"this\", \"that\", ...]\n}\nhere is the words that you can choose from:\n%v`
|
GuesserSimplePrompt = `we are playing game of alias;\n you were given a clue: \"%s\";\nplease return your guess and words that could be meant by the clue, but you do not wish to open yet, in json like:\n{\n\"guess\": \"most_relevant_word_to_the_clue\",\n\"could_be\": [\"this\", \"that\", ...]\n}\nhere is the words that you can choose from:\n%v`
|
||||||
MimeSimplePrompt = `we are playing alias;\nyou are to give one word clue and a number of words you mean your team to open; your team words: %v;\nhere are the words of opposite team you want to avoid: %v;\nand here is a black word that is critical not to pick: %s;\nplease return your clue, number of cards to open and what words you mean them to find using that clue in json like:\n{\n\"clue\": \"one-word-noun\",\n\"number\": \"number-from-0-to-9-as-string\",\n\"words_I_mean_my_team_to_open\": [\"this\", \"that\", ...]\n}\nplease return json only.\nunopen Blue cards left: %d;\nunopen Red cards left: %d;`
|
MimeSimplePrompt = `we are playing alias;\nyou are to give one word clue and a number of words you mean your team to open; your team words: %v;\nhere are the words of opposite team you want to avoid: %v;\nand here is a black word that is critical not to pick: %s;\nplease return your clue, number of cards to open and what words you mean them to find using that clue in json like:\n{\n\"clue\": \"one-word-noun\",\n\"number\": \"number-from-0-to-9-as-string\",\n\"words_I_mean_my_team_to_open\": [\"this\", \"that\", ...]\n}\nplease return json only.`
|
||||||
|
GuesserSimplePromptRU = `мы играем в alias;\n тебе дана подсказка (clue): \"%s\";\nпожалуйста, верни свою догадку (guess), а также слова, что тоже подходят к подсказке, но ты меньше в них уверен, в формате json; пример:\n{\n\"guess\": \"отгадка\",\n\"could_be\": [\"слово1\", \"слово2\", ...]\n}\nвот список слов из которых нужно выбрать:\n%v`
|
||||||
|
MimeSimplePromptRU = `мы играем в alias;\nтебе нужно дать подсказку одним словом и число слов, что ты подразумевал этой подсказкой; слова твоей комманды: %v;\nслова противоположной комманды, что ты хочешь избежать: %v;\nи вот ЧЕРНОЕ СЛОВО, открыв которое твоя комманда проиграет игру: %s;\nпожалуйста, верни подсказку (одним словом) и количество слов, что ты подразумеваешь в формате json; пример:\n{\n\"clue\": \"подсказка\",\n\"number\": \"число-от-0-до-9-as-string\",\n\"words_I_mean_my_team_to_open\": [\"слово1\", \"слово2\", ...]\n}\nпожалуйста верни только json.`
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertToSliceOfStrings(value any) ([]string, error) {
|
func convertToSliceOfStrings(value any) ([]string, error) {
|
||||||
@ -188,6 +188,11 @@ func (b *Bot) BotMove() {
|
|||||||
b.log.Error("bot loop", "error", err)
|
b.log.Error("bot loop", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if room.BotFailed {
|
||||||
|
if err := repo.RoomUnSetBotFailed(context.Background(), room.ID); err != nil {
|
||||||
|
b.log.Error("failed to unset bot failed bool", "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
// eventName := models.NotifyBacklogPrefix + room.ID
|
// eventName := models.NotifyBacklogPrefix + room.ID
|
||||||
eventName := models.NotifyRoomUpdatePrefix + room.ID
|
eventName := models.NotifyRoomUpdatePrefix + room.ID
|
||||||
eventPayload := ""
|
eventPayload := ""
|
||||||
@ -231,6 +236,9 @@ func (b *Bot) BotMove() {
|
|||||||
b.log.Warn("failed to write to journal", "entry", lj)
|
b.log.Warn("failed to write to journal", "entry", lj)
|
||||||
}
|
}
|
||||||
b.log.Error("bot loop", "error", err)
|
b.log.Error("bot loop", "error", err)
|
||||||
|
if err := repo.RoomSetBotFailed(context.Background(), room.ID); err != nil {
|
||||||
|
b.log.Error("failed to set bot failed bool", "error", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tempMap, err := b.LLMParser.ParseBytes(llmResp)
|
tempMap, err := b.LLMParser.ParseBytes(llmResp)
|
||||||
@ -545,6 +553,9 @@ func (b *Bot) BuildSimpleGuesserPrompt(room *models.Room) string {
|
|||||||
}
|
}
|
||||||
words[i] = card.Word
|
words[i] = card.Word
|
||||||
}
|
}
|
||||||
|
if strings.EqualFold(room.Settings.Language, "ru") {
|
||||||
|
return fmt.Sprintf(MimeSimplePromptRU, clueAction.Word, words)
|
||||||
|
}
|
||||||
return fmt.Sprintf(GuesserSimplePrompt, clueAction.Word, words)
|
return fmt.Sprintf(GuesserSimplePrompt, clueAction.Word, words)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,34 +584,20 @@ func (b *Bot) BuildSimpleMimePrompt(room *models.Room) string {
|
|||||||
theirwords = append(theirwords, card.Word)
|
theirwords = append(theirwords, card.Word)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(MimeSimplePrompt, ourwords, theirwords, blackWord, room.BlueCounter, room.RedCounter)
|
if strings.EqualFold(room.Settings.Language, "ru") {
|
||||||
|
return fmt.Sprintf(MimeSimplePromptRU, ourwords, theirwords, blackWord)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(MimeSimplePrompt, ourwords, theirwords, blackWord)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bot) BuildPrompt(room *models.Room) string {
|
func (b *Bot) BuildPrompt(room *models.Room) string {
|
||||||
if b.Role == "" {
|
if b.Role == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
// toText := make(map[string]any)
|
|
||||||
// toText["backlog"] = room.ActionHistory
|
|
||||||
// // mime sees all colors;
|
|
||||||
// // guesser sees only revealed ones
|
|
||||||
// if b.Role == models.UserRoleMime {
|
|
||||||
// toText["cards"] = room.Cards
|
|
||||||
// }
|
|
||||||
// data, err := json.Marshal(toText)
|
|
||||||
// if err != nil {
|
|
||||||
// b.log.Error("failed to marshal", "error", err)
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
// Escape the JSON string for inclusion in another JSON field
|
|
||||||
// escapedData := strings.ReplaceAll(string(data), `"`, `\\"`)
|
|
||||||
if b.Role == models.UserRoleMime {
|
if b.Role == models.UserRoleMime {
|
||||||
// return fmt.Sprintf(MimeSimplePrompt, b.Team, b.Team, room.BlueCounter, room.RedCounter, escapedData)
|
|
||||||
// return fmt.Sprintf(MimePrompt, b.Team, b.Team, room.BlueCounter, room.RedCounter, escapedData)
|
|
||||||
return b.BuildSimpleMimePrompt(room)
|
return b.BuildSimpleMimePrompt(room)
|
||||||
}
|
}
|
||||||
if b.Role == models.UserRoleGuesser {
|
if b.Role == models.UserRoleGuesser {
|
||||||
// return fmt.Sprintf(GuesserPrompt, b.Team, b.Team, room.BlueCounter, room.RedCounter, escapedData)
|
|
||||||
return b.BuildSimpleGuesserPrompt(room)
|
return b.BuildSimpleGuesserPrompt(room)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -666,16 +663,5 @@ func (b *Bot) CallLLM(prompt string) ([]byte, error) {
|
|||||||
b.log.Debug("llm resp", "body", string(body), "url", b.cfg.LLMConfig.URL, "attempt", attempt)
|
b.log.Debug("llm resp", "body", string(body), "url", b.cfg.LLMConfig.URL, "attempt", attempt)
|
||||||
return body, nil
|
return body, nil
|
||||||
}
|
}
|
||||||
entry := fmt.Sprintf("bot '%s' exceeded attempts to call llm;", b.BotName)
|
|
||||||
lj := models.Journal{
|
|
||||||
Entry: entry,
|
|
||||||
Username: b.BotName,
|
|
||||||
RoomID: b.RoomID,
|
|
||||||
}
|
|
||||||
if err := repo.JournalCreate(context.Background(), &lj); err != nil {
|
|
||||||
b.log.Warn("failed to write to journal", "entry", lj)
|
|
||||||
}
|
|
||||||
// notify room
|
|
||||||
// This line should not be reached because each error path returns in the loop.
|
|
||||||
return nil, errors.New("unknown error in retry loop")
|
return nil, errors.New("unknown error in retry loop")
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ CREATE TABLE rooms (
|
|||||||
mime_done BOOLEAN NOT NULL DEFAULT FALSE,
|
mime_done BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
is_running BOOLEAN NOT NULL DEFAULT FALSE,
|
is_running BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
is_over BOOLEAN NOT NULL DEFAULT FALSE,
|
is_over BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
bot_failed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
team_won TEXT NOT NULL DEFAULT '',
|
team_won TEXT NOT NULL DEFAULT '',
|
||||||
room_link TEXT NOT NULL DEFAULT ''
|
room_link TEXT NOT NULL DEFAULT ''
|
||||||
);
|
);
|
||||||
|
@ -178,6 +178,8 @@ type Room struct {
|
|||||||
BotMap map[string]BotPlayer `db:"-"`
|
BotMap map[string]BotPlayer `db:"-"`
|
||||||
LogJournal []Journal `db:"-"`
|
LogJournal []Journal `db:"-"`
|
||||||
Settings GameSettings `db:"-"`
|
Settings GameSettings `db:"-"`
|
||||||
|
//
|
||||||
|
BotFailed bool `db:"bot_failed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Room) FindColor(word string) (WordColor, bool) {
|
func (r *Room) FindColor(word string) (WordColor, bool) {
|
||||||
|
@ -15,6 +15,20 @@ type RoomsRepo interface {
|
|||||||
RoomCreate(ctx context.Context, room *models.Room) error
|
RoomCreate(ctx context.Context, room *models.Room) error
|
||||||
RoomDeleteByID(ctx context.Context, id string) error
|
RoomDeleteByID(ctx context.Context, id string) error
|
||||||
RoomUpdate(ctx context.Context, room *models.Room) error
|
RoomUpdate(ctx context.Context, room *models.Room) error
|
||||||
|
RoomSetBotFailed(ctx context.Context, roomID string) error
|
||||||
|
RoomUnSetBotFailed(ctx context.Context, roomID string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) RoomSetBotFailed(ctx context.Context, roomID string) error {
|
||||||
|
db := getDB(ctx, p.DB)
|
||||||
|
_, err := db.ExecContext(ctx, "UPDATE rooms SET bot_failed = true WHERE id = ?", roomID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) RoomUnSetBotFailed(ctx context.Context, roomID string) error {
|
||||||
|
db := getDB(ctx, p.DB)
|
||||||
|
_, err := db.ExecContext(ctx, "UPDATE rooms SET bot_failed = false WHERE id = ?", roomID)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) RoomList(ctx context.Context) ([]*models.Room, error) {
|
func (p *RepoProvider) RoomList(ctx context.Context) ([]*models.Room, error) {
|
||||||
|
10
todos.md
10
todos.md
@ -21,8 +21,8 @@
|
|||||||
- redo card .revealed use: it should mean that card is revealed for everybody, while mime should be able to see cards as is; +
|
- redo card .revealed use: it should mean that card is revealed for everybody, while mime should be able to see cards as is; +
|
||||||
- better styles and fluff;
|
- better styles and fluff;
|
||||||
- common auth system between sites;
|
- common auth system between sites;
|
||||||
- signup vs login;
|
- signup vs login; +
|
||||||
- passwords (to room and to login);
|
- passwords (to room and to login); +
|
||||||
===
|
===
|
||||||
- show in backlog (and with that in prompt to llm) how many cards are left to open, also additional comment: if guess was right;
|
- show in backlog (and with that in prompt to llm) how many cards are left to open, also additional comment: if guess was right;
|
||||||
- gameover to backlog;
|
- gameover to backlog;
|
||||||
@ -33,7 +33,7 @@
|
|||||||
- possibly turn markings into parts of names of users (first three letters?); +
|
- possibly turn markings into parts of names of users (first three letters?); +
|
||||||
- at game creation list languages and support them at backend; +
|
- at game creation list languages and support them at backend; +
|
||||||
- sql ping goroutine with reconnect on fail; +
|
- sql ping goroutine with reconnect on fail; +
|
||||||
- player stats: played games, lost, won, rating elo, opened opposite words, opened white words, opened black words.
|
- player stats: played games, lost, won, rating elo, opened opposite words, opened white words, opened black words. +
|
||||||
- at the end of the game, all colors should be revealed;
|
- at the end of the game, all colors should be revealed;
|
||||||
- tracing;
|
- tracing;
|
||||||
|
|
||||||
@ -91,5 +91,5 @@
|
|||||||
- mime sees the clue input out of turn; (eh)
|
- mime sees the clue input out of turn; (eh)
|
||||||
- there is a problem of two timers, they both could switch turn, but it is not easy to stop them from llmapi or handlers. +
|
- there is a problem of two timers, they both could switch turn, but it is not easy to stop them from llmapi or handlers. +
|
||||||
- journal still does not work; +
|
- journal still does not work; +
|
||||||
- lose/win game; then exit room (while being the creator), then press to stats -> cannot find session in db, although cookie in place and session in db;
|
- lose/win game; then exit room (while being the creator), then press to stats -> cannot find session in db, although cookie in place and session in db; +
|
||||||
- exit endpoints delets player from db;
|
- exit endpoints delets player from db; +
|
||||||
|
Reference in New Issue
Block a user