Skip to content

jotahcm/hanna

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🏑 Hanna – Home Assistant Nexus for Notification & Action

Hanna is an AI-powered personal assistant designed to help manage household tasks, utilities, and daily activities. Built as a learning project to explore LangChain, LLM agents, and modern web technologies, it features a conversational interface with persistent memory and Google service integrations.


✨ Features

Currently Implemented

  • 🧠 AI Chat Interface: Conversational assistant using OpenAI via LangChain/LangGraph
  • πŸ’Ύ Persistent Memory: Redis-based conversation history with multi-conversation support
  • πŸ” Secure Authentication: Clerk integration with JWT validation
  • πŸ”— Google Integration: OAuth2 flow for Gmail, Calendar, and Drive access
  • πŸ“¦ Modern Architecture: FastAPI backend with async patterns, Next.js 15 frontend
  • 🐳 Easy Development: One-command startup with Docker Compose

Planned Features

  • πŸ“ Document organization via Google Drive
  • πŸ—“οΈ Calendar event management
  • 🧰 Project and utility tracking
  • πŸ”” Reminder engine with notifications
  • πŸ“§ Email/mobile notification system

πŸ“ Project Structure

hanna/
β”œβ”€β”€ backend/              # FastAPI application
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ main.py      # App entry point, CORS, lifecycle
β”‚   β”‚   β”œβ”€β”€ core/        # Config, database, Redis setup
β”‚   β”‚   β”œβ”€β”€ auth/        # JWT validation, Google OAuth
β”‚   β”‚   β”œβ”€β”€ chat/        # Chat endpoints, LangGraph engine
β”‚   β”‚   β”œβ”€β”€ models/      # SQLAlchemy models
β”‚   β”‚   └── services/    # Google API integration
β”‚   └── requirements.txt
β”œβ”€β”€ frontend/             # Next.js 15 application
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ app/         # App router pages
β”‚   β”‚   β”œβ”€β”€ components/  # React components
β”‚   β”‚   └── lib/         # API client, utilities
β”‚   └── package.json
β”œβ”€β”€ mcp_servers/          # Model Context Protocol servers
β”œβ”€β”€ docker-compose.yml    # PostgreSQL + Redis containers
β”œβ”€β”€ start-dev.sh         # Development startup script
β”œβ”€β”€ stop-dev.sh          # Development shutdown script
└── CLAUDE.md            # AI assistant instructions

βš™οΈ Developing New Tools

When developing new tools for the AI agent (e.g., integrating with new services like Calendar, Drive, etc.), follow these guidelines to maintain consistency and organization within the project.

1. Pydantic Schemas for Tool Inputs/Outputs

All tool inputs and outputs should be defined using Pydantic BaseModel schemas. These schemas serve multiple purposes:

  • Input Validation: Ensure the AI agent provides valid arguments to the tool.
  • Output Definition: Clearly define the structure of the data returned by the tool.
  • LLM Documentation: LangChain uses these schemas to automatically generate documentation for the LLM, helping it understand how to use the tool.
  • Type Safety: Improve code readability and maintainability with strong type hinting.

Recommended Structure for Tool Schemas:

Create a dedicated directory for each tool under backend/app/tools/, and place its specific Pydantic schemas in a schemas.py file within that tool's directory.

backend/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ ...
β”‚   └── tools/             # Directory for all tool-related files
β”‚       β”œβ”€β”€ __init__.py
β”‚       β”œβ”€β”€ <tool_name>/   # e.g., gmail/, calendar/
β”‚       β”‚   β”œβ”€β”€ __init__.py
β”‚       β”‚   └── schemas.py # <--- Place tool-specific Pydantic schemas here
β”‚       └── ...

Example (for Gmail tool):

# backend/app/tools/gmail/schemas.py

from pydantic import BaseModel
from typing import List, Optional

class EmailSearchInput(BaseModel):
    """Input for searching emails."""
    query: str
    max_results: int = 3

# ... (other Gmail-related schemas like EmailSearchResult, EmailContentInput, etc.)

LangChain Tool Wrappers

Once your Pydantic schemas are defined, create the LangChain tool wrappers. These wrappers will encapsulate the logic for interacting with your service (e.g., gmail_service.py) and expose it to the AI agent.

Recommended Structure for Tool Wrappers:

Place the LangChain tool wrappers in a tools.py file within the same tool-specific directory.

backend/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ ...
β”‚   └── tools/
β”‚       β”œβ”€β”€ ...
β”‚       └── <tool_name>/
β”‚           β”œβ”€β”€ __init__.py
β”‚           β”œβ”€β”€ schemas.py
β”‚           └── tools.py   # <--- Place LangChain tool wrappers here
β”‚       └── ...

Example (for Gmail tool):

# backend/app/tools/gmail/tools.py

from langchain.tools import tool
from app.services.gmail_service import search_emails, get_email_content, download_attachment
from .schemas import EmailSearchInput, EmailContentInput, DownloadAttachmentInput, EmailSearchResults, EmailContentResult

@tool(args_schema=EmailSearchInput)
async def search_gmail_emails(query: str, max_results: int = 3) -> EmailSearchResults:
    """Searches for emails in Gmail based on a query."""
    # ... (implementation using search_emails from gmail_service)
    pass

# ... (other tool wrappers for get_email_content, download_attachment)

πŸš€ Getting Started

Quick Start (Recommended)

# Start entire development environment
./start-dev.sh

# Stop entire development environment
./stop-dev.sh

This will:

  • Start PostgreSQL and Redis via Docker Compose
  • Launch the FastAPI backend with hot reload
  • Start the Next.js frontend development server
  • Handle all necessary database migrations

Manual Setup

πŸ”§ Backend (FastAPI)

cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# Start PostgreSQL and Redis
docker compose up -d

# Run the backend
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

πŸ’» Frontend (Next.js)

cd frontend
npm install
npm run dev

Frontend runs at http://localhost:3000 and connects to backend at http://localhost:8000.


Testing Google Integrations

To test Google service integrations (e.g., Gmail, Calendar), you'll often need a user_id associated with an authenticated user. You can retrieve an existing user_id from the database using the following command:

docker exec hanna-db psql -U postgres -d hanna -c "SELECT user_id FROM google_oauth_tokens LIMIT 1;"

This command will return the user_id of the first entry in the google_oauth_tokens table.

Running Gmail Service Tests

To run the implemented Gmail service tests (located in backend/tests/services/test_gmail_service.py), navigate to the backend directory and execute the following command:

cd backend
python -m tests.services.test_gmail_service

This will execute the test script, which includes functions for searching emails, getting email content, and downloading attachments.


πŸ” Environment Configuration

Backend (backend/.env)

# OpenAI
OPENAI_API_KEY=your-openai-key

# Database
DATABASE_URL=postgresql+asyncpg://hanna:hanna@localhost:5432/hanna
REDIS_URL=redis://localhost:6379

# Clerk Authentication
CLERK_JWKS_URL=https://your-clerk-instance.clerk.accounts.dev/.well-known/jwks.json
CLERK_JWT_ISSUER=https://your-clerk-instance.clerk.accounts.dev

# Google OAuth
GOOGLE_CLIENT_SECRET_PATH=path/to/client_secret.json

# CORS
FRONTEND_ORIGIN=http://localhost:3000

Frontend (frontend/.env.local)

# API Configuration
NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1

# Clerk Configuration
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

πŸ—οΈ Architecture Overview

Backend Stack

  • FastAPI: Async Python web framework
  • LangChain/LangGraph: AI orchestration and conversation flow
  • SQLAlchemy: Async ORM for PostgreSQL
  • Redis: Session storage and chat memory
  • Pydantic: Data validation and settings

Frontend Stack

  • Next.js 15: React framework with App Router
  • React 19: UI library
  • TailwindCSS v4: Utility-first CSS
  • Clerk: Authentication and user management
  • TypeScript: Type safety

Key Integrations

  • OpenAI API: Powers the conversational AI
  • Google OAuth2: Secure access to Gmail, Calendar, and Drive
  • JWT Authentication: Secure API communication

πŸ“Œ Roadmap

  • Basic chat with OpenAI
  • LangChain/LangGraph integration with memory
  • Multi-user support with Clerk authentication
  • Google OAuth2 integration
  • Persistent conversation history
  • Docker Compose setup
  • User onboarding (name and home address personalization)
  • Google Calendar event management
  • Google Drive document search/access
  • Reminder engine with notifications
  • Project and utility tracking
  • Email/mobile notifications
  • LangChain agents for task automation

πŸ› οΈ Tech Stack

Core Technologies

  • Backend: FastAPI, Python 3.11+
  • Frontend: Next.js 15, React 19, TypeScript
  • Database: PostgreSQL with async SQLAlchemy
  • Cache: Redis
  • AI/ML: OpenAI API, LangChain, LangGraph

Authentication & Security

  • Clerk: User authentication and management
  • JWT: API authentication
  • OAuth2: Google service integration

Development Tools

  • Docker & Docker Compose: Containerization
  • ESLint: Code linting
  • Pydantic: Data validation
  • Uvicorn: ASGI server

🀝 Contributing

Hanna is a personal learning project β€” but PRs, issues, and ideas are welcome.


πŸ“„ License

MIT Β© Juan Pablo Hurtado

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published