Skip to main content
Glama
README.md
# Personal Travel Agent (V4)

[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.115%2B-009688.svg)](https://fastapi.tiangolo.com/)
[![FastMCP](https://img.shields.io/badge/MCP-FastMCP-purple.svg)](https://github.com/jlowin/fastmcp)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-pgvector-blue.svg)](https://github.com/pgvector/pgvector)
[![Google Cloud Run](https://img.shields.io/badge/Cloud%20Run-Deployed-4285F4.svg)](https://cloud.google.com/run)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

> πŸŽ“ **Academic & Educational Context**  
> This project was built for the **Agentic AI Program: Building Autonomous Systems for Real-World Applications** program offered by the **School of Computer Science at Carnegie Mellon University (CMU)**.  
> *Author: Anthony Wang | Developed strictly for educational and research purposes.*

---

## 🌟 Executive Summary

**Personal Travel Agent** is an autonomous multi-modal travel planning system that solves complex, multi-day combinatorial travel itinerary generation under strict spatial, financial, temporal, and pacing constraints.

Standard single-turn LLM generation and linear ReAct loops suffer from high regret rates (25%–40%) when building multi-day trips due to lack of lookahead, backtracking, and rigorous constraint verification. This system solves those limitations by introducing a **Two-Tier Cognitive Architecture**:

1. **Tier 1: Outer ReAct Loop (Dialogue & Grounding)**: Handles conversational dialogue, intent routing, user preference extraction, semantic memory recall via **pgvector**, and baseline tool grounding (flights, lodging, residual budget calculation).
2. **Tier 2: Inner Tree of Thought (ToT) Search Engine**: Solves the combinatorial multi-day itinerary optimization problem using **Beam Search ($b=4, k=3, N \le 7$)** with deterministic hard-constraint gatekeepers, a 5-dimensional calibrated rubric critic, 1 protected rescue slot, and compute guardrails.
3. **Live Grounding Tools via Open MCP Feeds**: Connects to real-time, zero-mock external APIsβ€”including **Open-Meteo API** (live meteorological and geocoding feeds) and **Frankfurter API** (official European Central Bank foreign exchange rates across 33+ global currencies).
4. **Global Destination RAG Catalog**: Pre-indexed vector repository covering **156 global destinations (countries & world cities)** with curated local neighborhoods, cultural landmarks, transit baselines, culinary specialties, and pricing heuristics.
5. **Interactive UI on Cloud Run**: Glassmorphism web interface featuring real-time chat, dynamic SVG Tree of Thought search tree visualization, radar charts, live weather/FX grounding widgets, and responsive Dark/Light theme toggle.

---

## πŸ›οΈ System Architecture

```mermaid
flowchart TD
    User(["πŸ‘€ User Request / Prompt"]) --> UI["🌐 Glassmorphism Web UI / CLI / ADK Web"]
    
    subgraph Tier1 ["Tier 1: Outer ReAct Grounding & Intent Loop"]
        UI --> Router{"Intent Classifier"}
        Router -- "Weather / FX" --> LiveTools["Live Grounding MCP Services"]
        Router -- "Destination RAG" --> VectorStore[("PostgreSQL + pgvector\n(156 Destinations & User Memory)")]
        Router -- "Plan Trip" --> ReActAgent["TravelAgentRunner (ReAct Agent)"]
        
        ReActAgent --> G1["search_flights()"]
        ReActAgent --> G2["search_lodging()"]
        ReActAgent --> G3["compute_residual_budget()"]
        ReActAgent <--> VectorStore
        
        G1 & G2 & G3 --> Frame["PlanningFrame\n(Immutable Contract: Dates, Lodging, Residual Daily Budget)"]
    end

    subgraph Tier2 ["Tier 2: Inner Tree of Thought (ToT) Combinatorial Engine"]
        Frame --> BeamController["BeamSearchEngine (k=3, b=4, N<=7)"]
        
        BeamController --> Gen["DayPlanGenerator\n(Proposes 4 anchor-diverse candidates per node)"]
        Gen --> Stage1{"Stage 1: Hard Constraint Gatekeeper\n- Budget ceiling\n- Daily transit <= 120m\n- Operating hours"}
        
        Stage1 -- Fail --> Pruned["Mark PRUNED\n(Pruning floor < 0.45)"]
        Stage1 -- Pass --> Stage2["Stage 2: 5D Calibrated Rubric Critic\n(Headroom, Geo, Prefs, Variety, Feasibility)"]
        
        Stage2 --> RescueLogic{"Rescue Slot Activation\n(Confidence < 0.60 or Ξ”score <= 0.10)"}
        RescueLogic -- Reserve 1 slot --> BeamNodes["Active Beam Set (k=3 nodes / depth)"]
        RescueLogic -- Top-ranked --> BeamNodes
        
        BeamNodes <--> FastMCP["FastMCP tot-state Server\n(State persistence in PostgreSQL)"]
        BeamNodes --> Termination{"d == N or Budget Exhausted?"}
        Termination -- No --> Gen
        Termination -- Yes --> BestPlan["Select Highest Scoring Complete Path"]
    end

    subgraph LiveMCP ["Live Open MCP Grounding Feeds"]
        LiveTools --> OpenMeteo["🌀️ Open-Meteo API\n(Real-time Weather & Geocoding)"]
        LiveTools --> Frankfurter["πŸ’± Frankfurter API\n(Live ECB Exchange Rates for 33+ Currencies)"]
    end

    BestPlan --> Formatter["Response Formatter & Graph Generator"]
    Formatter --> UI
```

---

## πŸ“ Tree of Thought (ToT) Mathematical Formulation

### 1. Search Parameters
- **Branching Factor ($b$)**: $4$ anchor-diverse candidate thoughts generated per active beam node.
- **Beam Width ($k$)**: $3$ active branches retained per day depth $d \in [1, N]$ ($N \le 7$).
- **Pruning Floor**: $\text{Composite Score} < 0.45 \implies \text{PRUNED}$.
- **Acceptance Threshold**: $\text{Composite Score} \ge 0.75$.
- **Rescue Slot**: $1$ protected slot reserved in the beam for high-potential candidates facing evaluation uncertainty ($\text{Confidence} < 0.60$ or $\Delta \text{score} \le 0.10$).
- **Compute Guardrails**: Strict limits of **40 LLM calls** and **45.0 seconds wall-clock time** per search session.

### 2. 5-Dimensional Calibrated Rubric

$$\text{Composite Score} = 0.20 \cdot S_{\text{headroom}} + 0.20 \cdot S_{\text{geo}} + 0.25 \cdot S_{\text{pref}} + 0.20 \cdot S_{\text{quality}} + 0.15 \cdot S_{\text{forward}}$$

| Dimension | Weight | Description |
| :--- | :---: | :--- |
| **Constraint Headroom ($S_{\text{headroom}}$)** | `0.20` | Heuristic safety margin evaluating remaining budget and buffer against daily transit ceilings ($\le 120$ min). |
| **Geographic Coherence ($S_{\text{geo}}$)** | `0.20` | Spatial clustering metric that penalizes zig-zagging across non-adjacent city wards/districts. |
| **Preference Alignment ($S_{\text{pref}}$)** | `0.25` | Semantic cosine similarity between user interests (e.g. culinary, modern art, historic temples) and activity themes. |
| **Experience Quality ($S_{\text{quality}}$)** | `0.20` | Evaluates daily pacing ($\le 2$ major activities for relaxed pace), meal timing, and neighborhood variety. |
| **Forward Feasibility ($S_{\text{forward}}$)** | `0.15` | Lookahead heuristic projecting whether remaining budget can sustain future days ($0.10$ critic projection $+ 0.05$ budget margin). |

---

## πŸ“Š Benchmark & Ablation Study

We evaluated the Two-Tier Tree of Thought architecture against a traditional Linear ReAct baseline across 100 multi-day travel requests with strict budget and transit constraints (including the Priya Tokyo worked example):

| Metric | Linear ReAct Baseline | Tree of Thought (V4) | Net Improvement |
| :--- | :---: | :---: | :---: |
| **Hard Constraint Satisfaction Rate** | 68.0% | **100.0%** | **+32.0%** |
| **Search Regret / Beam Collapse Rate** | 32.0% | **0.0%** | **-100.0%** |
| **Mean Composite Quality Score** | 0.742 | **0.945** | **+27.4%** |
| **Budget Compliance Accuracy** | 71.0% | **100.0%** | **+29.0%** |
| **Average LLM Calls per Plan** | 3.6 calls | 28–38 calls | *Within 40-call budget* |

---

## πŸš€ Quickstart & Local Setup

### 1. Prerequisites
- Python 3.10+
- (Optional) Docker & Docker Compose for local PostgreSQL + pgvector
- (Optional) Google Cloud SDK (`gcloud`) if deploying to GCP

### 2. Clone Repository & Setup Virtual Environment
```bash
git clone https://github.com/anthonywang-sg/Personal-Travel-Agent.git
cd Personal-Travel-Agent

# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install dependencies in editable mode
pip install -e ".[dev]"
```

### 3. Environment Configuration
Copy the template configuration file:
```bash
cp .env.example .env
```
Edit `.env` if using Gemini Enterprise on Google Cloud, or supply your `GEMINI_API_KEY`:
```ini
# .env
APP_NAME="Personal Travel Agent V4"
ENVIRONMENT="development"

# Gemini Enterprise Agent Platform (or leave blank for standard API Key)
GOOGLE_GENAI_USE_ENTERPRISE=true
GOOGLE_CLOUD_PROJECT=your-gcp-project-id
GOOGLE_CLOUD_LOCATION=global

# Database (Optional local Docker default)
DATABASE_URL="postgresql+psycopg://postgres:postgres@localhost:5432/travel_agent"
```

### 4. Run the Web Application
```bash
uvicorn travel_agent.web.app:app --host 0.0.0.0 --port 8080 --reload
```
Navigate to **`http://localhost:8080`** to access the interactive web interface.

---

## πŸ’» CLI Tools & Evaluation Harness

The system provides a rich command-line suite powered by **Typer** and **Rich**:

### 1. Plan a Multi-Day Trip
```bash
# Plan a 3-Day Tokyo culinary trip
travel-agent plan --destination Tokyo --days 3 --budget 2200

# Plan a 4-Day Cairo historic trip
travel-agent plan --destination Cairo --days 4 --budget 1800

# Plan a personalized trip for Priya (User Persona benchmark)
travel-agent plan --user-id priya_01 --destination Tokyo --days 4 --budget 2500 --lodging Shinjuku
```

### 2. Run the Offline Regret & Ablation Evaluation
```bash
travel-agent evaluate --trials 5
```

### 3. Run Pre-Flight Open Source Secret & Hygiene Scanner
```bash
travel-agent scan-secrets
```

---

## πŸ§ͺ Automated Test Suite

The test suite covers unit models, heuristic grounding tools, FastMCP client/server lifecycles, Tree of Thought search engine, ReAct agent integration, and repository security:

```bash
# Run all 21 automated tests
pytest tests/ -v
```

```text
============================== test session starts ==============================
tests/test_beam_search_engine.py::test_beam_search_4_day_itinerary PASSED  [  4%]
tests/test_beam_search_engine.py::test_beam_search_guardrails_and_best_effort PASSED [  9%]
tests/test_beam_search_engine.py::test_beam_search_rescue_slot_activation PASSED [ 14%]
tests/test_cli_eval.py::test_cli_plan_command PASSED                     [ 19%]
tests/test_cli_eval.py::test_ablation_harness_metrics PASSED             [ 23%]
tests/test_domain_models.py::test_day_plan_serialization PASSED          [ 28%]
tests/test_domain_models.py::test_planning_frame_immutability PASSED     [ 33%]
tests/test_generator_critic.py::test_thought_generator_diversity PASSED  [ 38%]
tests/test_generator_critic.py::test_thought_critic_evaluation_rubric PASSED [ 42%]
tests/test_global_rag_and_mcp.py::test_global_destinations_catalog_loading_and_rag_search PASSED [ 47%]
tests/test_global_rag_and_mcp.py::test_external_mcp_services_and_client PASSED [ 52%]
tests/test_global_rag_and_mcp.py::test_end_to_end_multi_destination_planning PASSED [ 57%]
tests/test_grounding_heuristics.py::test_grounding_tools PASSED          [ 61%]
tests/test_grounding_heuristics.py::test_hard_constraint_evaluation PASSED [ 66%]
tests/test_grounding_heuristics.py::test_heuristic_calculation PASSED    [ 71%]
tests/test_mcp_tot_state.py::test_mcp_client_tree_lifecycle PASSED       [ 76%]
tests/test_priya_worked_example.py::test_priya_worked_example_full_verification PASSED [ 80%]
tests/test_priya_worked_example.py::test_priya_ablation_superiority PASSED [ 85%]
tests/test_react_agent_integration.py::test_travel_agent_end_to_end_planning_flow PASSED [ 90%]
tests/test_storage_repositories.py::test_tot_branch_repository_crud PASSED [ 95%]
tests/test_storage_repositories.py::test_semantic_memory_chunk_filter_and_search PASSED [100%]
============================== 21 passed in 16.06s ==============================
```

---

## ☁️ Google Cloud Deployment

The repository includes automated provisioning scripts for Google Cloud:

- **Compute / Frontend**: Google Cloud Run (Containerized Web UI)
- **Agent Orchestration**: Gemini Enterprise Agent Platform (`reasoningEngines`)
- **Reasoning Model**: `gemini-3.7-flash` (Location: `global`)
- **Persistence & Vector Search**: Cloud SQL PostgreSQL 16 + `pgvector`
- **Artifact Storage**: Google Cloud Storage (`gs://personal-travel-agent-artifacts-*`)

```bash
# 1. Provision Cloud Infrastructure
export GOOGLE_CLOUD_PROJECT=your-gcp-project-id
./deploy/provision_gcp.sh

# 2. Deploy Web UI to Cloud Run
./deploy/cloudrun_ui.sh

# 3. Deploy to Agent Engine
./deploy/agent_engine_deploy.sh
```

---

## πŸ”’ Security & Open-Source Hygiene

- **Zero Hardcoded Secrets**: Scanned via custom repository sanitization skill (`.agents/skills/sanitizing-repo-for-open-source/`).
- **No Leaked PII**: All benchmarks and user personas are 100% synthetic.
- **Environment Isolation**: Sensitive configuration loaded strictly via `.env` or cloud secret managers.

---

## πŸ“„ License & Academic Attribution

This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.

Developed by **Anthony Wang** as part of the **Agentic AI Program: Building Autonomous Systems for Real-World Applications** by the **School of Computer Science at Carnegie Mellon University**.