File size: 4,466 Bytes
fd24688
38d55c9
 
 
 
 
 
fd24688
85b163a
38d55c9
 
 
 
 
 
 
 
 
 
 
4cb13ff
38d55c9
 
 
fd24688
4cb13ff
28dd405
38d55c9
 
 
 
 
 
 
05d38b6
fd24688
05d38b6
38d55c9
 
 
 
 
 
 
 
 
 
 
 
74fdc64
 
 
38d55c9
 
 
 
 
 
 
 
 
 
 
 
 
 
a81b987
c6a7801
74fdc64
38d55c9
 
 
 
 
 
 
a81b987
c6a7801
74fdc64
38d55c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d28bcdb
0f490ba
38d55c9
 
 
b699102
 
cd4ee00
0f490ba
d035db6
b388299
ed89e59
c532fed
ed89e59
 
 
 
c532fed
2464fda
2922a40
c532fed
b388299
bc1f421
2922a40
38734be
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import chess, chess.svg
from autogen import ConversableAgent, register_function
from typing_extensions import Annotated

made_move = False

board = chess.Board()
board_svgs = []

def get_legal_moves() -> Annotated[str, "A list of legal moves in UCI format"]:
    return "Possible moves are: " + ",".join(
        [str(move) for move in board.legal_moves]
    )

def make_move(move: Annotated[str, "A move in UCI format."]) -> Annotated[str, "Result of the move."]:
    move = chess.Move.from_uci(move)
    board.push_uci(str(move))
    global made_move
    made_move = True

    svg = chess.svg.board(
        board,
        arrows=[(move.from_square, move.to_square)],
        fill={move.from_square: "gray"},
        size=250
    )

    piece = board.piece_at(move.to_square)
    piece_symbol = piece.unicode_symbol()
    piece_name = (
        chess.piece_name(piece.piece_type).capitalize()
        if piece_symbol.isupper()
        else chess.piece_name(piece.piece_type)
    )

    board_svgs.append(svg)

    return f"Moved {piece_name} ({piece_symbol}) from "\
    f"{chess.SQUARE_NAMES[move.from_square]} to "\
    f"{chess.SQUARE_NAMES[move.to_square]}."

def check_made_move(msg):
    global made_move
    if made_move:
        made_move = False
        return True
    else:
        return False

def run_multi_agent(llm_white, llm_black, num_turns):   
    llm_config_white = {"model": llm_white}
    llm_config_black = {"model": llm_black}
    
    board_proxy = ConversableAgent(
        name="Board Proxy",
        llm_config=False,
        is_termination_msg=check_made_move,
        default_auto_reply="Please make a move.",
        human_input_mode="NEVER",
    )
    
    player_white = ConversableAgent(
        name="Player White",
        system_message="You are a chess player and you play as white. "
        "First call get_legal_moves(), to get a list of legal moves. "
        "Then call make_move(move) to make a move. "
        "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. "
        "Then continue playing.",
        llm_config=llm_config_white,
    )
    
    player_black = ConversableAgent(
        name="Player Black",
        system_message="You are a chess player and you play as black. "
        "First call get_legal_moves(), to get a list of legal moves. "
        "Then call make_move(move) to make a move. "
        "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. "
        "Then continue playing.",
        llm_config=llm_config_black,
    )
    
    for caller in [player_white, player_black]:
        register_function(
            get_legal_moves,
            caller=caller,
            executor=board_proxy,
            name="get_legal_moves",
            description="Get legal moves.",
        )
    
        register_function(
            make_move,
            caller=caller,
            executor=board_proxy,
            name="make_move",
            description="Call this tool to make a move.",
        )
    
    player_white.register_nested_chats(
        trigger=player_black,
        chat_queue=[
            {
                "sender": board_proxy,
                "recipient": player_white,
                "summary_method": "last_msg",
                "silent": True,
            }
        ],
    )
    
    player_black.register_nested_chats(
        trigger=player_white,
        chat_queue=[
            {
                "sender": board_proxy,
                "recipient": player_black,
                "summary_method": "last_msg",
                "silent": True,
            }
        ],
    )
       
    chat_result = player_black.initiate_chat(
        player_white,
        message="Let's play chess!",
        max_turns=num_turns,
        verbose=False
    )

    chat_history = chat_result.chat_history
    
    result = ""
    turn_num = 0

    for chat in chat_history:
        player = ""
        
        if turn_num % 2 == 0:
            player = "Player Black"
        else:
            player = "Player White"

        if turn_num > 0:
            result += f"**{player}, Move {turn_num}**\n{chat.get('content')}\n{board_svgs[turn_num - 1]}\n\n"
        
        turn_num += 1

    result = result.rstrip("\n\n")

    print("###")
    print(result)
    print("###")
    
    return result