From 610598bd06417edd569d0681b72b0de533497ed7 Mon Sep 17 00:00:00 2001 From: Madhu Date: Fri, 3 Jan 2025 00:38:18 +0530 Subject: [PATCH 01/16] Added AI BlackJack Game folder with Autogen Agents --- .../ai_blackjack_game/README.md | 0 .../ai_blackjack_game/ai_blackjack_agent.py | 134 ++++++++++++++++++ .../ai_blackjack_game/requirements.txt | 0 3 files changed, 134 insertions(+) create mode 100644 ai_agent_tutorials/ai_blackjack_game/README.md create mode 100644 ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py create mode 100644 ai_agent_tutorials/ai_blackjack_game/requirements.txt diff --git a/ai_agent_tutorials/ai_blackjack_game/README.md b/ai_agent_tutorials/ai_blackjack_game/README.md new file mode 100644 index 00000000..e69de29b diff --git a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py new file mode 100644 index 00000000..ce8e1458 --- /dev/null +++ b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py @@ -0,0 +1,134 @@ +import os +import random +import numpy as np +from autogen import ConversableAgent + +# Function to get OpenAI API key from user input +def get_openai_api_key(): + api_key = input("Please enter your OpenAI API key: ").strip() + if not api_key: + raise ValueError("API key cannot be empty.") + return api_key + +# Set OpenAI API key as environment variable +os.environ["OPENAI_API_KEY"] = get_openai_api_key() + +# Initialize deck +suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades'] +ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] +deck = [{'rank': rank, 'suit': suit} for suit in suits for rank in ranks] + +# Function to deal a card +def deal_card(deck): + return deck.pop() + +# Function to calculate hand value +def calculate_hand_value(hand): + value = 0 + aces = 0 + for card in hand: + rank = card['rank'] + if rank in ['J', 'Q', 'K']: + value += 10 + elif rank == 'A': + value += 11 + aces += 1 + else: + value += int(rank) + while value > 21 and aces: + value -= 10 + aces -= 1 + return value + +# Define the Player AI and Dealer AI using AutoGen +player_ai = ConversableAgent( + "player_ai", + system_message=""" + You are the Player AI in a game of Blackjack. Your goal is to maximize your winnings. + - You will receive your hand and the dealer's upcard. + - Decide whether to 'Hit' or 'Stand'. + - Respond with only 'H' for Hit or 'S' for Stand. + """, + llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": os.environ.get("OPENAI_API_KEY")}]}, + human_input_mode="NEVER", +) + +dealer_ai = ConversableAgent( + "dealer_ai", + system_message=""" + You are the Dealer AI in a game of Blackjack. + - You will receive the player's decision and manage the game accordingly. + - Follow standard dealer rules: Hit until hand value is at least 17. + - Do not make decisions for the player. + """, + llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": os.environ.get("OPENAI_API_KEY")}]}, + human_input_mode="NEVER", +) + +# Function to play a game of Blackjack +def play_blackjack(player_ai, dealer_ai, max_rounds=5): + for round_number in range(1, max_rounds + 1): + print(f"\n--- Round {round_number} ---") + random.shuffle(deck) + player_hand = [deal_card(deck), deal_card(deck)] + dealer_hand = [deal_card(deck), deal_card(deck)] + + # Player's turn + while True: + player_value = calculate_hand_value(player_hand) + dealer_upcard = dealer_hand[0] + print(f"Player's Hand: {player_hand} (Value: {player_value})") + print(f"Dealer's Upcard: {dealer_upcard}") + + # Player AI decides to Hit or Stand + player_ai_message = f"Your current hand is {player_hand} (Value: {player_value}). Dealer's upcard is {dealer_upcard}. Do you want to Hit or Stand? (H/S)" + response = player_ai.initiate_chat( + dealer_ai, + message=player_ai_message, + max_turns=1, + ) + # Extract the Player AI's decision + player_decision = response + if player_decision not in ['H', 'S']: + # Fallback decision if response is invalid + player_decision = 'S' + + if player_decision == 'H': # Hit + player_hand.append(deal_card(deck)) + print(f"Player draws: {player_hand[-1]}") + player_value = calculate_hand_value(player_hand) + if player_value > 21: + print(f"Player Busts! Hand: {player_hand} (Value: {player_value})") + break + elif player_decision == 'S': # Stand + print(f"Player stands with hand: {player_hand} (Value: {player_value})") + break + + # Dealer's turn + dealer_value = calculate_hand_value(dealer_hand) + print(f"Dealer reveals hidden card: {dealer_hand[1]}") + print(f"Dealer's Hand: {dealer_hand} (Value: {dealer_value})") + while dealer_value < 17: + dealer_hand.append(deal_card(deck)) + dealer_value = calculate_hand_value(dealer_hand) + print(f"Dealer draws: {dealer_hand[-1]}") + if dealer_value > 21: + print(f"Dealer Busts! Hand: {dealer_hand} (Value: {dealer_value})") + break + + # Determine winner + print(f"Player's Hand: {player_hand} (Value: {player_value})") + print(f"Dealer's Hand: {dealer_hand} (Value: {dealer_value})") + if player_value > 21: + print("Dealer Wins!") + elif dealer_value > 21: + print("Player Wins!") + elif player_value > dealer_value: + print("Player Wins!") + elif dealer_value > player_value: + print("Dealer Wins!") + else: + print("It's a Tie!") + +# Run the game +play_blackjack(player_ai, dealer_ai) \ No newline at end of file diff --git a/ai_agent_tutorials/ai_blackjack_game/requirements.txt b/ai_agent_tutorials/ai_blackjack_game/requirements.txt new file mode 100644 index 00000000..e69de29b From d90578cad2a5ba488ce725dfe7232b55d57bc007 Mon Sep 17 00:00:00 2001 From: Madhu Date: Fri, 3 Jan 2025 00:41:05 +0530 Subject: [PATCH 02/16] few readme requirements.txt additions --- .../ai_blackjack_game/README.md | 33 +++++++++++++++++++ .../ai_blackjack_game/requirements.txt | 4 +++ 2 files changed, 37 insertions(+) diff --git a/ai_agent_tutorials/ai_blackjack_game/README.md b/ai_agent_tutorials/ai_blackjack_game/README.md index e69de29b..e74c3c03 100644 --- a/ai_agent_tutorials/ai_blackjack_game/README.md +++ b/ai_agent_tutorials/ai_blackjack_game/README.md @@ -0,0 +1,33 @@ +# AI Blackjack Game + +This is a simple blackjack game that uses an AI agents as Player and Dealer to play the game. + + +### How to get Started? + +1. Clone the GitHub repository + +```bash +git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git +cd ai_agent_tutorials/ai_blackjack_game +``` +2. Install the required dependencies: + +```bash +pip install -r requirements.txt +``` +3. Get your OpenAI API Key + +- Sign up for an [OpenAI account](https://platform.openai.com/) (or the LLM provider of your choice) and obtain your API key. + +4. Run the Streamlit App +```bash +streamlit run ai_blackjack_agent.py +``` + +## Requirements + +- autogen +- numpy +- openai +- streamlit diff --git a/ai_agent_tutorials/ai_blackjack_game/requirements.txt b/ai_agent_tutorials/ai_blackjack_game/requirements.txt index e69de29b..9e83f1b3 100644 --- a/ai_agent_tutorials/ai_blackjack_game/requirements.txt +++ b/ai_agent_tutorials/ai_blackjack_game/requirements.txt @@ -0,0 +1,4 @@ +autogen +numpy +openai +streamlit \ No newline at end of file From 9e4df046b8e8dc711829bce58f87573a179cc6a1 Mon Sep 17 00:00:00 2001 From: Madhu Date: Fri, 3 Jan 2025 01:09:51 +0530 Subject: [PATCH 03/16] better prompts --- .../ai_blackjack_game/.cache/41/cache.db | Bin 0 -> 73728 bytes .../ai_blackjack_game/ai_blackjack_agent.py | 24 ++++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db diff --git a/ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db b/ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db new file mode 100644 index 0000000000000000000000000000000000000000..2d293263201f3dc90493e5be3e94bb95c6e7e79e GIT binary patch literal 73728 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 fPu@Ib4XQ literal 0 HcmV?d00001 diff --git a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py index ce8e1458..7306a595 100644 --- a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py +++ b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py @@ -1,6 +1,5 @@ import os import random -import numpy as np from autogen import ConversableAgent # Function to get OpenAI API key from user input @@ -11,7 +10,7 @@ def get_openai_api_key(): return api_key # Set OpenAI API key as environment variable -os.environ["OPENAI_API_KEY"] = get_openai_api_key() +OPENAI_API_KEY = get_openai_api_key() # Initialize deck suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades'] @@ -40,28 +39,31 @@ def calculate_hand_value(hand): aces -= 1 return value -# Define the Player AI and Dealer AI using AutoGen +# Define the Player AI using AutoGen player_ai = ConversableAgent( "player_ai", system_message=""" - You are the Player AI in a game of Blackjack. Your goal is to maximize your winnings. - - You will receive your hand and the dealer's upcard. + You are the Player AI in a game of Blackjack. Your goal is to maximize your winnings by making strategic decisions. + - You will receive your current hand and the dealer's upcard. - Decide whether to 'Hit' or 'Stand'. - Respond with only 'H' for Hit or 'S' for Stand. """, - llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": os.environ.get("OPENAI_API_KEY")}]}, + llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, human_input_mode="NEVER", ) +# Define the Dealer AI using AutoGen dealer_ai = ConversableAgent( "dealer_ai", system_message=""" - You are the Dealer AI in a game of Blackjack. - - You will receive the player's decision and manage the game accordingly. - - Follow standard dealer rules: Hit until hand value is at least 17. - - Do not make decisions for the player. + You are the Dealer AI in a game of Blackjack. Follow these rules: + 1. Start with two cards, one face up and one face down. + 2. After the player finishes their turn, reveal your hidden card. + 3. Hit until your hand value is at least 17. + 4. If your hand value exceeds 21, you bust. + 5. Do not make decisions for the player; only manage your own hand. """, - llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": os.environ.get("OPENAI_API_KEY")}]}, + llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, human_input_mode="NEVER", ) From 68f057f1b8ce58719d33521bac34fc98bae1f627 Mon Sep 17 00:00:00 2001 From: Madhu Date: Fri, 3 Jan 2025 01:20:36 +0530 Subject: [PATCH 04/16] more functioning code --- .../ai_blackjack_game/.cache/41/cache.db | Bin 73728 -> 180224 bytes .../ai_blackjack_game/ai_blackjack_agent.py | 83 ++++++++++++------ 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db b/ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db index 2d293263201f3dc90493e5be3e94bb95c6e7e79e..06eb4855a5d42b6e4410e46bd14abfa31b9a8b19 100644 GIT binary patch literal 180224 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 F6+St!Bp?N61VwOdMM$UKCs7EEB2F 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 w-`gSjKf(VmkN(g2BN09jbJr-T(jq delta 874 zcmZ`&OH30{6rJJq4Kszl+kzG9uRx;27*d-`+{v%}(H)5!Gfsw)KA2BsW{9|Hb=Smz zZB5wXM%Sc^Cax-bOx&0#aY0;&1YK50xi+FIeGWod(WMB-kof=DO>S9Jc&h) z<680^eZ07Sa|6x`h{XbCfU8gs|2ma6g9*s5-7jjX_*Q5Yy<5kNw9V`V=L^P;vYjz``u$ZEb-ALHMrgt?q-7i(^+NV%2 zKSS+#IZf4hU6a!bmSd@wj@u`TeX&S<0>vf!woV;QwwFvbwP2Z+YqyP~9^V0N7)o09 zRDDb~GFE&LI}sU0v4(@Rs;DW}%kmvuc%=9|7CuXcQ75mux-RR~ppHM3M4djbVn6O@ zI^9FX*Rk&5=0Ow{9c5Og=8SeHFn~Hm+ff{9J5;s(5aNPli-SgZ0VB`@d*mD0CBNY< zl;JVtz=0cN3!==M5&^bk~= zccZ$C!_^DcOiZ?-3%s^SRfk%poVIkTE)97b=Yu_lTnqdJ{GF}S-g-VMl&(K{B%Nb) z(0fGUtzvTngC^e35DU{B2?^8wgqUpZTF(y&IG4bM+0}cO`MGj-na}Wis2p16Kk+!% ziwpBd5<(z%5f_vrjOfqBaY2)$)tCKzYQMczs?LEO4t~K8_yQkchdo=A{Q%|Sj&+J) WsBrKV-oqQ%gvvo`rBuoEul)ftgabqX diff --git a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py index 7306a595..31b11186 100644 --- a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py +++ b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py @@ -57,18 +57,39 @@ def calculate_hand_value(hand): "dealer_ai", system_message=""" You are the Dealer AI in a game of Blackjack. Follow these rules: - 1. Start with two cards, one face up and one face down. - 2. After the player finishes their turn, reveal your hidden card. - 3. Hit until your hand value is at least 17. - 4. If your hand value exceeds 21, you bust. - 5. Do not make decisions for the player; only manage your own hand. + - You will receive your current hand and the player's final hand value. + - Decide whether to 'Hit' or 'Stand' based on the rules of Blackjack. + - You must hit until your hand value is at least 17. + - If your hand value exceeds 21, you bust. + - Respond with only 'H' for Hit or 'S' for Stand. + """, + llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, + human_input_mode="NEVER", +) + +# Define the Judge AI using AutoGen +judge_ai = ConversableAgent( + "judge_ai", + system_message=""" + You are the Judge AI in a game of Blackjack. You will be provided with the player's final hand and the dealer's final hand. + Your job is to determine the winner based on the rules of Blackjack: + + Rules: + - The player with the hand value closest to 21 without exceeding it wins. + - If both players have the same hand value, it's a tie. + - If both players bust (exceed 21), the dealer wins. + + Respond with: + - "Player" if the player wins. + - "Dealer" if the dealer wins. + - "Tie" if it's a tie. """, llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, human_input_mode="NEVER", ) # Function to play a game of Blackjack -def play_blackjack(player_ai, dealer_ai, max_rounds=5): +def play_blackjack(player_ai, dealer_ai, judge_ai, max_rounds=5): for round_number in range(1, max_rounds + 1): print(f"\n--- Round {round_number} ---") random.shuffle(deck) @@ -84,13 +105,12 @@ def play_blackjack(player_ai, dealer_ai, max_rounds=5): # Player AI decides to Hit or Stand player_ai_message = f"Your current hand is {player_hand} (Value: {player_value}). Dealer's upcard is {dealer_upcard}. Do you want to Hit or Stand? (H/S)" - response = player_ai.initiate_chat( + player_decision = player_ai.initiate_chat( dealer_ai, message=player_ai_message, max_turns=1, ) # Extract the Player AI's decision - player_decision = response if player_decision not in ['H', 'S']: # Fallback decision if response is invalid player_decision = 'S' @@ -110,27 +130,34 @@ def play_blackjack(player_ai, dealer_ai, max_rounds=5): dealer_value = calculate_hand_value(dealer_hand) print(f"Dealer reveals hidden card: {dealer_hand[1]}") print(f"Dealer's Hand: {dealer_hand} (Value: {dealer_value})") - while dealer_value < 17: - dealer_hand.append(deal_card(deck)) - dealer_value = calculate_hand_value(dealer_hand) - print(f"Dealer draws: {dealer_hand[-1]}") - if dealer_value > 21: - print(f"Dealer Busts! Hand: {dealer_hand} (Value: {dealer_value})") + while True: + # Dealer AI decides to Hit or Stand + dealer_ai_message = f"Your current hand is {dealer_hand} (Value: {dealer_value}). The player's final hand value is {player_value}. Do you want to Hit or Stand? (H/S)" + dealer_decision = dealer_ai.initiate_chat( + player_ai, # Communicating with the player AI + message=dealer_ai_message, + max_turns=1, + ) + # Extract the Dealer AI's decision + if dealer_decision not in ['H', 'S']: + # Fallback decision if response is invalid + dealer_decision = 'S' + + if dealer_decision == 'H': + dealer_hand.append(deal_card(deck)) + dealer_value = calculate_hand_value(dealer_hand) + print(f"Dealer draws: {dealer_hand[-1]}") + if dealer_value > 21: + print(f"Dealer Busts! Hand: {dealer_hand} (Value: {dealer_value})") + break + elif dealer_decision == 'S': + print(f"Dealer stands with hand: {dealer_hand} (Value: {dealer_value})") break - # Determine winner - print(f"Player's Hand: {player_hand} (Value: {player_value})") - print(f"Dealer's Hand: {dealer_hand} (Value: {dealer_value})") - if player_value > 21: - print("Dealer Wins!") - elif dealer_value > 21: - print("Player Wins!") - elif player_value > dealer_value: - print("Player Wins!") - elif dealer_value > player_value: - print("Dealer Wins!") - else: - print("It's a Tie!") + # Judge determines the winner + judge_ai_message = f"Player's final hand: {player_hand} (Value: {player_value}). Dealer's final hand: {dealer_hand} (Value: {dealer_value}). Who wins?" + winner = judge_ai.generate_reply(messages=[{"content": judge_ai_message, "role": "user"}]) + print(f"\n{winner} Wins!") # Run the game -play_blackjack(player_ai, dealer_ai) \ No newline at end of file +play_blackjack(player_ai, dealer_ai, judge_ai) \ No newline at end of file From 48700d21f09e0febec6b4a7fc82f99852667c58f Mon Sep 17 00:00:00 2001 From: Madhu Date: Fri, 3 Jan 2025 01:21:58 +0530 Subject: [PATCH 05/16] Added AI BlackJack Game folder with Autogen Agents --- .../ai_blackjack_game/.cache/41/cache.db | Bin 180224 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db diff --git a/ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db b/ai_agent_tutorials/ai_blackjack_game/.cache/41/cache.db deleted file mode 100644 index 06eb4855a5d42b6e4410e46bd14abfa31b9a8b19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180224 zcmeHw3v?UVc^*Itd`Tp=uV1g>tkLo!)1z+_KTo{0!7e^`Wht%1N6VyOY z-yk({@iNsraBgUnx-{002QvntCI_adMJAd=)IZ2CI+Z^v;tqY z;UjG?QUjy?ul6jZO|sOg-WQFx|yk55U_{e{5V)wQ;_+LNY%;SCPU%#wEP zb(ujgjSh`p8lcRVoavSw_aq$Xq~M1gKU!Z~-`d)0zZp{*Hkw(M@Y>`s7N?%x3j>)| z=OiUdOCk?LPYvJ&Yiwd@q-SD=8XlPG)E1N83m1E}ag8pWRE{tdtacYVDbpQgjxZdD z6h$Mt^@uhnjG($A%>X2$iHdc-6i75ZgFjG{ObL)6s3m8s6m z!ib0Jn6lTk9zANmq0zxuMU8E(g&M|D>ZEqpcqnT0BK*H};R2<|hN3J?kq3J?kq3J?kq3J?kq3J?kq3J?lxJ_Vk*IaYgYmlo6%6=S0MBXEkw=Gs=f z=C^;oac}M6hM1@*NU3+$9&8XqRjF@*KkzT0>%L=lE*Xu6wcj?WEjPz&El2j;9Ibt} z0bKoI%~{@jbENiIgQ7C3sHh^RJbCja`RCXPRNofaZ=RrqbglMP zOpJ%I&tHqZvVGWg@aA+a-I#I2D=TqMkfpekR9bIds_oj9IUb8K3GD~i8-MubRIO)! z=9@VwDaV;;7>5@uG0{UeCu?7*$$ZD*unFyF6r5%vcN*;P4=*xYG8t>Xd9n6%04<7~ zDoXKiLW+vqN)$1Q+9e|n#ntFamliR>^lhn@+GlIBYQ6oPrrN`H-Au5zq4uC1n+crw4{RoAX*A3U&DK%uzk9mo zK<(+8JXPBM73<0EUp`#xt0`n8uz$U^me#+q*a+4%mPHP$A2J{i~+YO?CnMf5z9HGl$rJ4+qa5bp8Z>ex1($>-=lyUpl|*{EqWa zoPPxR|5u&wIKSxpE$6Q}zu^2O=g&ER*7-Bef98B!?_P;VPR>avKqx>cKq#=?De&Ng z-D&$MYOJ@_H`p5Nwg*4_N?Q!l@0eMnw4I?o@Jbse#Z|CG!%o|^I0c^>DM>LhqErD< z{fLPond%v$#5l!JvpAJbicq~#hMS**|J~GCDH@fQaAyTkax#jPGx{)eH#Mm;vPvz9 zsz9kr62&nxuXIvU9B^(J4pGSj#l-pCJ})iByY(NtyQ!Xt3TMU_k%%%Y@MlDfiwc|u z9~0plFwH~qAzFk>q*lOCPYEK=qqugO%rKsAYEV=uNTn5xKKP7!p0ub?0JWo8<0(3j z`GvQe8j56w%XLM|974Q8x#>>)9mOUUHS+^sH`OmuaY?0O%sira#EA;n`V|c2W4ihm z;Wncy&?gR**T;vur35%fW}voCs!f)n2tNpAMNv_#?M5e6;Q8QZgg@rzG^Ueio#zC- zWolLeTETs*5?skLIB_61Tq7N1uf}oCI>q8^oQFRllT(K5?^%({-4k4?{&@5Ypr})) zv|;;_vJ6v*8icz!bqdd_cA1IKx1XWf{q3DpyOI=Dywfi-F)7X~?fAyBT>|DVg9xS! zba`I3(VI7PacQ` zQyR}XCJwWtlY-Yp5qX%7Ah_Z*|IE`fMuCZ2coaH7!GsXRSpmtWQ9y8x^Q(t}iQ5xh zVpf#g`S6>-Yp)~Rcv8D@YDs|ko_Su{b2O&kswdT-nU|TD)3{uiy6`({iGimFlLEgi zCkH$5mBPCVZ_3HZj+dwjq$J?6=`XT2joSy?ai8|d_PpE2lNjgQ;z_K(wqZsz&+H^5 zPw9%J}!LZugCzZ~W00{==>heZ$!9`mp1zcQV*l zsbf+Ca(l&YbtQq6ZcboStqF5dECHAc@Dip|Eq!pfFL&TUy5rUKjr7S>LpaQXS1ugZ z_G&~voq8S*!NG64dZHK3y9Pt3H#QX%18({1g>m0pynpWO1uuI&ovP;qNrW8c^vh|% zma6O1_R_}Cf&-7=tglvK8JvCiLUw_hFOg0;G~Z@=*p_ODO0(d>WR>)2sy?$Kr&Aq8 z?4Ehwx1e`YLliH?+l#DQ-P9OfAz=}gCAmtE49V2K za5%BT!*4_`jFw^j(H>8#)pR%_q9_m08VEnSH`6DDBf>Mn(fg?bralQ-T!f_yI*caS zq;UL3S~!8b?h_6O`-Q#tg?2d3z+;4mqar?i{?LD0oJ~2j37JkcY4fqm<)=OARGq}m zAr9`rsn4(6OiJy6nGB9yj2?hwxR-tUq7ClnIDmk_HNdTprW`<)S)j*J>x0dX6V80^ z%uUiu+Aplr>51H=4y)2UiYw{igQ;eCD6xcU92q%ePwi196&%)?J|m~?sl%&&3a}C? zBLc|*pQ^FM`?_7gxX@VX=X;$U~SaUr(U9_KxX=r)TC?V==W|zLI@O4A8q={e!iz#k zI41<}3n1Q|J^@YpacG{$(f22wh35ECXxffILmh_Z*;Z(d9)#xU{m>kF0-C3s&^*}; zP3vxG4mCovzaE->Sk>Q)7qJ$cxWA_cn%#EX+V|Xo)^=*oE&DsWKHc1wo>OWf|#k{L*imavg0zc8J09PaXTkbgB$^i6-b2IcbZU~Vdq`I zCpeIDuz&&mL6DWGb`TCSTpx=D?Gy`a0ZZ?il&eYpR@Fe4+Vty+fxwIqzjMj9Id;!i7-d+Mx?uE&YO%}=O;B`FtdeU)szQnnGKFNdT zv%ZD`(gn<4R+BasVg6;rjkTsMp3)YvI5(ZUDSi5Bk8Vz4Gg=RDJ|u$ySl4c`)&rBf z$V3K_Ss%-+HFQx^In7kpaA809B2ipaf=D<`s&>yy{oC^4e_RKF_Yr&xQyz4R%Y>!qtF`Mst@q<2|$;Tw4M^b4`9R2KcR zpz>&b^=Oy*)ye3CxmS-4m|wlz{IQ%QRA316IV?)^0tTd#J=$PbXrLcW*PS1Ny{(cMfiKLyRa-q0LU{;_N5ewXk-&^^3k`QWRSB zEnFeDW}D_-2?AoQ*12>LRbx^pW F6+St!Bp?N61VwOdMM$UKCs7EEB2F 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 w-`gSjKf(VmkN(g2BN09jbJr-T(jq From f579d005809259ab9e6451a22d40b636802a4f48 Mon Sep 17 00:00:00 2001 From: Madhu Date: Mon, 6 Jan 2025 02:03:03 +0530 Subject: [PATCH 06/16] NEW CODE: CHESS AGENTS WITH AUTOGEN --- ai_agent_tutorials/ai_chess_game/README.md | 34 ++++ .../ai_chess_game/ai_chess_agents.py | 170 ++++++++++++++++++ .../ai_chess_game/requirements.txt | 5 + 3 files changed, 209 insertions(+) create mode 100644 ai_agent_tutorials/ai_chess_game/README.md create mode 100644 ai_agent_tutorials/ai_chess_game/ai_chess_agents.py create mode 100644 ai_agent_tutorials/ai_chess_game/requirements.txt diff --git a/ai_agent_tutorials/ai_chess_game/README.md b/ai_agent_tutorials/ai_chess_game/README.md new file mode 100644 index 00000000..f7261b6d --- /dev/null +++ b/ai_agent_tutorials/ai_chess_game/README.md @@ -0,0 +1,34 @@ +# AI Blackjack Game + +This is a simple Chess game that uses an AI agents - Player black and player white to play the game. There's also a board proxy agent to execute the tools and manage the game. It is important to use a board proxy as a non-LLM "guard rail" to ensure the game is played correctly and to prevent agents from making illegal moves. + + +### How to get Started? + +1. Clone the GitHub repository + +```bash +git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git +cd ai_agent_tutorials/ai_chess_game +``` +2. Install the required dependencies: + +```bash +pip install -r requirements.txt +``` +3. Get your OpenAI API Key + +- Sign up for an [OpenAI account](https://platform.openai.com/) (or the LLM provider of your choice) and obtain your API key. + +4. Run the Streamlit App +```bash +streamlit run ai_chess_agents.py +``` + +## Requirements + +- autogen +- numpy +- openai +- streamlit +- chess \ No newline at end of file diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py new file mode 100644 index 00000000..99f3d7a1 --- /dev/null +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -0,0 +1,170 @@ +import os +from typing import List +import chess +import chess.svg +from IPython.display import display +from typing_extensions import Annotated +player_white_config_list = [ + { + "model": "gpt-4-turbo-preview", + "api_key": os.environ.get("OPENAI_API_KEY"), + }, +] + +player_black_config_list = [ + { + "model": "gpt-4-turbo-preview", + "api_key": os.environ.get("OPENAI_API_KEY"), + }, +] + + +# Initialize the board. +board = chess.Board() + +# Keep track of whether a move has been made. +made_move = False + +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 + # Display the board. + display( + chess.svg.board(board, arrows=[(move.from_square, move.to_square)], fill={move.from_square: "gray"}, size=200) + ) + # Get the piece name. + 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) + ) + + result_msg = f"Moved {piece_name} ({piece_symbol}) from {chess.SQUARE_NAMES[move.from_square]} to {chess.SQUARE_NAMES[move.to_square]}." + + # Add game state information + if board.is_checkmate(): + result_msg += f"\nCheckmate! {'White' if board.turn == chess.BLACK else 'Black'} wins!" + elif board.is_stalemate(): + result_msg += "\nGame ended in stalemate!" + elif board.is_insufficient_material(): + result_msg += "\nGame ended - insufficient material to checkmate!" + elif board.is_check(): + result_msg += "\nCheck!" + + return result_msg + +from autogen import ConversableAgent, register_function + +player_white = ConversableAgent( + name="Player_White", # Updated name + system_message="You are a chess player and you play as white. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_white_config_list, "cache_seed": None}, +) + +player_black = ConversableAgent( + name="Player_Black", # Updated name + system_message="You are a chess player and you play as black. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_black_config_list, "cache_seed": None}, +) + +# Check if the player has made a move, and reset the flag if move is made. +def check_made_move(msg): + global made_move + if made_move: + made_move = False + return True + else: + return False + +board_proxy = ConversableAgent( + name="Board_Proxy", # Updated name + llm_config=False, + # The board proxy will only terminate the conversation if the player has made a move. + is_termination_msg=check_made_move, + # The auto reply message is set to keep the player agent retrying until a move is made. + default_auto_reply="Please make a move.", + human_input_mode="NEVER", +) + +register_function( + make_move, + caller=player_white, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", +) + +register_function( + get_legal_moves, + caller=player_white, + executor=board_proxy, + name="get_legal_moves", + description="Get legal moves.", +) + +register_function( + make_move, + caller=player_black, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", +) + +register_function( + get_legal_moves, + caller=player_black, + executor=board_proxy, + name="get_legal_moves", + description="Get legal moves.", +) + +player_black.llm_config["tools"] + +player_white.register_nested_chats( + trigger=player_black, + chat_queue=[ + { + # The initial message is the one received by the player agent from + # the other player agent. + "sender": board_proxy, + "recipient": player_white, + # The final message is sent to the player agent. + "summary_method": "last_msg", + } + ], +) + +player_black.register_nested_chats( + trigger=player_white, + chat_queue=[ + { + # The initial message is the one received by the player agent from + # the other player agent. + "sender": board_proxy, + "recipient": player_black, + # The final message is sent to the player agent. + "summary_method": "last_msg", + } + ], +) + +# Clear the board. +board = chess.Board() + +# Remove max_turns to let the game continue until completion +chat_result = player_black.initiate_chat( + player_white, + message="Let's play chess! Your move.", + max_turns=10, +) \ No newline at end of file diff --git a/ai_agent_tutorials/ai_chess_game/requirements.txt b/ai_agent_tutorials/ai_chess_game/requirements.txt new file mode 100644 index 00000000..e8130a57 --- /dev/null +++ b/ai_agent_tutorials/ai_chess_game/requirements.txt @@ -0,0 +1,5 @@ +autogen +numpy +openai +streamlit +chess \ No newline at end of file From 4ac8a46e90db3b27e97aa600755a271cf064cff9 Mon Sep 17 00:00:00 2001 From: Madhu Date: Mon, 6 Jan 2025 18:02:40 +0530 Subject: [PATCH 07/16] Deleted unnecessary files from ai_blackjack_game --- .../ai_blackjack_game/README.md | 33 ---- .../ai_blackjack_game/ai_blackjack_agent.py | 163 ------------------ .../ai_blackjack_game/requirements.txt | 4 - 3 files changed, 200 deletions(-) delete mode 100644 ai_agent_tutorials/ai_blackjack_game/README.md delete mode 100644 ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py delete mode 100644 ai_agent_tutorials/ai_blackjack_game/requirements.txt diff --git a/ai_agent_tutorials/ai_blackjack_game/README.md b/ai_agent_tutorials/ai_blackjack_game/README.md deleted file mode 100644 index e74c3c03..00000000 --- a/ai_agent_tutorials/ai_blackjack_game/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# AI Blackjack Game - -This is a simple blackjack game that uses an AI agents as Player and Dealer to play the game. - - -### How to get Started? - -1. Clone the GitHub repository - -```bash -git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git -cd ai_agent_tutorials/ai_blackjack_game -``` -2. Install the required dependencies: - -```bash -pip install -r requirements.txt -``` -3. Get your OpenAI API Key - -- Sign up for an [OpenAI account](https://platform.openai.com/) (or the LLM provider of your choice) and obtain your API key. - -4. Run the Streamlit App -```bash -streamlit run ai_blackjack_agent.py -``` - -## Requirements - -- autogen -- numpy -- openai -- streamlit diff --git a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py b/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py deleted file mode 100644 index 31b11186..00000000 --- a/ai_agent_tutorials/ai_blackjack_game/ai_blackjack_agent.py +++ /dev/null @@ -1,163 +0,0 @@ -import os -import random -from autogen import ConversableAgent - -# Function to get OpenAI API key from user input -def get_openai_api_key(): - api_key = input("Please enter your OpenAI API key: ").strip() - if not api_key: - raise ValueError("API key cannot be empty.") - return api_key - -# Set OpenAI API key as environment variable -OPENAI_API_KEY = get_openai_api_key() - -# Initialize deck -suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades'] -ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] -deck = [{'rank': rank, 'suit': suit} for suit in suits for rank in ranks] - -# Function to deal a card -def deal_card(deck): - return deck.pop() - -# Function to calculate hand value -def calculate_hand_value(hand): - value = 0 - aces = 0 - for card in hand: - rank = card['rank'] - if rank in ['J', 'Q', 'K']: - value += 10 - elif rank == 'A': - value += 11 - aces += 1 - else: - value += int(rank) - while value > 21 and aces: - value -= 10 - aces -= 1 - return value - -# Define the Player AI using AutoGen -player_ai = ConversableAgent( - "player_ai", - system_message=""" - You are the Player AI in a game of Blackjack. Your goal is to maximize your winnings by making strategic decisions. - - You will receive your current hand and the dealer's upcard. - - Decide whether to 'Hit' or 'Stand'. - - Respond with only 'H' for Hit or 'S' for Stand. - """, - llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, - human_input_mode="NEVER", -) - -# Define the Dealer AI using AutoGen -dealer_ai = ConversableAgent( - "dealer_ai", - system_message=""" - You are the Dealer AI in a game of Blackjack. Follow these rules: - - You will receive your current hand and the player's final hand value. - - Decide whether to 'Hit' or 'Stand' based on the rules of Blackjack. - - You must hit until your hand value is at least 17. - - If your hand value exceeds 21, you bust. - - Respond with only 'H' for Hit or 'S' for Stand. - """, - llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, - human_input_mode="NEVER", -) - -# Define the Judge AI using AutoGen -judge_ai = ConversableAgent( - "judge_ai", - system_message=""" - You are the Judge AI in a game of Blackjack. You will be provided with the player's final hand and the dealer's final hand. - Your job is to determine the winner based on the rules of Blackjack: - - Rules: - - The player with the hand value closest to 21 without exceeding it wins. - - If both players have the same hand value, it's a tie. - - If both players bust (exceed 21), the dealer wins. - - Respond with: - - "Player" if the player wins. - - "Dealer" if the dealer wins. - - "Tie" if it's a tie. - """, - llm_config={"config_list": [{"model": "gpt-4", "temperature": 0.2, "api_key": OPENAI_API_KEY}]}, - human_input_mode="NEVER", -) - -# Function to play a game of Blackjack -def play_blackjack(player_ai, dealer_ai, judge_ai, max_rounds=5): - for round_number in range(1, max_rounds + 1): - print(f"\n--- Round {round_number} ---") - random.shuffle(deck) - player_hand = [deal_card(deck), deal_card(deck)] - dealer_hand = [deal_card(deck), deal_card(deck)] - - # Player's turn - while True: - player_value = calculate_hand_value(player_hand) - dealer_upcard = dealer_hand[0] - print(f"Player's Hand: {player_hand} (Value: {player_value})") - print(f"Dealer's Upcard: {dealer_upcard}") - - # Player AI decides to Hit or Stand - player_ai_message = f"Your current hand is {player_hand} (Value: {player_value}). Dealer's upcard is {dealer_upcard}. Do you want to Hit or Stand? (H/S)" - player_decision = player_ai.initiate_chat( - dealer_ai, - message=player_ai_message, - max_turns=1, - ) - # Extract the Player AI's decision - if player_decision not in ['H', 'S']: - # Fallback decision if response is invalid - player_decision = 'S' - - if player_decision == 'H': # Hit - player_hand.append(deal_card(deck)) - print(f"Player draws: {player_hand[-1]}") - player_value = calculate_hand_value(player_hand) - if player_value > 21: - print(f"Player Busts! Hand: {player_hand} (Value: {player_value})") - break - elif player_decision == 'S': # Stand - print(f"Player stands with hand: {player_hand} (Value: {player_value})") - break - - # Dealer's turn - dealer_value = calculate_hand_value(dealer_hand) - print(f"Dealer reveals hidden card: {dealer_hand[1]}") - print(f"Dealer's Hand: {dealer_hand} (Value: {dealer_value})") - while True: - # Dealer AI decides to Hit or Stand - dealer_ai_message = f"Your current hand is {dealer_hand} (Value: {dealer_value}). The player's final hand value is {player_value}. Do you want to Hit or Stand? (H/S)" - dealer_decision = dealer_ai.initiate_chat( - player_ai, # Communicating with the player AI - message=dealer_ai_message, - max_turns=1, - ) - # Extract the Dealer AI's decision - if dealer_decision not in ['H', 'S']: - # Fallback decision if response is invalid - dealer_decision = 'S' - - if dealer_decision == 'H': - dealer_hand.append(deal_card(deck)) - dealer_value = calculate_hand_value(dealer_hand) - print(f"Dealer draws: {dealer_hand[-1]}") - if dealer_value > 21: - print(f"Dealer Busts! Hand: {dealer_hand} (Value: {dealer_value})") - break - elif dealer_decision == 'S': - print(f"Dealer stands with hand: {dealer_hand} (Value: {dealer_value})") - break - - # Judge determines the winner - judge_ai_message = f"Player's final hand: {player_hand} (Value: {player_value}). Dealer's final hand: {dealer_hand} (Value: {dealer_value}). Who wins?" - winner = judge_ai.generate_reply(messages=[{"content": judge_ai_message, "role": "user"}]) - print(f"\n{winner} Wins!") - -# Run the game -play_blackjack(player_ai, dealer_ai, judge_ai) \ No newline at end of file diff --git a/ai_agent_tutorials/ai_blackjack_game/requirements.txt b/ai_agent_tutorials/ai_blackjack_game/requirements.txt deleted file mode 100644 index 9e83f1b3..00000000 --- a/ai_agent_tutorials/ai_blackjack_game/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -autogen -numpy -openai -streamlit \ No newline at end of file From 7357ca8dbdd4756ef58189d77c82e4f852e0ea66 Mon Sep 17 00:00:00 2001 From: Madhu Date: Mon, 6 Jan 2025 18:05:35 +0530 Subject: [PATCH 08/16] NEW CODE: CHESS AGENTS WITH AUTOGEN2 --- ai_agent_tutorials/ai_chess_game/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai_agent_tutorials/ai_chess_game/README.md b/ai_agent_tutorials/ai_chess_game/README.md index f7261b6d..e05906e4 100644 --- a/ai_agent_tutorials/ai_chess_game/README.md +++ b/ai_agent_tutorials/ai_chess_game/README.md @@ -1,4 +1,4 @@ -# AI Blackjack Game +# AI Chess Game - Autogen This is a simple Chess game that uses an AI agents - Player black and player white to play the game. There's also a board proxy agent to execute the tools and manage the game. It is important to use a board proxy as a non-LLM "guard rail" to ensure the game is played correctly and to prevent agents from making illegal moves. From 14040aac48369d2a8f0003d76a736e1a01d44254 Mon Sep 17 00:00:00 2001 From: Madhu Date: Tue, 7 Jan 2025 19:16:00 +0530 Subject: [PATCH 09/16] streamlit UI --- .../ai_chess_game/ai_chess_agents.py | 341 ++++++++++-------- .../ai_chess_game/requirements.txt | 8 +- 2 files changed, 192 insertions(+), 157 deletions(-) diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index 99f3d7a1..f4d4e8ef 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -1,170 +1,205 @@ import os -from typing import List import chess import chess.svg -from IPython.display import display -from typing_extensions import Annotated -player_white_config_list = [ - { - "model": "gpt-4-turbo-preview", - "api_key": os.environ.get("OPENAI_API_KEY"), - }, -] - -player_black_config_list = [ - { - "model": "gpt-4-turbo-preview", - "api_key": os.environ.get("OPENAI_API_KEY"), - }, -] - - -# Initialize the board. -board = chess.Board() - -# Keep track of whether a move has been made. -made_move = False +import streamlit as st +from typing import List, Annotated +from IPython.display import display, SVG +from autogen import ConversableAgent, register_function +# Initialize session state for the OpenAI API key and game state +if "openai_api_key" not in st.session_state: + st.session_state.openai_api_key = None +if "board" not in st.session_state: + st.session_state.board = chess.Board() +if "made_move" not in st.session_state: + st.session_state.made_move = False +if "board_svg" not in st.session_state: + st.session_state.board_svg = None + +# Streamlit sidebar for OpenAI API key input +st.sidebar.title("Chess Agent Configuration") +openai_api_key = st.sidebar.text_input("Enter your OpenAI API key:", type="password") +if openai_api_key: + st.session_state.openai_api_key = openai_api_key + st.sidebar.success("API key saved!") + +# Function to get legal moves 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]) + legal_moves = [str(move) for move in st.session_state.board.legal_moves] + return "Possible moves are: " + ",".join(legal_moves) +# Function to make a move 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 - # Display the board. - display( - chess.svg.board(board, arrows=[(move.from_square, move.to_square)], fill={move.from_square: "gray"}, size=200) - ) - # Get the piece name. - 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) - ) - - result_msg = f"Moved {piece_name} ({piece_symbol}) from {chess.SQUARE_NAMES[move.from_square]} to {chess.SQUARE_NAMES[move.to_square]}." - - # Add game state information - if board.is_checkmate(): - result_msg += f"\nCheckmate! {'White' if board.turn == chess.BLACK else 'Black'} wins!" - elif board.is_stalemate(): - result_msg += "\nGame ended in stalemate!" - elif board.is_insufficient_material(): - result_msg += "\nGame ended - insufficient material to checkmate!" - elif board.is_check(): - result_msg += "\nCheck!" + try: + chess_move = chess.Move.from_uci(move) + if chess_move not in st.session_state.board.legal_moves: + return f"Invalid move: {move}. Please call get_legal_moves() to see valid moves." - return result_msg - -from autogen import ConversableAgent, register_function - -player_white = ConversableAgent( - name="Player_White", # Updated name - system_message="You are a chess player and you play as white. " - "First call get_legal_moves() first, to get list of legal moves. " - "Then call make_move(move) to make a move.", - llm_config={"config_list": player_white_config_list, "cache_seed": None}, -) - -player_black = ConversableAgent( - name="Player_Black", # Updated name - system_message="You are a chess player and you play as black. " - "First call get_legal_moves() first, to get list of legal moves. " - "Then call make_move(move) to make a move.", - llm_config={"config_list": player_black_config_list, "cache_seed": None}, -) + st.session_state.board.push(chess_move) + st.session_state.made_move = True + + # Render board visualization + board_svg = chess.svg.board( + st.session_state.board, + arrows=[(chess_move.from_square, chess_move.to_square)], + fill={chess_move.from_square: "gray"}, + size=400 + ) + st.session_state.board_svg = board_svg # Save SVG to session state + + # Get moved piece details + moved_piece = st.session_state.board.piece_at(chess_move.to_square) + piece_unicode = moved_piece.unicode_symbol() + piece_type_name = chess.piece_name(moved_piece.piece_type) + piece_name = piece_type_name.capitalize() if piece_unicode.isupper() else piece_type_name + + # Build move description + move_desc = f"Moved {piece_name} ({piece_unicode}) from {chess.SQUARE_NAMES[chess_move.from_square]} to {chess.SQUARE_NAMES[chess_move.to_square]}." + + # Check game state + if st.session_state.board.is_checkmate(): + winner = 'White' if st.session_state.board.turn == chess.BLACK else 'Black' + move_desc += f"\nCheckmate! {winner} wins!" + elif st.session_state.board.is_stalemate(): + move_desc += "\nGame ended in stalemate!" + elif st.session_state.board.is_insufficient_material(): + move_desc += "\nGame ended - insufficient material to checkmate!" + elif st.session_state.board.is_check(): + move_desc += "\nCheck!" + + return move_desc + except ValueError: + return f"Invalid move format: {move}. Please use UCI format (e.g., 'e2e4')." # Check if the player has made a move, and reset the flag if move is made. def check_made_move(msg): - global made_move - if made_move: - made_move = False + if st.session_state.made_move: + st.session_state.made_move = False return True else: return False -board_proxy = ConversableAgent( - name="Board_Proxy", # Updated name - llm_config=False, - # The board proxy will only terminate the conversation if the player has made a move. - is_termination_msg=check_made_move, - # The auto reply message is set to keep the player agent retrying until a move is made. - default_auto_reply="Please make a move.", - human_input_mode="NEVER", -) - -register_function( - make_move, - caller=player_white, - executor=board_proxy, - name="make_move", - description="Call this tool to make a move.", -) - -register_function( - get_legal_moves, - caller=player_white, - executor=board_proxy, - name="get_legal_moves", - description="Get legal moves.", -) - -register_function( - make_move, - caller=player_black, - executor=board_proxy, - name="make_move", - description="Call this tool to make a move.", -) - -register_function( - get_legal_moves, - caller=player_black, - executor=board_proxy, - name="get_legal_moves", - description="Get legal moves.", -) - -player_black.llm_config["tools"] - -player_white.register_nested_chats( - trigger=player_black, - chat_queue=[ +# Initialize players and proxy agent if API key is provided +if st.session_state.openai_api_key: + player_white_config_list = [ { - # The initial message is the one received by the player agent from - # the other player agent. - "sender": board_proxy, - "recipient": player_white, - # The final message is sent to the player agent. - "summary_method": "last_msg", - } - ], -) - -player_black.register_nested_chats( - trigger=player_white, - chat_queue=[ + "model": "gpt-4-turbo-preview", + "api_key": st.session_state.openai_api_key, + }, + ] + + player_black_config_list = [ { - # The initial message is the one received by the player agent from - # the other player agent. - "sender": board_proxy, - "recipient": player_black, - # The final message is sent to the player agent. - "summary_method": "last_msg", - } - ], -) - -# Clear the board. -board = chess.Board() - -# Remove max_turns to let the game continue until completion -chat_result = player_black.initiate_chat( - player_white, - message="Let's play chess! Your move.", - max_turns=10, -) \ No newline at end of file + "model": "gpt-4-turbo-preview", + "api_key": st.session_state.openai_api_key, + }, + ] + + player_white = ConversableAgent( + name="Player_White", + system_message="You are a professional chess player and you play as white. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_white_config_list, "cache_seed": None}, + ) + + player_black = ConversableAgent( + name="Player_Black", + system_message="You are a professional chess player and you play as black. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_black_config_list, "cache_seed": None}, + ) + + # Proxy agent to manage the board and validate moves + 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", + ) + + # Register functions for both players + register_function( + make_move, + caller=player_white, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", + ) + + register_function( + get_legal_moves, + caller=player_white, + executor=board_proxy, + name="get_legal_moves", + description="Get legal moves.", + ) + + register_function( + make_move, + caller=player_black, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", + ) + + register_function( + get_legal_moves, + caller=player_black, + executor=board_proxy, + name="get_legal_moves", + description="Get legal moves.", + ) + + # Register nested chats for both players + player_white.register_nested_chats( + trigger=player_black, + chat_queue=[ + { + # The initial message is the one received by the player agent from + # the other player agent. + "sender": board_proxy, + "recipient": player_white, + # The final message is sent to the player agent. + "summary_method": "last_msg", + } + ], + ) + + player_black.register_nested_chats( + trigger=player_white, + chat_queue=[ + { + # The initial message is the one received by the player agent from + # the other player agent. + "sender": board_proxy, + "recipient": player_black, + # The final message is sent to the player agent. + "summary_method": "last_msg", + } + ], + ) + + # Streamlit UI for playing the game + st.title("Chess Agent Game") + if st.button("Start Game"): + st.session_state.board.reset() + st.session_state.made_move = False + st.session_state.board_svg = None + st.write("Game started! White's turn.") + + # Initiate the chat between Player_White and Board_Proxy + chat_result = player_black.initiate_chat( + player_white, + message="Let's play chess! You go first, its your move.", + max_turns=100, # Set a high enough number to allow the game to complete + ) + st.write(chat_result) + + # Display the chessboard SVG + if st.session_state.board_svg: + st.image(st.session_state.board_svg, caption="Chess Board", use_column_width=True) +else: + st.warning("Please enter your OpenAI API key in the sidebar to start the game.") \ No newline at end of file diff --git a/ai_agent_tutorials/ai_chess_game/requirements.txt b/ai_agent_tutorials/ai_chess_game/requirements.txt index e8130a57..5e786020 100644 --- a/ai_agent_tutorials/ai_chess_game/requirements.txt +++ b/ai_agent_tutorials/ai_chess_game/requirements.txt @@ -1,5 +1,5 @@ -autogen -numpy -openai streamlit -chess \ No newline at end of file +python-chess +autogen +cairosvg +pillow From 4bc3ffbc5b7d0abaac3cd9d5900541b20a63c198 Mon Sep 17 00:00:00 2001 From: Madhu Date: Thu, 9 Jan 2025 20:32:49 +0530 Subject: [PATCH 10/16] working on the output format --- ai_agent_tutorials/ai_chess_game/ai_chess_agents.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index f4d4e8ef..b812bd0b 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -194,12 +194,9 @@ def check_made_move(msg): chat_result = player_black.initiate_chat( player_white, message="Let's play chess! You go first, its your move.", - max_turns=100, # Set a high enough number to allow the game to complete + max_turns=5, # Set a high enough number to allow the game to complete ) - st.write(chat_result) + st.markdown(chat_result.summary) - # Display the chessboard SVG - if st.session_state.board_svg: - st.image(st.session_state.board_svg, caption="Chess Board", use_column_width=True) else: st.warning("Please enter your OpenAI API key in the sidebar to start the game.") \ No newline at end of file From 2ebc3f8d9e42dcf04c3e9d452715cb84687b7966 Mon Sep 17 00:00:00 2001 From: Madhu Date: Fri, 10 Jan 2025 21:59:58 +0530 Subject: [PATCH 11/16] chess --- ai_agent_tutorials/ai_chess_game/ai_chess_agents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index b812bd0b..9897de34 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -196,7 +196,7 @@ def check_made_move(msg): message="Let's play chess! You go first, its your move.", max_turns=5, # Set a high enough number to allow the game to complete ) - st.markdown(chat_result.summary) + st.markdown(chat_result.chat_history) else: st.warning("Please enter your OpenAI API key in the sidebar to start the game.") \ No newline at end of file From 56081c673f64a13194080cd725b7ca098fb4a03c Mon Sep 17 00:00:00 2001 From: Madhu Date: Tue, 14 Jan 2025 20:06:30 +0530 Subject: [PATCH 12/16] added new summary feature --- ai_agent_tutorials/ai_chess_game/README.md | 4 +++ .../ai_chess_game/ai_chess_agents.py | 25 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ai_agent_tutorials/ai_chess_game/README.md b/ai_agent_tutorials/ai_chess_game/README.md index e05906e4..d1b841f1 100644 --- a/ai_agent_tutorials/ai_chess_game/README.md +++ b/ai_agent_tutorials/ai_chess_game/README.md @@ -2,6 +2,10 @@ This is a simple Chess game that uses an AI agents - Player black and player white to play the game. There's also a board proxy agent to execute the tools and manage the game. It is important to use a board proxy as a non-LLM "guard rail" to ensure the game is played correctly and to prevent agents from making illegal moves. +Two agents (player_white and player_black) are initialized using the OpenAI API key. These agents are configured to play chess as white and black, respectively. +A board_proxy agent is created to manage the board state and validate moves. +Functions (make_move and available_moves) are registered with the agents to allow them to interact with the board. + ### How to get Started? diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index 9897de34..6b7a7484 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -24,9 +24,9 @@ st.sidebar.success("API key saved!") # Function to get legal moves -def get_legal_moves() -> Annotated[str, "A list of legal moves in UCI format"]: - legal_moves = [str(move) for move in st.session_state.board.legal_moves] - return "Possible moves are: " + ",".join(legal_moves) +def available_moves() -> Annotated[str, "A list of available legal moves in the UCI format"]: + available_moves = [str(move) for move in st.session_state.board.legal_moves] + return "Available moves are: " + ",".join(available_moves) # Function to make a move def make_move(move: Annotated[str, "A move in UCI format."]) -> Annotated[str, "Result of the move."]: @@ -83,14 +83,14 @@ def check_made_move(msg): if st.session_state.openai_api_key: player_white_config_list = [ { - "model": "gpt-4-turbo-preview", + "model": "gpt-4o-mini", "api_key": st.session_state.openai_api_key, }, ] player_black_config_list = [ { - "model": "gpt-4-turbo-preview", + "model": "gpt-4o-mini", "api_key": st.session_state.openai_api_key, }, ] @@ -130,10 +130,10 @@ def check_made_move(msg): ) register_function( - get_legal_moves, + available_moves, caller=player_white, executor=board_proxy, - name="get_legal_moves", + name="available_moves", description="Get legal moves.", ) @@ -146,10 +146,10 @@ def check_made_move(msg): ) register_function( - get_legal_moves, + available_moves, caller=player_black, executor=board_proxy, - name="get_legal_moves", + name="available_moves", description="Get legal moves.", ) @@ -192,11 +192,12 @@ def check_made_move(msg): # Initiate the chat between Player_White and Board_Proxy chat_result = player_black.initiate_chat( - player_white, + recipient=player_white, message="Let's play chess! You go first, its your move.", - max_turns=5, # Set a high enough number to allow the game to complete + max_turns=5, + summary_method="reflection_with_llm" # Set a high enough number to allow the game to complete ) - st.markdown(chat_result.chat_history) + st.markdown(chat_result.summary) else: st.warning("Please enter your OpenAI API key in the sidebar to start the game.") \ No newline at end of file From 1df6d6d62fb4524552d1251b47aa31e6fa80c5d7 Mon Sep 17 00:00:00 2001 From: Madhu Date: Tue, 14 Jan 2025 21:39:45 +0530 Subject: [PATCH 13/16] displaying ui --- .../ai_chess_game/ai_chess_agents.py | 270 ++++++++++-------- 1 file changed, 151 insertions(+), 119 deletions(-) diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index 6b7a7484..0f179a01 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -1,9 +1,6 @@ -import os import chess import chess.svg import streamlit as st -from typing import List, Annotated -from IPython.display import display, SVG from autogen import ConversableAgent, register_function # Initialize session state for the OpenAI API key and game state @@ -15,6 +12,8 @@ st.session_state.made_move = False if "board_svg" not in st.session_state: st.session_state.board_svg = None +if "move_history" not in st.session_state: + st.session_state.move_history = [] # Streamlit sidebar for OpenAI API key input st.sidebar.title("Chess Agent Configuration") @@ -24,12 +23,12 @@ st.sidebar.success("API key saved!") # Function to get legal moves -def available_moves() -> Annotated[str, "A list of available legal moves in the UCI format"]: +def available_moves() -> str: available_moves = [str(move) for move in st.session_state.board.legal_moves] return "Available moves are: " + ",".join(available_moves) # Function to make a move -def make_move(move: Annotated[str, "A move in UCI format."]) -> Annotated[str, "Result of the move."]: +def make_move(move: str) -> str: try: chess_move = chess.Move.from_uci(move) if chess_move not in st.session_state.board.legal_moves: @@ -46,6 +45,7 @@ def make_move(move: Annotated[str, "A move in UCI format."]) -> Annotated[str, " size=400 ) st.session_state.board_svg = board_svg # Save SVG to session state + st.session_state.move_history.append(board_svg) # Save move history # Get moved piece details moved_piece = st.session_state.board.piece_at(chess_move.to_square) @@ -81,123 +81,155 @@ def check_made_move(msg): # Initialize players and proxy agent if API key is provided if st.session_state.openai_api_key: - player_white_config_list = [ - { - "model": "gpt-4o-mini", - "api_key": st.session_state.openai_api_key, - }, - ] - - player_black_config_list = [ - { - "model": "gpt-4o-mini", - "api_key": st.session_state.openai_api_key, - }, - ] - - player_white = ConversableAgent( - name="Player_White", - system_message="You are a professional chess player and you play as white. " - "First call get_legal_moves() first, to get list of legal moves. " - "Then call make_move(move) to make a move.", - llm_config={"config_list": player_white_config_list, "cache_seed": None}, - ) - - player_black = ConversableAgent( - name="Player_Black", - system_message="You are a professional chess player and you play as black. " - "First call get_legal_moves() first, to get list of legal moves. " - "Then call make_move(move) to make a move.", - llm_config={"config_list": player_black_config_list, "cache_seed": None}, - ) - - # Proxy agent to manage the board and validate moves - 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", - ) - - # Register functions for both players - register_function( - make_move, - caller=player_white, - executor=board_proxy, - name="make_move", - description="Call this tool to make a move.", - ) - - register_function( - available_moves, - caller=player_white, - executor=board_proxy, - name="available_moves", - description="Get legal moves.", - ) - - register_function( - make_move, - caller=player_black, - executor=board_proxy, - name="make_move", - description="Call this tool to make a move.", - ) - - register_function( - available_moves, - caller=player_black, - executor=board_proxy, - name="available_moves", - description="Get legal moves.", - ) - - # Register nested chats for both players - player_white.register_nested_chats( - trigger=player_black, - chat_queue=[ + try: + player_white_config_list = [ { - # The initial message is the one received by the player agent from - # the other player agent. - "sender": board_proxy, - "recipient": player_white, - # The final message is sent to the player agent. - "summary_method": "last_msg", - } - ], - ) - - player_black.register_nested_chats( - trigger=player_white, - chat_queue=[ + "model": "gpt-4o-mini", + "api_key": st.session_state.openai_api_key, + }, + ] + + player_black_config_list = [ { - # The initial message is the one received by the player agent from - # the other player agent. - "sender": board_proxy, - "recipient": player_black, - # The final message is sent to the player agent. - "summary_method": "last_msg", - } - ], - ) - - # Streamlit UI for playing the game - st.title("Chess Agent Game") - if st.button("Start Game"): - st.session_state.board.reset() - st.session_state.made_move = False - st.session_state.board_svg = None - st.write("Game started! White's turn.") - - # Initiate the chat between Player_White and Board_Proxy - chat_result = player_black.initiate_chat( - recipient=player_white, - message="Let's play chess! You go first, its your move.", - max_turns=5, - summary_method="reflection_with_llm" # Set a high enough number to allow the game to complete + "model": "gpt-4o-mini", + "api_key": st.session_state.openai_api_key, + }, + ] + + player_white = ConversableAgent( + name="Player_White", + system_message="You are a professional chess player and you play as white. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_white_config_list, "cache_seed": None}, + ) + + player_black = ConversableAgent( + name="Player_Black", + system_message="You are a professional chess player and you play as black. " + "First call get_legal_moves() first, to get list of legal moves. " + "Then call make_move(move) to make a move.", + llm_config={"config_list": player_black_config_list, "cache_seed": None}, + ) + + # Proxy agent to manage the board and validate moves + 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", + ) + + # Register functions for both players + register_function( + make_move, + caller=player_white, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", + ) + + register_function( + available_moves, + caller=player_white, + executor=board_proxy, + name="available_moves", + description="Get legal moves.", + ) + + register_function( + make_move, + caller=player_black, + executor=board_proxy, + name="make_move", + description="Call this tool to make a move.", + ) + + register_function( + available_moves, + caller=player_black, + executor=board_proxy, + name="available_moves", + description="Get legal moves.", ) - st.markdown(chat_result.summary) + + # Register nested chats for both players + player_white.register_nested_chats( + trigger=player_black, + chat_queue=[ + { + "sender": board_proxy, + "recipient": player_white, + "summary_method": "last_msg", + } + ], + ) + + player_black.register_nested_chats( + trigger=player_white, + chat_queue=[ + { + "sender": board_proxy, + "recipient": player_black, + "summary_method": "last_msg", + } + ], + ) + + # Streamlit UI for playing the game + st.title("Chess with AG2 Agents") + st.info(""" +This chess game is played between two AutoGen AI agents: +- **Player White**: A GPT-4o-mini powered chess player controlling white pieces +- **Player Black**: A GPT-4o-mini powered chess player controlling black pieces + +The game is managed by a **Board Proxy Agent** that: +- Validates all moves +- Updates the chess board +- Manages turn-taking between players +- Provides legal move information +""") + + # Display the initial board state before the game starts + initial_board_svg = chess.svg.board(st.session_state.board, size=300) + st.subheader("Initial Board") + st.image(initial_board_svg) + + if st.button("Start Game"): + st.session_state.board.reset() + st.session_state.made_move = False + st.session_state.move_history = [] # Reset move history + st.session_state.board_svg = chess.svg.board(st.session_state.board, size=300) + st.info("The AI agents will now play against each other. Each agent will analyze the board, " + "request legal moves, and make strategic decisions.") + st.write("Game started! White's turn.") + + # Initiate the chat between Player_White and Board_Proxy + chat_result = player_black.initiate_chat( + recipient=player_white, + message="Let's play chess! You go first, its your move.", + max_turns=5, + summary_method="reflection_with_llm" + ) + st.markdown(chat_result.summary) + + # Display the move history (boards for each move) + st.subheader("Move History") + for i, move_svg in enumerate(st.session_state.move_history): + st.write(f"Move {i + 1}") + st.image(move_svg) + + # Reset Game button + if st.button("Reset Game"): + st.session_state.board.reset() + st.session_state.made_move = False + st.session_state.move_history = [] + st.session_state.board_svg = None + st.write("Game reset! Click 'Start Game' to begin a new game.") + + except Exception as e: + st.error(f"An error occurred: {e}. Please check your API key and try again.") else: st.warning("Please enter your OpenAI API key in the sidebar to start the game.") \ No newline at end of file From d47f8d479d2b02c31962a30efc0c30445ac87b14 Mon Sep 17 00:00:00 2001 From: Madhu Date: Tue, 14 Jan 2025 22:29:10 +0530 Subject: [PATCH 14/16] final changes --- ai_agent_tutorials/ai_chess_game/README.md | 9 +- .../ai_chess_game/ai_chess_agents.py | 136 +++++++++--------- .../ai_chess_game/requirements.txt | 4 +- 3 files changed, 73 insertions(+), 76 deletions(-) diff --git a/ai_agent_tutorials/ai_chess_game/README.md b/ai_agent_tutorials/ai_chess_game/README.md index d1b841f1..ae559f0a 100644 --- a/ai_agent_tutorials/ai_chess_game/README.md +++ b/ai_agent_tutorials/ai_chess_game/README.md @@ -2,7 +2,7 @@ This is a simple Chess game that uses an AI agents - Player black and player white to play the game. There's also a board proxy agent to execute the tools and manage the game. It is important to use a board proxy as a non-LLM "guard rail" to ensure the game is played correctly and to prevent agents from making illegal moves. -Two agents (player_white and player_black) are initialized using the OpenAI API key. These agents are configured to play chess as white and black, respectively. +Two agents (agent_white and agent_black) are initialized using the OpenAI API key. These agents are configured to play chess as white and black, respectively. A board_proxy agent is created to manage the board state and validate moves. Functions (make_move and available_moves) are registered with the agents to allow them to interact with the board. @@ -29,10 +29,3 @@ pip install -r requirements.txt streamlit run ai_chess_agents.py ``` -## Requirements - -- autogen -- numpy -- openai -- streamlit -- chess \ No newline at end of file diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index 0f179a01..b27f964f 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -3,7 +3,6 @@ import streamlit as st from autogen import ConversableAgent, register_function -# Initialize session state for the OpenAI API key and game state if "openai_api_key" not in st.session_state: st.session_state.openai_api_key = None if "board" not in st.session_state: @@ -14,49 +13,64 @@ st.session_state.board_svg = None if "move_history" not in st.session_state: st.session_state.move_history = [] +if "max_turns" not in st.session_state: + st.session_state.max_turns = 5 -# Streamlit sidebar for OpenAI API key input st.sidebar.title("Chess Agent Configuration") openai_api_key = st.sidebar.text_input("Enter your OpenAI API key:", type="password") if openai_api_key: st.session_state.openai_api_key = openai_api_key st.sidebar.success("API key saved!") -# Function to get legal moves +st.sidebar.info(""" +For a complete chess game with potential checkmate, it would take max_turns > 200 approximately. +However, this will consume significant API credits and a lot of time. +For demo purposes, using 5-10 turns is recommended. +""") + +max_turns_input = st.sidebar.number_input( + "Enter the number of turns (max_turns):", + min_value=1, + max_value=1000, + value=st.session_state.max_turns, + step=1 +) + +if max_turns_input: + st.session_state.max_turns = max_turns_input + st.sidebar.success(f"Max turns of total chess moves set to {st.session_state.max_turns}!") + +st.title("Chess with AutoGen Agents") + def available_moves() -> str: available_moves = [str(move) for move in st.session_state.board.legal_moves] return "Available moves are: " + ",".join(available_moves) -# Function to make a move -def make_move(move: str) -> str: +def execute_move(move: str) -> str: try: chess_move = chess.Move.from_uci(move) if chess_move not in st.session_state.board.legal_moves: - return f"Invalid move: {move}. Please call get_legal_moves() to see valid moves." + return f"Invalid move: {move}. Please call available_moves() to see valid moves." st.session_state.board.push(chess_move) st.session_state.made_move = True - # Render board visualization board_svg = chess.svg.board( st.session_state.board, arrows=[(chess_move.from_square, chess_move.to_square)], fill={chess_move.from_square: "gray"}, size=400 ) - st.session_state.board_svg = board_svg # Save SVG to session state - st.session_state.move_history.append(board_svg) # Save move history + st.session_state.board_svg = board_svg + st.session_state.move_history.append(board_svg) - # Get moved piece details moved_piece = st.session_state.board.piece_at(chess_move.to_square) piece_unicode = moved_piece.unicode_symbol() piece_type_name = chess.piece_name(moved_piece.piece_type) piece_name = piece_type_name.capitalize() if piece_unicode.isupper() else piece_type_name - # Build move description move_desc = f"Moved {piece_name} ({piece_unicode}) from {chess.SQUARE_NAMES[chess_move.from_square]} to {chess.SQUARE_NAMES[chess_move.to_square]}." - # Check game state if st.session_state.board.is_checkmate(): winner = 'White' if st.session_state.board.turn == chess.BLACK else 'Black' move_desc += f"\nCheckmate! {winner} wins!" @@ -71,7 +85,6 @@ def make_move(move: str) -> str: except ValueError: return f"Invalid move format: {move}. Please use UCI format (e.g., 'e2e4')." -# Check if the player has made a move, and reset the flag if move is made. def check_made_move(msg): if st.session_state.made_move: st.session_state.made_move = False @@ -79,119 +92,112 @@ def check_made_move(msg): else: return False -# Initialize players and proxy agent if API key is provided if st.session_state.openai_api_key: try: - player_white_config_list = [ + agent_white_config_list = [ { "model": "gpt-4o-mini", "api_key": st.session_state.openai_api_key, }, ] - player_black_config_list = [ + agent_black_config_list = [ { "model": "gpt-4o-mini", "api_key": st.session_state.openai_api_key, }, ] - player_white = ConversableAgent( - name="Player_White", + agent_white = ConversableAgent( + name="Agent_White", system_message="You are a professional chess player and you play as white. " - "First call get_legal_moves() first, to get list of legal moves. " - "Then call make_move(move) to make a move.", - llm_config={"config_list": player_white_config_list, "cache_seed": None}, + "First call available_moves() first, to get list of legal moves. " + "Then call execute_move(move) to make a move.", + llm_config={"config_list": agent_white_config_list, "cache_seed": None}, ) - player_black = ConversableAgent( - name="Player_Black", + agent_black = ConversableAgent( + name="Agent_Black", system_message="You are a professional chess player and you play as black. " - "First call get_legal_moves() first, to get list of legal moves. " - "Then call make_move(move) to make a move.", - llm_config={"config_list": player_black_config_list, "cache_seed": None}, + "First call available_moves() first, to get list of legal moves. " + "Then call execute_move(move) to make a move.", + llm_config={"config_list": agent_black_config_list, "cache_seed": None}, ) - # Proxy agent to manage the board and validate moves - board_proxy = ConversableAgent( - name="Board_Proxy", + game_master = ConversableAgent( + name="Game_Master", llm_config=False, is_termination_msg=check_made_move, default_auto_reply="Please make a move.", human_input_mode="NEVER", ) - # Register functions for both players register_function( - make_move, - caller=player_white, - executor=board_proxy, - name="make_move", + execute_move, + caller=agent_white, + executor=game_master, + name="execute_move", description="Call this tool to make a move.", ) register_function( available_moves, - caller=player_white, - executor=board_proxy, + caller=agent_white, + executor=game_master, name="available_moves", description="Get legal moves.", ) register_function( - make_move, - caller=player_black, - executor=board_proxy, - name="make_move", + execute_move, + caller=agent_black, + executor=game_master, + name="execute_move", description="Call this tool to make a move.", ) register_function( available_moves, - caller=player_black, - executor=board_proxy, + caller=agent_black, + executor=game_master, name="available_moves", description="Get legal moves.", ) - # Register nested chats for both players - player_white.register_nested_chats( - trigger=player_black, + agent_white.register_nested_chats( + trigger=agent_black, chat_queue=[ { - "sender": board_proxy, - "recipient": player_white, + "sender": game_master, + "recipient": agent_white, "summary_method": "last_msg", } ], ) - player_black.register_nested_chats( - trigger=player_white, + agent_black.register_nested_chats( + trigger=agent_white, chat_queue=[ { - "sender": board_proxy, - "recipient": player_black, + "sender": game_master, + "recipient": agent_black, "summary_method": "last_msg", } ], ) - # Streamlit UI for playing the game - st.title("Chess with AG2 Agents") st.info(""" -This chess game is played between two AutoGen AI agents: -- **Player White**: A GPT-4o-mini powered chess player controlling white pieces -- **Player Black**: A GPT-4o-mini powered chess player controlling black pieces +This chess game is played between two AG2 AI agents: +- **Agent White**: A GPT-4o-mini powered chess player controlling white pieces +- **Agent Black**: A GPT-4o-mini powered chess player controlling black pieces -The game is managed by a **Board Proxy Agent** that: +The game is managed by a **Game Master** that: - Validates all moves - Updates the chess board - Manages turn-taking between players - Provides legal move information """) - # Display the initial board state before the game starts initial_board_svg = chess.svg.board(st.session_state.board, size=300) st.subheader("Initial Board") st.image(initial_board_svg) @@ -199,28 +205,26 @@ def check_made_move(msg): if st.button("Start Game"): st.session_state.board.reset() st.session_state.made_move = False - st.session_state.move_history = [] # Reset move history + st.session_state.move_history = [] st.session_state.board_svg = chess.svg.board(st.session_state.board, size=300) st.info("The AI agents will now play against each other. Each agent will analyze the board, " - "request legal moves, and make strategic decisions.") + "request legal moves from the Game Master (proxy agent), and make strategic decisions.") + st.success("You can view the interaction between the agents in the terminal output, after the turns between agents end, you get view all the chess board moves displayed below!") st.write("Game started! White's turn.") - # Initiate the chat between Player_White and Board_Proxy - chat_result = player_black.initiate_chat( - recipient=player_white, + chat_result = agent_black.initiate_chat( + recipient=agent_white, message="Let's play chess! You go first, its your move.", - max_turns=5, + max_turns=st.session_state.max_turns, summary_method="reflection_with_llm" ) st.markdown(chat_result.summary) - # Display the move history (boards for each move) st.subheader("Move History") for i, move_svg in enumerate(st.session_state.move_history): st.write(f"Move {i + 1}") st.image(move_svg) - # Reset Game button if st.button("Reset Game"): st.session_state.board.reset() st.session_state.made_move = False diff --git a/ai_agent_tutorials/ai_chess_game/requirements.txt b/ai_agent_tutorials/ai_chess_game/requirements.txt index 5e786020..7f38e3df 100644 --- a/ai_agent_tutorials/ai_chess_game/requirements.txt +++ b/ai_agent_tutorials/ai_chess_game/requirements.txt @@ -1,5 +1,5 @@ streamlit -python-chess -autogen +chess==1.11.1 +autogen==0.6.1 cairosvg pillow From da9fd37d35e2dfe3cb7c4e602aa3ab4e63c928ec Mon Sep 17 00:00:00 2001 From: Madhu Date: Tue, 14 Jan 2025 22:34:48 +0530 Subject: [PATCH 15/16] final changes1 --- ai_agent_tutorials/ai_chess_game/ai_chess_agents.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index b27f964f..cb59e409 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -220,9 +220,16 @@ def check_made_move(msg): ) st.markdown(chat_result.summary) + # Display the move history (boards for each move) st.subheader("Move History") for i, move_svg in enumerate(st.session_state.move_history): - st.write(f"Move {i + 1}") + # Determine which agent made the move + if i % 2 == 0: + move_by = "Agent White" # Even-indexed moves are by White + else: + move_by = "Agent Black" # Odd-indexed moves are by Black + + st.write(f"Move {i + 1} by {move_by}") st.image(move_svg) if st.button("Reset Game"): From a6c13cc8529a27e0770de8dcb5f501bccfae08c4 Mon Sep 17 00:00:00 2001 From: Madhu Date: Tue, 14 Jan 2025 22:37:06 +0530 Subject: [PATCH 16/16] final changes1 --- .../ai_chess_game/ai_chess_agents.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py index cb59e409..912d49be 100644 --- a/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py +++ b/ai_agent_tutorials/ai_chess_game/ai_chess_agents.py @@ -52,25 +52,28 @@ def execute_move(move: str) -> str: if chess_move not in st.session_state.board.legal_moves: return f"Invalid move: {move}. Please call available_moves() to see valid moves." + # Update board state st.session_state.board.push(chess_move) st.session_state.made_move = True - board_svg = chess.svg.board( - st.session_state.board, - arrows=[(chess_move.from_square, chess_move.to_square)], - fill={chess_move.from_square: "gray"}, - size=400 - ) + # Generate and store board visualization + board_svg = chess.svg.board(st.session_state.board, + arrows=[(chess_move.from_square, chess_move.to_square)], + fill={chess_move.from_square: "gray"}, + size=400) st.session_state.board_svg = board_svg st.session_state.move_history.append(board_svg) + # Get piece information moved_piece = st.session_state.board.piece_at(chess_move.to_square) piece_unicode = moved_piece.unicode_symbol() piece_type_name = chess.piece_name(moved_piece.piece_type) piece_name = piece_type_name.capitalize() if piece_unicode.isupper() else piece_type_name - move_desc = f"Moved {piece_name} ({piece_unicode}) from {chess.SQUARE_NAMES[chess_move.from_square]} to {chess.SQUARE_NAMES[chess_move.to_square]}." - + # Generate move description + from_square = chess.SQUARE_NAMES[chess_move.from_square] + to_square = chess.SQUARE_NAMES[chess_move.to_square] + move_desc = f"Moved {piece_name} ({piece_unicode}) from {from_square} to {to_square}." if st.session_state.board.is_checkmate(): winner = 'White' if st.session_state.board.turn == chess.BLACK else 'Black' move_desc += f"\nCheckmate! {winner} wins!" @@ -111,7 +114,7 @@ def check_made_move(msg): agent_white = ConversableAgent( name="Agent_White", system_message="You are a professional chess player and you play as white. " - "First call available_moves() first, to get list of legal moves. " + "First call available_moves() first, to get list of legal available moves. " "Then call execute_move(move) to make a move.", llm_config={"config_list": agent_white_config_list, "cache_seed": None}, ) @@ -119,7 +122,7 @@ def check_made_move(msg): agent_black = ConversableAgent( name="Agent_Black", system_message="You are a professional chess player and you play as black. " - "First call available_moves() first, to get list of legal moves. " + "First call available_moves() first, to get list of legal available moves. " "Then call execute_move(move) to make a move.", llm_config={"config_list": agent_black_config_list, "cache_seed": None}, )