Installation¶
Prerequisites¶
- uv
libopusfor Discord voice (brew install opus,apt install libopus0,dnf install opus, orpacman -S opus)- A Discord application + bot token
(portal) with the
message_content,messages, andvoice_statesintents enabled - An OpenRouter API key
- (optional, voice only) One of: Azure Cognitive Services key + region, a Cartesia API key, or a Google Gemini API key
- (optional, voice only) A Deepgram API key for speech transcription
Environment variables¶
Create a .env in the repo root (loaded automatically on startup).
Only install-wide secrets and the active-familiar selector live here;
everything tunable about the familiar — LLM model per call site, TTS
voice, chattiness — lives in data/familiars/<id>/character.toml.
# required
DISCORD_BOT=<discord bot token>
OPENROUTER_API_KEY=<openrouter key>
# pick the familiar to load (or pass --familiar on the CLI)
FAMILIAR_ID=aria
# TTS credentials — set the one matching [tts].provider in character.toml
# Azure Speech (default provider):
AZURE_SPEECH_KEY=<azure cognitive services key>
AZURE_SPEECH_REGION=<azure region, e.g. eastus>
# Cartesia (provider="cartesia"):
CARTESIA_API_KEY=<cartesia key>
# Google Gemini TTS (provider="gemini"):
GOOGLE_API_KEY=<google ai studio key>
# optional — Deepgram speech transcription (voice channels only)
DEEPGRAM_API_KEY=<deepgram key>
Per-familiar model choice¶
LLM model selection is per-call-site and lives in the familiar's
character.toml under one [llm.<slot>] table per call site:
main_prose, post_process_style, reasoning_context,
history_summary, memory_search, and interjection_decision.
The checked-in reference profile at
data/familiars/_default/character.toml fills in every slot with
sensible defaults. A user's own character.toml only needs to
override the fields it wants to change — missing slots inherit from
the default profile on load. Copy the default to start a new
familiar:
cp -r data/familiars/_default data/familiars/my-familiar
# then edit data/familiars/my-familiar/character.toml
Good slot-level starting points for cheap / fast models (everything
except main_prose):
openai/gpt-4o-mini— cheapest OpenAI, fast, honours thenamefield, strong structured-output for the content-search TOOL/ANSWER protocol.anthropic/claude-3.5-haiku— similar tier / price on the Anthropic side.meta-llama/llama-3.1-8b-instruct— very cheap via OpenRouter, decent for simple summarisation.
The startup log prints each slot's resolved model on every launch.
Start¶
uv sync --dev
uv run familiar-connect run
uv run familiar-connect run --familiar aria
uv run familiar-connect -vv run --familiar aria
The run subcommand resolves the active familiar via --familiar
first, then FAMILIAR_ID. -v / -vv / -vvv tune logging
verbosity — -vv is the sweet spot for smoke tests.
CLI reference¶
The help text below is generated at build time from the argparse
parser in src/familiar_connect/cli.py. Run uv run familiar-connect
--help locally to get the same output.
usage: familiar-connect [-h] [--version] [-v] {run,version,metrics} ...
familiar-connect CLI tool
positional arguments:
{run,version,metrics}
Available commands
run Start the Discord bot
version Display package version
metrics View performance metrics collected by the bot
options:
-h, --help show this help message and exit
--version show program's version number and exit
-v, --verbose Increase verbosity (can be repeated: -v, -vv, -vvv)
usage: familiar-connect run [-h] [--familiar ID]
Start the familiar and connect to Discord
options:
-h, --help show this help message and exit
--familiar ID Folder name of the character to run (under data/familiars/).
Overrides FAMILIAR_ID.
Once the bot is online, see Slash commands for the smoke-test surface.