Enha: parsing llm resp [WIP]
This commit is contained in:
		| @@ -4,6 +4,7 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"golias/broker" | ||||
| 	"golias/config" | ||||
| 	"golias/models" | ||||
| 	"golias/pkg/cache" | ||||
| @@ -26,9 +27,22 @@ var ( | ||||
| 	SignalChanMap = make(map[string]chan bool) | ||||
| 	DoneChanMap   = make(map[string]chan bool) | ||||
| 	// 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 red team (people who would guess by your clue want open the red 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\"word_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` | ||||
| 	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 red team (people who would guess by your clue want open the red 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 red team (people who would guess by your clue want open the red cards) by given clue and a number of meant guesses;\nplease return your guesses and words that you did not wish to open, but think that they could be also meant by the clue 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 game info in json:\n%s` | ||||
| 	// notifier = | ||||
| ) | ||||
|  | ||||
| type MimeResp struct { | ||||
| 	Clue   string   `json:"clue"` | ||||
| 	Number string   `json:"number"` | ||||
| 	Answer []string `json:"words_I_mean_my_team_to_open"` | ||||
| } | ||||
|  | ||||
| type GusserResp struct { | ||||
| 	Guesses []string `json:"guesses"` | ||||
| 	CouldBe []string `json:"could_be"` | ||||
| } | ||||
|  | ||||
| type Bot struct { | ||||
| 	Role    string // gueeser | mime | ||||
| 	Team    string | ||||
| @@ -58,7 +72,8 @@ func (b *Bot) StartBot() { | ||||
| 			prompt := b.BuildPrompt(room) | ||||
| 			b.log.Debug("got prompt", "prompt", prompt) | ||||
| 			// call llm | ||||
| 			if err := b.CallLLM(prompt); err != nil { | ||||
| 			llmResp, err := b.CallLLM(prompt) | ||||
| 			if err != nil { | ||||
| 				b.log.Error("bot loop", "error", err) | ||||
| 				return | ||||
| 			} | ||||
| @@ -66,6 +81,40 @@ func (b *Bot) StartBot() { | ||||
| 			// if mime -> give clue | ||||
| 			// if guesser -> open card (does opening one card prompting new loop?) | ||||
| 			// send notification to sse broker | ||||
| 			switch b.Role { | ||||
| 			case models.UserRoleMime: | ||||
| 				// respMap := make(map[string]any) | ||||
| 				mimeResp := MimeResp{} | ||||
| 				if err := json.Unmarshal(llmResp, &mimeResp); err != nil { | ||||
| 					b.log.Error("failed to unmarshal mime resp", "error", err) | ||||
| 					return | ||||
| 				} | ||||
| 				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 | ||||
| 				// notify(models.NotifyBacklogPrefix+room.ID, clue+num) | ||||
| 			case models.UserRoleGuesser: | ||||
| 				gr := GusserResp{} | ||||
| 				if err := json.Unmarshal(llmResp, &gr); err != nil { | ||||
| 					b.log.Error("failed to unmarshal guesser resp", "error", err) | ||||
| 					return | ||||
| 				} | ||||
| 			default: | ||||
| 				b.log.Error("unexpected role", "role", b.Role) | ||||
| 				return | ||||
| 			} | ||||
| 			broker.Notifier.Notifier <- broker.NotificationEvent{ | ||||
| 				EventName: "", | ||||
| 				Payload:   "", | ||||
| 			} | ||||
| 		// update room info | ||||
| 		case <-DoneChanMap[b.BotName]: | ||||
| 			b.log.Debug("got done signal", "bot-name", b.BotName) | ||||
| 			return | ||||
| @@ -204,7 +253,7 @@ func (b *Bot) BuildPrompt(room *models.Room) string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (b *Bot) CallLLM(prompt string) error { | ||||
| func (b *Bot) CallLLM(prompt string) ([]byte, error) { | ||||
| 	method := "POST" | ||||
| 	payload := strings.NewReader(fmt.Sprintf(`{ | ||||
|   "model": "deepseek-chat", | ||||
| @@ -225,7 +274,7 @@ func (b *Bot) CallLLM(prompt string) error { | ||||
| 	req, err := http.NewRequest(method, b.cfg.LLMConfig.URL, payload) | ||||
| 	if err != nil { | ||||
| 		b.log.Error("failed to make new request", "error", err, "url", b.cfg.LLMConfig.URL) | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req.Header.Add("Content-Type", "application/json") | ||||
| 	req.Header.Add("Accept", "application/json") | ||||
| @@ -233,14 +282,20 @@ func (b *Bot) CallLLM(prompt string) error { | ||||
| 	res, err := client.Do(req) | ||||
| 	if err != nil { | ||||
| 		b.log.Error("failed to make request", "error", err, "url", b.cfg.LLMConfig.URL) | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer res.Body.Close() | ||||
| 	body, err := io.ReadAll(res.Body) | ||||
| 	if err != nil { | ||||
| 		b.log.Error("failed to read resp body", "error", err, "url", b.cfg.LLMConfig.URL) | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	b.log.Debug("llm resp", "body", string(body)) | ||||
| 	return nil | ||||
| 	// TODO: case where it has other text, not only json | ||||
| 	// TODO: how to know which resp it is? mime or guessser? | ||||
| 	// resp := &MimeResp{} | ||||
| 	// if err := json.Unmarshal(body, &resp); err != nil { | ||||
| 	// 	return nil, err | ||||
| 	// } | ||||
| 	return body, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								todos.md
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								todos.md
									
									
									
									
									
								
							| @@ -8,6 +8,7 @@ | ||||
| - add html icons of whos turn it is (like an image of big ? when mime is thinking); | ||||
| - there two places for bot to check if its its move: start-game; end-turn; | ||||
| - remove bot button (if game is not running); | ||||
| - show in backlog (and with that in prompt to llm) how many cards are left to open, also additional comment: if guess was right; | ||||
|  | ||||
| #### sse points | ||||
| - clue sse update; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder