Skip to content

seiggy/lucia-dotnet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

498 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Lucia β€” Autonomous Home Assistant AI

.NET Agent Framework License Home Assistant Latest Version

Lucia (pronounced LOO-sha) is an open-source, privacy-focused AI assistant that serves as a complete replacement for Amazon Alexa and Google Home. Built on the Microsoft Agent Framework with a multi-agent architecture, Lucia provides autonomous whole-home automation management through deep integration with Home Assistant. A full-featured React dashboard lets you manage agents, inspect traces, tune configuration, and export training dataβ€”all from a single UI.

β˜€οΈ About the Name

Lucia is named after Lucia, the ancient Nordic sun goddess associated with light, wisdom, and bringing illumination during the darkest time of year. In Norse mythology, Lucia represents the return of light and the power to guide through darknessβ€”a fitting name for an AI assistant that brings intelligent automation and insight to your home.

The name is pronounced LOO-sha (or LOO-thee-ah in traditional Nordic pronunciation), with the emphasis on the first syllable.

🎯 Key Features

  • πŸ€– Multi-Agent Orchestration β€” Router, dispatcher, and result aggregator executors coordinate specialized agents end-to-end using the A2A (Agent-to-Agent) protocol
  • 🧠 Semantic Understanding β€” Natural language processing using embeddings and semantic searchβ€”no rigid command structures required
  • πŸ” HybridEntityMatcher β€” Multi-weighted entity search combining Levenshtein distance, Jaro-Winkler similarity, phonetic matching (Soundex/Metaphone), alias resolution, and embedding similarityβ€”all tunable per-search
  • πŸ”’ Privacy First β€” Fully local operation with optional cloud LLM support; your data stays yours
  • 🏠 Deep Home Assistant Integration β€” Native integration via custom component with agent selection, conversation API, JSON-RPC communication, and WebSocket entity registry access
  • πŸ‘οΈ Entity Visibility Filtering β€” Control which Home Assistant entities Lucia can see via dashboard UI or by pulling the HA exposed-entity list over WebSocket
  • πŸ“Š Live Activity Dashboard β€” Real-time agent mesh visualization with SSE-powered event streaming, summary metrics, and activity timeline
  • πŸ“‹ Management Dashboard β€” React-based dark-themed dashboard with 20+ pages for agent management, trace inspection, configuration, entity management, and dataset exports
  • πŸ§™ Guided Setup Wizard β€” Multi-step onboarding with AI provider configuration, live connectivity tests, agent health gate, and Home Assistant plugin connection
  • πŸ“¦ Kubernetes Ready β€” Cloud-native deployment with .NET Aspire, Helm charts, and K8s manifests
  • ⏰ Alarm Clock System β€” CRON-scheduled alarms with volume ramping, voice dismissal/snooze, presence-based speaker routing, and sound library with file upload
  • πŸ“‘ Presence Detection β€” Auto-discovered motion/occupancy/mmWave sensors with room-level confidence scoring for context-aware automations
  • πŸ“… Scheduled Task System β€” Extensible CRON-based scheduler with MongoDB persistence supporting alarms, timers, and deferred agent actions
  • πŸ”Œ Extensible β€” Script-based plugin system for adding capabilities without recompiling. Plugin repository for discovery and one-click install.
  • πŸ› οΈ Runtime Agent Builder β€” Create custom agents via the dashboard with MCP tool integrationβ€”no code required
  • πŸ”Œ Model Provider System β€” Configure 6+ LLM backends (OpenAI, Azure OpenAI, Azure AI Inference, Ollama, Anthropic, Google Gemini) from the dashboard with per-agent model assignment
  • 🧭 General Knowledge Fallback β€” Built-in general-assistant handles open-ended requests when no specialist is a clean match
  • 🎭 Dynamic Agent Selection β€” Switch between specialized agents (light control, climate, scenes, music, timers, lists, etc.) without reconfiguring
  • πŸ’¬ Conversation Threading β€” Context-aware conversations with proper message threading support
  • ⚑ Two-Tier Prompt Caching β€” Independent routing and chat caches with semantic similarity matching, hot-reloadable thresholds, and infinite retention

Supported Inference Platforms

Platform Status
Azure OpenAI / AI Foundry βœ… Supported
OpenAI βœ… Supported
Ollama βœ… Supported
Anthropic (Claude) βœ… Supported
Google Gemini βœ… Supported
Azure AI Inference βœ… Supported
OpenAI-compatible (Open Router, etc.) βœ… Supported
GitHub Copilot SDK πŸ§ͺ Experimental
ONNX ❌ No function calling support

πŸš€ Quick Start

Prerequisites

  • Docker and Docker Compose
  • Home Assistant instance (2024.12 or later)
  • An LLM provider API key (Azure AI Foundry, OpenAI, Ollama, etc.)

Installation

  1. Create a docker-compose.yml anywhere on your machine:

    services:
      lucia-redis:
        image: redis:8.2-alpine
        container_name: lucia-redis
        networks: [lucia-network]
        ports: ["127.0.0.1:6379:6379"]
        command: >
          redis-server --appendonly yes
          --maxmemory 256mb --maxmemory-policy allkeys-lru
        volumes: [lucia-redis-data:/data]
        healthcheck:
          test: ["CMD", "redis-cli", "PING"]
          interval: 30s
          timeout: 10s
          retries: 3
        restart: unless-stopped
    
      lucia-mongo:
        image: mongo:8.0
        container_name: lucia-mongo
        networks: [lucia-network]
        ports: ["127.0.0.1:27017:27017"]
        volumes: [lucia-mongo-data:/data/db]
        healthcheck:
          test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"]
          interval: 30s
          timeout: 10s
          retries: 3
        restart: unless-stopped
    
      lucia:
        image: seiggy/lucia-agenthost:latest
        container_name: lucia
        depends_on:
          lucia-redis: { condition: service_healthy }
          lucia-mongo: { condition: service_healthy }
        networks: [lucia-network]
        ports: ["7233:8080"]
        environment:
          - ASPNETCORE_ENVIRONMENT=Production
          - ASPNETCORE_URLS=http://+:8080
          - ConnectionStrings__luciatraces=mongodb://lucia-mongo:27017/luciatraces
          - ConnectionStrings__luciaconfig=mongodb://lucia-mongo:27017/luciaconfig
          - ConnectionStrings__luciatasks=mongodb://lucia-mongo:27017/luciatasks
          - ConnectionStrings__redis=lucia-redis:6379
          - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
          - DOTNET_RUNNING_IN_CONTAINER=true
        healthcheck:
          test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"]
          interval: 30s
          timeout: 10s
          retries: 3
        restart: unless-stopped
    
    networks:
      lucia-network:
        driver: bridge
    
    volumes:
      lucia-redis-data:
      lucia-mongo-data:
  2. Start the stack

    docker compose up -d

Docker Image Variants

Image Tag GPU Size Use Case
seiggy/lucia-agenthost:latest None ~250MB Base orchestration (no voice)
seiggy/lucia-agenthost:voice NVIDIA CUDA 12.8 ~3GB Voice + NVIDIA GPU acceleration
seiggy/lucia-agenthost:voice-cpu None ~3GB Voice with CPU-only inference
seiggy/lucia-agenthost:ha-mono None ~350MB Home Assistant add-on (mono-container, no Redis/MongoDB)
Self-build only AMD ROCm 6.4 ~25GB Voice + AMD GPU acceleration

Note: The ROCm image is not published to Docker Hub due to its ~25GB size exceeding CI storage limits. AMD GPU users can build it locally:

docker build -t lucia:voice-rocm -f infra/docker/Dockerfile.voice-rocm .

The image is large because AMD's ROCm runtime (~20GB) is much less modular than NVIDIA's CUDA runtime (~1.5GB). This is an upstream constraint. If disk space is a concern, the voice-cpu image provides CPU-only inference that is still fast enough for real-time voice processing on modern hardware.

To use the voice variants, change the image in your docker-compose.yml:

# NVIDIA GPU (requires nvidia-container-toolkit)
image: seiggy/lucia-agenthost:voice

# AMD GPU (requires ROCm kernel driver + --device /dev/kfd --device /dev/dri)
image: seiggy/lucia-agenthost:voice-rocm

# CPU only (no GPU requirements)
image: seiggy/lucia-agenthost:voice-cpu

Home Assistant Add-on (Mono-Container)

The ha image variant runs Lucia as a single container with no external dependencies β€” no Redis, no MongoDB. It uses in-memory caching and SQLite for persistence, making it ideal for Home Assistant add-on deployments or resource-constrained devices.

Quick Start

docker build -f infra/docker/Dockerfile.ha -t lucia:ha .

docker run -d \
  --name lucia \
  --network host \
  -v lucia-data:/data \
  -v lucia-models:/app/models \
  -v lucia-plugins:/app/plugins \
  lucia:ha

Volumes

Mount Point Purpose Required
/data SQLite database (lucia.db) β€” all configuration, traces, tasks, and user data Yes β€” data persists across restarts
/app/models Wyoming voice models (STT, VAD, wake word, speaker embedding) Recommended β€” avoids re-downloading models
/app/plugins Lua/script plugins Optional

Ports

Port Protocol Purpose
8099 HTTP Web dashboard and REST API
10400 TCP Wyoming voice protocol

Environment Variables

Variable Default Description
DataProvider__Cache InMemory Cache backend (InMemory or Redis)
DataProvider__Store SQLite Persistence backend (SQLite or MongoDB)
DataProvider__SqlitePath /data/lucia.db SQLite database file path
HomeAssistant__BaseUrl β€” Home Assistant URL (e.g. http://homeassistant.local:8123)
HomeAssistant__AccessToken β€” Home Assistant long-lived access token

Data Provider Configuration

Lucia supports pluggable data providers, letting you choose between full-scale (Redis + MongoDB) and lightweight (InMemory + SQLite) backends:

Configuration Cache Store Use Case
Default Redis MongoDB Full deployment with dedicated infrastructure
Lightweight InMemory SQLite Home Assistant add-on, single-container, resource-constrained
Hybrid InMemory MongoDB Reduce infrastructure while keeping durable document store
Hybrid Redis SQLite Shared cache with embedded persistence

To switch providers on any deployment, set the environment variables:

# Lightweight mode (no external dependencies)
-e DataProvider__Cache=InMemory
-e DataProvider__Store=SQLite

# Default mode (requires Redis + MongoDB)
-e DataProvider__Cache=Redis
-e DataProvider__Store=MongoDB

Note: The HA image (Dockerfile.ha) defaults to InMemory + SQLite. The standard images (Dockerfile, Dockerfile.voice*) default to Redis + MongoDB.

  1. Open the Lucia Dashboard

    Navigate to http://localhost:7233. On first launch, the setup wizard guides you through configuration:

    Setup Wizard β€” Welcome

    Step 1 β€” Welcome: Overview of what the wizard will configure.

    Setup Wizard β€” Configure

    Step 2 β€” Configure: Generate a Dashboard API key and connect to your Home Assistant instance by entering its URL and a long-lived access token.

    Setup Wizard β€” Connect

    Step 3 β€” Connect HA Plugin: Generate an API key for the Home Assistant custom component, configure it in HA, and wait for the plugin to connect back to Lucia.

    Setup Wizard β€” Done

    Step 4 β€” Done: Setup is complete. You'll use the generated API key to sign in.

  2. Sign in to the Dashboard

    Login

    Enter the API key generated during setup to access the full dashboard.

  3. Install the Home Assistant Integration

    Option A: HACS (Recommended)

    1. Go to HACS β†’ Integrations β†’ three-dot menu β†’ Custom repositories
    2. Add repository URL: https://github.com/seiggy/lucia-dotnet
    3. Select category: Integration β†’ Click "Add"
    4. Find "Lucia" in HACS and click "Download"
    5. Restart Home Assistant
    6. Add integration: Settings β†’ Devices & Services β†’ Add Integration β†’ Lucia

    Option B: Manual Installation

    cp -r custom_components/lucia /path/to/homeassistant/custom_components/
    # Restart Home Assistant, then add the integration via UI

πŸ“Š Dashboard

Lucia includes a full-featured React dashboard for managing your agent platform. Built with React 19, Vite 7, TanStack Query, and Tailwind CSS, it runs as part of the Aspire-orchestrated development stack.

Activity

Activity Dashboard

The default landing page shows real-time platform metrics and a live agent mesh visualization. Summary cards display total requests, error rate, cache hit rate, and task completion. The interactive mesh graph (powered by React Flow) shows the orchestrator, agents, and tools with animated connections during active requests. A live activity feed streams SSE events as they happenβ€”routing decisions, tool calls, agent completions, and errorsβ€”all in real time.

Traces

Traces

Monitor every conversation passing through the orchestrator. Filter by label, agent, and date range. View stats at a glance with color-coded counters for positive, negative, unlabeled, and errored traces. Click any trace to see the full routing decision, agent execution details, and tool calls.

Agents

Agent Registry

View all registered agents with their capabilities, skills, and connection status. Register new A2A agents, refresh agent metadata, and send test messages directly from the dashboard. Each agent card shows its version, endpoint URL, supported capabilities (Push, Streaming, History), and associated skills.

Agent Definitions

Agent Definitions

Create and manage custom agents at runtimeβ€”no code changes required. Each agent definition includes a name, system prompt, optional model connection override, and a granular MCP tool picker. Tags indicate system vs. user-defined agents. Changes take effect immediately; agents are loaded from MongoDB on each invocation.

Model Providers

Model Providers

Manage LLM provider connections across the platform. Configure Azure AI Foundry, OpenAI, Ollama, and other OpenAI-compatible endpoints. Each provider card shows the model name, endpoint URL, and deployment type. Copilot-connected models display a badge.

MCP Servers

MCP Servers

Register and manage MCP (Model Context Protocol) tool servers. Add stdio-based local tools (e.g., dnx .NET tools) or remote HTTP/SSE servers. Connect servers to discover available tools, view connection status, and manage environment variables and authentication headers.

Configuration

Configuration

Schema-driven configuration editor with categorized settings. Manage Home Assistant connection details, orchestration parameters (RouterExecutor, AgentInvoker, ResultAggregator), Redis/MongoDB connection strings, Music Assistant integration, trace capture settings, and agent definitionsβ€”all from one page. Sensitive values are masked with a "Show secrets" toggle. Mobile-friendly with a dropdown category selector on small screens.

Dataset Exports

Exports

Export labeled conversation traces as training datasets. Filter by label, date range, and agent. Optionally include human corrections for RLHF-style fine-tuning. View export history and re-download previous exports.

Prompt Cache

Prompt Cache

Monitor the routing prompt cache that accelerates repeated queries. View cache statistics (total entries, hit rate, hits vs misses), browse cached entries with their routed agents and confidence scores, and clear the cache when needed. Tabbed view separates Router and Agent cache namespaces with independent stats.

Tasks

Tasks

Track active and archived tasks with status counters (Active, Completed, Failed, Cancelled). Switch between Active Tasks and Task History views to monitor ongoing work and review completed operations.

Entity Location

Manage the Home Assistant entity hierarchy β€” floors, areas, and entities β€” with visibility controls. Toggle entity visibility to control which devices Lucia agents can see. Pull the HA exposed-entity list over WebSocket for pre-filtered entity management. Search and filter entities by area, domain, or name.

Matcher Debug

Interactive testing page for the HybridEntityMatcher. Enter a search query and see scored results with per-signal breakdowns (Levenshtein, Jaro-Winkler, phonetic, embedding similarity, alias match). Useful for tuning match weights and diagnosing entity resolution issues.

πŸ—οΈ Architecture

Lucia uses the A2A (Agent-to-Agent) Protocol with JSON-RPC 2.0 for agent communication. The orchestrator routes incoming requests to the best-fit specialized agent, with results aggregated and returned to Home Assistant.

graph TB
    HA[Home Assistant] <-->|Conversation API| HP[Lucia Custom Component]
    HP <-->|JSON-RPC| AH[AgentHost]

    AH <--> O[Orchestrator]
    O <--> Router[RouterExecutor]
    O <--> Dispatch[AgentDispatchExecutor]
    O <--> Agg[ResultAggregatorExecutor]

    Dispatch <--> LA[LightAgent]
    Dispatch <--> CA[ClimateAgent]
    Dispatch <--> SA[SceneAgent]
    Dispatch <--> LiA[ListsAgent]
    Dispatch <--> GA[GeneralAgent]
    Dispatch <-->|A2A| A2A[A2AHost]

    A2A <--> MA[MusicAgent]
    A2A <--> TA[TimerAgent]

    AH <--> DB[(MongoDB)]
    AH <--> Cache[(Redis)]
    AH <--> Dashboard[React Dashboard]

    subgraph "LLM Providers"
        Azure[Azure AI Foundry]
        OAI[OpenAI]
        Ollama[Ollama]
        Anthropic[Anthropic]
        Gemini[Google Gemini]
    end

    Router -.-> Azure
    LA -.-> Azure
    GA -.-> OAI
    MA -.-> Azure
Loading

Communication Flow

  1. User Input β†’ Home Assistant receives a voice or text command
  2. Conversation API β†’ Lucia custom component sends the message via JSON-RPC
  3. Orchestrator β†’ RouterExecutor selects the best agent using semantic matching and prompt caching
  4. Agent Dispatch β†’ AgentDispatchExecutor forwards the request (in-process or via A2A)
  5. LLM Processing β†’ The selected agent calls its LLM with domain-specific tools
  6. Result Aggregation β†’ ResultAggregatorExecutor formats the final response
  7. Response β†’ JSON-RPC response returned to Home Assistant for speech output

Key Components

Component Description
AgentHost (lucia.AgentHost) Main API server hosting the orchestrator, agents, auth, configuration, and dashboard proxy
A2AHost (lucia.A2AHost) Satellite host for running agents as separate processes (MusicAgent, TimerAgent)
Orchestrator (lucia.Agents/Orchestration) Router β†’ Dispatch β†’ Aggregator pipeline for multi-agent coordination
Dashboard (lucia-dashboard) React 19 SPA with 20+ pages for management, traces, entity control, exports, and configuration
Home Assistant Integration (custom_components/lucia) Python custom component with conversation platform
HomeAssistant Client (lucia.HomeAssistant) Strongly-typed .NET client for the HA REST and WebSocket APIs
Entity Location Service (lucia.Agents/Services) Centralized entity resolution with hierarchical floor/area/entity search and Redis caching
HybridEntityMatcher (lucia.Agents/Models) Multi-weighted entity matching engine (Levenshtein, Jaro-Winkler, phonetic, embeddings, aliases)
Model Provider System (lucia.Agents/Services) Configurable LLM backend management with per-agent model assignment and connection testing
Plugin System (lucia.Agents/Extensions) Roslyn script plugin engine with four-hook lifecycle, repository management, and dashboard UI
Alarm Clock System (lucia.Agents/Alarms) CRON-scheduled alarms with volume ramping, sound library, and voice dismissal
Presence Detection (lucia.Agents/Services) Auto-discovered room-level presence with confidence-weighted sensor fusion

πŸ“ Project Structure

lucia-dotnet/
β”œβ”€β”€ lucia.AppHost/                # .NET Aspire orchestrator (recommended dev entrypoint)
β”œβ”€β”€ lucia.AgentHost/              # ASP.NET Core API host
β”‚   β”œβ”€β”€ Auth/                     # API key authentication and session management
β”‚   β”œβ”€β”€ Extensions/               # Setup, Configuration, A2A, Plugin, and Auth API endpoints
β”‚   └── plugins/                  # Agent Framework plugins
β”œβ”€β”€ lucia.A2AHost/                # A2A satellite agent host
β”‚   β”œβ”€β”€ AgentRegistry/            # Agent card registration
β”‚   β”œβ”€β”€ Extensions/               # A2A endpoint mapping
β”‚   └── Services/                 # Agent initialization
β”œβ”€β”€ lucia.Agents/                 # Shared agent implementations and orchestration
β”‚   β”œβ”€β”€ Abstractions/             # ILuciaPlugin, IWebSearchSkill, IEntityLocationService, IHybridEntityMatcher
β”‚   β”œβ”€β”€ Agents/                   # GeneralAgent, LightAgent, ClimateAgent, SceneAgent, ListsAgent, OrchestratorAgent
β”‚   β”œβ”€β”€ Configuration/            # Plugin, repository, and manifest models
β”‚   β”œβ”€β”€ Extensions/               # PluginLoader, PluginScriptHost, service registrations
β”‚   β”œβ”€β”€ Integration/              # SearchTermCache, SearchTermNormalizer
β”‚   β”œβ”€β”€ Models/                   # HybridEntityMatcher, HomeAssistantEntity, HybridMatchOptions
β”‚   β”œβ”€β”€ Orchestration/            # RouterExecutor, AgentDispatchExecutor, etc.
β”‚   β”œβ”€β”€ Registry/                 # Agent discovery and registration
β”‚   β”œβ”€β”€ Services/                 # EntityLocationService, PresenceDetection, PluginManagement, ModelProviders
β”‚   β”œβ”€β”€ Skills/                   # LightControlSkill, ClimateControlSkill, FanControlSkill, SceneControlSkill, ListSkill
β”‚   └── Training/                 # Trace capture and export
β”œβ”€β”€ lucia.MusicAgent/             # Music Assistant playback agent (A2AHost)
β”œβ”€β”€ lucia.TimerAgent/             # Timer and reminder agent (A2AHost)
β”œβ”€β”€ lucia.Data/                  # Lightweight data providers (InMemory cache + SQLite repositories)
β”œβ”€β”€ lucia.HomeAssistant/          # Strongly-typed HA REST API client
β”‚   β”œβ”€β”€ Models/                   # Entity, state, and service models
β”‚   β”œβ”€β”€ Services/                 # IHomeAssistantClient implementation
β”‚   └── Configuration/            # Client settings
β”œβ”€β”€ lucia-dashboard/              # React 19 + Vite 7 management dashboard
β”‚   └── src/
β”‚       β”œβ”€β”€ pages/                # Activity, Traces, Agents, AgentDefs, ModelProviders, McpServers, Config, Exports, Cache, Tasks, Alarms, Presence, Plugins, EntityLocation, MatcherDebug, SkillOptimizer, Lists
β”‚       β”œβ”€β”€ components/           # MeshGraph, PluginRepoDialog, RestartBanner, shared UI
β”‚       β”œβ”€β”€ hooks/                # useActivityStream and custom React hooks
β”‚       β”œβ”€β”€ context/              # Auth context and providers
β”‚       └── api.ts                # API client functions
β”œβ”€β”€ plugins/                      # Plugin scripts (each subfolder = one plugin)
β”‚   β”œβ”€β”€ metamcp/plugin.cs         # MetaMCP tool aggregation bridge
β”‚   └── searxng/plugin.cs         # SearXNG web search skill
β”œβ”€β”€ lucia-plugins.json            # Official plugin repository manifest
β”œβ”€β”€ lucia.ServiceDefaults/        # OpenTelemetry, health checks, resilience
β”œβ”€β”€ lucia.Tests/                  # xUnit tests (unit, integration, eval, plugin system)
β”œβ”€β”€ custom_components/lucia/      # Home Assistant Python custom component
β”‚   β”œβ”€β”€ conversation.py           # JSON-RPC conversation platform
β”‚   β”œβ”€β”€ config_flow.py            # HA configuration UI with agent selection
β”‚   └── translations/             # Multi-language UI strings
└── infra/                        # Deployment infrastructure
    β”œβ”€β”€ docker/                   # Dockerfiles and docker-compose.yml
    β”œβ”€β”€ kubernetes/
    β”‚   β”œβ”€β”€ manifests/            # K8s YAML manifests
    β”‚   └── helm/                 # Helm chart
    └── systemd/                  # systemd service units

πŸ”§ Configuration

Lucia uses a schema-driven configuration system stored in MongoDB. On first run, the setup wizard guides you through the essential settings. After setup, all configuration can be managed through the dashboard's Configuration page.

Headless setup (Docker / env)

When deploying with Docker or automation, you can skip the setup wizard by providing all required values via environment variables. If both a dashboard API key and a Home Assistant connection are present (in the config store or seeded from env), Lucia marks setup complete and the wizard is not shown.

Variable Purpose
DASHBOARD_API_KEY Dashboard login key (e.g. lk_...). Used to seed the Dashboard API key.
HOMEASSISTANT__BASEURL Home Assistant instance URL (e.g. http://homeassistant.local:8123).
HOMEASSISTANT__ACCESSTOKEN Long-lived access token from HA (Profile β†’ Long-Lived Access Tokens).
LUCIA_HA_API_KEY Optional: API key for the Home Assistant integration (same as shown in the wizard).
MUSICASSISTANT__INTEGRATIONID Optional: HA Music Assistant config entry ID for the music agent.

The Docker image includes the official plugins (MetaMCP, SearXNG) under /app/plugins. To register tools from env without using the dashboard:

Variable Purpose
SEARXNG_URL When set, the General Agent gets a web_search tool (SearXNG instance URL).
METAMCP_URL When set, MetaMCP is seeded as an MCP tool server (full URL to SSE or MCP endpoint).
METAMCP_API_KEY Optional: Bearer token for MetaMCP (e.g. from Open Web UI Dashboard β†’ Keys).

See infra/docker/.env.lucia.example for a full template. ComfyUI, Whisper, Piper, and Wyoming env vars are not used by Lucia (they may be used by other stacks such as Open Web UI).

Key Configuration Sections

Section Description
HomeAssistant Base URL, access token, API timeout, SSL validation
RouterExecutor Agent routing model, semantic similarity threshold
AgentInvoker Agent execution timeout settings
ResultAggregator Response aggregation settings
Redis Connection string and task persistence TTL
MusicAssistant Music Assistant integration settings
TraceCapture Conversation trace storage settings
ConnectionStrings AI Foundry, MongoDB, and Redis connection details
Agents Agent definitions and registration
ModelProviders LLM backend configurations (per-agent model assignment)
PromptCache Routing and chat cache thresholds (hot-reloadable)

Home Assistant Integration Setup

After installing the custom component:

  1. Go to Settings β†’ Devices & Services β†’ Add Integration β†’ Lucia
  2. Enter your Agent Repository URL (e.g., https://localhost:7235)
  3. Add the API Key generated during dashboard setup
  4. Configure agent selection β€” choose from discovered agents in the dropdown
  5. Set as your conversation agent under Settings β†’ Voice Assistants β†’ Assist

🀝 Agent System

A2A Protocol (Agent-to-Agent)

Agents communicate via the A2A Protocol with JSON-RPC 2.0. The AgentHost runs in-process agents (LightAgent, ClimateAgent, SceneAgent, ListsAgent, GeneralAgent, Orchestrator) while the A2AHost runs satellite agents (MusicAgent, TimerAgent) as separate processes.

Agent Discovery

# List all registered agents
curl http://localhost:5151/agents

Sending Messages

curl -X POST http://localhost:5151/a2a/light-agent \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "message/send",
    "params": {
      "message": {
        "kind": "message",
        "role": "user",
        "parts": [{"kind": "text", "text": "Turn on the living room lights"}],
        "messageId": "550e8400-e29b-41d4-a716-446655440000",
        "contextId": "550e8400-e29b-41d4-a716-446655440001"
      }
    },
    "id": 1
  }'

Creating Custom Agents (Runtime)

Lucia supports creating agents at runtime through the dashboard UI. Custom agents are stored in MongoDB and loaded dynamicallyβ€”no code changes or restarts required.

1. Register MCP Tool Servers

Navigate to MCP Servers in the dashboard and add your tool servers:

  • stdio transports β€” local processes (e.g., dnx my-tool, npx @scope/tool). The container ships with the .NET SDK, so dnx tools work out of the box. For npx, python, or other runtimes, extend the container image.
  • HTTP/SSE transports β€” remote MCP servers accessible via URL.

After adding a server, click Connect then Discover Tools to see available tools.

2. Define an Agent

Navigate to Agent Definitions and click New Agent:

Field Description
Name Unique agent identifier (e.g., research-agent)
Display Name Human-readable name for the dashboard
Instructions System prompt that defines the agent's behavior
Model Connection Optional override (blank = default model)
MCP Tools Select individual tools from registered MCP servers

3. Use the Agent

Once saved, the agent is immediately available to the orchestrator's router. The router considers the agent's description and tool capabilities when making routing decisions. No reload requiredβ€”agents are loaded from MongoDB on each invocation.

Extending the container for non-.NET runtimes:

# Example: Add Node.js for npx-based MCP tools
FROM ghcr.io/seiggy/lucia-dotnet:latest
RUN apt-get update && apt-get install -y nodejs npm

πŸ”Œ Plugin System

Lucia features a script-based plugin system powered by Roslyn CSharpScript. Plugins are plain C# files β€” no project files, no separate DLLs, no compilation step. Drop a folder with a plugin.cs into the plugins/ directory and Lucia loads it at startup.

Plugin Lifecycle

Plugins implement the ILuciaPlugin interface and participate in four lifecycle hooks, called in order:

Hook When Use Case
ConfigureServices(IHostApplicationBuilder) Before app is built Register DI services (e.g., IWebSearchSkill)
ExecuteAsync(IServiceProvider, CancellationToken) After app is built, before HTTP starts Run initialization, seed data
MapEndpoints(WebApplication) During endpoint registration Add custom HTTP endpoints
OnSystemReadyAsync(IServiceProvider, CancellationToken) After all agents are online Logic that depends on agents or Home Assistant

All hooks have default no-op implementations β€” only override what you need.

Creating a Plugin

1. Create a folder under plugins/ with your plugin's ID:

plugins/
└── my-plugin/
    └── plugin.cs

2. Write your plugin.cs β€” the script must define a class implementing ILuciaPlugin and end with an expression that returns an instance of it:

// plugins/my-plugin/plugin.cs
using lucia.Agents.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

public class MyPlugin : ILuciaPlugin
{
    public string PluginId => "my-plugin";

    public void ConfigureServices(IHostApplicationBuilder builder)
    {
        // Register services into the DI container before the app is built
        builder.Services.AddSingleton<IMyService, MyServiceImpl>();
    }

    public async Task ExecuteAsync(IServiceProvider services, CancellationToken ct = default)
    {
        var logger = services.GetRequiredService<ILoggerFactory>().CreateLogger("MyPlugin");
        logger.LogInformation("My plugin initialized.");
    }

    public async Task OnSystemReadyAsync(IServiceProvider services, CancellationToken ct = default)
    {
        // Agents and Home Assistant are fully available here
        var logger = services.GetRequiredService<ILoggerFactory>().CreateLogger("MyPlugin");
        logger.LogInformation("System ready β€” all agents online.");
    }
}

// The last expression MUST return an ILuciaPlugin instance
new MyPlugin()

3. That's it. Restart Lucia and your plugin will be discovered and loaded automatically.

Available Namespaces and Assemblies

Plugin scripts run in a sandboxed Roslyn environment with a curated set of assemblies and auto-imported namespaces. You do not need using directives for these β€” they are pre-imported:

Auto-imported namespaces:

Namespace Description
System Core .NET types
System.Collections.Generic Lists, dictionaries, etc.
System.Linq LINQ query operators
System.Threading CancellationToken, synchronization
System.Threading.Tasks Task, ValueTask, async patterns
System.Net.Http HttpClient, IHttpClientFactory
lucia.Agents.Abstractions ILuciaPlugin, IWebSearchSkill, etc.
Microsoft.Extensions.DependencyInjection IServiceCollection, AddSingleton, etc.
Microsoft.Extensions.Hosting IHostApplicationBuilder, BackgroundService
Microsoft.Extensions.Logging ILogger, ILoggerFactory
Microsoft.Extensions.Configuration IConfiguration
Microsoft.Extensions.AI AITool, AIFunctionFactory

Additional assemblies available (require explicit using in your script):

Assembly Key Types
System.Text.Json JsonSerializer, JsonSerializerOptions
System.ComponentModel.Primitives DescriptionAttribute
System.Diagnostics.DiagnosticSource ActivitySource, Meter, Counter<T>, Histogram<T>
Microsoft.AspNetCore WebApplication, IEndpointRouteBuilder

Note: If you need an assembly that isn't listed above, the plugin won't compile. File an issue or PR to add it to the host's reference set in PluginScriptHost.cs.

Plugin Examples

MetaMCP Bridge (plugins/metamcp/) β€” Seeds a MetaMCP tool server into the agent registry when METAMCP_URL (and optionally METAMCP_API_KEY) are set. The plugin runs in OnSystemReadyAsync so the host invokes it after agents and HA are ready.

SearXNG Web Search (plugins/searxng/) β€” Registers IWebSearchSkill so the GeneralAgent gains web search:

public sealed class SearXngPlugin : ILuciaPlugin
{
    public string PluginId => "searxng";

    public void ConfigureServices(IHostApplicationBuilder builder)
    {
        var url = builder.Configuration["SearXng:BaseUrl"];
        if (!string.IsNullOrWhiteSpace(url))
        {
            builder.Services.AddSingleton<IWebSearchSkill>(sp =>
                new SearXngWebSearchSkill(
                    sp.GetRequiredService<IHttpClientFactory>(),
                    url,
                    sp.GetRequiredService<ILoggerFactory>().CreateLogger<SearXngWebSearchSkill>()));
        }
    }
}
// ... skill class, then:
new SearXngPlugin()

Plugin Repository System

Plugins can be discovered, installed, and managed through the dashboard's Plugins page. Repositories are remote or local sources that provide a manifest of available plugins.

Repository Manifest (lucia-plugins.json)

Every repository is defined by a lucia-plugins.json manifest file:

{
  "id": "lucia-official",
  "name": "Lucia Official Plugins",
  "plugins": [
    {
      "id": "metamcp",
      "name": "MetaMCP Bridge",
      "description": "Bridges MetaMCP tool aggregation into Lucia agents.",
      "version": "1.0.0",
      "path": "plugins/metamcp"
    },
    {
      "id": "searxng",
      "name": "SearXNG Web Search",
      "description": "Privacy-respecting web search via SearXNG.",
      "version": "1.0.0",
      "path": "plugins/searxng"
    }
  ]
}
Field Required Description
id βœ… Unique repository identifier
name βœ… Human-readable repository name
plugins βœ… Array of plugin entries
plugins[].id βœ… Unique plugin identifier
plugins[].name βœ… Display name
plugins[].description βœ… Short description
plugins[].version βœ… SemVer version string
plugins[].path βœ… Path to the plugin folder, relative to the repo root
plugins[].author ❌ Author name
plugins[].tags ❌ Array of tags for categorization

Creating Your Own Plugin Repository

To publish your own plugins as a repository:

  1. Create a GitHub repository with your plugins under a plugins/ directory
  2. Add a lucia-plugins.json at the repo root with your manifest
  3. Each plugin must have a plugin.cs entry point in its folder
  4. Add the repo in Lucia β€” go to Plugins β†’ Repositories β†’ Add Repository, enter your GitHub URL and branch

Git Blob Source Strategies

When adding a Git-based repository, the blobSource field controls how plugin archives are downloaded:

Strategy Behavior
release (default) Fetches the latest GitHub Release. Looks for a {pluginId}.zip asset first, falls back to the release zipball, then to a branch archive. Best for production repositories.
tag Downloads the archive at a specific tag (Branch field = tag name). Useful for pinning to a known version.
branch Downloads the archive at branch HEAD. Best for development or bleeding-edge tracking.

The release strategy is recommended for production use β€” publish per-plugin zip files as GitHub Release assets for the fastest, most targeted downloads.

Managing Plugins via the Dashboard

The Plugins page has three tabs:

  • Installed β€” View, enable/disable, and uninstall plugins. Changes require an app restart (a banner will prompt you).
  • Store β€” Browse available plugins from all configured repositories. One-click install.
  • Repositories β€” Add, remove, and sync plugin repositories. Supports both local (development) and Git (production) sources.

πŸ§ͺ Development

Prerequisites

Building from Source

# Build the entire solution
dotnet build lucia-dotnet.slnx

# Run via Aspire (recommended β€” starts all services in mesh mode)
dotnet run --project lucia.AppHost

# Run tests (excludes slow eval tests)
dotnet test --filter 'Category!=Eval'

# Run all tests including LLM-based evals
dotnet test

# Run AgentHost directly (without Aspire)
dotnet run --project lucia.AgentHost

# Dashboard dev server (standalone)
cd lucia-dashboard && npm install && npm run dev

Service Endpoints

When running via Aspire AppHost:

Service HTTP HTTPS
AgentHost API http://localhost:5151 https://localhost:7235
Dashboard Assigned by Aspire β€”
Aspire Dashboard β€” https://localhost:17274
API Documentation (Scalar) β€” https://localhost:7235/scalar
Health Check http://localhost:5151/health β€”

Building the Docker Image Locally

To build from source instead of using the pre-built image:

git clone https://github.com/seiggy/lucia-dotnet.git
cd lucia-dotnet/infra/docker
docker compose up -d

The docker-compose.yml in the repo builds the image from the local Dockerfile. See infra/docker/DEPLOYMENT.md for the full deployment guide.

🐳 Deployment

Deployment Modes

Lucia supports two deployment topologies controlled by the Deployment__Mode environment variable:

Mode Value Description
Standalone (default) standalone All agents (Music, Timer, etc.) run embedded in the main AgentHost process. Simplest setup β€” single container plus Redis and MongoDB, or zero-dependency with the HA image (InMemory + SQLite). Recommended for most users.
Mesh mesh Agents run as separate A2A containers that register with the AgentHost over the network. Used for Kubernetes deployments, horizontal scaling, or multi-node distribution.

⚠️ Single-Instance Constraint: The AgentHost must run as a single instance (no horizontal scaling via replicas). The in-memory ScheduledTaskStore and ActiveTimerStore hold active alarms and timers β€” running multiple replicas would split scheduled task state across instances. For high availability, use a single replica with fast restart policies rather than multiple replicas behind a load balancer. This constraint applies to both standalone and mesh modes (the AgentHost itself must be single-instance; mesh agents can scale independently).

When to use each mode:

  • Standalone β€” Home lab, single-server, Docker Compose, or any deployment where simplicity matters. External A2A agents can still connect to a standalone AgentHost.
  • Mesh β€” Kubernetes clusters, multi-node setups, or when you want to scale individual agents independently. The Helm chart and K8s manifests default to mesh mode.

To switch modes, add the environment variable to your docker-compose.yml:

environment:
  - Deployment__Mode=mesh

Kubernetes

# Using manifests
kubectl apply -f infra/kubernetes/manifests/

# Using Helm
helm install lucia infra/kubernetes/helm/lucia-helm \
  --namespace lucia --create-namespace

The Kubernetes deployment runs in mesh mode by default, with Music Agent and Timer Agent as separate pods. See infra/kubernetes/ for manifests and Helm chart documentation.

systemd

For bare-metal or VM deployments, systemd service units are provided in infra/systemd/.

Home Assistant Add-on

Lucia can run as a Home Assistant add-on using the mono-container image:

  1. Build: docker build -f infra/docker/Dockerfile.ha -t lucia:ha .
  2. The add-on configuration is in ha-addon/ with config.yaml for the HA Supervisor
  3. All data persists in /data/lucia.db (SQLite) β€” back up this single file to preserve your configuration, traces, and scheduled tasks

See Home Assistant Add-on (Mono-Container) for full setup details.

πŸ“Š Monitoring and Observability

Lucia includes OpenTelemetry instrumentation out of the box via the lucia.ServiceDefaults project:

  • Traces β€” Distributed tracing across orchestrator, agents, and Home Assistant API calls
  • Metrics β€” Request rates, agent execution duration, LLM token usage
  • Logs β€” Structured logging with correlation IDs and agent-specific filtering

The Aspire Dashboard provides built-in log aggregation, trace visualization, and metrics during development. Lucia's own Activity Dashboard shows a live agent mesh graph and real-time event stream. For production, export to Prometheus, Grafana, Jaeger, or any OTLP-compatible backend.

πŸ—ΊοΈ Roadmap

βœ… Completed

  • Multi-agent orchestration with Router β†’ Dispatch β†’ Aggregator pipeline
  • LightAgent with semantic entity search
  • ClimateAgent with HVAC and fan control
  • SceneAgent for scene activation and management
  • ListsAgent for todo and reminder list management
  • MusicAgent for Music Assistant playback
  • TimerAgent with background timer lifecycle and satellite announce
  • Entity Location Service with floor/area/alias/feature resolution
  • HybridEntityMatcher with multi-weighted search (Levenshtein, Jaro-Winkler, phonetic, embeddings, aliases)
  • Unified entity architecture with HomeAssistantEntity base class and domain subtypes
  • Entity visibility filtering with dashboard controls and HA exposed-entity WebSocket support
  • Model Provider system with 6+ LLM backends configurable from the dashboard
  • Runtime MCP tool server registration and dynamic agent definitions with hot-reload
  • A2A Protocol (JSON-RPC 2.0) implementation
  • Home Assistant custom component with agent selection
  • Guided setup wizard with AI provider configuration, agent health gate, and resume flow
  • React management dashboard (20+ pages) with traces, entity management, exports, configuration
  • Live Activity Dashboard with real-time agent mesh visualization
  • Full OpenTelemetry coverage for LLM calls (gen_ai.* spans)
  • Per-agent error rate metrics and observability
  • Two-tier prompt caching (routing + chat) with semantic similarity and hot-reloadable thresholds
  • Helm charts and Kubernetes manifests
  • Multi-LLM support (Azure AI Foundry, OpenAI, Ollama, Anthropic, Google Gemini, Azure AI Inference)
  • Dataset export for fine-tuning workflows
  • Schema-driven configuration system
  • Playwright E2E tests for all agent routing modes
  • Scheduled Task System with CRON scheduling and MongoDB persistence
  • Alarm Clock System with volume ramping and voice dismissal
  • Presence Detection Service with auto-discovered sensors and confidence levels
  • Alarm Clocks dashboard page with CRON builder and sound management
  • Presence Detection dashboard page with sensor management
  • Alarm sound file upload with HA media library integration
  • Mesh mode deployment hardening (conditional service registration, URL resolution, endpoint deduplication)
  • Script-based plugin system with Roslyn CSharpScript, four-hook lifecycle, and plugin repository management
  • Plugin dashboard with store, install/uninstall, enable/disable, and repository management
  • Internal token authentication for service-to-service A2A communication
  • SemVer versioning with preview release support in CI/CD
  • Matcher debug API and dashboard page for testing entity search queries
  • Pluggable data providers (InMemory + SQLite) for mono-container deployment
  • Home Assistant add-on Dockerfile with CPU-only ONNX

πŸ”„ In Progress

  • Unified entity search pipeline (replacing per-skill entity lookups with HybridEntityMatcher)
  • WebSocket real-time event streaming from Home Assistant (persistent connection)
  • HACS store listing for one-click installation

⏳ Planned

  • CalendarAgent (calendar management and scheduling)
  • SecurityAgent (security monitoring and alerts)
  • Pattern recognition and automation suggestions
  • Local LLM optimization (Ollama performance tuning, edge deployment)
  • Voice integration (local STT/TTS)
  • GitHub Copilot SDK as a first-class LLM provider
  • Mobile companion app

See .docs/product/roadmap.md for the detailed roadmap.

🀝 Contributing

We welcome contributions! Whether you're fixing bugs, adding agents, or improving documentation.

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes following existing code style and conventions
  4. Add tests for new functionality
  5. Commit using conventional commits: git commit -m 'feat: add amazing feature'
  6. Push and open a Pull Request

Areas for Contribution

  • πŸ€– New specialized agents (security, calendar, media, etc.)
  • πŸ”Œ Community plugins (search providers, notification services, calendar integrations)
  • 🧠 Additional LLM provider integrations
  • 🏠 Enhanced Home Assistant integrations
  • πŸ“Š Dashboard features and improvements
  • πŸ“š Documentation
  • πŸ§ͺ Test coverage
  • 🌍 Translations for the Home Assistant custom component

πŸ“„ License

This project is licensed under the MIT License β€” see the LICENSE file for details.

πŸ™ Acknowledgments

πŸ“ž Support


Built with ❀️ for the Home Assistant community

About

Lucia is your whole home assistant that you always wanted

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors