Improved board representation, misc cleanup
Browse files- arena/board.py +3 -3
- arena/llm.py +9 -10
- arena/player.py +4 -2
arena/board.py
CHANGED
|
@@ -6,7 +6,7 @@ YELLOW = -1
|
|
| 6 |
EMPTY = 0
|
| 7 |
show = {EMPTY: "⚪️", RED: "🔴", YELLOW: "🟡"}
|
| 8 |
pieces = {EMPTY: "", RED: "red", YELLOW: "yellow"}
|
| 9 |
-
simple = {EMPTY: "
|
| 10 |
cols = "ABCDEFG"
|
| 11 |
|
| 12 |
|
|
@@ -85,10 +85,10 @@ class Board:
|
|
| 85 |
"""
|
| 86 |
An alternative representation, used in prompting so that the LLM sees this 2 ways
|
| 87 |
"""
|
| 88 |
-
result = "
|
| 89 |
for y in range(6):
|
| 90 |
for x in range(7):
|
| 91 |
-
result += simple[self.cells[5 - y][x]]
|
| 92 |
result += "\n"
|
| 93 |
return result
|
| 94 |
|
|
|
|
| 6 |
EMPTY = 0
|
| 7 |
show = {EMPTY: "⚪️", RED: "🔴", YELLOW: "🟡"}
|
| 8 |
pieces = {EMPTY: "", RED: "red", YELLOW: "yellow"}
|
| 9 |
+
simple = {EMPTY: "_", RED: "R", YELLOW: "Y"}
|
| 10 |
cols = "ABCDEFG"
|
| 11 |
|
| 12 |
|
|
|
|
| 85 |
"""
|
| 86 |
An alternative representation, used in prompting so that the LLM sees this 2 ways
|
| 87 |
"""
|
| 88 |
+
result = " A B C D E F G\n"
|
| 89 |
for y in range(6):
|
| 90 |
for x in range(7):
|
| 91 |
+
result += " " + simple[self.cells[5 - y][x]]
|
| 92 |
result += "\n"
|
| 93 |
return result
|
| 94 |
|
arena/llm.py
CHANGED
|
@@ -34,13 +34,8 @@ class LLM(ABC):
|
|
| 34 |
:param max_tokens: max number of tokens to generate
|
| 35 |
:return: the response from the AI
|
| 36 |
"""
|
| 37 |
-
|
| 38 |
-
print(f"Calling {self.model_name}")
|
| 39 |
-
print("System prompt:\n" + system)
|
| 40 |
-
print("User prompt:\n" + user)
|
| 41 |
result = self.protected_send(system, user, max_tokens)
|
| 42 |
-
print("Response:\n" + result)
|
| 43 |
-
print("_____")
|
| 44 |
left = result.find("{")
|
| 45 |
right = result.rfind("}")
|
| 46 |
if left > -1 and right > -1:
|
|
@@ -58,9 +53,9 @@ class LLM(ABC):
|
|
| 58 |
try:
|
| 59 |
return self._send(system, user, max_tokens)
|
| 60 |
except Exception as e:
|
| 61 |
-
|
| 62 |
if retries:
|
| 63 |
-
|
| 64 |
time.sleep(2)
|
| 65 |
return "{}"
|
| 66 |
|
|
@@ -301,7 +296,9 @@ class Ollama(LLM):
|
|
| 301 |
)
|
| 302 |
reply = response.choices[0].message.content
|
| 303 |
if "</think>" in reply:
|
| 304 |
-
|
|
|
|
|
|
|
| 305 |
reply = reply.split("</think>")[1]
|
| 306 |
return reply
|
| 307 |
|
|
@@ -357,7 +354,9 @@ class DeepSeekLocal(LLM):
|
|
| 357 |
)
|
| 358 |
reply = response.choices[0].message.content
|
| 359 |
if "</think>" in reply:
|
| 360 |
-
|
|
|
|
|
|
|
| 361 |
reply = reply.split("</think>")[1]
|
| 362 |
return reply
|
| 363 |
|
|
|
|
| 34 |
:param max_tokens: max number of tokens to generate
|
| 35 |
:return: the response from the AI
|
| 36 |
"""
|
| 37 |
+
|
|
|
|
|
|
|
|
|
|
| 38 |
result = self.protected_send(system, user, max_tokens)
|
|
|
|
|
|
|
| 39 |
left = result.find("{")
|
| 40 |
right = result.rfind("}")
|
| 41 |
if left > -1 and right > -1:
|
|
|
|
| 53 |
try:
|
| 54 |
return self._send(system, user, max_tokens)
|
| 55 |
except Exception as e:
|
| 56 |
+
logging.error(f"Exception on calling LLM of {e}")
|
| 57 |
if retries:
|
| 58 |
+
logging.warning("Waiting 2s and retrying")
|
| 59 |
time.sleep(2)
|
| 60 |
return "{}"
|
| 61 |
|
|
|
|
| 296 |
)
|
| 297 |
reply = response.choices[0].message.content
|
| 298 |
if "</think>" in reply:
|
| 299 |
+
logging.info(
|
| 300 |
+
"Thoughts:\n" + reply.split("</think>")[0].replace("<think>", "")
|
| 301 |
+
)
|
| 302 |
reply = reply.split("</think>")[1]
|
| 303 |
return reply
|
| 304 |
|
|
|
|
| 354 |
)
|
| 355 |
reply = response.choices[0].message.content
|
| 356 |
if "</think>" in reply:
|
| 357 |
+
logging.info(
|
| 358 |
+
"Thoughts:\n" + reply.split("</think>")[0].replace("<think>", "")
|
| 359 |
+
)
|
| 360 |
reply = reply.split("</think>")[1]
|
| 361 |
return reply
|
| 362 |
|
arena/player.py
CHANGED
|
@@ -2,6 +2,7 @@ from arena.llm import LLM
|
|
| 2 |
from arena.board import pieces, cols
|
| 3 |
import json
|
| 4 |
import random
|
|
|
|
| 5 |
|
| 6 |
|
| 7 |
class Player:
|
|
@@ -52,7 +53,7 @@ Here is the current board, with row 1 at the bottom of the board:
|
|
| 52 |
|
| 53 |
{board.json()}
|
| 54 |
|
| 55 |
-
Here's another way of looking at the board visually, where R represents a red counter
|
| 56 |
|
| 57 |
{board.alternative()}
|
| 58 |
|
|
@@ -110,7 +111,8 @@ You must pick one of these letters for your move_column: {legal_moves}{illegal_m
|
|
| 110 |
self.opportunities = result.get("opportunities") or ""
|
| 111 |
self.strategy = result.get("strategy") or ""
|
| 112 |
except Exception as e:
|
| 113 |
-
|
|
|
|
| 114 |
board.forfeit = True
|
| 115 |
board.winner = -1 * board.player
|
| 116 |
|
|
|
|
| 2 |
from arena.board import pieces, cols
|
| 3 |
import json
|
| 4 |
import random
|
| 5 |
+
import logging
|
| 6 |
|
| 7 |
|
| 8 |
class Player:
|
|
|
|
| 53 |
|
| 54 |
{board.json()}
|
| 55 |
|
| 56 |
+
Here's another way of looking at the board visually, where R represents a red counter, Y for a yellow counter, and _ represents an empty square.
|
| 57 |
|
| 58 |
{board.alternative()}
|
| 59 |
|
|
|
|
| 111 |
self.opportunities = result.get("opportunities") or ""
|
| 112 |
self.strategy = result.get("strategy") or ""
|
| 113 |
except Exception as e:
|
| 114 |
+
logging.error(f"Exception {e}")
|
| 115 |
+
logging.exception(e)
|
| 116 |
board.forfeit = True
|
| 117 |
board.winner = -1 * board.player
|
| 118 |
|