diff --git a/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/README.md b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/README.md new file mode 100644 index 000000000..1e96892bf --- /dev/null +++ b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/README.md @@ -0,0 +1,35 @@ +# OCI Weather Assistant API + +A FastAPI-based service that integrates with Oracle Cloud Infrastructure's Generative AI Agent and uses OpenWeather API to provide real-time weather forecasts. The agent invokes the `get_weather` tool automatically when weather-related questions are asked. + +## Features + +- FastAPI backend with async support +- OCI Generative AI Agent integration +- Weather tool using OpenWeather API +- `.env` configuration for secrets + +## Setup + +1. Clone the repo & install dependencies: + +```bash +git clone https://github.com/your-username/oci-weather-assistant.git +cd oci-weather-assistant +pip install -r requirements.txt + +## Create a .env file in the root directory: + +OCI_AI_AGENT_ENDPOINT_ID=ocid1.generativeaiendpoint.oc1..example +OCI_CONFIG_PROFILE=DEFAULT +OCI_REGION=us-chicago-1 +OPENWEATHER_API_KEY=your_openweather_api_key + +## Run the app + +uvicorn main:app --reload --port 8000 + +## UI + +To test the API via a simple UI, use the frontend from this repository: +🔗 https://github.com/ralungei/oci-genai-agent-blackbelt diff --git a/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/example.env b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/example.env new file mode 100644 index 000000000..b5770856e --- /dev/null +++ b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/example.env @@ -0,0 +1,4 @@ +OCI_AI_AGENT_ENDPOINT_ID=ocid1.generativeaiendpoint.oc1..example +OCI_CONFIG_PROFILE=DEFAULT +OCI_REGION=us-chicago-1 +OPENWEATHER_API_KEY=your_openweather_api_key diff --git a/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/main.py b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/main.py new file mode 100644 index 000000000..9c2369497 --- /dev/null +++ b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/main.py @@ -0,0 +1,134 @@ +from __future__ import annotations + +import os +from typing import Dict, Optional + +import requests +from dotenv import load_dotenv +from oci.addons.adk import Agent, AgentClient, tool +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel + +# --------------------------------------------------------------------------- +# Environment setup +# --------------------------------------------------------------------------- + +load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), ".env")) + +OCI_AI_AGENT_ENDPOINT_ID = os.getenv("OCI_AI_AGENT_ENDPOINT_ID") +OCI_CONFIG_PROFILE = os.getenv("OCI_CONFIG_PROFILE", "DEFAULT") +OCI_REGION = os.getenv("OCI_REGION", "us-chicago-1") +OPENWEATHER_API_KEY = os.getenv("OPENWEATHER_API_KEY", "") + + +# --------------------------------------------------------------------------- +# Tool definition +# --------------------------------------------------------------------------- + +@tool +def get_weather(location: str, units: str = "metric") -> Dict[str, str]: + """Return the current weather for *location* using OpenWeatherMap. + + Args: + location: City name (e.g. "Seattle" or "Seattle,US"). + units: Measurement system – "metric" (°C), "imperial" (°F), or + "standard" (Kelvin). Defaults to "metric". + + Returns: + A dict ready for the agent response, containing temperature, unit, + humidity, wind speed and a short description. + """ + + base_url = "https://api.openweathermap.org/data/2.5/weather" + params = { + "q": location, + "appid": OPENWEATHER_API_KEY, + "units": units, + } + + try: + resp = requests.get(base_url, params=params, timeout=10) + resp.raise_for_status() + except requests.RequestException as exc: + raise RuntimeError(f"Weather service unavailable: {exc}") from exc + + data = resp.json() + + main = data["main"] + weather = data["weather"][0] + wind = data.get("wind", {}) + + unit_symbol = {"metric": "°C", "imperial": "°F", "standard": "K"}.get(units, "°?") + + return { + "location": location, + "temperature": main["temp"], + "unit": unit_symbol, + "description": weather["description"], + "humidity_percent": main.get("humidity"), + "wind_speed_mps": wind.get("speed"), + } + + +# --------------------------------------------------------------------------- +# FastAPI setup +# --------------------------------------------------------------------------- +app = FastAPI() +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# --------------------------------------------------------------------------- +# Agent setup (reuse from main) +# --------------------------------------------------------------------------- +if not OCI_AI_AGENT_ENDPOINT_ID: + raise SystemExit("OCI_AI_AGENT_ENDPOINT_ID is not set. Check your .env file.") + +client = AgentClient( + auth_type="api_key", + profile=OCI_CONFIG_PROFILE, + region=OCI_REGION, +) + +agent = Agent( + client=client, + agent_endpoint_id=OCI_AI_AGENT_ENDPOINT_ID, + instructions=( + "You are a helpful assistant that answers weather questions. " + "Always invoke the get_weather tool when the user asks about the forecast." + ), + tools=[get_weather], +) + +agent.setup() + +# --------------------------------------------------------------------------- +# API request/response models +# --------------------------------------------------------------------------- +class ChatRequest(BaseModel): + question: str + execute_functions: Optional[bool] = True + session_id: Optional[str] = None + +# --------------------------------------------------------------------------- +# /chat endpoint +# --------------------------------------------------------------------------- +@app.post("/chat") +async def chat(request: ChatRequest): + try: + response = await agent.run_async(request.question) + return { + "answer": response.final_output, + "session_id": request.session_id or "session123" + } + except Exception as e: + return {"answer": str(e), "session_id": request.session_id or "session123"} + + +if __name__ == "__main__": + main() diff --git a/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/requirements.txt b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/requirements.txt new file mode 100644 index 000000000..a28882d35 --- /dev/null +++ b/ai/gen-ai-agents/oci_adk_projects/adk-weather-tool/requirements.txt @@ -0,0 +1,5 @@ +fastapi==0.111.0 +uvicorn==0.29.0 +requests==2.31.0 +python-dotenv==1.0.1 +oci==2.114.1 \ No newline at end of file