AI Assistant

Configuration > AI Assistant connects Athena to your own local, OpenAI-compatible model servers - Chat, Speech to text, and Text to speech are three fully independent servers, so nothing requires all three to actually be the same instance. Athena appends the standard API paths itself (/v1/chat/completions, /v1/audio/transcriptions, /v1/audio/speech, ...); a role's Server URL is just that server's own base URL.

Settings cards

Each of the following saves independently, with its own Save button - changing one never touches another card's already-saved values:

  • Discovery - the UDP port Athena listens on for a LlamaNexus server's own broadcast, plus a "Select discovered server" action per role that picks straight from whatever's currently broadcasting on your LAN instead of typing an address by hand.
  • Chat - Server URL, a Model picker (with a "Search Hugging Face for models…" option, reusing the same download flow the chat page's own model switcher has), and an optional API key. A LlamaNexus chat server needs its own non-standard /openai prefix included in the URL.
  • Speech to text - same shape as Chat, backed by a Whisper-compatible server (LlamaNexus can serve this role itself, via a managed whisper-server). Its own Model picker can also search Hugging Face for whisper.cpp models, though a picked model only takes effect once that server is restarted with it - unlike Chat, there's no live model switch here. A Language field (any of the 99 languages Whisper supports, or Auto-detect) is sent as a per-request override, but only actually does anything against a multilingual model - one without an ".en" suffix in its filename (e.g. ggml-base.bin, not ggml-base.en.bin); an English-only model ignores it and keeps transcribing as English regardless.
  • Text to speech - Server URL and a Voice picker instead of a Model field (an OpenAI-shaped request's model field is accepted but ignored by every self-hosted TTS server Athena actually targets, so there was never a real Model setting for this role). "Refresh voices" lists what's already downloaded on the server; "Search Hugging Face for voices…" searches every official Piper voice by name or language. Changing the voice takes effect on the very next spoken response - no restart needed.
  • Chat page tools - default on/off state for the File, Bash, Planning, and Agent delegation tools a chat session can use (see below), plus whether a non-admin user may also enable them for their own sessions.
  • Default system prompt - the persona/instructions used wherever an Area has no system prompt of its own.

Leave a role's Server URL blank to disable just that role - Chat-only with no voice input/output still works fine, and vice versa.

The chat page

/assistant is a full chat interface, not just a settings summary: multiple named sessions, streaming responses, an expandable "thinking" block for models that report reasoning, and a model switcher (loaded indicator per model, an Eject action, and the same Hugging Face search) mirroring LlamaNexus's own server-side model management. A microphone button records and transcribes through your configured Speech to text server; an auto-speak toggle plays each response back through Text to speech. Every response shows prompt/response/total token counts, elapsed time, and tokens/sec, right alongside its own Read aloud/Copy actions.

A "+" button next to the "/" command button attaches a file to a message: text/code files are read in the browser and inlined as context automatically, a PDF has its own text extracted locally (no external service, no separate AI call), and an image is sent to the model as a vision-style attachment for that one reply only - it isn't replayed back on later turns, keeping a long conversation from growing every time an image was shared in it.

The assistant always knows the current date/time - not a snapshot taken when the reply started (which a model could otherwise repeat verbatim even after a long "thinking" pause), but a live lookup against a virtual "Current Time" sensor it can search for like any other entity, in the Region settings card's own configured Timezone.

Tools (File, Bash, Planning, Agent)

Off by default, per-session: File and Bash give the chat model real file read/write and shell command access on the Athena server itself, gated behind a live confirmation before anything actually runs. Planning lets the model track its own multi-step todo list visibly in the conversation. Agent delegation lets it spin off a sub-task to a separate model call. These are only available on the interactive chat page - AI Action automations (below) never get file/shell access at all.

Per-Area settings

Locations & Areas > an Area's own "Assistant" button sets whether the assistant is enabled for that Area, an occupancy timeout (for area-based presence automations), an optional custom system prompt overriding the global default, and an "Announce responses via" media player - when set, a voice-satellite reply spoken in that Area also plays through that speaker (in addition to the satellite's own playback, which always happens regardless). This currently only actually announces when the picked media player wraps an ESPHome device's own media_player: entity - the other wrapped sources on the Media player page have no generic "play this URL" capability yet, so picking one of those is a no-op for now.

Voice-satellite hardware

Dedicated ESPHome voice-assistant hardware - the Home Assistant Voice Preview Edition, or any other device built with ESPHome's own voice_assistant: component - works with Athena directly, with nothing special to configure on the device's own side. Pair it as an ordinary device on the ESPHome page; Athena detects its voice capability automatically and subscribes to its pipeline right away.

Its wake word or button press streams microphone audio straight to Athena over that same connection. Athena transcribes it, runs it through a real chat turn with full control over every device in your house (not scoped to just that satellite's own room), and the spoken reply is fetched and played back by the satellite itself. Each satellite gets its own persistent chat session the first time it's used, visible afterward on the regular /assistant page's session list, right alongside anything you've typed there yourself.

Athena listens for a short pause after you've stopped talking to know your turn is over - automatically, with nothing to configure per device. If your satellite has its own physical stop button/action, that still works too and answers with whatever was captured up to that point, the same as a natural pause would.

A satellite also tells the model which room it's physically in, so a request that doesn't name a room explicitly (e.g. "turn on the light") defaults to that satellite's own Area rather than the model having no room to resolve it to - the model can still act on any other room too when one is actually named.

Two things need to be true for a satellite to actually respond:

  • The device is assigned to an Area, and that Area's own Assistant settings have the AI Assistant enabled - the same per-Area toggle described above. A satellite with no Area, or one assigned to an Area with the Assistant switched off, rejects the wake word immediately instead of listening.
  • The Server address (LAN) field on the Settings page's own Region card is filled in - Athena needs a URL a satellite on your network can reach it at, to hand back the audio file for its spoken reply.

Everything above needs a Chat, Speech to text, and Text to speech server all actually configured - a voice satellite goes through the exact same three roles the chat page and its own microphone button use.

AI Action automation node

A dedicated node type in the automation editor: a plain-language Instruction (e.g. "Turn off the lights if nobody is home"), an optional Persona area to borrow that Area's own system prompt from, a whitelist of Context entities the model can read, and a separate whitelist of Allowed actions it may actually control - two different lists, so a flow can let the model see more state than it's allowed to change. Every exchange (replies, tool calls, and their results) shows up in that automation's own Run History, the same place every other node type's activity already appears.