From aa49a0dcc9c09e3975f3097b37170f164f5063f2 Mon Sep 17 00:00:00 2001 From: ShubhamSaboo Date: Tue, 25 Feb 2025 21:51:38 -0600 Subject: [PATCH] Updated AI tac_tac_toe agent --- .../ai_tic_tac_toe_agent/README.md | 135 +++++---- .../agents.py | 0 .../ai_tic_tac_toe_agent.py | 259 ------------------ .../app.py | 0 .../ai_tic_tac_toe_agent/requirements.txt | 242 +++++++++++++++- .../utils.py | 0 .../ai_tic_tac_toe_game/README.md | 103 ------- .../ai_tic_tac_toe_game/requirements.txt | 238 ---------------- 8 files changed, 320 insertions(+), 657 deletions(-) rename ai_agent_tutorials/{ai_tic_tac_toe_game => ai_tic_tac_toe_agent}/agents.py (100%) delete mode 100644 ai_agent_tutorials/ai_tic_tac_toe_agent/ai_tic_tac_toe_agent.py rename ai_agent_tutorials/{ai_tic_tac_toe_game => ai_tic_tac_toe_agent}/app.py (100%) rename ai_agent_tutorials/{ai_tic_tac_toe_game => ai_tic_tac_toe_agent}/utils.py (100%) delete mode 100644 ai_agent_tutorials/ai_tic_tac_toe_game/README.md delete mode 100644 ai_agent_tutorials/ai_tic_tac_toe_game/requirements.txt diff --git a/ai_agent_tutorials/ai_tic_tac_toe_agent/README.md b/ai_agent_tutorials/ai_tic_tac_toe_agent/README.md index b5744d9..8ba563e 100644 --- a/ai_agent_tutorials/ai_tic_tac_toe_agent/README.md +++ b/ai_agent_tutorials/ai_tic_tac_toe_agent/README.md @@ -1,32 +1,23 @@ # 🎮 Agent X vs Agent O: Tic-Tac-Toe Game -An interactive Tic-Tac-Toe game where two AI agents powered by different language models compete against each other built on Agno Agent Framework and Streamlit as UI. Watch as GPT-4O battles against either DeepSeek V3 or Google's Gemini 1.5 Flash in this classic game. +An interactive Tic-Tac-Toe game where two AI agents powered by different language models compete against each other built on Agno Agent Framework and Streamlit as UI. + +This example shows how to build an interactive Tic Tac Toe game where AI agents compete against each other. The application showcases how to: +- Coordinate multiple AI agents in a turn-based game +- Use different language models for different players +- Create an interactive web interface with Streamlit +- Handle game state and move validation +- Display real-time game progress and move history ## Features +- Multiple AI models support (GPT-4, Claude, Gemini, etc.) +- Real-time game visualization +- Move history tracking with board states +- Interactive player selection +- Game state management +- Move validation and coordination -### Multi-Agent System -- Player X: OpenAI's Gemini Flash 2.0 -- Player O: DeepSeek v3 -- Judge: GPT-4o for game outcome validation - -### Interactive Interface -- Real-time game board visualization -- Move-by-move analysis -- Agent response tracking -- Clear game status updates - -### Strategic Gameplay -- AI-powered move decisions -- Winning strategy implementation -- Opponent move blocking -- Victory condition monitoring - -## Prerequisites -- Python 3.8+ -- OpenAI API key -- Either DeepSeek API key or Google API key (for Player O) - -## How to Run +## How to Run? 1. **Setup Environment** ```bash @@ -38,40 +29,78 @@ An interactive Tic-Tac-Toe game where two AI agents powered by different languag pip install -r requirements.txt ``` -2. **Configure API Keys** - - Get OpenAI API key from [OpenAI Platform](https://platform.openai.com) - - Get Google API key from [Google AI Studio](https://aistudio.google.com) (if using Gemini) - - Get DeepSeek API key from DeepSeek platform [Deepseek platform](https://www.deepseek.com) (if using DeepSeek v3 model) +### 2. Install dependencies -4. **Run the Application** - ```bash - streamlit run ai_tic_tac_toe_agent.py - ``` +```shell +pip install -r requirements.txt +``` -5. **Using the Interface** - - Enter your API keys in the sidebar - - Click "Start Game" to begin - - Watch as the AI agents battle it out! - - Monitor the game progress and final results +### 3. Export API Keys -## Game Components +The game supports multiple AI models. Export the API keys for the models you want to use: -- **Game Board** - - 3x3 interactive grid - - Real-time move visualization - - Clear symbol placement (X/O) +```shell +# Required for OpenAI models +export OPENAI_API_KEY=*** -- **AI Agent Players** - - Player X: Strategic offensive moves - - Player O: Defensive countermoves since this agent started later - - AI Judge: Game outcome validation +# Optional - for additional models +export ANTHROPIC_API_KEY=*** # For Claude models +export GOOGLE_API_KEY=*** # For Gemini models +export GROQ_API_KEY=*** # For Groq models +``` -- **Game Flow** - - Alternating turns between AIs - - Move validation and error handling - - Winner determination - - Draw detection +### 4. Run the Game -## Disclaimer ⚠️ +```shell +streamlit run app.py +``` -This is a demonstration project showcasing AI capabilities in game playing. API costs will apply based on your usage of the OpenAI, DeepSeek, or Google APIs. +- Open [localhost:8501](http://localhost:8501) to view the game interface + +## How It Works + +The game consists of three agents: + +1. **Master Agent (Referee)** + - Coordinates the game + - Validates moves + - Maintains game state + - Determines game outcome + +2. **Two Player Agents** + - Make strategic moves + - Analyze board state + - Follow game rules + - Respond to opponent moves + +## Available Models + +The game supports various AI models: +- GPT-4o (OpenAI) +- GPT-o3-mini (OpenAI) +- Gemini (Google) +- Llama 3 (Groq) +- Claude (Anthropic) + +## Game Features + +1. **Interactive Board** + - Real-time updates + - Visual move tracking + - Clear game status display + +2. **Move History** + - Detailed move tracking + - Board state visualization + - Player action timeline + +3. **Game Controls** + - Start/Pause game + - Reset board + - Select AI models + - View game history + +4. **Performance Analysis** + - Move timing + - Strategy tracking + - Game statistics diff --git a/ai_agent_tutorials/ai_tic_tac_toe_game/agents.py b/ai_agent_tutorials/ai_tic_tac_toe_agent/agents.py similarity index 100% rename from ai_agent_tutorials/ai_tic_tac_toe_game/agents.py rename to ai_agent_tutorials/ai_tic_tac_toe_agent/agents.py diff --git a/ai_agent_tutorials/ai_tic_tac_toe_agent/ai_tic_tac_toe_agent.py b/ai_agent_tutorials/ai_tic_tac_toe_agent/ai_tic_tac_toe_agent.py deleted file mode 100644 index 084d344..0000000 --- a/ai_agent_tutorials/ai_tic_tac_toe_agent/ai_tic_tac_toe_agent.py +++ /dev/null @@ -1,259 +0,0 @@ -import re -import streamlit as st -from agno.agent import Agent -from agno.models.openai import OpenAIChat -from agno.models.deepseek import DeepSeek -from agno.models.google import Gemini - -# Streamlit App Title -st.title("🎮 Agent X vs Agent O: Tic-Tac-Toe Game") - -# Enhanced Welcome Message -with st.chat_message("assistant"): - st.markdown(""" - **Welcome to the Tic-Tac-Toe AI Battle!** 🎮 - This project pits two advanced AI agents against each other in a classic game of Tic-Tac-Toe. - Here's what you need to know: - """) - st.info(""" - - **Player X**: Powered by Google's Gemini Flash 2.0. - - **Player O**: Powered by DeepSeek v3. - - **How to Play**: Enter your API keys in the sidebar, click **Start Game**, and watch the AI battle it out! - - **Goal**: The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins. - - **Draw**: If the board fills up without a winner, the game ends in a draw. - """) - st.markdown("Ready to see who wins? Click the **Start Game** button below! 🚀") - -# Initialize the game board in session state -if 'board' not in st.session_state: - st.session_state.board = [[None, None, None], - [None, None, None], - [None, None, None]] - -# Function to display the board with better styling -def display_board(board): - st.markdown(""" - - """, unsafe_allow_html=True) - - st.write("Current Board:") - board_html = '
' - for row in board: - for cell in row: - cell_value = cell if cell is not None else " " - board_html += f'
{cell_value}
' - board_html += '
' - st.markdown(board_html, unsafe_allow_html=True) - -# Function to get the board state as a string -def get_board_state(board): - rows = [] - for i, row in enumerate(board): - row_str = " | ".join([f"({i},{j}) {cell or ' '}" for j, cell in enumerate(row)]) - rows.append(f"Row {i}: {row_str}") - return "\n".join(rows) - -# Function to check for a winner -def check_winner(board): - # Check rows - for row in board: - if row[0] == row[1] == row[2] and row[0] is not None: - return row[0] - # Check columns - for col in range(3): - if board[0][col] == board[1][col] == board[2][col] and board[0][col] is not None: - return board[0][col] - # Check diagonals - if board[0][0] == board[1][1] == board[2][2] and board[0][0] is not None: - return board[0][0] - if board[0][2] == board[1][1] == board[2][0] and board[0][2] is not None: - return board[0][2] - # Check for draw - if all(cell is not None for row in board for cell in row): - return "Draw" - return None - -# Sidebar for API keys -st.sidebar.header("API Keys") -openai_api_key = st.sidebar.text_input("Enter your OpenAI API Key", type="password") -deepseek_api_key = st.sidebar.text_input("Enter your DeepSeek API Key", type="password") -google_api_key = st.sidebar.text_input("Enter your Google API Key (for Gemini)", type="password") - -if openai_api_key: - st.session_state.openai_api_key = openai_api_key -if deepseek_api_key: - st.session_state.deepseek_api_key = deepseek_api_key -if google_api_key: - st.session_state.google_api_key = google_api_key - -# Initialize agents if API keys are provided -if 'openai_api_key' in st.session_state: - player_x = Agent( - name="Player X", - model=Gemini(id="gemini-2.0-flash-exp", api_key=st.session_state.google_api_key), - instructions=[ - "You are a Tic-Tac-Toe player using the symbol 'X'.", - "Your opponent is using the symbol 'O'. Block their potential winning moves.", - "Make your move in the format 'row, col' based on the current board state.", - "Strategize to win by placing your symbol in a way that blocks your opponent from forming a straight line.", - "Do not include any explanations or extra text. Only provide the move.", - "Row and column indices start from 0.", - ], - markdown=True, - ) - - # Initialize Player O with DeepSeek or Google Gemini - if 'deepseek_api_key' in st.session_state: - player_o = Agent( - name="Player O", - model=DeepSeek(id="deepseek-chat", api_key=st.session_state.deepseek_api_key), - instructions=[ - "You are a Tic-Tac-Toe player using the symbol 'O'.", - "Your opponent is using the symbol 'X'. Block their potential winning moves.", - "Make your move in the format 'row, col' based on the current board state.", - "Strategize to win by placing your symbol in a way that blocks your opponent from forming a straight line.", - "Do not include any explanations or extra text. Only provide the move.", - "Row and column indices start from 0.", - ], - markdown=True, - ) - else: - st.warning("Please provide either a DeepSeek API key or a Google API key for Player O.") - - judge = Agent( - name="Judge", - model=OpenAIChat(id="gpt-4o", temperature=0.1, api_key=st.session_state.openai_api_key), - instructions=[ - "You are the judge of a Tic-Tac-Toe game.", - "The board is presented as rows with positions separated by '|'.", - "Rows are labeled from 0 to 2, and columns from 0 to 2.", - "Example board state:", - "Row 0: (0,0) X | (0,1) | (0,2) O", - "Row 1: (1,0) O | (1,1) X | (1,2) X", - "Row 2: (2,0) X | (2,1) O | (2,2) O", - "Determine the winner based on this board state.", - "The winner is the player with three of their symbols in a straight line (row, column, or diagonal).", - "If the board is full and there is no winner, declare a draw.", - "Provide only the result (e.g., 'Player X wins', 'Player O wins', 'Draw').", - ], - markdown=True, - ) - - # Function to extract the move from the agent's response - def extract_move(response): - content = response.content.strip() - match = re.search(r'\d\s*,\s*\d', content) - if match: - move = match.group().replace(' ', '') - return move - numbers = re.findall(r'\d+', content) - if len(numbers) >= 2: - row = int(numbers[0]) - col = int(numbers[1]) - return f"{row},{col}" - return None - - # Game loop - def play_game(): - if 'current_player' not in st.session_state: - st.session_state.current_player = player_x - if 'symbol' not in st.session_state: - st.session_state.symbol = "X" - if 'move_count' not in st.session_state: - st.session_state.move_count = 0 - - max_moves = 9 - winner = None # Initialize winner variable - - while st.session_state.move_count < max_moves: - # Display the board - display_board(st.session_state.board) - - # Prepare the board state for the agent - board_state = get_board_state(st.session_state.board) - move_prompt = ( - f"Current board state:\n{board_state}\n" - f"{st.session_state.current_player.name}'s turn. Make your move in the format 'row, col'." - ) - - # Get the current player's move - with st.chat_message("assistant"): - st.write(f"**{st.session_state.current_player.name}'s turn:**") - move_response = st.session_state.current_player.run(move_prompt) - st.code(f"Agent {st.session_state.current_player.name} response:\n{move_response.content}", language="markdown") - move = extract_move(move_response) - st.write(f"**Extracted move:** {move}") - - if move is None: - st.error("Invalid move! Please use the format 'row, col'.") - continue - - try: - row, col = map(int, move.split(',')) - if st.session_state.board[row][col] is not None: - st.error("Invalid move! Cell already occupied.") - continue - st.session_state.board[row][col] = st.session_state.symbol - except (ValueError, IndexError): - st.error("Invalid move! Please use the format 'row, col'.") - continue - - # Check for a winner or draw - winner = check_winner(st.session_state.board) - if winner: - break # Exit the loop if there's a winner - - # Switch players - st.session_state.current_player = player_o if st.session_state.current_player == player_x else player_x - st.session_state.symbol = "O" if st.session_state.symbol == "X" else "X" - st.session_state.move_count += 1 - - # After the game loop, display the final board and involve the judge agent - st.write("**Final Board:**") - display_board(st.session_state.board) - - if winner: - st.success(f"**Result:** {winner}") - else: - st.success("**Result:** Draw") - - # Judge's announcement - st.write("\n**Game Over. Judge is determining the result...**") - st.write("**Final board state passed to judge:**") - st.code(get_board_state(st.session_state.board), language="markdown") - judge_prompt = ( - f"Final board state:\n{get_board_state(st.session_state.board)}\n" - f"Determine the winner and announce the result." - ) - judge_response = judge.run(judge_prompt) - st.code(f"Judge's raw response:\n{judge_response.content}", language="markdown") - announcement = judge_response.content.strip() - st.success(f"**Judge's Announcement:** {announcement}") - - # Start Game Button - if st.button("Start Game"): - st.session_state.board = [[None, None, None], - [None, None, None], - [None, None, None]] - st.session_state.current_player = player_x - st.session_state.symbol = "X" - st.session_state.move_count = 0 - play_game() -else: - st.warning("Please enter your OpenAI API key and either Deepseek/Gemini API key to start the game.") \ No newline at end of file diff --git a/ai_agent_tutorials/ai_tic_tac_toe_game/app.py b/ai_agent_tutorials/ai_tic_tac_toe_agent/app.py similarity index 100% rename from ai_agent_tutorials/ai_tic_tac_toe_game/app.py rename to ai_agent_tutorials/ai_tic_tac_toe_agent/app.py diff --git a/ai_agent_tutorials/ai_tic_tac_toe_agent/requirements.txt b/ai_agent_tutorials/ai_tic_tac_toe_agent/requirements.txt index e7c8c1c..c275c18 100644 --- a/ai_agent_tutorials/ai_tic_tac_toe_agent/requirements.txt +++ b/ai_agent_tutorials/ai_tic_tac_toe_agent/requirements.txt @@ -1,4 +1,238 @@ -streamlit==1.41.1 -agno -openai==1.58.1 -google-generativeai==0.8.3 \ No newline at end of file +# This file was autogenerated by uv via the following command: +# ./generate_requirements.sh +agno==1.1.6 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +altair==5.5.0 + # via streamlit +annotated-types==0.7.0 + # via pydantic +anthropic==0.47.1 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +anyio==4.8.0 + # via + # anthropic + # groq + # httpx + # openai +attrs==25.1.0 + # via + # jsonschema + # referencing +blinker==1.9.0 + # via streamlit +build==1.2.2.post1 + # via pip-tools +cachetools==5.5.2 + # via + # google-auth + # streamlit +certifi==2025.1.31 + # via + # httpcore + # httpx + # requests +charset-normalizer==3.4.1 + # via requests +click==8.1.8 + # via + # pip-tools + # streamlit + # typer +distro==1.9.0 + # via + # anthropic + # groq + # openai +docstring-parser==0.16 + # via agno +gitdb==4.0.12 + # via gitpython +gitpython==3.1.44 + # via + # agno + # streamlit +google-auth==2.38.0 + # via google-genai +google-genai==1.3.0 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +groq==0.18.0 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +h11==0.14.0 + # via httpcore +httpcore==1.0.7 + # via httpx +httpx==0.28.1 + # via + # agno + # anthropic + # google-genai + # groq + # ollama + # openai +idna==3.10 + # via + # anyio + # httpx + # requests +jinja2==3.1.5 + # via + # altair + # pydeck +jiter==0.8.2 + # via + # anthropic + # openai +jsonschema==4.23.0 + # via altair +jsonschema-specifications==2024.10.1 + # via jsonschema +markdown-it-py==3.0.0 + # via rich +markupsafe==3.0.2 + # via jinja2 +mdurl==0.1.2 + # via markdown-it-py +narwhals==1.28.0 + # via altair +nest-asyncio==1.6.0 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +numpy==2.2.3 + # via + # pandas + # pydeck + # streamlit +ollama==0.4.7 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +openai==1.64.0 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +packaging==24.2 + # via + # altair + # build + # streamlit +pandas==2.2.3 + # via streamlit +pathlib==1.0.1 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +pillow==11.1.0 + # via + # -r cookbook/examples/apps/tic_tac_toe/requirements.in + # streamlit +pip==25.0.1 + # via pip-tools +pip-tools==7.4.1 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +protobuf==5.29.3 + # via streamlit +pyarrow==19.0.1 + # via streamlit +pyasn1==0.6.1 + # via + # pyasn1-modules + # rsa +pyasn1-modules==0.4.1 + # via google-auth +pydantic==2.10.6 + # via + # agno + # anthropic + # google-genai + # groq + # ollama + # openai + # pydantic-settings +pydantic-core==2.27.2 + # via pydantic +pydantic-settings==2.8.0 + # via agno +pydeck==0.9.1 + # via streamlit +pygments==2.19.1 + # via rich +pyproject-hooks==1.2.0 + # via + # build + # pip-tools +python-dateutil==2.9.0.post0 + # via pandas +python-dotenv==1.0.1 + # via + # -r cookbook/examples/apps/tic_tac_toe/requirements.in + # agno + # pydantic-settings +python-multipart==0.0.20 + # via agno +pytz==2025.1 + # via pandas +pyyaml==6.0.2 + # via agno +referencing==0.36.2 + # via + # jsonschema + # jsonschema-specifications +requests==2.32.3 + # via + # google-genai + # streamlit +rich==13.9.4 + # via + # -r cookbook/examples/apps/tic_tac_toe/requirements.in + # agno + # streamlit + # typer +rpds-py==0.23.1 + # via + # jsonschema + # referencing +rsa==4.9 + # via google-auth +setuptools==75.8.0 + # via pip-tools +shellingham==1.5.4 + # via typer +six==1.17.0 + # via python-dateutil +smmap==5.0.2 + # via gitdb +sniffio==1.3.1 + # via + # anthropic + # anyio + # groq + # openai +streamlit==1.42.2 + # via -r cookbook/examples/apps/tic_tac_toe/requirements.in +tenacity==9.0.0 + # via streamlit +toml==0.10.2 + # via streamlit +tomli==2.2.1 + # via agno +tornado==6.4.2 + # via streamlit +tqdm==4.67.1 + # via openai +typer==0.15.1 + # via agno +typing-extensions==4.12.2 + # via + # agno + # altair + # anthropic + # anyio + # google-genai + # groq + # openai + # pydantic + # pydantic-core + # referencing + # streamlit + # typer +tzdata==2025.1 + # via pandas +urllib3==2.3.0 + # via requests +websockets==14.2 + # via google-genai +wheel==0.45.1 + # via pip-tools diff --git a/ai_agent_tutorials/ai_tic_tac_toe_game/utils.py b/ai_agent_tutorials/ai_tic_tac_toe_agent/utils.py similarity index 100% rename from ai_agent_tutorials/ai_tic_tac_toe_game/utils.py rename to ai_agent_tutorials/ai_tic_tac_toe_agent/utils.py diff --git a/ai_agent_tutorials/ai_tic_tac_toe_game/README.md b/ai_agent_tutorials/ai_tic_tac_toe_game/README.md deleted file mode 100644 index 7e8681f..0000000 --- a/ai_agent_tutorials/ai_tic_tac_toe_game/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# Agent Tic Tac Toe - -This example shows how to build an interactive Tic Tac Toe game where AI agents compete against each other. The application showcases how to: -- Coordinate multiple AI agents in a turn-based game -- Use different language models for different players -- Create an interactive web interface with Streamlit -- Handle game state and move validation -- Display real-time game progress and move history - -## Features -- Multiple AI models support (GPT-4, Claude, Gemini, etc.) -- Real-time game visualization -- Move history tracking with board states -- Interactive player selection -- Game state management -- Move validation and coordination - -### 1. Create a virtual environment - -```shell -python3 -m venv .venv -source .venv/bin/activate -``` - -### 2. Install dependencies - -```shell -pip install -r ai_agent_tutorials/ai_tic_tac_toe_game/requirements.txt -``` - -### 3. Export API Keys - -The game supports multiple AI models. Export the API keys for the models you want to use: - -```shell -# Required for OpenAI models -export OPENAI_API_KEY=*** - -# Optional - for additional models -export ANTHROPIC_API_KEY=*** # For Claude models -export GOOGLE_API_KEY=*** # For Gemini models -export GROQ_API_KEY=*** # For Groq models -``` - -### 4. Run the Game - -```shell -streamlit run ai_agent_tutorials/ai_tic_tac_toe_game/app.py -``` - -- Open [localhost:8501](http://localhost:8501) to view the game interface - -## How It Works - -The game consists of three agents: - -1. **Master Agent (Referee)** - - Coordinates the game - - Validates moves - - Maintains game state - - Determines game outcome - -2. **Two Player Agents** - - Make strategic moves - - Analyze board state - - Follow game rules - - Respond to opponent moves - -## Available Models - -The game supports various AI models: -- GPT-4o (OpenAI) -- GPT-o3-mini (OpenAI) -- Gemini (Google) -- Llama 3 (Groq) -- Claude (Anthropic) - -## Game Features - -1. **Interactive Board** - - Real-time updates - - Visual move tracking - - Clear game status display - -2. **Move History** - - Detailed move tracking - - Board state visualization - - Player action timeline - -3. **Game Controls** - - Start/Pause game - - Reset board - - Select AI models - - View game history - -4. **Performance Analysis** - - Move timing - - Strategy tracking - - Game statistics - -## Support - -Join our [Discord community](https://agno.link/discord) for help and discussions. diff --git a/ai_agent_tutorials/ai_tic_tac_toe_game/requirements.txt b/ai_agent_tutorials/ai_tic_tac_toe_game/requirements.txt deleted file mode 100644 index c275c18..0000000 --- a/ai_agent_tutorials/ai_tic_tac_toe_game/requirements.txt +++ /dev/null @@ -1,238 +0,0 @@ -# This file was autogenerated by uv via the following command: -# ./generate_requirements.sh -agno==1.1.6 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -altair==5.5.0 - # via streamlit -annotated-types==0.7.0 - # via pydantic -anthropic==0.47.1 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -anyio==4.8.0 - # via - # anthropic - # groq - # httpx - # openai -attrs==25.1.0 - # via - # jsonschema - # referencing -blinker==1.9.0 - # via streamlit -build==1.2.2.post1 - # via pip-tools -cachetools==5.5.2 - # via - # google-auth - # streamlit -certifi==2025.1.31 - # via - # httpcore - # httpx - # requests -charset-normalizer==3.4.1 - # via requests -click==8.1.8 - # via - # pip-tools - # streamlit - # typer -distro==1.9.0 - # via - # anthropic - # groq - # openai -docstring-parser==0.16 - # via agno -gitdb==4.0.12 - # via gitpython -gitpython==3.1.44 - # via - # agno - # streamlit -google-auth==2.38.0 - # via google-genai -google-genai==1.3.0 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -groq==0.18.0 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -h11==0.14.0 - # via httpcore -httpcore==1.0.7 - # via httpx -httpx==0.28.1 - # via - # agno - # anthropic - # google-genai - # groq - # ollama - # openai -idna==3.10 - # via - # anyio - # httpx - # requests -jinja2==3.1.5 - # via - # altair - # pydeck -jiter==0.8.2 - # via - # anthropic - # openai -jsonschema==4.23.0 - # via altair -jsonschema-specifications==2024.10.1 - # via jsonschema -markdown-it-py==3.0.0 - # via rich -markupsafe==3.0.2 - # via jinja2 -mdurl==0.1.2 - # via markdown-it-py -narwhals==1.28.0 - # via altair -nest-asyncio==1.6.0 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -numpy==2.2.3 - # via - # pandas - # pydeck - # streamlit -ollama==0.4.7 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -openai==1.64.0 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -packaging==24.2 - # via - # altair - # build - # streamlit -pandas==2.2.3 - # via streamlit -pathlib==1.0.1 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -pillow==11.1.0 - # via - # -r cookbook/examples/apps/tic_tac_toe/requirements.in - # streamlit -pip==25.0.1 - # via pip-tools -pip-tools==7.4.1 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -protobuf==5.29.3 - # via streamlit -pyarrow==19.0.1 - # via streamlit -pyasn1==0.6.1 - # via - # pyasn1-modules - # rsa -pyasn1-modules==0.4.1 - # via google-auth -pydantic==2.10.6 - # via - # agno - # anthropic - # google-genai - # groq - # ollama - # openai - # pydantic-settings -pydantic-core==2.27.2 - # via pydantic -pydantic-settings==2.8.0 - # via agno -pydeck==0.9.1 - # via streamlit -pygments==2.19.1 - # via rich -pyproject-hooks==1.2.0 - # via - # build - # pip-tools -python-dateutil==2.9.0.post0 - # via pandas -python-dotenv==1.0.1 - # via - # -r cookbook/examples/apps/tic_tac_toe/requirements.in - # agno - # pydantic-settings -python-multipart==0.0.20 - # via agno -pytz==2025.1 - # via pandas -pyyaml==6.0.2 - # via agno -referencing==0.36.2 - # via - # jsonschema - # jsonschema-specifications -requests==2.32.3 - # via - # google-genai - # streamlit -rich==13.9.4 - # via - # -r cookbook/examples/apps/tic_tac_toe/requirements.in - # agno - # streamlit - # typer -rpds-py==0.23.1 - # via - # jsonschema - # referencing -rsa==4.9 - # via google-auth -setuptools==75.8.0 - # via pip-tools -shellingham==1.5.4 - # via typer -six==1.17.0 - # via python-dateutil -smmap==5.0.2 - # via gitdb -sniffio==1.3.1 - # via - # anthropic - # anyio - # groq - # openai -streamlit==1.42.2 - # via -r cookbook/examples/apps/tic_tac_toe/requirements.in -tenacity==9.0.0 - # via streamlit -toml==0.10.2 - # via streamlit -tomli==2.2.1 - # via agno -tornado==6.4.2 - # via streamlit -tqdm==4.67.1 - # via openai -typer==0.15.1 - # via agno -typing-extensions==4.12.2 - # via - # agno - # altair - # anthropic - # anyio - # google-genai - # groq - # openai - # pydantic - # pydantic-core - # referencing - # streamlit - # typer -tzdata==2025.1 - # via pandas -urllib3==2.3.0 - # via requests -websockets==14.2 - # via google-genai -wheel==0.45.1 - # via pip-tools