From 6ca1f4ebdf2a809a5be8b94536ca1dacd00597b8 Mon Sep 17 00:00:00 2001 From: Kowser Date: Mon, 27 Jul 2026 18:59:50 -0700 Subject: [PATCH] Fix ADK examples 14-20: hoist tool closures to module level Tools were defined as functions nested inside main(), which are never picklable under the SDK's default spawn start method. Hoisting them to module scope makes them importable by qualified name, matching every other example and satisfying probe_spawn_safety. --- examples/agents/adk/14_callbacks.py | 66 +++++---- examples/agents/adk/15_global_instruction.py | 72 ++++----- examples/agents/adk/16_customer_service.py | 126 ++++++++-------- examples/agents/adk/17_financial_advisor.py | 147 ++++++++++--------- examples/agents/adk/18_order_processing.py | 126 ++++++++-------- examples/agents/adk/19_supply_chain.py | 137 ++++++++--------- examples/agents/adk/20_blog_writer.py | 76 +++++----- 7 files changed, 387 insertions(+), 363 deletions(-) diff --git a/examples/agents/adk/14_callbacks.py b/examples/agents/adk/14_callbacks.py index 24b71e86e..9d8f37010 100644 --- a/examples/agents/adk/14_callbacks.py +++ b/examples/agents/adk/14_callbacks.py @@ -21,39 +21,41 @@ from settings import settings -def main(): - # Tools - def lookup_customer(customer_id: str) -> dict: - """Look up customer information by ID.""" - customers = { - "C001": {"name": "Alice Smith", "tier": "gold", "balance": 1500.00}, - "C002": {"name": "Bob Jones", "tier": "silver", "balance": 320.50}, - "C003": {"name": "Carol White", "tier": "bronze", "balance": 50.00}, - } - customer = customers.get(customer_id.upper()) - if customer: - return {"found": True, "customer_id": customer_id, **customer} - return {"found": False, "error": f"Customer {customer_id} not found"} - - def apply_discount(customer_id: str, discount_percent: float) -> dict: - """Apply a discount to a customer's account.""" - if discount_percent > 50: - return {"error": "Discount cannot exceed 50%"} - return { - "status": "success", - "customer_id": customer_id, - "discount_applied": f"{discount_percent}%", - "message": f"Applied {discount_percent}% discount to {customer_id}", - } - - def check_order_status(order_id: str) -> dict: - """Check the status of an order.""" - orders = { - "ORD-1001": {"status": "shipped", "tracking": "TRK-98765", "eta": "2025-04-20"}, - "ORD-1002": {"status": "processing", "tracking": None, "eta": "2025-04-25"}, - } - return orders.get(order_id.upper(), {"error": f"Order {order_id} not found"}) +def lookup_customer(customer_id: str) -> dict: + """Look up customer information by ID.""" + customers = { + "C001": {"name": "Alice Smith", "tier": "gold", "balance": 1500.00}, + "C002": {"name": "Bob Jones", "tier": "silver", "balance": 320.50}, + "C003": {"name": "Carol White", "tier": "bronze", "balance": 50.00}, + } + customer = customers.get(customer_id.upper()) + if customer: + return {"found": True, "customer_id": customer_id, **customer} + return {"found": False, "error": f"Customer {customer_id} not found"} + + +def apply_discount(customer_id: str, discount_percent: float) -> dict: + """Apply a discount to a customer's account.""" + if discount_percent > 50: + return {"error": "Discount cannot exceed 50%"} + return { + "status": "success", + "customer_id": customer_id, + "discount_applied": f"{discount_percent}%", + "message": f"Applied {discount_percent}% discount to {customer_id}", + } + + +def check_order_status(order_id: str) -> dict: + """Check the status of an order.""" + orders = { + "ORD-1001": {"status": "shipped", "tracking": "TRK-98765", "eta": "2025-04-20"}, + "ORD-1002": {"status": "processing", "tracking": None, "eta": "2025-04-25"}, + } + return orders.get(order_id.upper(), {"error": f"Order {order_id} not found"}) + +def main(): agent = Agent( name="customer_service_agent", model=settings.llm_model, diff --git a/examples/agents/adk/15_global_instruction.py b/examples/agents/adk/15_global_instruction.py index 59e4a204e..9235cfd75 100644 --- a/examples/agents/adk/15_global_instruction.py +++ b/examples/agents/adk/15_global_instruction.py @@ -17,42 +17,44 @@ from settings import settings -def main(): - def get_product_info(product_name: str) -> dict: - """Look up product information.""" - products = { - "widget pro": { - "name": "Widget Pro", - "price": 49.99, - "category": "electronics", - "in_stock": True, - "rating": 4.7, - }, - "gadget max": { - "name": "Gadget Max", - "price": 89.99, - "category": "electronics", - "in_stock": False, - "rating": 4.2, - }, - "smart lamp": { - "name": "Smart Lamp", - "price": 34.99, - "category": "home", - "in_stock": True, - "rating": 4.5, - }, - } - return products.get(product_name.lower(), {"error": f"Product '{product_name}' not found"}) - - def get_store_hours(location: str) -> dict: - """Get store hours for a location.""" - stores = { - "downtown": {"hours": "9 AM - 9 PM", "open_today": True}, - "mall": {"hours": "10 AM - 8 PM", "open_today": True}, - } - return stores.get(location.lower(), {"error": f"Location '{location}' not found"}) +def get_product_info(product_name: str) -> dict: + """Look up product information.""" + products = { + "widget pro": { + "name": "Widget Pro", + "price": 49.99, + "category": "electronics", + "in_stock": True, + "rating": 4.7, + }, + "gadget max": { + "name": "Gadget Max", + "price": 89.99, + "category": "electronics", + "in_stock": False, + "rating": 4.2, + }, + "smart lamp": { + "name": "Smart Lamp", + "price": 34.99, + "category": "home", + "in_stock": True, + "rating": 4.5, + }, + } + return products.get(product_name.lower(), {"error": f"Product '{product_name}' not found"}) + + +def get_store_hours(location: str) -> dict: + """Get store hours for a location.""" + stores = { + "downtown": {"hours": "9 AM - 9 PM", "open_today": True}, + "mall": {"hours": "10 AM - 8 PM", "open_today": True}, + } + return stores.get(location.lower(), {"error": f"Location '{location}' not found"}) + +def main(): agent = Agent( name="store_assistant", model=settings.llm_model, diff --git a/examples/agents/adk/16_customer_service.py b/examples/agents/adk/16_customer_service.py index 261783021..a1b3eee3b 100644 --- a/examples/agents/adk/16_customer_service.py +++ b/examples/agents/adk/16_customer_service.py @@ -16,68 +16,72 @@ from settings import settings -def main(): - # ── Domain tools ────────────────────────────────────────────── - - def get_account_details(account_id: str) -> dict: - """Retrieve account details for a customer.""" - accounts = { - "ACC-001": { - "name": "Alice Johnson", - "email": "alice@example.com", - "plan": "Premium", - "balance": 142.50, - "status": "active", - }, - "ACC-002": { - "name": "Bob Martinez", - "email": "bob@example.com", - "plan": "Basic", - "balance": 0.00, - "status": "active", - }, - } - return accounts.get(account_id.upper(), {"error": f"Account {account_id} not found"}) - - def get_billing_history(account_id: str, num_months: int = 3) -> dict: - """Get billing history for an account.""" - history = { - "ACC-001": [ - {"month": "March 2025", "amount": 49.99, "status": "paid"}, - {"month": "February 2025", "amount": 49.99, "status": "paid"}, - {"month": "January 2025", "amount": 42.50, "status": "paid"}, - ], - } - records = history.get(account_id.upper(), []) - return {"account_id": account_id, "billing_history": records[:num_months]} - - def submit_support_ticket(account_id: str, category: str, description: str) -> dict: - """Submit a support ticket for a customer issue.""" - valid_categories = ["billing", "technical", "account", "general"] - if category.lower() not in valid_categories: - return {"error": f"Invalid category. Must be one of: {valid_categories}"} - return { - "ticket_id": "TKT-2025-0042", - "account_id": account_id, - "category": category, - "status": "open", - "message": f"Ticket created for {category} issue", - } - - def update_account_plan(account_id: str, new_plan: str) -> dict: - """Update the subscription plan for an account.""" - plans = {"basic": 19.99, "premium": 49.99, "enterprise": 99.99} - price = plans.get(new_plan.lower()) - if not price: - return {"error": f"Invalid plan. Available: {list(plans.keys())}"} - return { - "status": "success", - "account_id": account_id, - "new_plan": new_plan, - "new_price": f"${price}/month", - "effective_date": "Next billing cycle", - } +# ── Domain tools ────────────────────────────────────────────── + +def get_account_details(account_id: str) -> dict: + """Retrieve account details for a customer.""" + accounts = { + "ACC-001": { + "name": "Alice Johnson", + "email": "alice@example.com", + "plan": "Premium", + "balance": 142.50, + "status": "active", + }, + "ACC-002": { + "name": "Bob Martinez", + "email": "bob@example.com", + "plan": "Basic", + "balance": 0.00, + "status": "active", + }, + } + return accounts.get(account_id.upper(), {"error": f"Account {account_id} not found"}) + + +def get_billing_history(account_id: str, num_months: int = 3) -> dict: + """Get billing history for an account.""" + history = { + "ACC-001": [ + {"month": "March 2025", "amount": 49.99, "status": "paid"}, + {"month": "February 2025", "amount": 49.99, "status": "paid"}, + {"month": "January 2025", "amount": 42.50, "status": "paid"}, + ], + } + records = history.get(account_id.upper(), []) + return {"account_id": account_id, "billing_history": records[:num_months]} + + +def submit_support_ticket(account_id: str, category: str, description: str) -> dict: + """Submit a support ticket for a customer issue.""" + valid_categories = ["billing", "technical", "account", "general"] + if category.lower() not in valid_categories: + return {"error": f"Invalid category. Must be one of: {valid_categories}"} + return { + "ticket_id": "TKT-2025-0042", + "account_id": account_id, + "category": category, + "status": "open", + "message": f"Ticket created for {category} issue", + } + + +def update_account_plan(account_id: str, new_plan: str) -> dict: + """Update the subscription plan for an account.""" + plans = {"basic": 19.99, "premium": 49.99, "enterprise": 99.99} + price = plans.get(new_plan.lower()) + if not price: + return {"error": f"Invalid plan. Available: {list(plans.keys())}"} + return { + "status": "success", + "account_id": account_id, + "new_plan": new_plan, + "new_price": f"${price}/month", + "effective_date": "Next billing cycle", + } + +def main(): agent = Agent( name="customer_service_rep", model=settings.llm_model, diff --git a/examples/agents/adk/17_financial_advisor.py b/examples/agents/adk/17_financial_advisor.py index 4ad792d96..18bd843c7 100644 --- a/examples/agents/adk/17_financial_advisor.py +++ b/examples/agents/adk/17_financial_advisor.py @@ -17,78 +17,83 @@ from settings import settings -def main(): - # ── Portfolio tools ─────────────────────────────────────────── - - def get_portfolio(client_id: str) -> dict: - """Get the investment portfolio for a client.""" - portfolios = { - "CLT-001": { - "client": "Sarah Chen", - "total_value": 250000, - "holdings": [ - {"asset": "AAPL", "shares": 100, "value": 17500}, - {"asset": "GOOGL", "shares": 50, "value": 8750}, - {"asset": "US Treasury Bonds", "units": 200, "value": 200000}, - {"asset": "S&P 500 ETF", "shares": 150, "value": 23750}, - ], - "risk_profile": "moderate", - }, - } - return portfolios.get(client_id.upper(), {"error": f"Client {client_id} not found"}) - - def calculate_returns(asset: str, period_months: int = 12) -> dict: - """Calculate returns for an asset over a period.""" - returns = { - "AAPL": {"return_pct": 15.2, "annualized": 15.2}, - "GOOGL": {"return_pct": 22.1, "annualized": 22.1}, - "US Treasury Bonds": {"return_pct": 4.5, "annualized": 4.5}, - "S&P 500 ETF": {"return_pct": 12.8, "annualized": 12.8}, - } - data = returns.get(asset, {"return_pct": 0, "annualized": 0}) - return {"asset": asset, "period_months": period_months, **data} - - # ── Market tools ────────────────────────────────────────────── - - def get_market_data(sector: str) -> dict: - """Get current market data for a sector.""" - sectors = { - "technology": {"trend": "bullish", "pe_ratio": 28.5, "ytd_return": "18.3%"}, - "healthcare": {"trend": "neutral", "pe_ratio": 22.1, "ytd_return": "8.7%"}, - "energy": {"trend": "bearish", "pe_ratio": 15.3, "ytd_return": "-2.1%"}, - "bonds": {"trend": "stable", "yield": "4.5%", "ytd_return": "3.2%"}, - } - return sectors.get(sector.lower(), {"error": f"Sector '{sector}' not found"}) - - def get_economic_indicators() -> dict: - """Get current key economic indicators.""" - return { - "gdp_growth": "2.1%", - "inflation": "3.2%", - "unemployment": "3.8%", - "fed_rate": "5.25%", - "consumer_confidence": 102.5, - } - - # ── Tax tools ───────────────────────────────────────────────── - - def estimate_tax_impact(gains: float, holding_period_months: int) -> dict: - """Estimate tax impact of selling an investment.""" - if holding_period_months >= 12: - rate = 0.15 # Long-term capital gains - category = "long-term" - else: - rate = 0.32 # Short-term (ordinary income) - category = "short-term" - tax = round(gains * rate, 2) - return { - "gains": gains, - "holding_period": f"{holding_period_months} months", - "category": category, - "tax_rate": f"{rate*100}%", - "estimated_tax": tax, - } +# ── Portfolio tools ─────────────────────────────────────────── + +def get_portfolio(client_id: str) -> dict: + """Get the investment portfolio for a client.""" + portfolios = { + "CLT-001": { + "client": "Sarah Chen", + "total_value": 250000, + "holdings": [ + {"asset": "AAPL", "shares": 100, "value": 17500}, + {"asset": "GOOGL", "shares": 50, "value": 8750}, + {"asset": "US Treasury Bonds", "units": 200, "value": 200000}, + {"asset": "S&P 500 ETF", "shares": 150, "value": 23750}, + ], + "risk_profile": "moderate", + }, + } + return portfolios.get(client_id.upper(), {"error": f"Client {client_id} not found"}) + + +def calculate_returns(asset: str, period_months: int = 12) -> dict: + """Calculate returns for an asset over a period.""" + returns = { + "AAPL": {"return_pct": 15.2, "annualized": 15.2}, + "GOOGL": {"return_pct": 22.1, "annualized": 22.1}, + "US Treasury Bonds": {"return_pct": 4.5, "annualized": 4.5}, + "S&P 500 ETF": {"return_pct": 12.8, "annualized": 12.8}, + } + data = returns.get(asset, {"return_pct": 0, "annualized": 0}) + return {"asset": asset, "period_months": period_months, **data} + + +# ── Market tools ────────────────────────────────────────────── + +def get_market_data(sector: str) -> dict: + """Get current market data for a sector.""" + sectors = { + "technology": {"trend": "bullish", "pe_ratio": 28.5, "ytd_return": "18.3%"}, + "healthcare": {"trend": "neutral", "pe_ratio": 22.1, "ytd_return": "8.7%"}, + "energy": {"trend": "bearish", "pe_ratio": 15.3, "ytd_return": "-2.1%"}, + "bonds": {"trend": "stable", "yield": "4.5%", "ytd_return": "3.2%"}, + } + return sectors.get(sector.lower(), {"error": f"Sector '{sector}' not found"}) + + +def get_economic_indicators() -> dict: + """Get current key economic indicators.""" + return { + "gdp_growth": "2.1%", + "inflation": "3.2%", + "unemployment": "3.8%", + "fed_rate": "5.25%", + "consumer_confidence": 102.5, + } + + +# ── Tax tools ───────────────────────────────────────────────── + +def estimate_tax_impact(gains: float, holding_period_months: int) -> dict: + """Estimate tax impact of selling an investment.""" + if holding_period_months >= 12: + rate = 0.15 # Long-term capital gains + category = "long-term" + else: + rate = 0.32 # Short-term (ordinary income) + category = "short-term" + tax = round(gains * rate, 2) + return { + "gains": gains, + "holding_period": f"{holding_period_months} months", + "category": category, + "tax_rate": f"{rate*100}%", + "estimated_tax": tax, + } + +def main(): # ── Sub-agents ──────────────────────────────────────────────── portfolio_analyst = Agent( diff --git a/examples/agents/adk/18_order_processing.py b/examples/agents/adk/18_order_processing.py index 0e03f1242..60c451d5f 100644 --- a/examples/agents/adk/18_order_processing.py +++ b/examples/agents/adk/18_order_processing.py @@ -16,68 +16,72 @@ from settings import settings -def main(): - def search_catalog(query: str, category: str = "all") -> dict: - """Search the product catalog.""" - catalog = [ - {"sku": "LAP-001", "name": "ProBook Laptop 15\"", "category": "laptops", "price": 1299.99, "stock": 23}, - {"sku": "LAP-002", "name": "UltraSlim Notebook 13\"", "category": "laptops", "price": 899.99, "stock": 45}, - {"sku": "ACC-001", "name": "Wireless Mouse", "category": "accessories", "price": 29.99, "stock": 200}, - {"sku": "ACC-002", "name": "USB-C Dock", "category": "accessories", "price": 79.99, "stock": 67}, - {"sku": "MON-001", "name": "4K Monitor 27\"", "category": "monitors", "price": 449.99, "stock": 12}, - ] - results = [] - for item in catalog: - if category != "all" and item["category"] != category: - continue - if query.lower() in item["name"].lower() or query.lower() in item["category"]: - results.append(item) - if not results: - results = [item for item in catalog if category == "all" or item["category"] == category] - return {"results": results[:5], "total_found": len(results)} - - def check_stock(sku: str) -> dict: - """Check real-time stock availability for a SKU.""" - stock_data = { - "LAP-001": {"available": True, "quantity": 23, "warehouse": "West"}, - "LAP-002": {"available": True, "quantity": 45, "warehouse": "East"}, - "ACC-001": {"available": True, "quantity": 200, "warehouse": "Central"}, - "ACC-002": {"available": True, "quantity": 67, "warehouse": "Central"}, - "MON-001": {"available": True, "quantity": 12, "warehouse": "West"}, - } - return stock_data.get(sku.upper(), {"available": False, "quantity": 0}) - - def calculate_total(item_skus: str, shipping_method: str = "standard") -> dict: - """Calculate order total with tax and shipping. item_skus is a comma-separated list of SKUs.""" - items = [s.strip() for s in item_skus.split(",")] - prices = {"LAP-001": 1299.99, "LAP-002": 899.99, "ACC-001": 29.99, "ACC-002": 79.99, "MON-001": 449.99} - shipping_rates = {"standard": 9.99, "express": 24.99, "overnight": 49.99} - - subtotal = sum(prices.get(sku, 0) for sku in items) - tax = round(subtotal * 0.085, 2) # 8.5% tax - shipping = shipping_rates.get(shipping_method, 9.99) - total = round(subtotal + tax + shipping, 2) - - return { - "subtotal": subtotal, - "tax": tax, - "shipping": shipping, - "shipping_method": shipping_method, - "total": total, - } - - def place_order(item_skus: str, shipping_method: str = "standard", payment_method: str = "credit_card") -> dict: - """Place an order. item_skus is a comma-separated list of SKUs.""" - items = [s.strip() for s in item_skus.split(",")] - return { - "order_id": "ORD-2025-0789", - "status": "confirmed", - "items": items, - "shipping_method": shipping_method, - "payment_method": payment_method, - "estimated_delivery": "2025-04-22" if shipping_method == "standard" else "2025-04-18", - } +def search_catalog(query: str, category: str = "all") -> dict: + """Search the product catalog.""" + catalog = [ + {"sku": "LAP-001", "name": "ProBook Laptop 15\"", "category": "laptops", "price": 1299.99, "stock": 23}, + {"sku": "LAP-002", "name": "UltraSlim Notebook 13\"", "category": "laptops", "price": 899.99, "stock": 45}, + {"sku": "ACC-001", "name": "Wireless Mouse", "category": "accessories", "price": 29.99, "stock": 200}, + {"sku": "ACC-002", "name": "USB-C Dock", "category": "accessories", "price": 79.99, "stock": 67}, + {"sku": "MON-001", "name": "4K Monitor 27\"", "category": "monitors", "price": 449.99, "stock": 12}, + ] + results = [] + for item in catalog: + if category != "all" and item["category"] != category: + continue + if query.lower() in item["name"].lower() or query.lower() in item["category"]: + results.append(item) + if not results: + results = [item for item in catalog if category == "all" or item["category"] == category] + return {"results": results[:5], "total_found": len(results)} + + +def check_stock(sku: str) -> dict: + """Check real-time stock availability for a SKU.""" + stock_data = { + "LAP-001": {"available": True, "quantity": 23, "warehouse": "West"}, + "LAP-002": {"available": True, "quantity": 45, "warehouse": "East"}, + "ACC-001": {"available": True, "quantity": 200, "warehouse": "Central"}, + "ACC-002": {"available": True, "quantity": 67, "warehouse": "Central"}, + "MON-001": {"available": True, "quantity": 12, "warehouse": "West"}, + } + return stock_data.get(sku.upper(), {"available": False, "quantity": 0}) + + +def calculate_total(item_skus: str, shipping_method: str = "standard") -> dict: + """Calculate order total with tax and shipping. item_skus is a comma-separated list of SKUs.""" + items = [s.strip() for s in item_skus.split(",")] + prices = {"LAP-001": 1299.99, "LAP-002": 899.99, "ACC-001": 29.99, "ACC-002": 79.99, "MON-001": 449.99} + shipping_rates = {"standard": 9.99, "express": 24.99, "overnight": 49.99} + + subtotal = sum(prices.get(sku, 0) for sku in items) + tax = round(subtotal * 0.085, 2) # 8.5% tax + shipping = shipping_rates.get(shipping_method, 9.99) + total = round(subtotal + tax + shipping, 2) + + return { + "subtotal": subtotal, + "tax": tax, + "shipping": shipping, + "shipping_method": shipping_method, + "total": total, + } + + +def place_order(item_skus: str, shipping_method: str = "standard", payment_method: str = "credit_card") -> dict: + """Place an order. item_skus is a comma-separated list of SKUs.""" + items = [s.strip() for s in item_skus.split(",")] + return { + "order_id": "ORD-2025-0789", + "status": "confirmed", + "items": items, + "shipping_method": shipping_method, + "payment_method": payment_method, + "estimated_delivery": "2025-04-22" if shipping_method == "standard" else "2025-04-18", + } + +def main(): agent = Agent( name="order_processor", model=settings.llm_model, diff --git a/examples/agents/adk/19_supply_chain.py b/examples/agents/adk/19_supply_chain.py index 151398a65..c0691f380 100644 --- a/examples/agents/adk/19_supply_chain.py +++ b/examples/agents/adk/19_supply_chain.py @@ -16,76 +16,81 @@ from settings import settings -def main(): - # ── Inventory tools ─────────────────────────────────────────── - - def get_inventory_levels(warehouse: str) -> dict: - """Get current inventory levels at a warehouse.""" - warehouses = { - "west": { - "warehouse": "West Coast", - "items": [ - {"sku": "WIDGET-A", "quantity": 5000, "reorder_point": 2000}, - {"sku": "WIDGET-B", "quantity": 1200, "reorder_point": 1500}, - {"sku": "GADGET-X", "quantity": 800, "reorder_point": 500}, - ], - }, - "east": { - "warehouse": "East Coast", - "items": [ - {"sku": "WIDGET-A", "quantity": 3200, "reorder_point": 2000}, - {"sku": "WIDGET-B", "quantity": 4500, "reorder_point": 1500}, - {"sku": "GADGET-X", "quantity": 200, "reorder_point": 500}, - ], - }, - } - return warehouses.get(warehouse.lower(), {"error": f"Warehouse '{warehouse}' not found"}) - - def check_supplier_status(sku: str) -> dict: - """Check supplier availability and lead times.""" - suppliers = { - "WIDGET-A": {"supplier": "WidgetCorp", "lead_time_days": 14, "min_order": 1000, "unit_cost": 2.50}, - "WIDGET-B": {"supplier": "WidgetCorp", "lead_time_days": 21, "min_order": 500, "unit_cost": 4.75}, - "GADGET-X": {"supplier": "GadgetWorks", "lead_time_days": 30, "min_order": 200, "unit_cost": 12.00}, - } - return suppliers.get(sku.upper(), {"error": f"No supplier for SKU {sku}"}) - - # ── Logistics tools ─────────────────────────────────────────── - - def get_shipping_routes(origin: str, destination: str) -> dict: - """Get available shipping routes between warehouses.""" - return { - "origin": origin, - "destination": destination, - "routes": [ - {"method": "Ground", "transit_days": 5, "cost_per_unit": 0.50}, - {"method": "Rail", "transit_days": 3, "cost_per_unit": 0.75}, - {"method": "Air", "transit_days": 1, "cost_per_unit": 2.00}, +# ── Inventory tools ─────────────────────────────────────────── + +def get_inventory_levels(warehouse: str) -> dict: + """Get current inventory levels at a warehouse.""" + warehouses = { + "west": { + "warehouse": "West Coast", + "items": [ + {"sku": "WIDGET-A", "quantity": 5000, "reorder_point": 2000}, + {"sku": "WIDGET-B", "quantity": 1200, "reorder_point": 1500}, + {"sku": "GADGET-X", "quantity": 800, "reorder_point": 500}, ], - } - - def get_pending_shipments() -> dict: - """Get all pending shipments in the system.""" - return { - "shipments": [ - {"id": "SHP-001", "sku": "WIDGET-A", "qty": 2000, "status": "in_transit", "eta": "2025-04-18"}, - {"id": "SHP-002", "sku": "GADGET-X", "qty": 500, "status": "processing", "eta": "2025-05-01"}, + }, + "east": { + "warehouse": "East Coast", + "items": [ + {"sku": "WIDGET-A", "quantity": 3200, "reorder_point": 2000}, + {"sku": "WIDGET-B", "quantity": 4500, "reorder_point": 1500}, + {"sku": "GADGET-X", "quantity": 200, "reorder_point": 500}, ], - } - - # ── Demand tools ────────────────────────────────────────────── + }, + } + return warehouses.get(warehouse.lower(), {"error": f"Warehouse '{warehouse}' not found"}) + + +def check_supplier_status(sku: str) -> dict: + """Check supplier availability and lead times.""" + suppliers = { + "WIDGET-A": {"supplier": "WidgetCorp", "lead_time_days": 14, "min_order": 1000, "unit_cost": 2.50}, + "WIDGET-B": {"supplier": "WidgetCorp", "lead_time_days": 21, "min_order": 500, "unit_cost": 4.75}, + "GADGET-X": {"supplier": "GadgetWorks", "lead_time_days": 30, "min_order": 200, "unit_cost": 12.00}, + } + return suppliers.get(sku.upper(), {"error": f"No supplier for SKU {sku}"}) + + +# ── Logistics tools ─────────────────────────────────────────── + +def get_shipping_routes(origin: str, destination: str) -> dict: + """Get available shipping routes between warehouses.""" + return { + "origin": origin, + "destination": destination, + "routes": [ + {"method": "Ground", "transit_days": 5, "cost_per_unit": 0.50}, + {"method": "Rail", "transit_days": 3, "cost_per_unit": 0.75}, + {"method": "Air", "transit_days": 1, "cost_per_unit": 2.00}, + ], + } + + +def get_pending_shipments() -> dict: + """Get all pending shipments in the system.""" + return { + "shipments": [ + {"id": "SHP-001", "sku": "WIDGET-A", "qty": 2000, "status": "in_transit", "eta": "2025-04-18"}, + {"id": "SHP-002", "sku": "GADGET-X", "qty": 500, "status": "processing", "eta": "2025-05-01"}, + ], + } + + +# ── Demand tools ────────────────────────────────────────────── + +def get_demand_forecast(sku: str, weeks_ahead: int = 4) -> dict: + """Get demand forecast for a SKU.""" + forecasts = { + "WIDGET-A": {"weekly_demand": 800, "trend": "increasing", "confidence": 0.85}, + "WIDGET-B": {"weekly_demand": 300, "trend": "stable", "confidence": 0.90}, + "GADGET-X": {"weekly_demand": 150, "trend": "decreasing", "confidence": 0.75}, + } + data = forecasts.get(sku.upper(), {"weekly_demand": 0, "trend": "unknown"}) + data["total_forecast"] = data.get("weekly_demand", 0) * weeks_ahead + return {"sku": sku, "weeks_ahead": weeks_ahead, **data} - def get_demand_forecast(sku: str, weeks_ahead: int = 4) -> dict: - """Get demand forecast for a SKU.""" - forecasts = { - "WIDGET-A": {"weekly_demand": 800, "trend": "increasing", "confidence": 0.85}, - "WIDGET-B": {"weekly_demand": 300, "trend": "stable", "confidence": 0.90}, - "GADGET-X": {"weekly_demand": 150, "trend": "decreasing", "confidence": 0.75}, - } - data = forecasts.get(sku.upper(), {"weekly_demand": 0, "trend": "unknown"}) - data["total_forecast"] = data.get("weekly_demand", 0) * weeks_ahead - return {"sku": sku, "weeks_ahead": weeks_ahead, **data} +def main(): # ── Sub-agents ──────────────────────────────────────────────── inventory_agent = Agent( diff --git a/examples/agents/adk/20_blog_writer.py b/examples/agents/adk/20_blog_writer.py index 477f876c7..e76f5a346 100644 --- a/examples/agents/adk/20_blog_writer.py +++ b/examples/agents/adk/20_blog_writer.py @@ -16,44 +16,46 @@ from settings import settings -def main(): - def search_topic(topic: str) -> dict: - """Search for information about a topic.""" - topics = { - "ai": { - "key_points": [ - "AI adoption grew 72% in enterprises in 2024", - "Generative AI is transforming content creation and coding", - "AI safety and regulation are top policy priorities", - ], - "sources": ["TechReview", "AI Journal", "Industry Report 2024"], - }, - "sustainability": { - "key_points": [ - "Renewable energy hit 30% of global electricity in 2024", - "Carbon capture technology is scaling rapidly", - "Green bonds market exceeded $500B", - ], - "sources": ["GreenTech Weekly", "Climate Report", "Energy Journal"], - }, - } - for key, data in topics.items(): - if key in topic.lower(): - return {"found": True, **data} - return { - "found": True, - "key_points": [f"Key insight about {topic}"], - "sources": ["General Research"], - } - - def check_seo_keywords(topic: str) -> dict: - """Get SEO keyword suggestions for a topic.""" - return { - "primary_keyword": topic.lower().replace(" ", "-"), - "related_keywords": [f"{topic} trends", f"{topic} 2025", f"best {topic} practices"], - "search_volume": "high", - } +def search_topic(topic: str) -> dict: + """Search for information about a topic.""" + topics = { + "ai": { + "key_points": [ + "AI adoption grew 72% in enterprises in 2024", + "Generative AI is transforming content creation and coding", + "AI safety and regulation are top policy priorities", + ], + "sources": ["TechReview", "AI Journal", "Industry Report 2024"], + }, + "sustainability": { + "key_points": [ + "Renewable energy hit 30% of global electricity in 2024", + "Carbon capture technology is scaling rapidly", + "Green bonds market exceeded $500B", + ], + "sources": ["GreenTech Weekly", "Climate Report", "Energy Journal"], + }, + } + for key, data in topics.items(): + if key in topic.lower(): + return {"found": True, **data} + return { + "found": True, + "key_points": [f"Key insight about {topic}"], + "sources": ["General Research"], + } + + +def check_seo_keywords(topic: str) -> dict: + """Get SEO keyword suggestions for a topic.""" + return { + "primary_keyword": topic.lower().replace(" ", "-"), + "related_keywords": [f"{topic} trends", f"{topic} 2025", f"best {topic} practices"], + "search_volume": "high", + } + +def main(): # Research agent gathers information researcher = Agent( name="blog_researcher",