---
name: co-fita-odysseus
type: reference
title: "Odysseus Dashboard — Co-Fita Unified Workspace"
description: "Full-featured AI workspace: FastAPI backend, vanilla JS frontend, SQLAlchemy persistence, chat sessions, model routing, governance kanban, task scheduler, and MCP server integration."
tags: [co-fita, odysseus, dashboard, fastapi, architecture, harness]
timestamp: 2026-07-21
---

# Odysseus Dashboard

The Odysseus Dashboard is the primary user-facing workspace of the [[co-fita-harness]]. It is a self-hosted, full-stack web application providing unified access to LLM chat, model routing, document editing, email, calendar, image generation, research automation, and a multi-agent governance system. Forked from the open-source Odysseus project, it has been extended with Co-Fita-specific modules: the governance kanban, the companion bridge for LAN pairing, and deep [[mcp-ecosystem]] integration.

## Origin and Fork

The base project is a comprehensive AI workspace that ships with:

- FastAPI (Python 3.13+) backend
- Vanilla JS frontend (no framework, no build step)
- SQLAlchemy + SQLite persistence
- Multi-user auth with bcrypt, TOTP 2FA, and API tokens
- 54 route modules, 95 src modules, 33 tool implementations
- MCP server integration for email, memory, RAG, and image generation

The Co-Fita fork adds governance, companion pairing, and wires the dashboard into the broader [[co-fita-harness]] ecosystem.

## Architecture Overview

```mermaid
graph TB
    subgraph Frontend["Frontend (Vanilla JS)"]
        UI[static/index.html]
        JS["static/js/*.js<br>(chat, settings, notes, email, governance, ...)"]
        CSS["static/style.css<br>(36K+ lines)"]
    end

    subgraph FastAPI["FastAPI Application (app.py)"]
        MW["SecurityHeadersMiddleware<br>+ CORS + GZip"]
        Router["54 Route Modules<br>(routes/*.py)"]
        Auth["AuthManager<br>(bcrypt + TOTP + sessions)"]
    end

    subgraph Core["Core Layer (core/)"]
        DB["database.py<br>(28 SQLAlchemy models)"]
        SM["session_manager.py"]
        MM["middleware.py<br>(require_admin, internal tool token)"]
        CT["constants.py"]
    end

    subgraph Services["Service Layer (src/ + services/)"]
        AL["agent_loop.py<br>(LLM orchestration)"]
        TI["tool_implementations.py<br>(33 do_* functions)"]
        TS["task_scheduler.py<br>(cron + one-off tasks)"]
        Gov["governance_engine.py<br>(proposals, congress, plans)"]
        LLM["llm_core.py<br>(model routing)"]
        BG["bg_monitor.py<br>(background monitoring)"]
    end

    subgraph MCP["MCP Servers (mcp_servers/)"]
        EMail["email_server.py"]
        Mem["memory_server.py"]
        RAG["rag_server.py"]
        IMG["image_gen_server.py"]
    end

    subgraph Data["Persistence"]
        SQLite["SQLite (data/app.db)"]
        AuthJSON["data/auth.json"]
        SessionsJSON["data/sessions.json"]
    end

    subgraph Companion["Companion Bridge"]
        Pair["pairing.py<br>(LAN discovery + QR)"]
        CRoutes["routes.py<br>(/api/companion/*)"]
    end

    UI --> JS --> Router
    MW --> Router
    Router --> Auth
    Router --> SM
    Router --> AL
    SM --> DB
    DB --> SQLite
    Auth --> AuthJSON
    Auth --> SessionsJSON
    AL --> TI
    AL --> LLM
    TS --> SM
    Gov --> DB
    Router --> Gov
    EMail --> SQLite
    Mem --> SQLite
    RAG --> SQLite
    IMG --> LLM
    Pair --> CRoutes
    CRoutes --> Router
```

## Technology Stack

| Layer | Technology | Notes |
|---|---|---|
| **Runtime** | Python 3.13+ | `requires-python = ">=3.13"` |
| **Web framework** | FastAPI + Uvicorn | Async, auto-docs at `/docs` |
| **ORM** | SQLAlchemy | 28 model classes, SQLite default |
| **Database** | SQLite (via `data/app.db`) | Foreign keys enforced via PRAGMA |
| **Auth** | bcrypt passwords, pyotp TOTP, session tokens | 7-day token TTL |
| **Frontend** | Vanilla JS, CSS | No build step, no framework |
| **Package manager** | uv | PEP 723 scripts |
| **MCP** | `mcp` library (stdio transport) | 4 built-in servers |
| **Encryption** | Fernet (at-rest) | API keys, signatures, email passwords |
| **Embeddings** | fastembed + ChromaDB | RAG document indexing |
| **PDF** | pypdf, PyMuPDF | Document processing |
| **Calendar** | icalendar, caldav | Local + CalDAV sync |

## Data Model (28 SQLAlchemy Models)

The database layer at `core/database.py` defines the full persistence schema:

| Model | Table | Purpose |
|---|---|---|
| `Session` | `sessions` | Chat sessions with model, owner, mode, folder |
| `ChatMessage` | `chat_messages` | Individual messages within sessions |
| `Document` | `documents` | Living AI-editable documents with versioning |
| `DocumentVersion` | `document_versions` | Immutable snapshots |
| `GalleryAlbum` | `gallery_albums` | Photo albums |
| `GalleryImage` | `gallery_images` | Photo metadata + EXIF |
| `EmailAccount` | `email_accounts` | IMAP/SMTP/OAuth2 credentials (encrypted) |
| `ModelEndpoint` | `model_endpoints` | Admin-configured LLM endpoints |
| `ProviderAuthSession` | `provider_auth_sessions` | OAuth refresh tokens (encrypted) |
| `McpServer` | `mcp_servers` | Admin-configured MCP tool servers |
| `Comparison` | `comparisons` | A/B model comparison results |
| `Signature` | `signatures` | User visual signatures (encrypted) |
| `ApiToken` | `api_tokens` | External integration bearer tokens |
| `Webhook` | `webhooks` | Outgoing event webhooks |
| `UserTool` | `user_tools` | User-created sandboxed mini-apps |
| `UserToolData` | `user_tool_data` | Key-value storage for user tools |
| `CrewMember` | `crew_members` | Custom AI personas |
| `ScheduledTask` | `scheduled_tasks` | Cron + one-off + event-triggered tasks |
| `TaskRun` | `task_runs` | Execution history for tasks |
| `Memory` | `memories` | Persistent fact storage |
| `Note` | `notes` | Keep-style notes and checklists |
| `CalendarCal` | `calendars` | Calendar definitions |
| `CalendarEvent` | `calendar_events` | Calendar events with CalDAV sync |
| `CalendarDeletedEvent` | `caldav_deleted_events` | Delete tombstones for CalDAV |
| `Integration` | `integrations` | External service connections |
| `EditorDraft` | `editor_drafts` | Gallery editor session state |
| `GovernanceProposal` | `governance_proposals` | Kanban proposals with ELO rating |
| `CongressSession` | `congress_sessions` | Multi-agent congress records |
| `QuinquennialPlan` | `quinquennial_plans` | Long-term strategic plans |

## Authentication and Multi-User System

The `AuthManager` in `core/auth.py` implements:

- **Multi-user accounts** stored in `data/auth.json` (bcrypt hashed passwords)
- **Session tokens** with 7-day TTL, persisted to `data/sessions.json`
- **TOTP 2FA** via pyotp with QR code provisioning and 8 backup codes
- **Admin / user roles** with granular privileges:
  - `can_use_agent`, `can_use_browser`, `can_use_bash`, `can_use_documents`
  - `can_use_research`, `can_generate_images`, `can_manage_memory`
  - `max_messages_per_day`, `allowed_models`, `block_all_models`
- **Reserved usernames** (`internal-tool`, `api`, `demo`, `system`) to prevent sentinel impersonation
- **API tokens** (bearer auth) for external integrations like n8n, Make
- **Internal tool loopback** via `X-Odysseus-Internal-Token` header for in-process agent tool calls

The middleware layer (`core/middleware.py`) adds:

- `SecurityHeadersMiddleware`: CSP with per-request nonces, HSTS, X-Frame-Options, Referrer-Policy
- `require_admin` decorator: validates admin status on sensitive routes
- CORS preflight detection to avoid 401 on OPTIONS requests

## Route Organization (54 Modules)

Routes are organized flat in `routes/` but map to logical domains:

| Domain | Files | Complexity |
|---|---|---|
| **Email** | `email_routes.py`, `email_helpers.py`, `email_pollers.py` | HIGH |
| **Chat / Agent** | `chat_routes.py`, `chat_helpers.py`, `shell_routes.py`, `codex_routes.py`, `skills_routes.py` | HIGH |
| **Cookbook** | `cookbook_routes.py`, `cookbook_helpers.py`, `cookbook_output.py` | MEDIUM |
| **Model / LLM** | `model_routes.py`, `assistant_routes.py`, `copilot_routes.py` | MEDIUM |
| **Calendar** | `calendar_routes.py`, `contacts_routes.py` | MEDIUM |
| **Documents** | `document_routes.py`, `document_helpers.py` | LOW |
| **Auth** | `auth_routes.py`, `api_token_routes.py`, `device_flow.py` | LOW |
| **Tasks** | `task_routes.py` | LOW |
| **Gallery** | `gallery_routes.py`, `gallery_helpers.py` | LOW |
| **Governance** | `governance_routes.py` | LOW (Co-Fita extension) |
| **Companion** | `companion/routes.py` | LOW (Co-Fita extension) |
| **Other** | `prefs_routes.py`, `upload_routes.py`, `vault_routes.py`, `webhook_routes.py`, etc. | LOW individual |

## Key Subsystems

### Agent Loop

`src/agent_loop.py` (2,961 lines) is the LLM orchestration core. It handles:

- Prompt assembly from session history + system prompt + tools
- Request classification (chat vs. agent mode)
- Tool call dispatch via `tool_implementations.py`
- Runaway detection and conversation guardrails
- Context budget management and compaction

### Task Scheduler

`src/task_scheduler.py` (2,330 lines) provides:

- **Cron-based recurring tasks** with `croniter`
- **One-off scheduled tasks** at a specific datetime
- **Event-triggered tasks** (fire every N events of a type)
- **Task chaining** via `then_task_id` (task B runs after task A completes)
- **Webhook triggers** for external integration
- Background scanning for due tasks with `asyncio` sleep loops

### Model Routing

`src/llm_core.py` handles model endpoint discovery and request routing:

- Auto-discovery via `/v1/models` endpoint probing
- Background refresh with TTL and backoff
- Per-user endpoint ownership and visibility
- Tool-support detection (function calling / `tool_calls`)
- Provider auth sessions for OAuth-backed providers

### Background Monitor

`src/bg_monitor.py` runs background health checks, email polling, calendar sync, and other maintenance tasks that keep the dashboard operational without user interaction.

## Companion Bridge

The `companion/` module enables LAN client pairing (e.g. a phone connecting to the dashboard):

| Endpoint | Auth | Purpose |
|---|---|---|
| `GET /api/companion/ping` | session or token | Health check |
| `GET /api/companion/info` | session or token | Server identity + capabilities |
| `GET /api/companion/models` | session or token | Caller's model endpoints |
| `GET /api/companion/pair` | admin cookie | Pairing form |
| `POST /api/companion/pair` | admin cookie | Mint one-time pairing token |

LAN discovery uses a UDP-connect trick to find the egress interface IP, then renders a QR code for phone scanning.

## File Layout

```
dashboard/
├── app.py                      # FastAPI entrypoint (1,145 lines)
├── pyproject.toml              # uv dependencies
├── core/                       # 10 files — auth, DB, middleware, session
│   ├── auth.py                 # Multi-user auth + TOTP 2FA
│   ├── database.py             # 28 SQLAlchemy models (2,265 lines)
│   ├── models.py               # Pure data models
│   ├── session_manager.py      # Session CRUD + persistence
│   ├── middleware.py            # Security headers + require_admin
│   ├── constants.py            # Re-exports from src/constants.py
│   ├── atomic_io.py            # Atomic file writes
│   ├── exceptions.py           # Custom exception classes
│   └── platform_compat.py      # Platform-specific shims
├── src/                        # 95 modules — business logic
│   ├── agent_loop.py           # LLM orchestration
│   ├── tool_implementations.py # 33 tool execution functions
│   ├── task_scheduler.py       # Cron + one-off + event tasks
│   ├── llm_core.py             # Model routing
│   ├── governance_engine.py    # Proposal lifecycle + congress
│   ├── bg_monitor.py           # Background monitoring
│   ├── ai_interaction.py       # Chat completion logic
│   ├── agent_tools/            # Filesystem, subprocess, web
│   └── search/                 # Search subsystem
├── routes/                     # 54 route modules
│   ├── governance_routes.py    # Kanban API (Co-Fita extension)
│   ├── chat_routes.py          # Chat/session API
│   ├── email_routes.py         # Email API
│   └── ... (51 more)
├── mcp_servers/                # 4 MCP tool servers
│   ├── email_server.py         # Email tools
│   ├── memory_server.py        # Memory management
│   ├── rag_server.py           # RAG document management
│   └── image_gen_server.py     # Image generation
├── services/                   # Domain services
│   ├── memory/                 # Memory extraction + vector store
│   ├── research/               # Research automation
│   ├── hwfit/                  # Hardware fitness profiling
│   └── shell/                  # Shell session management
├── companion/                  # LAN pairing bridge
│   ├── pairing.py              # Token minting + QR + LAN discovery
│   └── routes.py               # /api/companion/* endpoints
├── static/                     # Frontend
│   ├── index.html, login.html  # Entry points
│   ├── style.css               # 36,653 lines
│   └── js/                     # Vanilla JS modules
│       ├── governance.js       # Kanban UI
│       ├── chat.js             # Chat interface
│       ├── settings.js         # Settings panel
│       └── ... (15+ modules)
├── integrations/               # External harness bridges
│   ├── claude/                 # Claude Code skill
│   └── codex/                  # Codex integration
└── tests/                      # 583 test files
```

## Startup and Configuration

The application boots via `app.py`:

1. Load `.env` via `python-dotenv`
2. Initialize `core.database` (creates tables + runs 30+ idempotent migrations)
3. Initialize `AuthManager` (loads `data/auth.json`, migrates legacy formats)
4. Initialize `SessionManager` (loads recent session metadata, lazy-hydrates messages)
5. Mount static files and register all route modules
6. Apply middleware stack: GZip, CORS, SecurityHeaders, Auth
7. Start Uvicorn (default port 7000)

Environment variables:

| Variable | Default | Purpose |
|---|---|---|
| `AUTH_ENABLED` | `true` | Toggle authentication |
| `ODYSSEUS_DATA_DIR` | `./data` | Writable data directory |
| `DATABASE_URL` | `sqlite:///data/app.db` | Database connection |
| `APP_PORT` | `7000` | Server port |
| `ODYSSEUS_INTERNAL_TOKEN` | auto-generated | Internal tool loopback auth |

## Cross-References

- [[co-fita-harness]] -- The parent harness that owns this dashboard
- [[co-fita-mcp-servers]] -- Deep dive into the MCP server ecosystem
- [[co-fita-kanban]] -- Deep dive into the governance kanban system
- [[mcp-ecosystem]] -- The broader Model Context Protocol ecosystem
- [[fitalabs-infra]] -- Infrastructure and deployment

## Design Philosophy

The dashboard embodies the Co-Fita principle of **emergence over rigid planning**. It is a single-binary, self-contained workspace that does not require Docker, Kubernetes, or any external service broker. SQLite handles persistence. Vanilla JS handles the UI. FastAPI handles the API. The governance system allows the human principal (Alefita) and AI agents to collaboratively evolve the workspace itself through proposals, debates, and congress votes.

> "Systems are hypersigils -- living narratives that manifest reality through code."

The Odysseus Dashboard is the operational surface of that hypersigil.
