bstraehle commited on
Commit
6f6d82b
1 Parent(s): 5a051f0

Update multi_agent.py

Browse files
Files changed (1) hide show
  1. multi_agent.py +148 -146
multi_agent.py CHANGED
@@ -2,164 +2,166 @@ import chess, chess.svg, math
2
  from autogen import ConversableAgent, register_function
3
  from typing_extensions import Annotated
4
 
5
- class MultiAgent:
6
- made_move = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- board = chess.Board()
9
- board_svgs = []
 
10
 
11
- def get_legal_moves(self) -> Annotated[str, "A list of legal moves in UCI format"]:
12
- return "Possible moves are: " + ",".join(
13
- [str(move) for move in self.board.legal_moves]
14
- )
15
 
16
- def make_move(self, move: Annotated[str, "A move in UCI format."]) -> Annotated[str, "Result of the move."]:
17
- move = chess.Move.from_uci(move)
18
- self.board.push_uci(str(move))
19
- self.made_move = True
 
 
 
 
 
 
 
 
20
 
21
- self.board_svgs.append(chess.svg.board(
22
- self.board,
23
- arrows=[(move.from_square, move.to_square)],
24
- fill={move.from_square: "gray"},
25
- size=250
26
- ))
27
-
28
- piece = self.board.piece_at(move.to_square)
29
- piece_symbol = piece.unicode_symbol()
30
- piece_name = (
31
- chess.piece_name(piece.piece_type).capitalize()
32
- if piece_symbol.isupper()
33
- else chess.piece_name(piece.piece_type)
34
- )
35
 
36
- return f"Moved {piece_name} ({piece_symbol}) from "\
37
- f"{chess.SQUARE_NAMES[move.from_square]} to "\
38
- f"{chess.SQUARE_NAMES[move.to_square]}."
39
 
40
- def check_made_move(self, msg):
41
- if self.made_move:
42
- self.made_move = False
43
- return True
44
- else:
45
- return False
46
 
47
- def get_num_turns(self, num_moves):
48
- # Each turn includes two moves (one by each player)
49
- # The first move by player black kicks off the chat
50
- # The first move by player white starts the game
 
 
 
51
 
52
- num_turns = math.ceil(num_moves / 2)
53
-
54
- if num_moves % 2 == 0:
55
- num_turns += 1
56
-
57
- return num_turns
 
 
58
 
59
- def run_multi_agent(self, llm_white, llm_black, num_moves):
60
- llm_config_white = {"model": llm_white}
61
- llm_config_black = {"model": llm_black}
62
-
63
- board_proxy = ConversableAgent(
64
- name="Board Proxy",
65
- llm_config=False,
66
- is_termination_msg=self.check_made_move,
67
- default_auto_reply="Please make a move.",
68
- human_input_mode="NEVER",
69
- )
70
-
71
- player_white = ConversableAgent(
72
- name="Player White",
73
- system_message="You are a chess player and you play as white. "
74
- "First call get_legal_moves(), to get a list of legal moves. "
75
- "Then call make_move(move) to make a move. "
76
- "After a move is made, analyze the move in 3 bullet points. Respond in format **Analysis:** move from/to, unordered list, your turn player black.",
77
- llm_config=llm_config_white,
78
- )
79
-
80
- player_black = ConversableAgent(
81
- name="Player Black",
82
- system_message="You are a chess player and you play as black. "
83
- "First call get_legal_moves(), to get a list of legal moves. "
84
- "Then call make_move(move) to make a move. "
85
- "After a move is made, analyze the move in 3 bullet points. Respond in format **Analysis:** move from/to, unordered list, your turn player white.",
86
- llm_config=llm_config_black,
87
- )
88
-
89
- for caller in [player_white, player_black]:
90
- register_function(
91
- MultiAgent.get_legal_moves,
92
- caller=caller,
93
- executor=board_proxy,
94
- name="get_legal_moves",
95
- description="Call this tool to get legal moves.",
96
- )
97
-
98
- register_function(
99
- MultiAgent.make_move,
100
- caller=caller,
101
- executor=board_proxy,
102
- name="make_move",
103
- description="Call this tool to make a move.",
104
- )
105
-
106
- player_white.register_nested_chats(
107
- trigger=player_black,
108
- chat_queue=[
109
- {
110
- "sender": board_proxy,
111
- "recipient": player_white,
112
- "summary_method": "last_msg",
113
- "silent": False,
114
- }
115
- ],
116
- )
117
-
118
- player_black.register_nested_chats(
119
- trigger=player_white,
120
- chat_queue=[
121
- {
122
- "sender": board_proxy,
123
- "recipient": player_black,
124
- "summary_method": "last_msg",
125
- "silent": False,
126
- }
127
- ],
128
  )
129
 
130
- chat_result = None
131
- chat_history = []
132
-
133
- try:
134
- chat_result = player_black.initiate_chat(
135
- player_white,
136
- message="Let's play chess!",
137
- max_turns=self.get_num_turns(num_moves),
138
- verbose=True
139
- )
140
- except Exception as e:
141
- print(f"Error: {e}")
142
- finally:
143
- if chat_result != None:
144
- chat_history = chat_result.chat_history
145
-
146
- result = ""
147
- num_move = 0
148
 
149
- for chat in chat_history:
150
- player = ""
151
-
152
- if num_move % 2 == 0:
153
- player = "Player Black"
154
- else:
155
- player = "Player White"
 
 
 
 
156
 
157
- if num_move > 0:
158
- result += f"**{player}, Move {num_move}**<br>{chat.get('content')}<br>{self.board_svgs[num_move - 1]}<br><br>"
159
-
160
- num_move += 1
 
 
 
 
 
 
 
 
 
 
161
 
162
- if num_moves % 2 == 0 and num_move == num_moves + 1:
163
- break
 
 
 
 
 
 
 
 
 
 
164
 
165
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  from autogen import ConversableAgent, register_function
3
  from typing_extensions import Annotated
4
 
5
+ made_move = False
6
+
7
+ board = chess.Board()
8
+ board_svgs = []
9
+
10
+ def get_legal_moves() -> Annotated[str, "A list of legal moves in UCI format"]:
11
+ return "Possible moves are: " + ",".join(
12
+ [str(move) for move in board.legal_moves]
13
+ )
14
+
15
+ def make_move(move: Annotated[str, "A move in UCI format."]) -> Annotated[str, "Result of the move."]:
16
+ move = chess.Move.from_uci(move)
17
+ board.push_uci(str(move))
18
+ global made_move
19
+ made_move = True
20
+
21
+ board_svgs.append(chess.svg.board(
22
+ board,
23
+ arrows=[(move.from_square, move.to_square)],
24
+ fill={move.from_square: "gray"},
25
+ size=250
26
+ ))
27
+
28
+ piece = board.piece_at(move.to_square)
29
+ piece_symbol = piece.unicode_symbol()
30
+ piece_name = (
31
+ chess.piece_name(piece.piece_type).capitalize()
32
+ if piece_symbol.isupper()
33
+ else chess.piece_name(piece.piece_type)
34
+ )
35
 
36
+ return f"Moved {piece_name} ({piece_symbol}) from "\
37
+ f"{chess.SQUARE_NAMES[move.from_square]} to "\
38
+ f"{chess.SQUARE_NAMES[move.to_square]}."
39
 
40
+ def check_made_move(msg):
41
+ global made_move
 
 
42
 
43
+ if made_move:
44
+ made_move = False
45
+ return True
46
+ else:
47
+ return False
48
+
49
+ def get_num_turns(num_moves):
50
+ # Each turn includes two moves (one by each player)
51
+ # The first move by player black kicks off the chat
52
+ # The first move by player white starts the game
53
+
54
+ num_turns = math.ceil(num_moves / 2)
55
 
56
+ if num_moves % 2 == 0:
57
+ num_turns += 1
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ return num_turns
 
 
60
 
61
+ def run_multi_agent(llm_white, llm_black, num_moves):
62
+ llm_config_white = {"model": llm_white}
63
+ llm_config_black = {"model": llm_black}
 
 
 
64
 
65
+ board_proxy = ConversableAgent(
66
+ name="Board Proxy",
67
+ llm_config=False,
68
+ is_termination_msg=check_made_move,
69
+ default_auto_reply="Please make a move.",
70
+ human_input_mode="NEVER",
71
+ )
72
 
73
+ player_white = ConversableAgent(
74
+ name="Player White",
75
+ system_message="You are a chess player and you play as white. "
76
+ "First call get_legal_moves(), to get a list of legal moves. "
77
+ "Then call make_move(move) to make a move. "
78
+ "After a move is made, analyze the move in 3 bullet points. Respond in format **Analysis:** move from/to, unordered list, your turn player black.",
79
+ llm_config=llm_config_white,
80
+ )
81
 
82
+ player_black = ConversableAgent(
83
+ name="Player Black",
84
+ system_message="You are a chess player and you play as black. "
85
+ "First call get_legal_moves(), to get a list of legal moves. "
86
+ "Then call make_move(move) to make a move. "
87
+ "After a move is made, analyze the move in 3 bullet points. Respond in format **Analysis:** move from/to, unordered list, your turn player white.",
88
+ llm_config=llm_config_black,
89
+ )
90
+
91
+ for caller in [player_white, player_black]:
92
+ register_function(
93
+ get_legal_moves,
94
+ caller=caller,
95
+ executor=board_proxy,
96
+ name="get_legal_moves",
97
+ description="Call this tool to get legal moves.",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  )
99
 
100
+ register_function(
101
+ make_move,
102
+ caller=caller,
103
+ executor=board_proxy,
104
+ name="make_move",
105
+ description="Call this tool to make a move.",
106
+ )
 
 
 
 
 
 
 
 
 
 
 
107
 
108
+ player_white.register_nested_chats(
109
+ trigger=player_black,
110
+ chat_queue=[
111
+ {
112
+ "sender": board_proxy,
113
+ "recipient": player_white,
114
+ "summary_method": "last_msg",
115
+ "silent": False,
116
+ }
117
+ ],
118
+ )
119
 
120
+ player_black.register_nested_chats(
121
+ trigger=player_white,
122
+ chat_queue=[
123
+ {
124
+ "sender": board_proxy,
125
+ "recipient": player_black,
126
+ "summary_method": "last_msg",
127
+ "silent": False,
128
+ }
129
+ ],
130
+ )
131
+
132
+ chat_result = None
133
+ chat_history = []
134
 
135
+ try:
136
+ chat_result = player_black.initiate_chat(
137
+ player_white,
138
+ message="Let's play chess!",
139
+ max_turns=get_num_turns(num_moves),
140
+ verbose=True
141
+ )
142
+ except Exception as e:
143
+ print(f"Error: {e}")
144
+ finally:
145
+ if chat_result != None:
146
+ chat_history = chat_result.chat_history
147
 
148
+ result = ""
149
+ num_move = 0
150
+
151
+ for chat in chat_history:
152
+ player = ""
153
+
154
+ if num_move % 2 == 0:
155
+ player = "Player Black"
156
+ else:
157
+ player = "Player White"
158
+
159
+ if num_move > 0:
160
+ result += f"**{player}, Move {num_move}**<br>{chat.get('content')}<br>{board_svgs[num_move - 1]}<br><br>"
161
+
162
+ num_move += 1
163
+
164
+ if num_moves % 2 == 0 and num_move == num_moves + 1:
165
+ break
166
+
167
+ return result