Enha: llm errors to journal
This commit is contained in:
		| @@ -222,21 +222,27 @@ func (b *Bot) BotMove() { | |||||||
| 	// call llm | 	// call llm | ||||||
| 	llmResp, err := b.CallLLM(prompt) | 	llmResp, err := b.CallLLM(prompt) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		room.LogJournal = append(room.LogJournal, models.Journal{ | 		lj := models.Journal{ | ||||||
| 			Entry:    "send call got error: " + err.Error(), | 			Entry:    fmt.Sprintf("bot '%s' exceeded attempts to call llm;", b.BotName), | ||||||
| 			Username: b.BotName, | 			Username: b.BotName, | ||||||
| 			RoomID:   room.ID, | 			RoomID:   b.RoomID, | ||||||
| 		}) | 		} | ||||||
|  | 		if err := repo.JournalCreate(context.Background(), &lj); err != nil { | ||||||
|  | 			b.log.Warn("failed to write to journal", "entry", lj) | ||||||
|  | 		} | ||||||
| 		b.log.Error("bot loop", "error", err) | 		b.log.Error("bot loop", "error", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	tempMap, err := b.LLMParser.ParseBytes(llmResp) | 	tempMap, err := b.LLMParser.ParseBytes(llmResp) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		room.LogJournal = append(room.LogJournal, models.Journal{ | 		lj := models.Journal{ | ||||||
| 			Entry:    "parse resp got error: " + err.Error(), | 			Entry:    fmt.Sprintf("bot '%s' parsing resp failed;", b.BotName), | ||||||
| 			Username: b.BotName, | 			Username: b.BotName, | ||||||
| 			RoomID:   room.ID, | 			RoomID:   b.RoomID, | ||||||
| 		}) | 		} | ||||||
|  | 		if err := repo.JournalCreate(context.Background(), &lj); err != nil { | ||||||
|  | 			b.log.Warn("failed to write to journal", "entry", lj) | ||||||
|  | 		} | ||||||
| 		b.log.Error("bot loop", "error", err, "resp", string(llmResp)) | 		b.log.Error("bot loop", "error", err, "resp", string(llmResp)) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -245,6 +251,22 @@ func (b *Bot) BotMove() { | |||||||
| 		mimeResp := MimeResp{} | 		mimeResp := MimeResp{} | ||||||
| 		b.log.Info("mime resp log", "mimeResp", tempMap) | 		b.log.Info("mime resp log", "mimeResp", tempMap) | ||||||
| 		mimeResp.Clue = strings.ToLower(tempMap["clue"].(string)) | 		mimeResp.Clue = strings.ToLower(tempMap["clue"].(string)) | ||||||
|  | 		for _, card := range room.Cards { | ||||||
|  | 			if strings.ToLower(card.Word) == mimeResp.Clue { | ||||||
|  | 				b.log.Warn("bot-mime clue is one of the words on the board; retrying", "clue", mimeResp.Clue, "bot", b.BotName) | ||||||
|  | 				entry := fmt.Sprintf("bot-mime '%s' gave a clue '%s' which is one of the words on the board. retrying.", b.BotName, mimeResp.Clue) | ||||||
|  | 				lj := models.Journal{ | ||||||
|  | 					Entry:    entry, | ||||||
|  | 					Username: b.BotName, | ||||||
|  | 					RoomID:   room.ID, | ||||||
|  | 				} | ||||||
|  | 				room.LogJournal = append(room.LogJournal, lj) | ||||||
|  | 				if err := repo.JournalCreate(context.Background(), &lj); err != nil { | ||||||
|  | 					b.log.Warn("failed to write to journal", "entry", lj) | ||||||
|  | 				} | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		var ok bool | 		var ok bool | ||||||
| 		mimeResp.Number, ok = tempMap["number"].(string) | 		mimeResp.Number, ok = tempMap["number"].(string) | ||||||
| 		if !ok { | 		if !ok { | ||||||
| @@ -596,7 +618,7 @@ func (b *Bot) CallLLM(prompt string) ([]byte, error) { | |||||||
| 		req, err := http.NewRequest(method, b.cfg.LLMConfig.URL, payloadReader) | 		req, err := http.NewRequest(method, b.cfg.LLMConfig.URL, payloadReader) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if attempt == maxRetries-1 { | 			if attempt == maxRetries-1 { | ||||||
| 				return nil, fmt.Errorf("failed to create request: %w", err) | 				return nil, fmt.Errorf("LLM call failed after %d retries on request creation: %w", maxRetries, err) | ||||||
| 			} | 			} | ||||||
| 			b.log.Error("failed to make new request; will retry", "error", err, "url", b.cfg.LLMConfig.URL, "attempt", attempt) | 			b.log.Error("failed to make new request; will retry", "error", err, "url", b.cfg.LLMConfig.URL, "attempt", attempt) | ||||||
| 			time.Sleep(time.Duration(baseDelay) * time.Second * time.Duration(attempt+1)) | 			time.Sleep(time.Duration(baseDelay) * time.Second * time.Duration(attempt+1)) | ||||||
| @@ -608,7 +630,7 @@ func (b *Bot) CallLLM(prompt string) ([]byte, error) { | |||||||
| 		resp, err := client.Do(req) | 		resp, err := client.Do(req) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if attempt == maxRetries-1 { | 			if attempt == maxRetries-1 { | ||||||
| 				return nil, fmt.Errorf("http request failed: %w", err) | 				return nil, fmt.Errorf("LLM call failed after %d retries on client.Do: %w", maxRetries, err) | ||||||
| 			} | 			} | ||||||
| 			b.log.Error("http request failed; will retry", "error", err, "url", b.cfg.LLMConfig.URL, "attempt", attempt) | 			b.log.Error("http request failed; will retry", "error", err, "url", b.cfg.LLMConfig.URL, "attempt", attempt) | ||||||
| 			delay := time.Duration(baseDelay*(attempt+1)) * time.Second | 			delay := time.Duration(baseDelay*(attempt+1)) * time.Second | ||||||
| @@ -619,7 +641,7 @@ func (b *Bot) CallLLM(prompt string) ([]byte, error) { | |||||||
| 		resp.Body.Close() | 		resp.Body.Close() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if attempt == maxRetries-1 { | 			if attempt == maxRetries-1 { | ||||||
| 				return nil, fmt.Errorf("failed to read response body: %w", err) | 				return nil, fmt.Errorf("LLM call failed after %d retries on reading body: %w", maxRetries, err) | ||||||
| 			} | 			} | ||||||
| 			b.log.Error("failed to read response body; will retry", "error", err, "url", b.cfg.LLMConfig.URL, "attempt", attempt) | 			b.log.Error("failed to read response body; will retry", "error", err, "url", b.cfg.LLMConfig.URL, "attempt", attempt) | ||||||
| 			delay := time.Duration(baseDelay*(attempt+1)) * time.Second | 			delay := time.Duration(baseDelay*(attempt+1)) * time.Second | ||||||
| @@ -629,7 +651,7 @@ func (b *Bot) CallLLM(prompt string) ([]byte, error) { | |||||||
| 		// Check status code | 		// Check status code | ||||||
| 		if resp.StatusCode >= 400 && resp.StatusCode < 600 { | 		if resp.StatusCode >= 400 && resp.StatusCode < 600 { | ||||||
| 			if attempt == maxRetries-1 { | 			if attempt == maxRetries-1 { | ||||||
| 				return nil, fmt.Errorf("after %d retries, still got status %d", maxRetries, resp.StatusCode) | 				return nil, fmt.Errorf("LLM call failed after %d retries, got status %d", maxRetries, resp.StatusCode) | ||||||
| 			} | 			} | ||||||
| 			b.log.Warn("retriable status code; will retry", "code", resp.StatusCode, "attempt", attempt) | 			b.log.Warn("retriable status code; will retry", "code", resp.StatusCode, "attempt", attempt) | ||||||
| 			delay := time.Duration((baseDelay * (1 << attempt))) * time.Second | 			delay := time.Duration((baseDelay * (1 << attempt))) * time.Second | ||||||
| @@ -644,7 +666,16 @@ 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. | 	// 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") | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								todos.md
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								todos.md
									
									
									
									
									
								
							| @@ -34,6 +34,7 @@ | |||||||
| - 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; | ||||||
|  |  | ||||||
| #### sse points | #### sse points | ||||||
| - clue sse update; | - clue sse update; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder