From 53dfb652bfa5650bc5d3628f9cd731ffa761c93a Mon Sep 17 00:00:00 2001 From: Shubhamsaboo Date: Sun, 3 Aug 2025 18:01:01 -0500 Subject: [PATCH] feat: add AI Real Estate Agent Team and Enterprise MCP AI Agent Team - Introduced a new AI Real Estate Agent Team with multi-agent capabilities for property search, market analysis, and valuation. - Added comprehensive README documentation detailing features, setup instructions, and API requirements. - Implemented the Enterprise MCP AI Agent Team for orchestrating knowledge management across local files and SaaS platforms, including specialized agents for Notion, GitHub, and Figma. - Enhanced the overall architecture with intelligent routing and task delegation using the Model Context Protocol (MCP). - Included necessary requirements for both teams to ensure proper functionality. --- .../ai_real_estate_agent_team}/README.md | 30 +- .../real_estate_agent_team.py} | 490 +++++++++++++----- .../requirements.txt | 2 + .../1_starter_agent/README.md | 33 +- .../.env.example | 0 .../__init__.py | 0 .../creative_writing_agent/agent.py | 26 + .../1_starter_agent/greeting_agent/agent.py | 22 - .../.env.example | 0 .../__init__.py | 0 .../agent.py | 0 .../.env.example | 0 .../__init__.py | 0 .../agent.py | 0 .../2_model_agnostic_agent/README.md | 24 +- .../.env.example | 3 + .../README.md | 187 +++++++ .../5_1_in_memory_conversation_agent/agent.py | 75 +++ .../5_1_in_memory_conversation_agent/app.py | 52 ++ .../requirements.txt | 4 + .../.env.example | 3 + .../README.md | 204 ++++++++ .../agent.py | 86 +++ .../5_2_persistent_conversation_agent/app.py | 63 +++ .../requirements.txt | 5 + .../5_memory_agent/README.md | 190 +++++++ .../google_adk_tutorials/README.md | 27 +- .../enterprise_orchestrator_team/README.md | 24 +- .../enterprise_orchestrator_team/__init__.py | 18 +- .../enterprise_orchestrator_team/agent.py | 36 +- .../requirements.txt | 0 31 files changed, 1345 insertions(+), 259 deletions(-) rename advanced_ai_agents/multi_agent_apps/{ai_multiagent_realtor => agent_teams/ai_real_estate_agent_team}/README.md (85%) rename advanced_ai_agents/multi_agent_apps/{ai_multiagent_realtor/ai_multiagent_realtor.py => agent_teams/ai_real_estate_agent_team/real_estate_agent_team.py} (51%) rename advanced_ai_agents/multi_agent_apps/{ai_multiagent_realtor => agent_teams/ai_real_estate_agent_team}/requirements.txt (71%) rename ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/{greeting_agent => creative_writing_agent}/.env.example (100%) rename ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/{greeting_agent => creative_writing_agent}/__init__.py (100%) create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/agent.py delete mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/agent.py rename ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/{anthropic_adk_agent => 2_1_openai_adk_agent}/.env.example (100%) rename ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/{anthropic_adk_agent => 2_1_openai_adk_agent}/__init__.py (100%) rename ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/{openai_adk_agent => 2_1_openai_adk_agent}/agent.py (100%) rename ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/{openai_adk_agent => 2_2_anthropic_adk_agent}/.env.example (100%) rename ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/{openai_adk_agent => 2_2_anthropic_adk_agent}/__init__.py (100%) rename ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/{anthropic_adk_agent => 2_2_anthropic_adk_agent}/agent.py (100%) create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/.env.example create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/README.md create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/agent.py create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/app.py create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/requirements.txt create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/.env.example create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/README.md create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/agent.py create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/app.py create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/requirements.txt create mode 100644 ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/README.md rename {advanced_ai_agents/multi_agent_apps/agent_teams => mcp_ai_agents}/enterprise_orchestrator_team/README.md (96%) rename {advanced_ai_agents/multi_agent_apps/agent_teams => mcp_ai_agents}/enterprise_orchestrator_team/__init__.py (50%) rename {advanced_ai_agents/multi_agent_apps/agent_teams => mcp_ai_agents}/enterprise_orchestrator_team/agent.py (91%) rename {advanced_ai_agents/multi_agent_apps/agent_teams => mcp_ai_agents}/enterprise_orchestrator_team/requirements.txt (100%) diff --git a/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/README.md b/advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/README.md similarity index 85% rename from advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/README.md rename to advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/README.md index 01fed7d..06bd8e8 100644 --- a/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/README.md +++ b/advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/README.md @@ -1,6 +1,6 @@ -# AI Multi-Agent Real Estate Team 🏠 +# 🏠 AI Real Estate Agent Team -The **AI Multi-Agent Real Estate Team** is a sophisticated property search and analysis platform powered by specialized AI agents with firecrawl's extarct endpoint. This application provides comprehensive real estate insights, market analysis, and property recommendations using advanced web scraping and AI-powered search capabilities. +The **AI Real Estate Agent Team** is a sophisticated property search and analysis platform powered by specialized AI agents with firecrawl's extract endpoint. This application provides comprehensive real estate insights, market analysis, and property recommendations using advanced web scraping and AI-powered search capabilities. ## Features @@ -31,9 +31,9 @@ The **AI Multi-Agent Real Estate Team** is a sophisticated property search and a - **Smart Fallback System**: - Primary: Firecrawl extract endpoint for structured data - - Fallback: Perplexity AI search when extract returns no results + - Fallback: Google Search when extract returns no results - Seamless transition between data sources - - "Rigorously" indicator when using AI-powered search + - Google Search indicator when using web search - **Interactive UI Features**: - Real-time agent progression tracking @@ -48,12 +48,12 @@ Follow the steps below to set up and run the application: ### 1. **Get API Keys**: - **OpenAI API Key**: Get from [OpenAI Platform](https://platform.openai.com/api-keys) - **Firecrawl API Key**: Get from [Firecrawl](https://firecrawl.dev) - - **Perplexity API Key**: Get from [Perplexity AI](https://www.perplexity.ai/settings/api) + - **Google Search**: No API key required - uses Agno's GoogleSearchTools ### 2. **Clone the Repository**: ```bash git clone https://github.com/your-username/awesome-llm-apps.git - cd awesome-llm-apps/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor + cd awesome-llm-apps/advanced_ai_agents/multi_agent_apps/ai_real_estate_agent_team ``` ### 3. **Set Up Environment Variables**: @@ -61,10 +61,8 @@ Follow the steps below to set up and run the application: ``` OPENAI_API_KEY=your_openai_api_key_here FIRECRAWL_API_KEY=your_firecrawl_api_key_here - PERPLEXITY_API_KEY=your_perplexity_api_key_here ``` - - **Note**: Never commit your `.env` file to version control. The `.gitignore` file is already configured to exclude it. + **Google Search is included automatically** - no API key required for fallback search functionality. ### 4. **Install Dependencies**: ```bash @@ -73,7 +71,7 @@ Follow the steps below to set up and run the application: ### 5. **Run the Streamlit App**: ```bash - streamlit run ai_multiagent_realtor.py + streamlit run real_estate_agent_team.py ``` ## Usage Guide @@ -143,8 +141,8 @@ Follow the steps below to set up and run the application: ## File Structure ``` -ai_multiagent_realtor/ -β”œβ”€β”€ ai_multiagent_realtor.py # Main application file +ai_real_estate_agent_team/ +β”œβ”€β”€ real_estate_agent_team.py # Main application file β”œβ”€β”€ requirements.txt # Python dependencies β”œβ”€β”€ README.md # This documentation └── .env # Environment variables (create this) @@ -162,10 +160,10 @@ ai_multiagent_realtor/ - **Usage**: Property listing extraction from real estate websites - **Rate Limits**: Firecrawl standard rate limits -### **Perplexity API** -- **Model**: Sonar Pro -- **Usage**: AI-powered property search fallback -- **Rate Limits**: Perplexity standard rate limits +### **Google Search** +- **Tool**: Agno GoogleSearchTools +- **Usage**: Web search for property listings fallback +- **Rate Limits**: Google Search standard rate limits ## Troubleshooting diff --git a/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/ai_multiagent_realtor.py b/advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/real_estate_agent_team.py similarity index 51% rename from advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/ai_multiagent_realtor.py rename to advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/real_estate_agent_team.py index f48d20a..cda7d44 100644 --- a/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/ai_multiagent_realtor.py +++ b/advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/real_estate_agent_team.py @@ -6,6 +6,7 @@ import requests from agno.agent import Agent from agno.team import Team from agno.models.openai import OpenAIChat +from agno.tools.googlesearch import GoogleSearchTools from dotenv import load_dotenv from firecrawl import FirecrawlApp from pydantic import BaseModel, Field @@ -17,7 +18,6 @@ load_dotenv() # API keys - must be set in environment variables DEFAULT_OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "") DEFAULT_FIRECRAWL_API_KEY = os.getenv("FIRECRAWL_API_KEY", "") -DEFAULT_PERPLEXITY_API_KEY = os.getenv("PERPLEXITY_API_KEY", "") # Pydantic schemas class PropertyDetails(BaseModel): @@ -78,39 +78,33 @@ def extract_property_listings(url, user_criteria=None): except Exception as e: return {"error": f"Failed to extract listings: {str(e)}"} -def search_perplexity_properties(city, state, user_criteria): - """Search for properties using Perplexity API""" +def search_google_properties(city, state, user_criteria): + """Search for properties using Google Search""" try: - api_key = os.getenv("PERPLEXITY_API_KEY", DEFAULT_PERPLEXITY_API_KEY) - + # Create Google Search query search_query = f""" - Find real estate properties for sale in {city}, {state} matching: - - Budget: {user_criteria.get('budget_range', 'Any')} - - Type: {user_criteria.get('property_type', 'Any')} - - Bedrooms: {user_criteria.get('bedrooms', 'Any')} - - Bathrooms: {user_criteria.get('bathrooms', 'Any')} - - Min Sqft: {user_criteria.get('min_sqft', 'Any')} - - Features: {user_criteria.get('special_features', 'Any')} - - Search: Zillow, Realtor.com, Trulia, Homes.com, Redfin - Provide: detailed property info, market insights, neighborhood analysis - Include: specific addresses, prices, features, listing URLs, market trends + Find real estate properties for sale {city} {state} + budget {user_criteria.get('budget_range', '')} + {user_criteria.get('property_type', '')} + {user_criteria.get('bedrooms', '')} bedrooms + {user_criteria.get('bathrooms', '')} bathrooms + {user_criteria.get('min_sqft', '')} sqft + {user_criteria.get('special_features', '')} + site:zillow.com OR site:realtor.com OR site:trulia.com OR site:homes.com OR site:redfin.com """ - response = requests.post( - 'https://api.perplexity.ai/chat/completions', - headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}, - json={'model': 'sonar-pro', 'messages': [{'role': 'user', 'content': search_query}]} + # Use GoogleSearchTools to perform the search + google_search = GoogleSearchTools() + search_results = google_search.google_search( + query=search_query, + max_results=10, + language="en" ) - if response.status_code == 200: - content = response.json()['choices'][0]['message']['content'] - return {"success": True, "content": content, "source": "Perplexity Search"} - else: - return {"error": f"Perplexity API error: {response.status_code}"} + return {"success": True, "content": search_results, "source": "Google Search"} except Exception as e: - return {"error": f"Perplexity search failed: {str(e)}"} + return {"error": f"Google search failed: {str(e)}"} def search_real_estate_websites(city, state, user_criteria, selected_websites, update_callback): """Search real estate websites""" @@ -132,24 +126,24 @@ def search_real_estate_websites(city, state, user_criteria, selected_websites, u for i, (site_name, search_url) in enumerate(search_urls.items()): try: progress = 0.2 + (i * 0.6 / len(search_urls)) - update_callback(progress, f"Searching {site_name}...", f"Analyzing {site_name}") + update_callback(progress, f"Searching {site_name}...", f"πŸ” Analyzing {site_name}...") if i > 0: - time.sleep(2) + time.sleep(1.5) # Reduced delay for better UX result = extract_property_listings(search_url, user_criteria) if "error" not in result and len(result.get('properties', [])) > 0: results[site_name] = result property_count = len(result.get('properties', [])) - update_callback(progress + 0.3, f"Found {property_count} properties on {site_name}", f"Successfully analyzed {site_name}") + update_callback(progress + 0.3, f"Found {property_count} properties on {site_name}", f"βœ… Successfully analyzed {site_name} ({property_count} properties)") else: results[site_name] = {"error": f"No data from {site_name}"} - update_callback(progress + 0.3, f"Analyzing {site_name}", f"Gathering insights from {site_name}") + update_callback(progress + 0.3, f"Analyzing {site_name}", f"⚠️ No properties found on {site_name}") except Exception as e: results[site_name] = {"error": f"Error: {str(e)}"} - update_callback(progress + 0.3, f"Analyzing {site_name}", f"Processing {site_name}") + update_callback(progress + 0.3, f"Analyzing {site_name}", f"❌ Error processing {site_name}") return results @@ -160,11 +154,14 @@ def create_firecrawl_tools(user_criteria): result = extract_property_listings(url, user_criteria) return json.dumps(result, indent=2) if "error" not in result else f"Error: {result['error']}" - def perplexity_search_tool(city: str, state: str) -> str: - result = search_perplexity_properties(city, state, user_criteria) + def google_search_tool(city: str, state: str) -> str: + result = search_google_properties(city, state, user_criteria) return json.dumps(result, indent=2) if "error" not in result else f"Error: {result['error']}" - return [extract_listings_tool, perplexity_search_tool] + # Include both Firecrawl extract and Google Search tools + tools = [extract_listings_tool, google_search_tool] + + return tools def create_real_estate_agents(llm, firecrawl_tools, user_criteria): """Create specialized agents""" @@ -179,7 +176,7 @@ def create_real_estate_agents(llm, firecrawl_tools, user_criteria): 1. SEARCH FOR PROPERTIES: - Use Firecrawl extract tools to search real estate websites - Focus on properties matching user criteria - - Use Perplexity search tool if no properties found + - Use Google Search tool if extract methods don't find properties 2. GATHER PROPERTY DATA: - Extract detailed property information @@ -191,7 +188,8 @@ def create_real_estate_agents(llm, firecrawl_tools, user_criteria): - Include clickable listing URLs - Rank by match quality - IMPORTANT: Always use perplexity_search_tool if extract methods don't find properties. + IMPORTANT: Use google_search_tool if extract methods don't find properties. + Google Search will find relevant real estate listings from Zillow, Realtor.com, Trulia, Homes.com, and Redfin. Focus on finding properties that match user's exact criteria. """, ) @@ -282,13 +280,13 @@ def create_real_estate_team(llm, firecrawl_tools, user_criteria): property_search_agent, market_analysis_agent, property_valuation_agent = create_real_estate_agents(llm, firecrawl_tools, user_criteria) return Team( - name="Real Estate Analysis Team", + name="🏠 AI Real Estate Agent Team", mode="coordinate", model=llm, members=[property_search_agent, market_analysis_agent, property_valuation_agent], instructions=[ - "You are a professional real estate analysis team.", - "1. Property Search Agent: Find properties using extract + Perplexity fallback", + "You are a professional AI Real Estate Agent Team.", + "1. Property Search Agent: Find properties using extract + Google Search fallback", "2. Market Analysis Agent: Provide ELABORATE market trends and neighborhood insights", "3. Property Valuation Agent: Give ELABORATE property valuations and investment analysis", "IMPORTANT: Provide detailed, actionable insights with specific data points.", @@ -301,8 +299,11 @@ def create_real_estate_team(llm, firecrawl_tools, user_criteria): def display_property_results(result): """Display property results with clickable links""" - st.markdown("## Property Analysis Report") - st.markdown("### AI-Powered Real Estate Recommendations") + st.markdown(""" +
+

πŸ€– AI-Powered Real Estate Recommendations

+
+ """, unsafe_allow_html=True) if hasattr(result, 'content'): result_text = result.content @@ -310,7 +311,7 @@ def display_property_results(result): result_text = str(result) # Display the full text result with markdown support for links - st.markdown("### Analysis Report") + st.markdown("### πŸ“‹ Analysis Report") st.markdown(result_text) # Extract and display clickable links @@ -318,92 +319,277 @@ def display_property_results(result): urls = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', result_text) if urls: - st.markdown("### πŸ”— Property Links") + st.markdown(""" +
+

πŸ”— Property Links

+ """, unsafe_allow_html=True) + for i, url in enumerate(set(urls), 1): - st.markdown(f"{i}. [{url}]({url})") + st.markdown(f""" +
+ + {i}. {url} + +
+ """, unsafe_allow_html=True) + + st.markdown("
", unsafe_allow_html=True) def main(): - st.set_page_config(page_title="AI Multi-Agent Real Estate Team", page_icon="🏠", layout="wide") + st.set_page_config( + page_title="AI Real Estate Agent Team", + page_icon="🏠", + layout="wide", + initial_sidebar_state="expanded" + ) - st.title("AI Multi-Agent Real Estate Team") - st.markdown("### Find Your Dream Home with Specialized AI Agents") + # Custom CSS for better styling + st.markdown(""" + + """, unsafe_allow_html=True) + + # Beautiful header + st.markdown(""" +
+

🏠 AI Real Estate Agent Team

+

Find Your Dream Home with Specialized AI Agents

+
+ """, unsafe_allow_html=True) # Sidebar configuration with st.sidebar: - st.header("Configuration") + st.markdown(""" +
+

βš™οΈ Configuration

+
+ """, unsafe_allow_html=True) # API Key inputs with validation - openai_key = st.text_input("OpenAI API Key", value=DEFAULT_OPENAI_API_KEY, type="password", - help="Get your API key from https://platform.openai.com/api-keys") - firecrawl_key = st.text_input("Firecrawl API Key", value=DEFAULT_FIRECRAWL_API_KEY, type="password", - help="Get your API key from https://firecrawl.dev") - perplexity_key = st.text_input("Perplexity API Key", value=DEFAULT_PERPLEXITY_API_KEY, type="password", - help="Get your API key from https://www.perplexity.ai/settings/api") - - # Show API key status - if openai_key: - st.success("βœ… OpenAI API Key provided") - else: - st.error("❌ OpenAI API Key required") + with st.expander("πŸ”‘ API Keys", expanded=True): + openai_key = st.text_input( + "OpenAI API Key", + value=DEFAULT_OPENAI_API_KEY, + type="password", + help="Get your API key from https://platform.openai.com/api-keys", + placeholder="sk-..." + ) + firecrawl_key = st.text_input( + "Firecrawl API Key", + value=DEFAULT_FIRECRAWL_API_KEY, + type="password", + help="Get your API key from https://firecrawl.dev", + placeholder="fc_..." + ) - if firecrawl_key: - st.success("βœ… Firecrawl API Key provided") - else: - st.error("❌ Firecrawl API Key required") - - if perplexity_key: - st.success("βœ… Perplexity API Key provided") - else: - st.error("❌ Perplexity API Key required") - - # Update environment variables - if openai_key: os.environ["OPENAI_API_KEY"] = openai_key - if firecrawl_key: os.environ["FIRECRAWL_API_KEY"] = firecrawl_key - if perplexity_key: os.environ["PERPLEXITY_API_KEY"] = perplexity_key - - st.markdown("---") + # Update environment variables + if openai_key: os.environ["OPENAI_API_KEY"] = openai_key + if firecrawl_key: os.environ["FIRECRAWL_API_KEY"] = firecrawl_key # Website selection - st.subheader("Select Websites to Search") - available_websites = ["Zillow", "Realtor.com", "Trulia", "Homes.com"] - selected_websites = [site for site in available_websites if st.checkbox(site, value=site in ["Zillow", "Realtor.com"])] + with st.expander("🌐 Search Sources", expanded=True): + st.markdown("**Select real estate websites to search:**") + available_websites = ["Zillow", "Realtor.com", "Trulia", "Homes.com"] + selected_websites = [site for site in available_websites if st.checkbox(site, value=site in ["Zillow", "Realtor.com"])] + + if selected_websites: + st.markdown(f'
βœ… {len(selected_websites)} sources selected
', unsafe_allow_html=True) + else: + st.markdown('
⚠️ Please select at least one website
', unsafe_allow_html=True) - if selected_websites: - st.success(f"Selected: {', '.join(selected_websites)}") - else: - st.warning("Please select at least one website") - - st.markdown("---") - st.markdown("### How it works") - st.markdown(""" - 1. **Property Search Agent** - Uses extract + Perplexity fallback - 2. **Market Analysis Agent** - Analyzes trends and neighborhood insights - 3. **Property Valuation Agent** - Evaluates values and investment potential - """) + # How it works + with st.expander("πŸ€– How It Works", expanded=False): + st.markdown(""" +
+

πŸ” Property Search Agent

+

Uses extract + Google Search fallback

+
+
+

πŸ“Š Market Analysis Agent

+

Analyzes trends and neighborhood insights

+
+
+

πŸ’° Property Valuation Agent

+

Evaluates values and investment potential

+
+ """, unsafe_allow_html=True) # Main form - st.header("Your Property Requirements") + st.markdown(""" +
+

🏠 Your Property Requirements

+ """, unsafe_allow_html=True) with st.form("property_preferences"): + # Location and Budget Section + st.markdown("### πŸ“ Location & Budget") col1, col2 = st.columns(2) with col1: - city = st.text_input("City", placeholder="e.g., San Francisco") - state = st.text_input("State/Province (optional)", placeholder="e.g., CA") - min_price = st.number_input("Minimum Price ($)", min_value=0, value=500000, step=50000) - max_price = st.number_input("Maximum Price ($)", min_value=0, value=1500000, step=50000) + city = st.text_input( + "πŸ™οΈ City", + placeholder="e.g., San Francisco", + help="Enter the city where you want to buy property" + ) + state = st.text_input( + "πŸ—ΊοΈ State/Province (optional)", + placeholder="e.g., CA", + help="Enter the state or province (optional)" + ) with col2: - property_type = st.selectbox("Property Type", ["Any", "House", "Condo", "Townhouse", "Apartment"]) - bedrooms = st.selectbox("Bedrooms", ["Any", "1", "2", "3", "4", "5+"]) - bathrooms = st.selectbox("Bathrooms", ["Any", "1", "1.5", "2", "2.5", "3", "3.5", "4+"]) - min_sqft = st.number_input("Minimum Square Feet", min_value=0, value=1000, step=100) + min_price = st.number_input( + "πŸ’° Minimum Price ($)", + min_value=0, + value=500000, + step=50000, + help="Your minimum budget for the property" + ) + max_price = st.number_input( + "πŸ’° Maximum Price ($)", + min_value=0, + value=1500000, + step=50000, + help="Your maximum budget for the property" + ) - special_features = st.text_area("Special Features", placeholder="e.g., Parking, Yard, View, Near public transport, etc.") - timeline = st.selectbox("Timeline", ["Flexible", "1-3 months", "3-6 months", "6+ months"]) - urgency = st.selectbox("Urgency", ["Not urgent", "Somewhat urgent", "Very urgent"]) + # Property Details Section + st.markdown("### 🏑 Property Details") + col1, col2, col3 = st.columns(3) - submitted = st.form_submit_button("Start Property Analysis", type="primary") + with col1: + property_type = st.selectbox( + "🏠 Property Type", + ["Any", "House", "Condo", "Townhouse", "Apartment"], + help="Type of property you're looking for" + ) + bedrooms = st.selectbox( + "πŸ›οΈ Bedrooms", + ["Any", "1", "2", "3", "4", "5+"], + help="Number of bedrooms required" + ) + + with col2: + bathrooms = st.selectbox( + "🚿 Bathrooms", + ["Any", "1", "1.5", "2", "2.5", "3", "3.5", "4+"], + help="Number of bathrooms required" + ) + min_sqft = st.number_input( + "πŸ“ Minimum Square Feet", + min_value=0, + value=1000, + step=100, + help="Minimum square footage required" + ) + + with col3: + timeline = st.selectbox( + "⏰ Timeline", + ["Flexible", "1-3 months", "3-6 months", "6+ months"], + help="When do you plan to buy?" + ) + urgency = st.selectbox( + "🚨 Urgency", + ["Not urgent", "Somewhat urgent", "Very urgent"], + help="How urgent is your purchase?" + ) + + # Special Features + st.markdown("### ✨ Special Features") + special_features = st.text_area( + "🎯 Special Features & Requirements", + placeholder="e.g., Parking, Yard, View, Near public transport, Good schools, Walkable neighborhood, etc.", + help="Any specific features or requirements you're looking for" + ) + + # Submit button with custom styling + col1, col2, col3 = st.columns([1, 2, 1]) + with col2: + submitted = st.form_submit_button( + "πŸš€ Start Property Analysis", + type="primary", + use_container_width=True + ) + + st.markdown("
", unsafe_allow_html=True) # Process form submission if submitted: @@ -413,15 +599,17 @@ def main(): missing_items.append("OpenAI API Key") if not firecrawl_key: missing_items.append("Firecrawl API Key") - if not perplexity_key: - missing_items.append("Perplexity API Key") if not city: missing_items.append("City") if not selected_websites: missing_items.append("At least one website selection") if missing_items: - st.error(f"Please provide: {', '.join(missing_items)}") + st.markdown(f""" +
+ ⚠️ Please provide: {', '.join(missing_items)} +
+ """, unsafe_allow_html=True) return try: @@ -441,20 +629,33 @@ def main(): real_estate_team = create_real_estate_team(llm, firecrawl_tools, user_criteria) except Exception as e: - st.error(f"Error initializing: {str(e)}") + st.markdown(f""" +
+ ❌ Error initializing: {str(e)} +
+ """, unsafe_allow_html=True) return # Display progress - st.markdown("---") - st.header("Property Analysis in Progress") + st.markdown(""" +
+

πŸš€ Property Analysis in Progress

+
+
πŸ”
+
AI Agents are working together to find your perfect home
+
+
+ """, unsafe_allow_html=True) status_container = st.container() with status_container: - st.subheader("Current Activity") + st.markdown("### πŸ“Š Current Activity") + progress_bar = st.progress(0) current_activity = st.empty() def update_progress(progress, status, activity=None): if activity: + progress_bar.progress(progress) current_activity.text(activity) try: @@ -469,10 +670,10 @@ def main(): # Process results successful_searches = sum(1 for result in search_results.values() if "error" not in result) total_properties = sum(len(result.get('properties', [])) for result in search_results.values() if "error" not in result) - use_perplexity_fallback = total_properties == 0 + use_google_fallback = total_properties == 0 - if use_perplexity_fallback: - update_progress(0.85, "Running analysis...", "πŸ” Searching rigorously across real estate platforms...") + if use_google_fallback: + update_progress(0.85, "Running analysis...", "πŸ” Searching Google for real estate listings...") else: update_progress(0.85, "Running analysis...", "Property Search Agent: Analyzing search results") @@ -506,50 +707,71 @@ def main(): Include relevant links and sources when possible. """ - # Show agent progression + # Show agent progression with better messaging agent_messages = [ - "Property Search Agent: Processing property data", - "Market Analysis Agent: Analyzing market trends", - "Property Valuation Agent: Evaluating property values" + "πŸ” Property Search Agent: Processing property data and listings", + "πŸ“Š Market Analysis Agent: Analyzing market trends and neighborhood insights", + "πŸ’° Property Valuation Agent: Evaluating property values and investment potential" ] for i, message in enumerate(agent_messages): progress = 0.87 + (i * 0.03) update_progress(progress, "Analysis in progress...", message) - time.sleep(1) + time.sleep(1.5) # Slightly longer for better UX - # Execute agents - if use_perplexity_fallback: - with st.spinner("πŸ” Searching rigorously across real estate platforms..."): + # Execute agents with better UX + if use_google_fallback: + with st.spinner("πŸ” Searching Google for real estate listings..."): result = real_estate_team.run(prompt) else: - result = real_estate_team.run(prompt) + with st.spinner("πŸ€– AI Agents are analyzing your property requirements..."): + result = real_estate_team.run(prompt) agent_duration = time.time() - agent_start total_time = time.time() - start_time # Display results - st.markdown("---") + st.markdown(""" +
+

πŸŽ‰ Analysis Complete!

+ """, unsafe_allow_html=True) display_property_results(result) + st.markdown("
", unsafe_allow_html=True) - # Download button + # Download button with better styling if hasattr(result, 'content'): download_content = result.content else: download_content = str(result) - st.download_button( - label="Download Report", - data=download_content, - file_name="property_analysis_report.md", - mime="text/markdown" - ) + col1, col2, col3 = st.columns([1, 2, 1]) + with col2: + st.download_button( + label="πŸ“„ Download Full Report", + data=download_content, + file_name="property_analysis_report.md", + mime="text/markdown", + use_container_width=True + ) - # Timing info - st.info(f"⏱️ Total time: {total_time:.2f}s | Search: {search_duration:.2f}s | Agents: {agent_duration:.2f}s") + # Timing info with better styling + st.markdown(f""" +
+

⏱️ Performance Metrics

+

+ Total: {total_time:.2f}s | + Search: {search_duration:.2f}s | + AI Analysis: {agent_duration:.2f}s +

+
+ """, unsafe_allow_html=True) except Exception as e: - st.error(f"An error occurred: {str(e)}") + st.markdown(f""" +
+ ❌ An error occurred: {str(e)} +
+ """, unsafe_allow_html=True) if __name__ == "__main__": main() \ No newline at end of file diff --git a/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/requirements.txt b/advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/requirements.txt similarity index 71% rename from advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/requirements.txt rename to advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/requirements.txt index 3b30c71..4e1c53b 100644 --- a/advanced_ai_agents/multi_agent_apps/ai_multiagent_realtor/requirements.txt +++ b/advanced_ai_agents/multi_agent_apps/agent_teams/ai_real_estate_agent_team/requirements.txt @@ -5,3 +5,5 @@ firecrawl-py>=0.1.0 pydantic>=2.0.0 python-dotenv>=1.0.0 requests>=2.31.0 +googlesearch-python>=1.2.3 +pycountry>=23.12.11 diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/README.md b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/README.md index e022001..02cf490 100644 --- a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/README.md +++ b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/README.md @@ -40,9 +40,10 @@ from google.adk.agents import LlmAgent ## πŸš€ Tutorial Overview -In this tutorial, we'll create a **Simple Greeting Agent** that: -- Takes user input (name, mood, etc.) -- Generates personalized greetings +In this tutorial, we'll create a **Creative Writing Agent** that: +- Helps users develop story ideas and characters +- Provides writing prompts and inspiration +- Assists with plot structure and pacing - Demonstrates basic ADK functionality ## πŸ“ Project Structure @@ -51,10 +52,9 @@ In this tutorial, we'll create a **Simple Greeting Agent** that: 1_starter_agent/ β”œβ”€β”€ README.md # This file - concept explanation β”œβ”€β”€ requirements.txt # Dependencies -└── greeting_agent/ # Agent implementation +└── creative_writing_agent/ # Agent implementation β”œβ”€β”€ __init__.py # Makes it a Python package - β”œβ”€β”€ agent.py # Main agent code - └── env.example # Environment variables template + └── agent.py # Main agent code ``` ## 🎯 Learning Objectives @@ -69,36 +69,29 @@ By the end of this tutorial, you'll understand: 1. **Set up your environment**: ```bash - cd greeting_agent - - # Copy the environment template - cp env.example .env - - # Edit .env and add your Google AI API key + # Make sure you have your Google AI API key # Get your API key from: https://aistudio.google.com/ ``` 2. **Install dependencies**: ```bash - # Navigate back to the 1_starter_agent directory - cd .. - # Install required packages pip install -r requirements.txt ``` -3. **Run the greeting agent**: +3. **Run the creative writing agent**: ```bash # Start the ADK web interface adk web - # In the web interface, select: greeting_agent + # In the web interface, select: creative_writing_agent ``` 4. **Test your agent**: - - Try different greetings: "Hello, I'm John and I'm feeling great today!" - - Experiment with different moods and names - - See how the agent personalizes responses + - Try asking for story ideas: "I want to write a story about a magical forest" + - Get character help: "Help me create a protagonist for my sci-fi story" + - Request writing prompts: "Give me a creative writing prompt" + - Ask for plot advice: "How can I structure my story's climax?" ## πŸ”— Next Steps diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/.env.example b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/.env.example similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/.env.example rename to ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/.env.example diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/__init__.py b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/__init__.py similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/__init__.py rename to ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/__init__.py diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/agent.py b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/agent.py new file mode 100644 index 0000000..1cd52ca --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/creative_writing_agent/agent.py @@ -0,0 +1,26 @@ +from google.adk.agents import LlmAgent + +# Create a creative writing agent +root_agent = LlmAgent( + name="creative_writing_agent", + model="gemini-2.5-flash", + description="A creative writing assistant that helps with stories, poems, and creative content", + instruction=""" + You are a creative writing assistant. + + Your role is to: + - Help users develop story ideas + - Assist with character development + - Provide writing prompts and inspiration + - Help with plot structure and pacing + - Offer feedback on creative writing + + When users want to write creatively: + - Ask engaging questions to develop ideas + - Suggest creative elements and themes + - Help structure stories and narratives + - Provide constructive feedback + + Keep responses creative, inspiring, and supportive of artistic expression. + """ +) \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/agent.py b/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/agent.py deleted file mode 100644 index 7b11f33..0000000 --- a/ai_agent_framework_crash_course/google_adk_tutorials/1_starter_agent/greeting_agent/agent.py +++ /dev/null @@ -1,22 +0,0 @@ -from google.adk.agents import LlmAgent - -# Create a simple greeting agent -root_agent = LlmAgent( - name="greeting_agent", - model="gemini-2.0-flash", - description="A friendly agent that creates personalized greetings", - instruction=""" - You are a friendly greeting assistant. - - When users provide information about themselves (name, mood, occasion, etc.), - create warm, personalized greetings that make them feel welcome. - - Be creative and consider: - - Their name (if provided) - - Their current mood or situation - - The time of day or occasion - - Adding a touch of humor or positivity - - Keep responses friendly, concise, and personalized to the user's input. - """ -) \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/anthropic_adk_agent/.env.example b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_1_openai_adk_agent/.env.example similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/anthropic_adk_agent/.env.example rename to ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_1_openai_adk_agent/.env.example diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/anthropic_adk_agent/__init__.py b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_1_openai_adk_agent/__init__.py similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/anthropic_adk_agent/__init__.py rename to ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_1_openai_adk_agent/__init__.py diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/openai_adk_agent/agent.py b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_1_openai_adk_agent/agent.py similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/openai_adk_agent/agent.py rename to ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_1_openai_adk_agent/agent.py diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/openai_adk_agent/.env.example b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_2_anthropic_adk_agent/.env.example similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/openai_adk_agent/.env.example rename to ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_2_anthropic_adk_agent/.env.example diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/openai_adk_agent/__init__.py b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_2_anthropic_adk_agent/__init__.py similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/openai_adk_agent/__init__.py rename to ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_2_anthropic_adk_agent/__init__.py diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/anthropic_adk_agent/agent.py b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_2_anthropic_adk_agent/agent.py similarity index 100% rename from ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/anthropic_adk_agent/agent.py rename to ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/2_2_anthropic_adk_agent/agent.py diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/README.md b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/README.md index 2db4bb4..8cec95e 100644 --- a/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/README.md +++ b/ai_agent_framework_crash_course/google_adk_tutorials/2_model_agnostic_agent/README.md @@ -21,22 +21,22 @@ Learn how to create agents that work with **different AI models** using OpenRout ``` 2_model_agnostic_agent/ -β”œβ”€β”€ README.md # This overview -β”œβ”€β”€ requirements.txt # Shared dependencies -β”œβ”€β”€ openai_adk_agent/ # OpenAI GPT-4 agent -β”‚ └── agent.py # Agent implementation -└── anthropic_adk_agent/ # Anthropic Claude agent - └── agent.py # Agent implementation +β”œβ”€β”€ README.md # This overview +β”œβ”€β”€ requirements.txt # Shared dependencies +β”œβ”€β”€ 2_1_openai_adk_agent/ # OpenAI GPT-4 agent +β”‚ └── agent.py # Agent implementation +└── 2_2_anthropic_adk_agent/ # Anthropic Claude agent + └── agent.py # Agent implementation ``` ## πŸ”§ Available Agents -### **OpenAI Agent** (`openai_adk_agent/`) +### **OpenAI Agent** (`2_1_openai_adk_agent/`) - **Model**: GPT-4 via OpenRouter - **Agent Name**: `root_agent` (required by ADK) - **Features**: Fun fact tool with OpenAI personality -### **Anthropic Agent** (`anthropic_adk_agent/`) +### **Anthropic Agent** (`2_2_anthropic_adk_agent/`) - **Model**: Claude 4 Sonnet via OpenRouter - **Agent Name**: `root_agent` (required by ADK) - **Features**: Fun fact tool with Claude personality @@ -50,12 +50,12 @@ Learn how to create agents that work with **different AI models** using OpenRout ### 2. **Set Environment Variable** Create a `.env` file in each agent folder: -**In `openai_adk_agent/.env`:** +**In `2_1_openai_adk_agent/.env`:** ```bash OPENROUTER_API_KEY=your_openrouter_api_key_here ``` -**In `anthropic_adk_agent/.env`:** +**In `2_2_anthropic_adk_agent/.env`:** ```bash OPENROUTER_API_KEY=your_openrouter_api_key_here ``` @@ -68,7 +68,7 @@ pip install -r requirements.txt ### 4. **Test OpenAI Agent** ```bash -cd openai_adk_agent +cd 2_1_openai_adk_agent adk web ``` - Try asking: "Tell me a fun fact!" @@ -76,7 +76,7 @@ adk web ### 5. **Test Anthropic Agent** ```bash -cd anthropic_adk_agent +cd 2_2_anthropic_adk_agent adk web ``` - Try asking: "Tell me a fun fact!" diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/.env.example b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/.env.example new file mode 100644 index 0000000..f5cfcfb --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/.env.example @@ -0,0 +1,3 @@ +# If using Gemini via Google AI Studio +GOOGLE_GENAI_USE_VERTEXAI=False +GOOGLE_API_KEY="your-api-key" \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/README.md b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/README.md new file mode 100644 index 0000000..47a7766 --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/README.md @@ -0,0 +1,187 @@ +# 🧠 Tutorial 5.1: In-Memory Conversation Agent + +Welcome to your first step into session management! This tutorial teaches you how to create an AI agent that can remember conversations within a single session using `InMemorySessionService`. + +## 🎯 What You'll Learn + +- **InMemorySessionService**: Basic session management for temporary conversations +- **Session Creation**: How to create and manage conversation sessions +- **State Management**: Storing and retrieving conversation context +- **Event Tracking**: Recording conversation history +- **Multi-turn Conversations**: Building agents that remember context + +## 🧠 Core Concept: In-Memory Sessions + +**InMemorySessionService** stores session data in your computer's RAM (memory). This means: +- βœ… **Fast access** - No database queries needed +- βœ… **Simple setup** - No external dependencies +- ❌ **Temporary storage** - Data is lost when the program stops +- ❌ **No persistence** - Can't remember across program restarts + +Perfect for: +- Development and testing +- Temporary conversations +- Prototyping memory features +- Single-session applications + +## πŸ”§ Key Components + +### 1. **InMemorySessionService** +```python +from google.adk.sessions import InMemorySessionService +``` + +### 2. **Session Lifecycle** +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CREATE │───▢│ USE │───▢│ CLOSE β”‚ +β”‚ SESSION β”‚ β”‚ SESSION β”‚ β”‚ SESSION β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### 3. **Session Data Structure** +```python +{ + "session_id": "unique_session_id", + "user_id": "user_identifier", + "state": { + "conversation_history": [...], + "user_preferences": {...}, + "current_context": "..." + }, + "events": [ + {"type": "user_input", "content": "...", "timestamp": "..."}, + {"type": "agent_response", "content": "...", "timestamp": "..."} + ] +} +``` + +## πŸš€ Tutorial Overview + +In this tutorial, we'll create a **Personal Assistant Agent** that: +- Remembers your name and preferences +- Tracks conversation history +- Provides personalized responses +- Demonstrates basic session management + +## πŸ“ Project Structure + +``` +5_1_in_memory_conversation/ +β”œβ”€β”€ README.md # This file - concept explanation +β”œβ”€β”€ requirements.txt # Dependencies +β”œβ”€β”€ agent.py # Main agent with session management +└── app.py # Streamlit web interface +``` + +## 🎯 Learning Objectives + +By the end of this tutorial, you'll understand: +- βœ… How to create and manage sessions +- βœ… How to store and retrieve conversation state +- βœ… How to track conversation events +- βœ… How to build multi-turn conversations +- βœ… Basic session lifecycle management + +## πŸš€ Getting Started + +1. **Install dependencies**: + ```bash + pip install -r requirements.txt + ``` + +2. **Set up your environment**: + ```bash + # Create a .env file with your Google AI API key + echo "GOOGLE_API_KEY=your_api_key_here" > .env + ``` + +3. **Run the agent**: + ```bash + # Start the Streamlit app + streamlit run app.py + ``` + +4. **Test the memory**: + - Tell the agent your name: "My name is John" + - Ask about your preferences: "What do you know about me?" + - Have a conversation and see how it remembers context + +## πŸ” Code Walkthrough + +### Key Session Management Code: + +```python +# 1. Create session service +session_service = InMemorySessionService() + +# 2. Create a new session +session = await session_service.create_session( + app_name="personal_assistant", + user_id="user123" +) + +# 3. Update session state +await session_service.update_session_state( + session_id=session.session_id, + state={"user_name": "John", "preferences": ["travel", "music"]} +) + +# 4. Add events to track conversation +await session_service.add_event( + session_id=session.session_id, + event_type="user_input", + content="My name is John" +) +``` + +## 🎯 Testing Your Agent + +Try these conversation flows to test memory: + +### Flow 1: Personal Information +``` +User: "My name is Alice" +Agent: "Nice to meet you, Alice! How can I help you today?" + +User: "What's my name?" +Agent: "Your name is Alice! I remember you told me that." +``` + +### Flow 2: Preferences +``` +User: "I love pizza and hiking" +Agent: "Great! I'll remember that you love pizza and hiking." + +User: "What are my interests?" +Agent: "Based on our conversation, you love pizza and hiking!" +``` + +### Flow 3: Context Continuity +``` +User: "I'm planning a trip" +Agent: "That sounds exciting! Since you mentioned hiking, would you like recommendations for hiking destinations?" + +User: "Yes, where should I go?" +Agent: "Given your love for hiking, I'd recommend..." +``` + +## πŸ”— Next Steps + +After completing this tutorial, you'll be ready for: +- **[Tutorial 5.2: Persistent Conversation](../5_2_persistent_conversation/README.md)** - Learn database-based session storage +- **[Tutorial 5.3: Cloud Memory](../5_3_cloud_memory/README.md)** - Explore cloud-based memory solutions + +## πŸ’‘ Pro Tips + +- **Test Multi-turn Conversations**: Have extended conversations to see memory in action +- **Monitor Session State**: Use the web interface to inspect what the agent remembers +- **Experiment with State**: Try storing different types of data in the session state +- **Understand Limitations**: Remember that in-memory sessions are temporary + +## 🚨 Important Notes + +- **Data Loss**: In-memory sessions are lost when you restart the application +- **Single Process**: Sessions only work within the same Python process +- **Memory Usage**: Large conversation histories will consume RAM +- **Development Only**: Use in-memory sessions for development, not production \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/agent.py b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/agent.py new file mode 100644 index 0000000..01ecc30 --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/agent.py @@ -0,0 +1,75 @@ +import asyncio +import os +import uuid +from google.adk.agents import LlmAgent +from google.adk.sessions import InMemorySessionService +from google.adk.runners import Runner +from google.genai import types +from dotenv import load_dotenv + +# Load environment variables (for API key) +load_dotenv() + +# Create session service and agent +session_service = InMemorySessionService() +agent = LlmAgent( + name="memory_agent", + model="gemini-2.5-flash", + description="A simple agent that remembers conversations", + instruction="You are a helpful assistant. Remember what users tell you and reference it in future conversations." +) + +# Create runner with session service +runner = Runner( + agent=agent, + app_name="demo", + session_service=session_service +) + +async def chat(user_id: str, message: str) -> str: + """Simple chat function with memory using Runner""" + session_id = f"session_{user_id}" + + # Create or get session + session = await session_service.get_session(app_name="demo", user_id=user_id, session_id=session_id) + if not session: + # Create new session with initial state + session = await session_service.create_session( + app_name="demo", + user_id=user_id, + session_id=session_id, + state={"conversation_history": []} + ) + + # Create user content + user_content = types.Content( + role='user', + parts=[types.Part(text=message)] + ) + + # Run the agent with session + response_text = "" + async for event in runner.run_async( + user_id=user_id, + session_id=session_id, + new_message=user_content + ): + if event.is_final_response(): + if event.content and event.content.parts: + response_text = event.content.parts[0].text + break + + return response_text + +# Test the memory +if __name__ == "__main__": + async def test(): + user_id = "test_user" + messages = ["My name is Alice", "What's my name?", "I love pizza", "What do I love?"] + + for msg in messages: + print(f"\nUser: {msg}") + response = await chat(user_id, msg) + print(f"Assistant: {response}") + + asyncio.run(test()) \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/app.py b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/app.py new file mode 100644 index 0000000..d66321a --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/app.py @@ -0,0 +1,52 @@ +import streamlit as st +import asyncio +from agent import chat + +# Page configuration +st.set_page_config(page_title="In-Memory Agent", page_icon="🧠") + +# Title +st.title("🧠 In-Memory Conversation Agent") +st.markdown("Simple demo of `InMemorySessionService` - agent remembers conversations within a session.") + +# Initialize chat history +if "messages" not in st.session_state: + st.session_state.messages = [] + +# Display chat messages +for message in st.session_state.messages: + with st.chat_message(message["role"]): + st.markdown(message["content"]) + +# Chat input +if prompt := st.chat_input("Say something..."): + # Add user message + st.session_state.messages.append({"role": "user", "content": prompt}) + with st.chat_message("user"): + st.markdown(prompt) + + # Get response + with st.chat_message("assistant"): + with st.spinner("Thinking..."): + response = asyncio.run(chat("demo_user", prompt)) + st.markdown(response) + + # Add assistant response + st.session_state.messages.append({"role": "assistant", "content": response}) + +# Clear button +if st.button("Clear Chat"): + st.session_state.messages = [] + st.rerun() + +# Sidebar info +with st.sidebar: + st.header("ℹ️ How it works") + st.markdown(""" + 1. **Session Creation**: Creates session for user + 2. **State Storage**: Saves conversation history + 3. **Memory Retrieval**: Uses previous context + 4. **Temporary**: Lost when app restarts + + **Test**: Tell it your name, then ask "What's my name?" + """) \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/requirements.txt b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/requirements.txt new file mode 100644 index 0000000..0a14da2 --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_1_in_memory_conversation_agent/requirements.txt @@ -0,0 +1,4 @@ +google-adk==1.9.0 +streamlit>=1.47.1 +python-dotenv>=1.1.1 +asyncio \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/.env.example b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/.env.example new file mode 100644 index 0000000..f5cfcfb --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/.env.example @@ -0,0 +1,3 @@ +# If using Gemini via Google AI Studio +GOOGLE_GENAI_USE_VERTEXAI=False +GOOGLE_API_KEY="your-api-key" \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/README.md b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/README.md new file mode 100644 index 0000000..80046ff --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/README.md @@ -0,0 +1,204 @@ +# πŸ—„οΈ Tutorial 5.2: Persistent Conversation Agent + +Welcome to persistent session management! This tutorial teaches you how to create an AI agent that can remember conversations across multiple sessions using `DatabaseSessionService` with SQLite. + +## 🎯 What You'll Learn + +- **DatabaseSessionService**: Persistent session storage with SQLite +- **Cross-Session Memory**: Remembering conversations across program restarts +- **Database Management**: Setting up and managing session databases +- **Data Persistence**: Long-term storage of conversation history +- **Session Recovery**: Retrieving previous conversations + +## 🧠 Core Concept: Persistent Sessions + +**DatabaseSessionService** stores session data in a SQLite database file. This means: +- βœ… **Persistent storage** - Data survives program restarts +- βœ… **Cross-session memory** - Remember conversations across sessions +- βœ… **Data integrity** - ACID compliance with SQLite +- βœ… **Scalable** - Can handle multiple users and sessions +- ❌ **Setup required** - Need to initialize database +- ❌ **File-based** - Limited to single machine + +Perfect for: +- Production applications +- Multi-user systems +- Long-term conversation history +- Data analysis and insights + +## πŸ”§ Key Components + +### 1. **DatabaseSessionService** +```python +from google.adk.sessions import DatabaseSessionService +``` + +### 2. **Database Structure** +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ SQLITE DATABASE β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ SESSIONS β”‚ β”‚ STATE β”‚ β”‚ EVENTS β”‚ β”‚ +β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ +β”‚ β”‚ session_id β”‚ β”‚ session_id β”‚ β”‚ event_id β”‚ β”‚ +β”‚ β”‚ user_id β”‚ β”‚ state_data β”‚ β”‚ session_id β”‚ β”‚ +β”‚ β”‚ app_name β”‚ β”‚ updated_at β”‚ β”‚ event_type β”‚ β”‚ +β”‚ β”‚ created_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ content β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ timestamp β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### 3. **Session Lifecycle with Persistence** +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CREATE │───▢│ USE │───▢│ CLOSE β”‚ +β”‚ SESSION β”‚ β”‚ SESSION β”‚ β”‚ SESSION β”‚ +β”‚ (DB) β”‚ β”‚ (DB) β”‚ β”‚ (DB) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Database β”‚ β”‚ Database β”‚ β”‚ Database β”‚ +β”‚ Created β”‚ β”‚ Updated β”‚ β”‚ Archived β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## πŸš€ Tutorial Overview + +In this tutorial, we'll create a **Simple Persistent Agent** that: +- Remembers conversations across program restarts +- Uses SQLite database for persistent storage +- Demonstrates basic cross-session memory +- Shows the difference from in-memory sessions + +## πŸ“ Project Structure + +``` +5_2_persistent_conversation/ +β”œβ”€β”€ README.md # This file - concept explanation +β”œβ”€β”€ requirements.txt # Dependencies +β”œβ”€β”€ agent.py # Main agent with database session management +β”œβ”€β”€ app.py # Streamlit web interface +└── sessions.db # SQLite database (created automatically) +``` + +## 🎯 Learning Objectives + +By the end of this tutorial, you'll understand: +- βœ… How to set up DatabaseSessionService with SQLite +- βœ… How to create persistent sessions +- βœ… How to retrieve conversation history across sessions +- βœ… How to manage database connections and transactions +- βœ… How to build agents that remember long-term + +## πŸš€ Getting Started + +1. **Install dependencies**: + ```bash + pip install -r requirements.txt + ``` + +2. **Set up your environment**: + ```bash + # Create a .env file with your Google AI API key + echo "GOOGLE_API_KEY=your_api_key_here" > .env + ``` + +3. **Run the agent**: + ```bash + # Start the Streamlit app + streamlit run app.py + ``` + +4. **Test persistence**: + - Have a conversation with the agent + - Close the browser/app + - Restart the app + - Continue the conversation - it will remember! + +## πŸ” Code Walkthrough + +### Key Database Session Management Code: + +```python +# 1. Create database session service +session_service = DatabaseSessionService( + db_url="sqlite:///sessions.db" +) + +# 2. Initialize database (creates tables) +await session_service.initialize() + +# 3. Create or retrieve session +session = await session_service.get_session( + app_name="demo", + user_id="user123", + session_id="session_user123" +) + +# 4. Use with Runner for agent execution +async for event in runner.run_async( + user_id=user_id, + session_id=session_id, + new_message=user_content +): + # Handle response +``` + +## 🎯 Testing Your Agent + +Try these persistence tests: + +### Test 1: Cross-Session Memory +``` +Session 1: +User: "My name is Bob" +Agent: "Nice to meet you, Bob!" + +Session 2 (after restart): +User: "What's my name?" +Agent: "Your name is Bob!" +``` + +### Test 2: Interest Memory +``` +Session 1: +User: "I love coding" +Agent: "That's great! Coding is a wonderful skill." + +Session 2 (after restart): +User: "What do I love?" +Agent: "You love coding!" +``` + +### Test 3: Database Verification +``` +1. Have a conversation +2. Check for sessions.db file in project directory +3. Restart the app +4. Continue conversation - it remembers! +``` + +## πŸ”— Next Steps + +After completing this tutorial, you'll be ready for: +- **[Tutorial 5.3: Cloud Memory](../5_3_cloud_memory/README.md)** - Learn cloud-based session storage +- **Advanced Database Patterns** - Multi-user session management +- **Data Analytics** - Analyzing conversation patterns + +## πŸ’‘ Pro Tips + +- **Database Location**: The SQLite file is created in your project directory +- **Backup Strategy**: Consider backing up the sessions.db file +- **Performance**: SQLite is fast for small to medium applications +- **Scaling**: For large applications, consider PostgreSQL or cloud databases + +## 🚨 Important Notes + +- **Database File**: A `sessions.db` file will be created in your project directory +- **Data Persistence**: Conversations survive program restarts +- **File Permissions**: Ensure write permissions in the project directory +- **Backup**: The database file contains all conversation data - back it up! \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/agent.py b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/agent.py new file mode 100644 index 0000000..53c3c21 --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/agent.py @@ -0,0 +1,86 @@ +import asyncio +import os +from google.adk.agents import LlmAgent +from google.adk.sessions import DatabaseSessionService +from google.adk.runners import Runner +from google.genai import types +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + +# Create database session service for persistent storage +session_service = DatabaseSessionService( + db_url="sqlite:///sessions.db" +) + +# Create a simple agent with persistent memory +agent = LlmAgent( + name="persistent_agent", + model="gemini-2.5-flash", + description="A simple agent that remembers conversations in a database", + instruction="You are a helpful assistant. Remember what users tell you and reference it in future conversations. Your memory persists across program restarts." +) + +# Create runner with database session service +runner = Runner( + agent=agent, + app_name="demo", + session_service=session_service +) + +async def chat(user_id: str, message: str) -> str: + """Simple chat function with persistent database memory""" + session_id = f"session_{user_id}" + + # Get or create session + session = await session_service.get_session( + app_name="demo", + user_id=user_id, + session_id=session_id + ) + if not session: + # Create new session with initial state + session = await session_service.create_session( + app_name="demo", + user_id=user_id, + session_id=session_id, + state={"conversation_history": []} + ) + + # Create user content + user_content = types.Content( + role='user', + parts=[types.Part(text=message)] + ) + + # Run the agent with session + response_text = "" + async for event in runner.run_async( + user_id=user_id, + session_id=session_id, + new_message=user_content + ): + if event.is_final_response(): + if event.content and event.content.parts: + response_text = event.content.parts[0].text + break + + return response_text + +# Test the persistent memory +if __name__ == "__main__": + async def test(): + # Initialize database + await session_service.initialize() + print("βœ… Database initialized") + + user_id = "test_user" + messages = ["My name is Bob", "What's my name?", "I love coding", "What do I love?"] + + for msg in messages: + print(f"\nUser: {msg}") + response = await chat(user_id, msg) + print(f"Assistant: {response}") + + asyncio.run(test()) \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/app.py b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/app.py new file mode 100644 index 0000000..6eb5e83 --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/app.py @@ -0,0 +1,63 @@ +import streamlit as st +import asyncio +from agent import chat, session_service + +# Page configuration +st.set_page_config(page_title="Persistent Agent", page_icon="πŸ—„οΈ") + +# Title +st.title("πŸ—„οΈ Persistent Conversation Agent") +st.markdown("Simple demo of `DatabaseSessionService` - agent remembers conversations across program restarts using SQLite database.") + +# Initialize chat history +if "messages" not in st.session_state: + st.session_state.messages = [] + +# Display chat messages +for message in st.session_state.messages: + with st.chat_message(message["role"]): + st.markdown(message["content"]) + +# Chat input +if prompt := st.chat_input("Say something..."): + # Add user message + st.session_state.messages.append({"role": "user", "content": prompt}) + with st.chat_message("user"): + st.markdown(prompt) + + # Get response + with st.chat_message("assistant"): + with st.spinner("Thinking with persistent memory..."): + response = asyncio.run(chat("demo_user", prompt)) + st.markdown(response) + + # Add assistant response + st.session_state.messages.append({"role": "assistant", "content": response}) + +# Clear button +if st.button("Clear Chat"): + st.session_state.messages = [] + st.rerun() + +# Sidebar info +with st.sidebar: + st.header("ℹ️ How it works") + st.markdown(""" + 1. **Database Storage**: Uses SQLite database (sessions.db) + 2. **Persistent Memory**: Survives program restarts + 3. **Cross-Session**: Remembers across multiple sessions + 4. **Simple State**: Basic conversation history + + **Test**: Tell it your name, restart the app, ask "What's my name?" + + **Database**: Check `sessions.db` file in project directory + """) + + st.markdown("---") + st.markdown("### πŸ—„οΈ Database Info") + st.markdown(""" + **File:** `sessions.db` + **Type:** SQLite database + **Persistence:** Survives restarts + **Location:** Project directory + """) \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/requirements.txt b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/requirements.txt new file mode 100644 index 0000000..f33c212 --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/5_2_persistent_conversation_agent/requirements.txt @@ -0,0 +1,5 @@ +google-adk>=0.1.0 +streamlit>=1.28.0 +python-dotenv>=1.0.0 +sqlalchemy>=2.0.0 +asyncio \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/README.md b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/README.md new file mode 100644 index 0000000..159a8cc --- /dev/null +++ b/ai_agent_framework_crash_course/google_adk_tutorials/5_memory_agent/README.md @@ -0,0 +1,190 @@ +# 🧠 Tutorial 5: Memory Agents - Sessions, State & Events + +Welcome to the memory and session management tutorial! This tutorial teaches you how to create AI agents that can remember conversations, maintain context, and provide personalized experiences across multiple interactions. + +## 🎯 What You'll Learn + +- **Session Management**: How agents maintain conversation context +- **State Persistence**: Storing and retrieving conversation data +- **Event Tracking**: Understanding conversation flow and history +- **Memory Types**: In-memory, database, and cloud-based memory solutions +- **Personalization**: Creating agents that remember user preferences + +## 🧠 Core Concepts + +### 1. **Sessions** - The Conversation Container + +A **Session** is like a conversation thread that keeps track of all interactions between a user and an agent. + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ SESSION LIFECYCLE β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ CREATE │───▢│ ACTIVE │───▢│ CLOSED β”‚ β”‚ +β”‚ β”‚ SESSION β”‚ β”‚ CONVERSATIONβ”‚ β”‚ SESSION β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β–Ό β–Ό β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ User ID β”‚ β”‚ Events β”‚ β”‚ Memory β”‚ β”‚ +β”‚ β”‚ Created β”‚ β”‚ State β”‚ β”‚ Stored β”‚ β”‚ +β”‚ β”‚ Timestamp β”‚ β”‚ History β”‚ β”‚ Archived β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +**Example**: When you start chatting with a travel agent, a session is created. All your questions about flights, hotels, and preferences are stored in that session. + +### 2. **State** - The Current Context + +**State** represents the current context and data that the agent needs to remember during a conversation. + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ SESSION STATE β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ USER STATE β”‚ β”‚ AGENT STATE β”‚ β”‚ APP STATE β”‚ β”‚ +β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ +β”‚ β”‚ β€’ User ID β”‚ β”‚ β€’ Agent Name β”‚ β”‚ β€’ Session IDβ”‚ β”‚ +β”‚ β”‚ β€’ Preferences β”‚ β”‚ β€’ Current Task β”‚ β”‚ β€’ Timestamp β”‚ β”‚ +β”‚ β”‚ β€’ History β”‚ β”‚ β€’ Tools Used β”‚ β”‚ β€’ Status β”‚ β”‚ +β”‚ β”‚ β€’ Context β”‚ β”‚ β€’ Memory β”‚ β”‚ β€’ Metadata β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +**Example**: A travel agent's state might include: +- User's preferred destinations +- Budget constraints +- Travel dates +- Previous recommendations + +### 3. **Events** - The Conversation History + +**Events** are individual interactions that make up the conversation history. + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ EVENT FLOW β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ USER │───▢│ AGENT │───▢│ RESPONSE β”‚ β”‚ +β”‚ β”‚ MESSAGE β”‚ β”‚ PROCESSING β”‚ β”‚ GENERATED β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β–Ό β–Ό β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Event Type: β”‚ β”‚ Event Type: β”‚ β”‚ Event Type: β”‚ β”‚ +β”‚ β”‚ user_input β”‚ β”‚ processing β”‚ β”‚ response β”‚ β”‚ +β”‚ β”‚ Timestamp β”‚ β”‚ Timestamp β”‚ β”‚ Timestamp β”‚ β”‚ +β”‚ β”‚ Content β”‚ β”‚ Duration β”‚ β”‚ Content β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +**Example Event Sequence**: +1. **User Event**: "I want to go to Paris" +2. **Agent Event**: Processing request, checking preferences +3. **Response Event**: "Great! I see you prefer luxury hotels. Here are some options..." + +### 4. **Session Runtime Flow** + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ SESSION RUNTIME FLOW β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ 1. SESSION CREATION β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ User starts │───▢ Create Session with User ID β”‚ +β”‚ β”‚ conversationβ”‚ Initialize State & Memory β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ 2. CONVERSATION LOOP β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ User │───▢│ Agent │───▢│ Update β”‚ β”‚ +β”‚ β”‚ Input β”‚ β”‚ Processes β”‚ β”‚ State β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β–Ό β–Ό β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Record β”‚ β”‚ Use Context β”‚ β”‚ Store β”‚ β”‚ +β”‚ β”‚ Event β”‚ β”‚ & Memory β”‚ β”‚ Response β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ 3. SESSION CLOSURE β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ User ends │───▢ Save Final State β”‚ +β”‚ β”‚ conversationβ”‚ Archive Session β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Store in Memory Bank β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## 🎯 Tutorial Structure + +This tutorial is divided into three progressive levels: + +### πŸ“š **Tutorials** + +1. **[5_1_in_memory_conversation](./5_1_in_memory_conversation/README.md)** - Basic session management + - InMemorySessionService for temporary conversations + - Simple state management + - Event tracking basics + +2. **[5_2_persistent_conversation](./5_2_persistent_conversation/README.md)** - Database persistence + - DatabaseSessionService with SQLite + - Persistent state storage + - Conversation history across sessions + +## πŸ› οΈ Prerequisites + +Before starting this tutorial, ensure you have: + +- **Python 3.11+** installed +- **Google AI API Key** from [Google AI Studio](https://aistudio.google.com/) +- **SQLite** (usually comes with Python) +- Basic understanding of databases (for tutorial 5_2) + +## πŸ“– How to Use This Course + +Each tutorial follows a consistent structure: + +- **README.md**: Concept explanation and learning objectives +- **agent.py**: Contains the agent implementation +- **requirements.txt**: Dependencies for the tutorial +- **app.py**: Streamlit web interface (where applicable) + +### Learning Approach: +1. **Read the README** to understand the memory concept +2. **Examine the code** to see session management implementation +3. **Run the example** to see memory in action +4. **Experiment** by having multi-turn conversations +5. **Move to the next tutorial** when ready + +## 🎯 Tutorial Features + +Each tutorial includes: +- βœ… **Clear concept explanation** +- βœ… **Minimal, working code examples** +- βœ… **Real-world use cases** +- βœ… **Step-by-step instructions** +- βœ… **Memory persistence demonstration** + +## πŸ”— Next Steps + +After completing this tutorial, you'll be ready for: +- **Advanced Agent Patterns** - Multi-agent systems +- **Custom Memory Implementations** - Building your own memory services +- **Production Deployment** - Scaling memory agents + +## πŸ’‘ Pro Tips + +- **Start Simple**: Begin with in-memory sessions before moving to persistence +- **Test Conversations**: Have multi-turn conversations to see memory in action +- **Monitor State**: Use the ADK web interface to inspect session state +- **Plan Memory Strategy**: Choose the right memory service for your use case \ No newline at end of file diff --git a/ai_agent_framework_crash_course/google_adk_tutorials/README.md b/ai_agent_framework_crash_course/google_adk_tutorials/README.md index a5cfb45..120d8e1 100644 --- a/ai_agent_framework_crash_course/google_adk_tutorials/README.md +++ b/ai_agent_framework_crash_course/google_adk_tutorials/README.md @@ -26,29 +26,30 @@ This crash course covers the essential concepts of Google ADK through hands-on t - Simple text processing 2. **[2_model_agnostic_agent](./2_model_agnostic_agent/README.md)** - Model-agnostic agent development - - Google Gemini models (AI Studio & Vertex AI) - - Anthropic Claude integration - - Local models with Ollama - - LiteLLM integration for multiple providers + - **[2.1 OpenAI Agent](./2_model_agnostic_agent/2_1_openai_adk_agent/README.md)** - OpenAI integration + - **[2.2 Anthropic Claude Agent](./2_model_agnostic_agent/2_2_anthropic_adk_agent/README.md)** - Claude integration 3. **[3_structured_output_agent](./3_structured_output_agent/README.md)** - Type-safe responses - - Pydantic schemas - - Structured data validation - - Business logic implementation + - **[3.1 Customer Support Ticket Agent](./3_structured_output_agent/3_1_customer_support_ticket_agent/README.md)** - Pydantic schemas + - **[3.2 Email Agent](./3_structured_output_agent/3_2_email_agent/README.md)** - Structured data validation 4. **[4_tool_using_agent](./4_tool_using_agent/README.md)** - Agent with tools - - Built-in tools (Search, Code Execution) - - Function tools (Custom Python functions) - - Third-party tools (LangChain, CrewAI) - - MCP tools integration + - **[4.1 Built-in Tools](./4_tool_using_agent/4_1_builtin_tools/README.md)** - Search, Code Execution + - **[4.2 Function Tools](./4_tool_using_agent/4_2_function_tools/README.md)** - Custom Python functions + - **[4.3 Third-party Tools](./4_tool_using_agent/4_3_thirdparty_tools/README.md)** - LangChain, CrewAI + - **[4.4 MCP Tools](./4_tool_using_agent/4_4_mcp_tools/README.md)** - MCP tools integration -5. **More tutorials coming soon!** +5. **[5_memory_agent](./5_memory_agent/README.md)** - Memory and session management + - **[5.1 In-Memory Conversation](./5_memory_agent/5_1_in_memory_conversation/README.md)** - Basic session management + - **[5.2 Persistent Conversation](./5_memory_agent/5_2_persistent_conversation/README.md)** - Database storage with SQLite + +6. **More tutorials coming soon!** ## πŸ› οΈ Prerequisites Before starting this crash course, ensure you have: -- **Python 3.8+** installed +- **Python 3.11+** installed - **Google AI API Key** from [Google AI Studio](https://aistudio.google.com/) - Basic understanding of Python and APIs diff --git a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/README.md b/mcp_ai_agents/enterprise_orchestrator_team/README.md similarity index 96% rename from advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/README.md rename to mcp_ai_agents/enterprise_orchestrator_team/README.md index cd2a68e..81b4a5a 100644 --- a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/README.md +++ b/mcp_ai_agents/enterprise_orchestrator_team/README.md @@ -1,4 +1,4 @@ -# Enterprise Knowledge Orchestrator +# Enterprise MCP AI Agent Team A production-grade multi-agent system built with Google ADK that orchestrates knowledge management across local files and SaaS platforms using MCP (Model Context Protocol). @@ -9,30 +9,30 @@ This system combines: - **Notion MCP Server** - for managing Notion workspaces and content - **Composio MCP Server** - for GitHub and Figma integration - **Intelligent Router/Orchestrator** - context-aware task delegation with state management -- **4 Specialized Agents** - each handling specific platform capabilities +- **4 Specialized AI Agents** - each handling specific platform capabilities ## Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Router/Orchestrator Agent β”‚ +β”‚ Enterprise MCP AI Agent Team β”‚ β”‚ (Coordinator/Dispatcher Pattern) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ File Analysis β”‚ β”‚ Notion Agent β”‚ β”‚ GitHub Agent β”‚ β”‚ -β”‚ β”‚ Agent β”‚ β”‚ (Optional) β”‚ β”‚ (Optional) β”‚ β”‚ +β”‚ β”‚ AI Agent β”‚ β”‚ (Optional) β”‚ β”‚ (Optional) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Filesystem MCP β”‚ β”‚ Notion MCP β”‚ β”‚ Composio MCP β”‚ β”‚ β”‚ β”‚ Server β”‚ β”‚ Server β”‚ β”‚ Server β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Local Documents β”‚ β”‚ Notion Pages & β”‚ β”‚ GitHub Repos β”‚ β”‚ β”‚ β”‚ (PDF, DOC, XLS) β”‚ β”‚ Databases β”‚ β”‚ & Issues β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ +β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Figma Agent β”‚ β”‚ Composio MCP β”‚ β”‚ β”‚ β”‚ (Optional) β”‚ β”‚ Server β”‚ β”‚ @@ -78,11 +78,11 @@ This system combines: - Searches for design elements and styles - Manages design system components -### 🎯 Router/Orchestrator Agent -- Analyzes user requests and determines which agents should handle them -- Routes tasks to appropriate specialized agents based on capabilities -- Coordinates multi-step workflows that require multiple agents -- Shares context and results between agents through session state +### 🎯 Enterprise MCP AI Agent Team (Router/Orchestrator) +- Analyzes user requests and determines which AI agents should handle them +- Routes tasks to appropriate specialized AI agents based on capabilities +- Coordinates multi-step workflows that require multiple AI agents +- Shares context and results between AI agents through session state - Provides comprehensive results and recommendations ### πŸ›‘οΈ Error Handling & Graceful Degradation diff --git a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/__init__.py b/mcp_ai_agents/enterprise_orchestrator_team/__init__.py similarity index 50% rename from advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/__init__.py rename to mcp_ai_agents/enterprise_orchestrator_team/__init__.py index adc3dc0..e780f9e 100644 --- a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/__init__.py +++ b/mcp_ai_agents/enterprise_orchestrator_team/__init__.py @@ -1,28 +1,28 @@ """ -Enterprise Knowledge Orchestrator +Enterprise MCP AI Agent Team A production-grade multi-agent system built with Google ADK that orchestrates knowledge management across local files and SaaS platforms using MCP (Model Context Protocol). This package provides: -- File Analysis Agent for local document processing -- Notion Agent for Notion workspace management -- GitHub Agent for repository and issue management -- Figma Agent for design file management -- Router/Orchestrator Agent for intelligent task coordination +- File Analysis AI Agent for local document processing +- Notion AI Agent for Notion workspace management +- GitHub AI Agent for repository and issue management +- Figma AI Agent for design file management +- Enterprise MCP AI Agent Team (Router/Orchestrator) for intelligent task coordination """ from .agent import ( - EnterpriseKnowledgeOrchestrator, + EnterpriseMCPAIAgentTeam, root_agent # Add root_agent for ADK web ) __version__ = "1.0.0" -__author__ = "Enterprise Knowledge Team" +__author__ = "Enterprise MCP AI Agent Team" __description__ = "Multi-agent knowledge management system with Google ADK and MCP" __all__ = [ - "EnterpriseKnowledgeOrchestrator", + "EnterpriseMCPAIAgentTeam", "root_agent" # Export root_agent ] \ No newline at end of file diff --git a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/agent.py b/mcp_ai_agents/enterprise_orchestrator_team/agent.py similarity index 91% rename from advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/agent.py rename to mcp_ai_agents/enterprise_orchestrator_team/agent.py index e51ffde..8d0b5f1 100644 --- a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/agent.py +++ b/mcp_ai_agents/enterprise_orchestrator_team/agent.py @@ -1,9 +1,3 @@ -#!/usr/bin/env python3 -""" -Enterprise Knowledge Orchestrator - Complete Multi-Agent System with MCP Tools -Full implementation for ADK Web with all MCP tools (filesystem, Notion, GitHub, Figma) -""" - import os import asyncio import logging @@ -57,7 +51,7 @@ async def create_mcp_agents_with_tools(): name="FileAnalysisAgent", model="gemini-2.0-flash", description="Analyzes local documents and extracts key information", - instruction=f"""You are a File Analysis Agent with DIRECT ACCESS to the filesystem at: {folder_path} + instruction=f"""You are a File Analysis AI Agent with DIRECT ACCESS to the filesystem at: {folder_path} You have MCP tools that allow you to: - List files and directories (list_directory) @@ -267,8 +261,8 @@ Current version provides guidance and best practices for Figma operations.""" return agents -class EnterpriseKnowledgeOrchestrator: - """Enterprise Knowledge Orchestrator - Multi-Agent System with MCP Tools""" +class EnterpriseMCPAIAgentTeam: + """Enterprise MCP AI Agent Team - Multi-Agent System with MCP Tools""" def __init__(self): """Initialize the orchestrator""" @@ -287,10 +281,10 @@ class EnterpriseKnowledgeOrchestrator: # Create root agent with comprehensive routing instructions self.root_agent = LlmAgent( - name="EnterpriseKnowledgeOrchestrator", + name="EnterpriseMCPAIAgentTeam", model="gemini-2.0-flash", - description="Enterprise Knowledge Orchestrator - Multi-agent system with MCP tools", - instruction="""You are an Enterprise Knowledge Orchestrator that routes tasks to specialized agents. + description="Enterprise MCP AI Agent Team - Multi-agent system with MCP tools", + instruction="""You are an Enterprise MCP AI Agent Team that routes tasks to specialized agents. You have access to multiple specialized agents with MCP tools and can coordinate between them: @@ -335,10 +329,10 @@ The agents have real MCP tools connected - they can perform actual operations!"" def _create_fallback_agents(self): """Create fallback agents without MCP tools""" self.root_agent = LlmAgent( - name="EnterpriseKnowledgeOrchestrator", + name="EnterpriseMCPAIAgentTeam", model="gemini-2.0-flash", - description="Enterprise Knowledge Orchestrator - Multi-agent system", - instruction="""You are an Enterprise Knowledge Orchestrator that routes tasks to specialized agents. + description="Enterprise MCP AI Agent Team - Multi-agent system", + instruction="""You are an Enterprise MCP AI Agent Team that routes tasks to specialized agents. You have access to multiple specialized agents and can coordinate between them: @@ -404,16 +398,16 @@ For full MCP tool functionality, ensure all environment variables are set correc # Create root_agent for ADK Web compatibility try: - orchestrator = EnterpriseKnowledgeOrchestrator() + orchestrator = EnterpriseMCPAIAgentTeam() root_agent = orchestrator.root_agent - logger.info("βœ… EnterpriseKnowledgeOrchestrator class and root_agent created successfully") + logger.info("βœ… EnterpriseMCPAIAgentTeam class and root_agent created successfully") except Exception as e: - logger.error(f"❌ Failed to create EnterpriseKnowledgeOrchestrator: {str(e)}") + logger.error(f"❌ Failed to create EnterpriseMCPAIAgentTeam: {str(e)}") # Fallback: create basic root_agent root_agent = LlmAgent( - name="EnterpriseKnowledgeOrchestrator", + name="EnterpriseMCPAIAgentTeam", model="gemini-2.0-flash", - description="Enterprise Knowledge Orchestrator - Basic multi-agent system", - instruction="You are an Enterprise Knowledge Orchestrator that routes tasks to specialized agents.", + description="Enterprise MCP AI Agent Team - Basic multi-agent system", + instruction="You are an Enterprise MCP AI Agent Team that routes tasks to specialized agents.", sub_agents=[] ) \ No newline at end of file diff --git a/advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/requirements.txt b/mcp_ai_agents/enterprise_orchestrator_team/requirements.txt similarity index 100% rename from advanced_ai_agents/multi_agent_apps/agent_teams/enterprise_orchestrator_team/requirements.txt rename to mcp_ai_agents/enterprise_orchestrator_team/requirements.txt