Skip to main content

Angie — 24/7 personal AI assistant

Project description

Angie — Personal AI Assistant

CI Python FastAPI Next.js SQLAlchemy MySQL Redis Celery Docker Ruff License

Your 24/7 personal AI assistant. Always on. Always working.

Angie is a self-hosted, event-driven AI assistant that runs as a persistent background daemon on your infrastructure. Angie connects to your real-world tools — email, calendar, smart home devices, music, GitHub, Slack, Discord, and more — and acts on your behalf through a fleet of specialized agents powered by GitHub Copilot's LLM.

Unlike chat-only AI tools, Angie is proactive and persistent: Angie wakes up on a schedule, monitors your channels, executes multi-step workflows, and reports back without being asked. Angie remembers context about you through a layered prompt hierarchy, so every interaction is personalized to your preferences, communication style, and routines.

What Angie can do

  • Real time chat interface — Chat directly with Angie and your fleet of AI agents.
  • Unified inbox — (UNDER DEVELOPMENT) Connect Slack, Discord, iMessage, and email in one place. Angie routes incoming messages to the right agent automatically.
  • Scheduled tasks — (UNDER DEVELOPMENT) Set cron jobs that run agents on a schedule ("every weekday at 8am, summarize my email and post to Slack").
  • Multi-step workflows — (UNDER DEVELOPMENT) Chain agents together: check calendar → summarize emails → control smart lights → send morning briefing.
  • Smart home control — (UNDER DEVELOPMENT) Adjust Philips Hue lighting and Home Assistant automations via natural language.
  • Developer workflows — Query GitHub issues, open PRs, and summarize repository activity.
  • Media control — (UNDER DEVELOPMENT) Control Spotify playback, switch playlists, and manage your queue.
  • Network management — (UNDER DEVELOPMENT) Inspect your UniFi network, connected devices, and bandwidth stats.
  • Personalized context — Onboarding builds a private profile (personality, communication style, preferences) that shapes every LLM interaction.
  • REST API + Web UI — Full FastAPI backend with a Next.js dashboard for managing agents, teams, workflows, tasks, and events in real time.

Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                          Channels                               │
│  Slack(soon) · Discord(soon) · iMessage (soon) · Angie UI Chat  │
└───────────────────────────┬─────────────────────────────────────┘
                            │ Events: infer task from user input
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                       Angie Daemon Loop                         │
│   EventRouter  →  TaskDispatcher  →  Celery Queue  →  Worker    │
│          ↑                                  ↑                   │
│     CronEngine                       AgentRegistry              │
└─────────────────────────────────────────────────────────────────┘
                            │ Task: units of work, assigned to agents/teams
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                         Agent Fleet                             │
│  System: cron · task-manager · workflow-manager · event-manager │
│  Email: gmail · outlook · yahoo · spam · correspondence         │
│  Calendar: gcal   Media: spotify   Dev: github                  │
│  Smart Home: hue · home-assistant   Networking: ubiquiti        │
└─────────────────────────────────────────────────────────────────┘
                            │ Agents & Teams: single teams of AI agents
                            ▼
┌───────────┐   ┌───────────────────┐   ┌───────────────────────┐
│   MySQL   │-->│   FastAPI (API)   │<->│     Redis Cache       │
│    DB     │<--│     /api/v1/*     │<->│    Celery broker      │
└───────────┘   └───────────────────┘   └───────────────────────┘
                           │ 
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│              Next.js Web UI  (frontend/)                        │
│  Dashboard · Agents · Teams · Workflows · Tasks · Events        │
│  Real-time Chat · Settings                                      │
└─────────────────────────────────────────────────────────────────┘

Key Concepts

Concept Description
Event Any trigger: user message, cron tick, webhook, task completion
Task A unit of work dispatched from an event to an agent
Agent A pydantic-ai powered worker that can handle specific task types
Team A named group of agents that collaborate on related tasks
Workflow An ordered sequence of steps across agents/teams for a goal
Prompt Hierarchy SYSTEM → ANGIE → AGENT/USER — layered context fed to every LLM call

Tech Stack

Layer Technology
Language Python 3.12, uv
AI framework pydantic-ai (GitHub Models, OpenAI, Anthropic)
API FastAPI + SQLAlchemy 2.0 async
Database MySQL 8 (aiomysql driver)
Cache / Queue Redis + Celery
Scheduler APScheduler
Channels Slack SDK · discord.py · BlueBubbles REST · SMTP/IMAP
CLI Click
Frontend Next.js 15 · TypeScript · Tailwind CSS v3
Build PyInstaller (standalone angie binary)
CI/CD GitHub Actions
Dev Docker Compose, Ruff, pytest

Quick Start

Prerequisites

  • Python 3.12+, uv
  • Docker Desktop (for MySQL + Redis)
  • Node.js 20+ (for frontend)

1. Clone and install

git clone https://github.com/your-org/angie.git
cd angie
make install          # uv sync --dev --all-extras
cp .env.example .env  # fill in SECRET_KEY, DB_PASSWORD, GITHUB_TOKEN

2. Start backing services

make docker-up        # starts MySQL + Redis containers
make migrate          # runs Alembic migrations

3. Run Angie

# Start the daemon (background loop + Celery worker)
angie daemon start

# Or start services individually:
uvicorn angie.api.app:create_app --factory --reload   # API on :8000
celery -A angie.queue.celery_app worker -l info       # Worker

# Frontend dev server:
cd frontend && npm run dev    # UI on :3000

4. Onboarding

On first run, Angie needs to learn about you:

angie setup

This asks a series of questions and generates personalized prompts/user/<id>/ markdown files that become part of every LLM interaction.


CLI Reference

angie --help

# Daemon
angie daemon start          # Start background daemon
angie daemon stop
angie daemon status

# One-shot queries
angie ask "What's on my calendar today?"

# Configuration
angie config slack           # Set Slack bot token
angie config discord         # Set Discord bot token
angie config imessage        # Set BlueBubbles URL
angie config email           # Set SMTP/IMAP credentials

# Prompt management
angie prompts list           # Show all active prompts
angie prompts edit           # Open prompt in $EDITOR
angie prompts reset          # Re-run onboarding for a prompt

# Status
angie status                 # Show active tasks, registered agents

Agent Fleet

Agents are pydantic-ai powered workers. Each declares:

  • slug — unique identifier used for routing
  • capabilities — keywords that trigger auto-selection
  • execute(task) — async method that does the work

Built-in Agents

Slug Category Description
cron-manager System Create, list, delete cron jobs
task-manager System Manage task queue and status
workflow-manager System Trigger and monitor workflows
event-manager System Inspect and replay events
gmail-agent Email Gmail read/send/search
outlook-agent Email Office 365 mail
yahoo-agent Email Yahoo Mail
spam-deletion Email Delete spam across providers
correspondence Email Draft and send replies
gcal-agent Calendar Google Calendar CRUD
spotify-agent Media Playback control, playlists
github-agent Dev Issues, PRs, repos
hue-agent Smart Home Philips Hue lighting
home-assistant Smart Home Home Assistant integration
ubiquiti-agent Networking UniFi network management

Adding a New Agent

# src/angie/agents/my_category/my_agent.py
from angie.agents.base import BaseAgent

class MyAgent(BaseAgent):
    name = "My Agent"
    slug = "my-agent"
    description = "Does something useful"
    capabilities = ["useful", "something"]

    async def execute(self, task: dict) -> dict:
        # Use the underlying SDK / API here
        return {"status": "success", "result": "done"}

Then add to AGENT_MODULES in src/angie/agents/registry.py.


Teams & Workflows

Creating a Team (API)

curl -X POST http://localhost:8000/api/v1/teams/ \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"Email Team","slug":"email","agent_slugs":["gmail-agent","outlook-agent","spam-deletion"]}'

Defining a Workflow (API)

curl -X POST http://localhost:8000/api/v1/workflows/ \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "name": "Morning Briefing",
    "slug": "morning-briefing",
    "trigger_event": "cron",
    "steps": [
      {"order": 1, "name": "Check calendar", "agent_slug": "gcal-agent"},
      {"order": 2, "name": "Check email", "agent_slug": "gmail-agent"},
      {"order": 3, "name": "Report to Slack", "agent_slug": "task-manager"}
    ]
  }'

Prompt Hierarchy

Every LLM call is built from layered prompts:

prompts/
  system.md          ← Core safety/persona rules (SYSTEM_PROMPT)
  angie.md           ← Angie's personality and behavior (ANGIE_PROMPT)
  user/<id>/         ← Generated from onboarding (USER_PROMPTS)
    personality.md
    communication.md
    preferences.md

For agent tasks: SYSTEM → ANGIE → AGENT_PROMPT For user interactions: SYSTEM → ANGIE → USER_PROMPTS

Reconfigure at any time:

angie prompts edit
angie setup           # re-run full onboarding

Development

make help             # list all targets

make install          # install deps
make check            # lint + format check
make fix              # auto-fix lint + format
make md-check         # check Markdown formatting
make md-fix           # auto-format Markdown files
make test             # run all tests (unit + e2e)
make test-cov         # with coverage report
make test-single K=test_name  # single test

make migrate-new MSG="add column"  # new migration
make migrate          # apply migrations

make docker-up        # start MySQL + Redis
make docker-down      # stop
make docker-reset     # stop + wipe volumes

make build            # PyInstaller standalone binary → dist/angie
make dist             # build sdist + wheel into dist/
make clean-dist       # remove distribution artifacts
make clean            # remove all build artifacts

Project Structure

angie/
├── src/angie/
│   ├── agents/         # Agent implementations + registry + teams
│   ├── api/            # FastAPI app + routers
│   ├── cache/          # Redis client + @cached decorator
│   ├── channels/       # Slack, Discord, iMessage, Email, WebChat
│   ├── cli/            # Click CLI commands
│   ├── core/           # Events, tasks, prompts, cron, loop, feedback
│   ├── db/             # SQLAlchemy session + generic repository
│   ├── models/         # SQLAlchemy ORM models
│   └── queue/          # Celery app + workers
├── frontend/           # Next.js 15 web UI
├── tests/
│   ├── e2e/            # End-to-end flow tests
│   ├── integration/    # (future) API integration tests
│   └── unit/           # Unit tests
├── prompts/            # Jinja2 prompt templates
├── alembic/            # DB migrations
├── docker/             # Dockerfiles
├── docker-compose.yml
├── Makefile
└── angie.spec          # PyInstaller spec

Environment Variables & API Key Permissions

Copy .env.example to .env. The sections below describe every credential, where to obtain it, and the exact permissions/scopes required.


Core (required)

Variable Description
SECRET_KEY JWT signing secret. Generate with openssl rand -hex 32. Keep this private.
DB_PASSWORD MySQL password for the angie database user.

LLM Provider Selection

Angie supports three LLM providers. Set LLM_PROVIDER to choose:

Provider LLM_PROVIDER Required Variables
GitHub Models API (default) github GITHUB_TOKEN, COPILOT_MODEL
OpenAI openai OPENAI_API_KEY, COPILOT_MODEL
Anthropic Claude anthropic ANTHROPIC_API_KEY, ANTHROPIC_MODEL

LLM — GitHub Models API (default)

Variable Description
GITHUB_TOKEN GitHub OAuth token used to obtain a short-lived Copilot session token.
COPILOT_MODEL Model to use (default: gpt-4o). Other options: gpt-4o-mini, o1-mini.
COPILOT_API_BASE Copilot OpenAI-compatible endpoint (default: https://api.githubcopilot.com).

How to get GITHUB_TOKEN:

  1. Go to GitHub → Settings → Developer Settings → Personal Access Tokens → Tokens (classic)
  2. Click Generate new token (classic)
  3. Under Scopes, enable:
    • read:user — required to identify your account
    • No additional scopes are needed; Copilot access is governed by your GitHub Copilot subscription, not token scopes
  4. You must have an active GitHub Copilot Individual, Business, or Enterprise subscription
  5. Paste the ghp_... token as GITHUB_TOKEN

Alternative: Run gh auth token after authenticating with the GitHub CLI to get a token that already has the right access.


OpenAI

Variable Description
OPENAI_API_KEY OpenAI API key (sk-...).
COPILOT_MODEL Model to use (default: gpt-4o).

Get from: platform.openai.com → API Keys → Create new secret key. No special permissions needed — any key with access to gpt-4o works.


Anthropic Claude

Variable Description
ANTHROPIC_API_KEY Anthropic API key (sk-ant-...).
ANTHROPIC_MODEL Model to use (default: claude-sonnet-4-20250514). Other options: claude-opus-4-20250514, claude-haiku-4-20250514.

Get from: console.anthropic.com → API Keys → Create Key.


Slack (optional)

Variable Description
SLACK_BOT_TOKEN Bot OAuth token (xoxb-...) — for posting messages and reading channel events
SLACK_APP_TOKEN App-level token (xapp-...) — required for Socket Mode (real-time events without a public URL)
SLACK_SIGNING_SECRET Used to verify that incoming webhooks are from Slack

How to create a Slack app:

  1. Go to api.slack.com/appsCreate New App → From scratch
  2. Under OAuth & Permissions → Bot Token Scopes, add:
    • channels:history — read messages in public channels
    • channels:read — list channels
    • chat:write — post messages as the bot
    • im:history — read direct messages
    • im:read — list DM conversations
    • im:write — open DM conversations
    • users:read — look up user info (for @-mentioning)
    • app_mentions:read — receive @Angie mentions
  3. Under Event Subscriptions, enable and subscribe to:
    • message.channels, message.im, app_mention
  4. Under Socket Mode, enable Socket Mode and generate an App-Level Token with scope connections:write → this becomes SLACK_APP_TOKEN
  5. Install the app to your workspace → copy the Bot User OAuth TokenSLACK_BOT_TOKEN
  6. Under Basic Information → Signing SecretSLACK_SIGNING_SECRET

Discord (optional)

Variable Description
DISCORD_BOT_TOKEN Bot token from the Discord Developer Portal

How to create a Discord bot:

  1. Go to discord.com/developers/applicationsNew Application
  2. Under Bot, click Add Bot → copy the TokenDISCORD_BOT_TOKEN
  3. Under Bot → Privileged Gateway Intents, enable:
    • Message Content Intent — required to read message text
    • Server Members Intent — required to look up user info
    • Presence Intent — optional, for presence-aware responses
  4. Under OAuth2 → URL Generator, select scopes:
    • bot with permissions: Send Messages, Read Message History, View Channels, Add Reactions
  5. Use the generated URL to invite the bot to your server

iMessage via BlueBubbles (optional)

Variable Description
BLUEBUBBLES_URL URL of your BlueBubbles server (e.g. https://your-server.ngrok.io)
BLUEBUBBLES_PASSWORD BlueBubbles server password

Requirements:

  • A Mac that stays on with iMessage signed in
  • BlueBubbles Server installed and running on that Mac
  • A way to expose the server publicly (ngrok, Cloudflare Tunnel, or static IP)
  • No Apple credentials needed — BlueBubbles uses the Mac's existing iMessage session

Email — SMTP/IMAP (optional)

Variable Description
EMAIL_SMTP_HOST SMTP server hostname (e.g. smtp.gmail.com)
EMAIL_SMTP_PORT SMTP port (default: 587 for STARTTLS)
EMAIL_IMAP_HOST IMAP server hostname (e.g. imap.gmail.com)
EMAIL_IMAP_PORT IMAP port (default: 993 for SSL)
EMAIL_USERNAME Email address (e.g. you@gmail.com)
EMAIL_PASSWORD App password (not your regular password — see below)

Gmail setup:

  1. Enable 2-Step Verification on your Google account
  2. Go to Google Account → Security → App passwords
  3. Create an app password for "Mail" → use this as EMAIL_PASSWORD
  4. SMTP: smtp.gmail.com:587, IMAP: imap.gmail.com:993

Other providers: Use standard SMTP/IMAP settings. For Office 365: SMTP smtp.office365.com:587, IMAP outlook.office365.com:993.


Google Calendar (optional)

Variable Description
GOOGLE_CREDENTIALS_FILE Path to your credentials.json from Google Cloud Console
GOOGLE_TOKEN_FILE Path where Angie stores the OAuth token (default: token.json)

Setup:

  1. Go to console.cloud.google.com → create a project
  2. Enable the Google Calendar API
  3. Under APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID (Desktop app)
  4. Download the JSON → save as credentials.json → set GOOGLE_CREDENTIALS_FILE
  5. Required OAuth scopes:
    • https://www.googleapis.com/auth/calendar — full read/write access to calendars
    • https://www.googleapis.com/auth/calendar.events — create/edit/delete events
  6. On first run, a browser window opens for authorization; the token is saved automatically

Spotify (optional)

Variable Description
SPOTIFY_CLIENT_ID Spotify app client ID
SPOTIFY_CLIENT_SECRET Spotify app client secret
SPOTIFY_REDIRECT_URI OAuth callback URL (default: http://localhost:8080/callback)

Setup:

  1. Go to developer.spotify.com/dashboardCreate app
  2. Set the Redirect URI to http://localhost:8080/callback
  3. Copy Client ID and Client Secret
  4. Required scopes (requested at runtime):
    • user-read-playback-state — current track and device
    • user-modify-playback-state — play/pause/skip/volume
    • user-read-currently-playing — now-playing info
    • playlist-read-private — access private playlists
    • playlist-modify-public, playlist-modify-private — create/edit playlists

Philips Hue (optional)

Variable Description
HUE_BRIDGE_IP Local IP address of your Hue Bridge (e.g. 192.168.1.100)
HUE_USERNAME API username registered on the bridge

Setup:

  1. Find your bridge IP in the Hue app or at discovery.meethue.com
  2. Press the link button on the physical bridge
  3. Within 30 seconds, POST to http://<bridge_ip>/api with {"devicetype":"angie"} to get your username
  4. No cloud account or API key needed — this is a local LAN API

Home Assistant (optional)

Variable Description
HOME_ASSISTANT_URL Base URL of your Home Assistant instance (e.g. http://homeassistant.local:8123)
HOME_ASSISTANT_TOKEN Long-lived access token

Setup:

  1. In Home Assistant, go to Profile → Long-Lived Access Tokens → Create Token
  2. Give it a name (e.g. "Angie") and copy the token
  3. The token inherits your user's permissions — use an account with access to the devices Angie should control

UniFi / Ubiquiti (optional)

Variable Description
UNIFI_HOST UniFi Controller URL (e.g. https://192.168.1.1 or https://unifi.ui.com)
UNIFI_USERNAME Controller admin username
UNIFI_PASSWORD Controller admin password

Requirements:

  • A local UniFi Network Controller (self-hosted) or UniFi Cloud (unifi.ui.com)
  • Admin credentials — a read-only account works for monitoring; admin is needed for device management
  • For cloud access, use your Ubiquiti SSO credentials

GitHub Agent (optional — separate from Copilot token)

Variable Description
GITHUB_PAT Personal Access Token for the GitHub agent (repo queries, PRs, issues)

This is separate from GITHUB_TOKEN (which is for LLM). Create a fine-grained token at GitHub → Settings → Developer Settings → Fine-grained tokens with:

  • Contents: Read — read repository files
  • Issues: Read and Write — create/update issues
  • Pull requests: Read and Write — create/update PRs
  • Metadata: Read — required for all fine-grained tokens

CI/CD

Three GitHub Actions workflows:

  • ci.yml — runs on every push/PR: lint → format → markdown format → test → security → Docker build
  • deploy.yml — runs on v* tags: build PyInstaller binary → GitHub Release + publish to PyPI (OIDC trusted publishing)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

angie_ai-0.1.0.tar.gz (463.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

angie_ai-0.1.0-py3-none-any.whl (127.4 kB view details)

Uploaded Python 3

File details

Details for the file angie_ai-0.1.0.tar.gz.

File metadata

  • Download URL: angie_ai-0.1.0.tar.gz
  • Upload date:
  • Size: 463.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for angie_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fccdcaf551763f7599b65ee77e75aeaee01f0f7820b8093bdf740c71bcbbda9b
MD5 528a47d8409fb97b4763206763424785
BLAKE2b-256 5140a6719cddae8411c1dbf7d359c86a9e5ac5ecc33d4d55c55c6733983f964f

See more details on using hashes here.

File details

Details for the file angie_ai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: angie_ai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 127.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for angie_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1fda5f3fdbe92eabd79d2dc4d21f35189f2df462b0bf30ade08c2276a78d1459
MD5 f8664b015f11e3cf32dad0f4f4a5cd2a
BLAKE2b-256 36b53431a39095676a1583c779a09febbd6f2b010b6f4d130ff94ed7a783d6c8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page