diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/.gitignore b/aws/amazon-bedrock-agentcore/travel_assistant/.gitignore new file mode 100644 index 0000000..a5cbf6c --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/.gitignore @@ -0,0 +1,66 @@ +# Environment variables and secrets +.env +.env.local +.env.*.local +*.key +*.pem + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments +venv/ +env/ +ENV/ +.venv + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Logs +*.log + +# Testing +.pytest_cache/ +.coverage +htmlcov/ +.tox/ + +# Bedrock AgentCore +.bedrock_agentcore/ +.bedrock_agentcore.yaml + +# Screenshots (if generated) +screenshots/ +*.png +!docs/*.png + +# Temporary files +tmp/ +temp/ +*.tmp + diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/QUICKSTART.md b/aws/amazon-bedrock-agentcore/travel_assistant/QUICKSTART.md new file mode 100644 index 0000000..0011ffe --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/QUICKSTART.md @@ -0,0 +1,133 @@ +# Quick Start Guide + +Get the Travel Assistant Agent running in 5 minutes! + +## Prerequisites Checklist + +- [ ] Python 3.11+ installed +- [ ] AWS Account with Bedrock access +- [ ] AWS CLI configured (`aws configure`) +- [ ] Bedrock AgentCore SDK installed (`pip install bedrock-agentcore`) +- [ ] (Optional) AgentCore CLI access for deployment + +## Step 1: Get API Keys + +### Tavily API Key (Required) +1. Visit [https://tavily.com](https://tavily.com) +2. Sign up and get your API key +3. Save it for the next step + +### Elastic API Key (Optional - for observability) +1. Visit [https://cloud.elastic.co](https://cloud.elastic.co) +2. Create a serverless deployment +3. Go to Management > API Keys > Create API Key +4. Save the key and OTLP endpoint + +## Step 2: Install Dependencies + +```bash +pip install -r requirements.txt +``` + +## Step 3: Configure Environment + +```bash +# Option 1: Export directly +export TAVILY_API_KEY="your-key-here" + +# Option 2: Create .env file +cp env.example .env +# Edit .env with your values +``` + +## Step 4: Launch the Agent + +Choose one of the following methods: + +**Note**: Requires access to the `agentcore` CLI tool from Bedrock AgentCore Starter Toolkit. + +1. Set AWS credentials (required before running agentcore): +```bash +export AWS_ACCESS_KEY_ID=your-aws-access-key-id +export AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key +export AWS_REGION=us-east-1 +export AWS_PROFILE=your-aws-profile # Optional +``` + +2. Configure the entrypoint: +```bash +agentcore configure --entrypoint claudeserver.py --name travel_assistant_quickstart +``` + +3. Launch with minimal config: +```bash +agentcore launch --env TAVILY_API_KEY="your-tavily-key" +``` + +4. Or launch with full observability: +```bash +agentcore launch \ + --env OTEL_EXPORTER_OTLP_ENDPOINT="https://your-id.ingest.region.cloud.elastic.co:443" \ + --env OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey your-elastic-key" \ + --env OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \ + --env OTEL_METRICS_EXPORTER="otlp" \ + --env OTEL_TRACES_EXPORTER="otlp" \ + --env OTEL_LOGS_EXPORTER="otlp" \ + --env OTEL_RESOURCE_ATTRIBUTES="service.name=travel_assistant_quickstart,service.version=1.0.0" \ + --env AGENT_OBSERVABILITY_ENABLED="true" \ + --env DISABLE_ADOT_OBSERVABILITY="true" \ + --env TAVILY_API_KEY="your-tavily-key" +``` + +## Step 5: Test It! + +**Quick test:** +```bash +agentcore invoke '{"prompt":"Best places to visit in Netherlands"}' +``` + +**Using test scripts:** + +Fast search (5-10 seconds): +```bash +./invoke.sh +``` + +Delayed search (120+ seconds): +```bash +./invoke_india_best_places.sh +``` + +## Expected Output + +You should see: +- Search results from both Tavily and DuckDuckGo +- Travel recommendations with descriptions +- Source URLs for more information + +## Step 6: Verify Observability (If Configured) + +1. Go to your Elastic Cloud deployment +2. Navigate to **Observability** > **APM** +3. Find the `travel_assistant` service +4. View traces, metrics, and logs + +## Troubleshooting + +**"TAVILY_API_KEY not set"** +- Make sure you exported the variable or passed it via `--env` + +**"Bedrock Access Denied"** +- Enable Claude 3.5 Sonnet model in AWS Bedrock console +- Check IAM permissions + +**"Timeout Error"** +- Increase timeout settings +- For India search, this is expected (120s delay) + +**No Observability Data** +- Verify OTLP endpoint is correct +- Check Elastic API key permissions +- Ensure all OTEL_* variables are set + + diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/README.md b/aws/amazon-bedrock-agentcore/travel_assistant/README.md new file mode 100644 index 0000000..4ca18ee --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/README.md @@ -0,0 +1,341 @@ +# Travel Assistant Agent + +A multi-search travel recommendation agent built with AWS Bedrock AgentCore, Strands, and multiple search providers. This agent compares search latency and results between **Tavily** and **DuckDuckGo** search engines to provide comprehensive travel recommendations. + +## Overview + +This travel assistant agent demonstrates: + +- **Dual Search Engine Integration**: Simultaneously uses Tavily and DuckDuckGo to compare search performance and results +- **Latency Comparison**: Measures and compares response times between different search providers +- **Custom Tool with Delay**: Includes a special `country_specific_search` tool with intentional delay for testing long-running operations +- **Observability**: Full integration with Elastic Observability for monitoring and tracing +- **AWS Bedrock Integration**: Uses Claude 3.5 Sonnet via AWS Bedrock for intelligent travel recommendations + +## Features + +### Search Tools + +1. **web_search (Tavily)**: Fast, AI-optimized search using Tavily Search API +2. **web_search_ddg (DuckDuckGo)**: Traditional web search using DuckDuckGo +3. **country_specific_search**: Specialized tool for India travel searches with 120-second delay + +### Country-Specific Search Logic + +The `country_specific_search` tool includes a **120-second delay** before executing. This is designed to: + +- **Test Long-Running Operations**: Simulate real-world scenarios where certain operations take extended time +- **Observability Testing**: Validate that tracing and monitoring correctly handle long-duration spans +- **Timeout Handling**: Test the agent's behavior with slow-responding tools +- **User Experience Testing**: Demonstrate how to handle operations that require significant wait times + +The delay is intentional and serves as a testing mechanism for production-grade agent deployments where some operations may naturally take longer. + +## Architecture + +``` +┌─────────────────┐ +│ AgentCore │ +│ Runtime │ +└────────┬────────┘ + │ + v +┌─────────────────┐ ┌──────────────┐ +│ Strands Agent │────>│ Claude 3.5 │ +│ │ │ (Bedrock) │ +└────────┬────────┘ └──────────────┘ + │ + ├────> Tavily Search (Fast) + ├────> DuckDuckGo Search (Comparison) + └────> Country-Specific Search (Delayed) +``` + +## Prerequisites + +- AWS Account with Bedrock access +- Python 3.11+ +- AgentCore CLI installed + +## Setup Instructions + +### 1. Install AgentCore SDK + +```bash +pip install bedrock-agentcore +``` + +**Note**: The `agentcore` CLI command requires the Bedrock AgentCore Starter Toolkit, which may need to be installed separately or accessed through AWS preview programs. + +### 2. Obtain Tavily API Key + +1. Visit [https://tavily.com](https://tavily.com) +2. Sign up for a free account +3. Navigate to your dashboard +4. Copy your API key from the API Keys section +5. Free tier includes 1,000 searches per month + +### 3. Set Up Elastic Observability (Optional but Recommended) + +#### Create Elastic Serverless Account + +1. Go to [https://cloud.elastic.co](https://cloud.elastic.co) +2. Click "Start free trial" or "Sign up" +3. Choose "Serverless" deployment option +4. Select your cloud provider and region +5. Create your deployment (usually takes 1-2 minutes) + +#### Obtain Elastic API Key + +1. Once your Elastic deployment is ready, navigate to your deployment +2. Go to **Management** > **Stack Management** > **API Keys** +3. Click **"Create API Key"** +4. Give it a name (e.g., "AgentCore Observability") +5. Set appropriate privileges or use default +6. Click **Create API Key** +7. **Copy and save** the API key immediately (you won't be able to see it again) + +#### Get OTLP Endpoint + +1. In your Elastic deployment, go to **Observability** > **APM** +2. Click **"Add data"** +3. Select **"OpenTelemetry"** +4. Copy the **OTLP Endpoint URL** displayed (format: `https://.ingest..cloud.elastic.co:443`) + +### 4. Configure AWS Credentials + +Ensure your AWS credentials are configured. You can use AWS CLI configuration: + +```bash +aws configure +``` + +Or set environment variables directly (required for agentcore CLI): + +```bash +export AWS_ACCESS_KEY_ID=your-aws-access-key-id +export AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key +export AWS_REGION=us-east-1 +export AWS_PROFILE=your-aws-profile # Optional, if using AWS profiles +``` + +**Note**: The agentcore CLI requires these environment variables to be set before running configuration and deployment commands. + +### 5. Install Dependencies + +```bash +pip install -r requirements.txt +``` + +### 6. Configure AgentCore (CLI Method) + +**If you have access to the `agentcore` CLI**, first set your AWS credentials: + +```bash +# Set AWS credentials for AgentCore +export AWS_ACCESS_KEY_ID=your-aws-access-key-id +export AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key +export AWS_REGION=us-east-1 +export AWS_PROFILE=your-aws-profile # Optional, if using AWS profiles +``` + +Then configure the entrypoint: + +```bash +agentcore configure --entrypoint claudeserver.py --name travel_assistant_quickstart +``` + +This command: +- Sets `claudeserver.py` as the agent entrypoint +- Names the agent `travel_assistant_quickstart` +- Configures the runtime environment +- Creates `.bedrock_agentcore.yaml` configuration file (excluded from git) + +## Configuration + +### Environment Variables + +Create a `.env` file or export the following: + +```bash +# Required +export TAVILY_API_KEY="your-tavily-api-key-here" + +# Optional - AWS Configuration +export AWS_DEFAULT_REGION="us-east-1" +export BEDROCK_MODEL_ID="us.anthropic.claude-3-5-sonnet-20240620-v1:0" + +# Optional - Observability (Elastic) +export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-deployment-id.ingest.region.cloud.elastic.co:443" +export OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey your-elastic-api-key-here" +export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" +export OTEL_METRICS_EXPORTER="otlp" +export OTEL_TRACES_EXPORTER="otlp" +export OTEL_LOGS_EXPORTER="otlp" +export OTEL_RESOURCE_ATTRIBUTES="service.name=travel_assistant,service.version=1.0.0,deployment.environment=production" +export AGENT_OBSERVABILITY_ENABLED="true" +export DISABLE_ADOT_OBSERVABILITY="true" + +# Optional - Logging +export AGENT_RUNTIME_LOG_LEVEL="INFO" +``` + +## Launching the Agent + +**Important**: Make sure you've run `agentcore configure --entrypoint claudeserver.py --name travel_assistant_quickstart` before launching (see step 6 above). + +### Basic Launch (Without Observability) + +```bash +agentcore launch --env TAVILY_API_KEY="your-tavily-api-key" +``` + +### Full Launch (With Elastic Observability) + +```bash +agentcore launch \ + --env OTEL_EXPORTER_OTLP_ENDPOINT="https://.ingest..cloud.elastic.co:443" \ + --env OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey " \ + --env OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \ + --env OTEL_METRICS_EXPORTER="otlp" \ + --env OTEL_TRACES_EXPORTER="otlp" \ + --env OTEL_LOGS_EXPORTER="otlp" \ + --env OTEL_RESOURCE_ATTRIBUTES="service.name=travel_assistant_quickstart,service.version=1.0.0,deployment.environment=production" \ + --env AGENT_OBSERVABILITY_ENABLED="true" \ + --env DISABLE_ADOT_OBSERVABILITY="true" \ + --env TAVILY_API_KEY="" +``` + +**Note**: Replace placeholders (`<...>`) with your actual credentials. + +## Testing the Agent + +### Regular Search (Netherlands Example) + +This will use both Tavily and DuckDuckGo search engines: + +```bash +./invoke.sh +``` + +Or manually: + +```bash +START=$(date +%s) +agentcore invoke '{"prompt":"Best places to visit in Netherlands"}' +END=$(date +%s) +echo "Time taken: $((END - START)) seconds" +``` + +### Delayed Search (India Example) + +This triggers the `country_specific_search` tool with 120-second delay: + +```bash +./invoke_india_best_places.sh +``` + +Or manually: + +```bash +START=$(date +%s) +agentcore invoke '{"prompt":"Best places to visit in India"}' +END=$(date +%s) +echo "Time taken: $((END - START)) seconds" +``` + +**Expected behavior**: The India search will take approximately 120+ seconds due to the intentional delay in the `country_specific_search` tool. + +## Comparing Search Latency + +The agent is designed to compare latency between: + +1. **Tavily Search** (`web_search`): Typically faster, optimized for AI applications +2. **DuckDuckGo Search** (`web_search_ddg`): Traditional web search, may vary in speed + +The agent will call both search engines for most queries, allowing you to observe: +- Response time differences +- Result quality differences +- API reliability + +You can monitor these metrics in Elastic Observability if configured. + +## Project Structure + +``` +travel_assistant/ +├── claudeserver.py # Main agent implementation +├── requirements.txt # Python dependencies +├── .gitignore # Git ignore patterns +├── README.md # This file +├── QUICKSTART.md # 5-minute setup guide +├── env.example # Environment template +├── invoke.sh # Test script (Netherlands) +├── invoke_india_best_places.sh # Test script (India with delay) +└── launch_with_observability.sh # Full launch script with observability +``` + +## Key Components + +### claudeserver.py + +- **Tools**: Three search tools (Tavily, DuckDuckGo, Country-specific) +- **Agent**: Strands Agent with Claude 3.5 Sonnet +- **Telemetry**: OpenTelemetry integration for observability +- **Entrypoint**: BedrockAgentCore app entrypoint + + +## Observability + +When Elastic Observability is configured, you can monitor: + +- **Traces**: Full execution traces including tool calls +- **Metrics**: Performance metrics, latency distributions +- **Logs**: Structured logs from the agent +- **Spans**: Individual operation timing (search calls, LLM calls, etc.) + +Access your Elastic deployment to view: +- APM (Application Performance Monitoring) +- Service maps +- Trace timelines +- Error tracking + + +## Troubleshooting + +### Common Issues + +1. **agentcore: command not found** + - Install the Bedrock AgentCore Starter Toolkit: `pip install bedrock-agentcore-starter-toolkit` + - Verify installation: `agentcore --help` + +2. **Tavily API Key Error** + - Ensure `TAVILY_API_KEY` is set correctly + - Verify your API key is active at tavily.com + +3. **AWS Bedrock Access Denied** + - Enable Bedrock model access in AWS Console + - Verify IAM permissions for Bedrock + +4. **Observability Not Working** + - Check Elastic OTLP endpoint is accessible + - Verify API key has correct permissions + - Ensure OTEL environment variables are set + +5. **Timeout on India Search** + - This is expected! The tool has a 120-second delay + - Ensure your timeout settings are >= 130 seconds + + +## Security Notes + +- Never commit API keys or credentials +- Use environment variables for sensitive data +- Rotate API keys regularly +- Use AWS Secrets Manager for production deployments + +## Support + +For issues or questions: +- AWS Bedrock AgentCore: [AWS Documentation](https://docs.aws.amazon.com/bedrock/) +- Tavily API: [Tavily Documentation](https://docs.tavily.com/) +- Elastic Observability: [Elastic Documentation](https://www.elastic.co/guide/) diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/claudeserver.py b/aws/amazon-bedrock-agentcore/travel_assistant/claudeserver.py new file mode 100644 index 0000000..e1c35aa --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/claudeserver.py @@ -0,0 +1,248 @@ +import os +import logging +import time +from bedrock_agentcore.runtime import BedrockAgentCoreApp +from strands import Agent, tool +from strands.models import BedrockModel +from strands.telemetry import StrandsTelemetry +from tavily import TavilyClient +from duckduckgo_search import DDGS + +# Optional OpenTelemetry imports for custom resource configuration +try: + from opentelemetry.sdk.resources import Resource + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry import trace as trace_api + from opentelemetry import propagate + from opentelemetry.baggage.propagation import W3CBaggagePropagator + from opentelemetry.propagators.composite import CompositePropagator + from opentelemetry.trace.propagation.tracecontext import ( + TraceContextTextMapPropagator, + ) + + OTEL_AVAILABLE = True +except ImportError: + OTEL_AVAILABLE = False + +logging.basicConfig(level=logging.ERROR, format="[%(levelname)s] %(message)s") +logger = logging.getLogger(__name__) +logger.setLevel(os.getenv("AGENT_RUNTIME_LOG_LEVEL", "INFO").upper()) + + +@tool +def web_search(query: str) -> str: + """ + Search the web for information using Tavily Search API. + + Args: + query: The search query + + Returns: + A string containing the search results + """ + try: + # Get Tavily API key from environment variable + api_key = os.getenv("TAVILY_API_KEY") + if not api_key: + return "Error: TAVILY_API_KEY environment variable not set. Please sign up at https://tavily.com to get your API key." + + tavily_client = TavilyClient(api_key=api_key) + response = tavily_client.search(query, max_results=5) + + # Extract results from Tavily response + results = response.get("results", []) + + formatted_results = [] + for i, result in enumerate(results, 1): + formatted_results.append( + f"{i}. {result.get('title', 'No title')}\n" + f" {result.get('content', 'No summary')}\n" + f" Source: {result.get('url', 'No URL')}\n" + ) + + return "\n".join(formatted_results) if formatted_results else "No results found." + + except Exception as e: + return f"Error searching the web: {str(e)}" + + +@tool +def web_search_ddg(query: str) -> str: + """ + Search the web for information using DuckDuckGo Search. + + Args: + query: The search query + + Returns: + A string containing the search results + """ + try: + # Initialize DuckDuckGo search client + ddgs = DDGS() + + # Perform search with max_results=5 + results = list(ddgs.text(query, max_results=5)) + + formatted_results = [] + for i, result in enumerate(results, 1): + formatted_results.append( + f"{i}. {result.get('title', 'No title')}\n" + f" {result.get('body', 'No summary')}\n" + f" Source: {result.get('href', 'No URL')}\n" + ) + + return "\n".join(formatted_results) if formatted_results else "No results found." + + except Exception as e: + return f"Error searching the web with DuckDuckGo: {str(e)}" + + +@tool +def country_specific_search(query: str) -> str: + """ + Search for best places to visit in India with a 120-second delay before performing the search. + This tool waits for 2 minutes before executing a Tavily search about India travel destinations. + + Args: + query: The search query (should be about best places to visit in India) + + Returns: + A string containing the search results after the delay + """ + try: + logger.info("Delayed India search initiated. Waiting 120 seconds before performing search...") + + # Wait for 120 seconds + time.sleep(120) + + logger.info("Wait complete. Performing Tavily search for India destinations...") + + # Get Tavily API key from environment variable + api_key = os.getenv("TAVILY_API_KEY") + if not api_key: + return "Error: TAVILY_API_KEY environment variable not set. Please sign up at https://tavily.com to get your API key." + + # Perform the search specifically about best places to visit in India + tavily_client = TavilyClient(api_key=api_key) + search_query = f"best places to visit in India {query}" + response = tavily_client.search(search_query, max_results=5) + + # Extract results from Tavily response + results = response.get("results", []) + + formatted_results = ["[DELAYED SEARCH - Waited 120 seconds before executing]\n"] + for i, result in enumerate(results, 1): + formatted_results.append( + f"{i}. {result.get('title', 'No title')}\n" + f" {result.get('content', 'No summary')}\n" + f" Source: {result.get('url', 'No URL')}\n" + ) + + return "\n".join(formatted_results) if len(formatted_results) > 1 else "No results found after delayed search." + + except Exception as e: + return f"Error in delayed India search: {str(e)}" + + +# Function to initialize Bedrock model +def get_bedrock_model(): + region = os.getenv("AWS_DEFAULT_REGION", "us-east-1") + model_id = os.getenv("BEDROCK_MODEL_ID", "us.anthropic.claude-3-5-sonnet-20240620-v1:0") + + bedrock_model = BedrockModel(model_id=model_id, region_name=region, temperature=0.0, max_tokens=1024) + return bedrock_model + + +# Initialize the Bedrock model +bedrock_model = get_bedrock_model() + + +# Define the agent's system prompt +system_prompt = """You are an experienced travel agent specializing in personalized travel recommendations +with access to real-time web information from multiple search engines. Your role is to find dream destinations +matching user preferences by using BOTH available search tools to gather comprehensive information. + +IMPORTANT: When responding to queries: +1. Use BOTH web_search (Tavily) and web_search_ddg (DuckDuckGo) tools for each query +2. Clearly identify results from each search engine in your response +3. Format your response to show: + - Results from Tavily Search (use web_search) + - Results from DuckDuckGo Search (use web_search_ddg) +4. SPECIAL CASE: If someone asks specifically about "best places to visit in India", use the + country_specific_search tool which will wait 120 seconds before performing a specialized Tavily search +5. Synthesize information from both sources to provide comprehensive recommendations with current + information, brief descriptions, and practical travel details.""" + + +app = BedrockAgentCoreApp() + + +def initialize_agent(): + """Initialize the agent with proper telemetry configuration.""" + + if OTEL_AVAILABLE: + try: + # Create a custom resource that respects OTEL_RESOURCE_ATTRIBUTES from environment + # This will automatically merge env vars with any explicit attributes + custom_resource = Resource.create( + attributes={ + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.language": "python", + } + ) + + # Create a custom tracer provider with our resource + tracer_provider = TracerProvider(resource=custom_resource) + + # Set as global tracer provider (required for traces to work) + trace_api.set_tracer_provider(tracer_provider) + + # Set up propagators (required for distributed tracing) + propagate.set_global_textmap( + CompositePropagator( + [ + W3CBaggagePropagator(), + TraceContextTextMapPropagator(), + ] + ) + ) + + # Initialize Strands telemetry with the custom tracer provider + strands_telemetry = StrandsTelemetry(tracer_provider=tracer_provider) + strands_telemetry.setup_otlp_exporter() + + logger.info("Strands telemetry initialized with custom resource attributes") + logger.info(f"Resource attributes: {custom_resource.attributes}") + except Exception as e: + logger.warning("Telemetry setup failed: %s", str(e)) + else: + logger.warning("Telemetry setup skipped - OpenTelemetry packages not available") + + # Create and cache the agent + agent = Agent( + model=bedrock_model, + system_prompt=system_prompt, + tools=[web_search, web_search_ddg, country_specific_search], + ) + + return agent + + +@app.entrypoint +def strands_agent_bedrock(payload, context=None): + """ + Invoke the agent with a payload + """ + user_input = payload.get("prompt") + logger.info("[%s] User input: %s", context.session_id, user_input) + + # Initialize agent with proper configuration + agent = initialize_agent() + + response = agent(user_input) + return response.message["content"][0]["text"] + + +if __name__ == "__main__": + app.run() diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/env.example b/aws/amazon-bedrock-agentcore/travel_assistant/env.example new file mode 100644 index 0000000..c2014b3 --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/env.example @@ -0,0 +1,49 @@ +# =========================================== +# Travel Assistant Agent Configuration +# =========================================== +# Copy this file to .env and fill in your actual values + +# ============================================ +# REQUIRED: Tavily Search API Key +# ============================================ +# Get your API key from: https://tavily.com +TAVILY_API_KEY=your-tavily-api-key-here + +# ============================================ +# AWS Configuration +# ============================================ +AWS_DEFAULT_REGION=us-east-1 +AWS_ACCESS_KEY_ID=your-aws-access-key +AWS_SECRET_ACCESS_KEY=your-aws-secret-key +BEDROCK_MODEL_ID=us.anthropic.claude-3-5-sonnet-20240620-v1:0 + +# ============================================ +# Elastic Observability (Optional) +# ============================================ +# Get these from your Elastic Cloud deployment +# Documentation: https://cloud.elastic.co + +# OTLP Endpoint - Replace with your deployment ID and region +OTEL_EXPORTER_OTLP_ENDPOINT=https://your-deployment-id.ingest.your-region.cloud.elastic.co:443 + +# Elastic API Key - Replace with your actual API key +OTEL_EXPORTER_OTLP_HEADERS=Authorization=ApiKey your-elastic-api-key-here + +# OpenTelemetry Configuration +OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf +OTEL_METRICS_EXPORTER=otlp +OTEL_TRACES_EXPORTER=otlp +OTEL_LOGS_EXPORTER=otlp + +# Resource Attributes - Customize as needed +OTEL_RESOURCE_ATTRIBUTES=service.name=travel_assistant,service.version=1.0.0,deployment.environment=production + +# AgentCore Observability Flags +AGENT_OBSERVABILITY_ENABLED=true +DISABLE_ADOT_OBSERVABILITY=true + +# ============================================ +# Agent Configuration +# ============================================ +AGENT_RUNTIME_LOG_LEVEL=INFO + diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/invoke.sh b/aws/amazon-bedrock-agentcore/travel_assistant/invoke.sh new file mode 100755 index 0000000..c8a1a98 --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/invoke.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Test script for regular search (no delay) +# This will use both Tavily and DuckDuckGo search engines + +START=$(date +%s) +agentcore invoke '{"prompt":"Best places to visit in Netherlands"}' +END=$(date +%s) +echo "Time taken: $((END - START)) seconds" diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/invoke_india_best_places.sh b/aws/amazon-bedrock-agentcore/travel_assistant/invoke_india_best_places.sh new file mode 100755 index 0000000..5710371 --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/invoke_india_best_places.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Test script for country-specific search with 120-second delay +# This triggers the special India search tool + +START=$(date +%s) +agentcore invoke '{"prompt":"Best places to visit in India"}' +END=$(date +%s) +echo "Time taken: $((END - START)) seconds" +echo "Note: Expected time is 120+ seconds due to intentional delay" diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/launch_with_observability.sh b/aws/amazon-bedrock-agentcore/travel_assistant/launch_with_observability.sh new file mode 100644 index 0000000..4a60a62 --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/launch_with_observability.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Launch script with full observability configuration +# Make sure to replace placeholder values with your actual credentials + +agentcore launch \ + --env OTEL_EXPORTER_OTLP_ENDPOINT="https://your-deployment-id.ingest.your-region.cloud.elastic.co:443" \ + --env OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey your-elastic-api-key" \ + --env OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \ + --env OTEL_METRICS_EXPORTER="otlp" \ + --env OTEL_TRACES_EXPORTER="otlp" \ + --env OTEL_LOGS_EXPORTER="otlp" \ + --env OTEL_RESOURCE_ATTRIBUTES="service.name=travel_assistant_quickstart,service.version=1.0.0,deployment.environment=production" \ + --env AGENT_OBSERVABILITY_ENABLED="true" \ + --env DISABLE_ADOT_OBSERVABILITY="true" \ + --env TAVILY_API_KEY="your-tavily-api-key" + diff --git a/aws/amazon-bedrock-agentcore/travel_assistant/requirements.txt b/aws/amazon-bedrock-agentcore/travel_assistant/requirements.txt new file mode 100644 index 0000000..c7fb0db --- /dev/null +++ b/aws/amazon-bedrock-agentcore/travel_assistant/requirements.txt @@ -0,0 +1,9 @@ +bedrock-agentcore +bedrock-agentcore-starter-toolkit +strands-agents==1.17.0 +strands-agents-tools +tavily-python +duckduckgo-search +opentelemetry-api +opentelemetry-sdk +opentelemetry-exporter-otlp-proto-http \ No newline at end of file diff --git a/langchainChat/langtrace-elastic-demo-readme.md b/langchainChat/langtrace-elastic-demo-readme.md index 81e5042..bee3d86 100644 --- a/langchainChat/langtrace-elastic-demo-readme.md +++ b/langchainChat/langtrace-elastic-demo-readme.md @@ -75,7 +75,7 @@ Type 'quit' to exit the chat. ## Example Trace -![Alt text](/langtrace/img/Xnapper-2024-08-16-12.36.03.png "Langtrace traces") +![Alt text](img/Xnapper-2024-08-16-12.36.03.png "Langtrace traces") ## How it works