> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fs.soquincy.qzz.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Freesona: .env File and Runtime /config

> Set up your .env file and use runtime /config commands to tune every Freesona behavior — from AI provider selection to timing constants.

Freesona has two configuration layers. The **`.env` file** handles startup configuration — credentials, provider selection, file paths, and optional integration keys. This file is read once when the bot launches and requires a restart to change. The **runtime config** layer handles tunable behavior values — polling intervals, timeouts, generation pacing — via `/config` commands that take effect immediately without a restart.

***

## Environment Variables

Copy `.env.sample` to `.env` and fill in your values before launching the bot:

```bash theme={null}
cp .env.sample .env
```

### Required

These three variables must be set. The bot refuses to start if any of them is missing or still holds a placeholder value.

| Variable      | Description                                                                                     |
| ------------- | ----------------------------------------------------------------------------------------------- |
| `BOT_TOKEN`   | Your Discord bot token from the [Developer Portal](https://discord.com/developers/applications) |
| `CHANNEL_ID`  | Numeric channel ID (Discord snowflake) where the bot posts its startup message                  |
| `AI_PROVIDER` | Active AI provider: `gemini`, `openai`, `ollama`, `nim`, `azure`, `groq`, or `openrouter`       |

### AI Provider Keys

You only need to set the key for the provider you've selected in `AI_PROVIDER`. Leave the others blank.

| Provider         | `AI_PROVIDER` value | Variable(s) to set                   | Notes                                                                                            |
| ---------------- | ------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------ |
| Google Gemini    | `gemini`            | `GOOGLE_API_KEY`                     | Default provider                                                                                 |
| OpenAI           | `openai`            | `OPENAI_API_KEY`                     | Also set `OPENAI_BASE_URL` (default: `https://api.openai.com/v1/chat/completions`)               |
| Ollama           | `ollama`            | `OLLAMA_BASE_URL`                    | Defaults to `http://localhost:11434/api/chat` if not set                                         |
| NVIDIA NIM       | `nim`               | `NVIDIA_API_KEY`                     | Also set `NVIDIA_NIM_BASE_URL` (default: `https://integrate.api.nvidia.com/v1/chat/completions`) |
| Azure AI Foundry | `azure`             | `AZURE_AI_KEY` + `AZURE_AI_BASE_URL` | `AZURE_AI_BASE_URL` is your Azure AI Foundry endpoint                                            |
| Groq             | `groq`              | `GROQ_API_KEY`                       | Base URL defaults to `https://api.groq.com/openai/v1/chat/completions`                           |
| OpenRouter       | `openrouter`        | `OPENROUTER_API_KEY`                 | Optionally set `OPENROUTER_SITE_URL` and `OPENROUTER_SITE_NAME`                                  |

You can also set `MODEL_NAME` to override the default model for your chosen provider, or use `AI_PROVIDER_MODEL` to set a per-provider model override that persists across provider switches.

### Optional Integrations

These variables unlock specific features. The bot starts and runs normally without them — the corresponding commands will simply be unavailable or fall back to a different method.

| Variable                                     | Description                                                                                          |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `MVSEP_API_KEY`                              | Required for audio stem separation via the `~separate` command (MVSEP module)                        |
| `MVSEP_WEBHOOK_URL`                          | Public URL for MVSEP task completion callbacks (e.g. `https://your-host.example.com/webhooks/mvsep`) |
| `MVSEP_WEBHOOK_SEND_MAIL_ON_ERROR`           | Set to `true` to have MVSEP send an email on task error (default: `false`)                           |
| `WOLFRAM_APPID_SHORT`                        | Wolfram Short Answer API key used by the `~math` command for direct computation                      |
| `WOLFRAM_APPID_LLM`                          | Wolfram LLM API key used as a fallback if the short answer API doesn't return a result               |
| `LOGOKIT_TOKEN`                              | LogoKit API token for fetching publication logos in RSS feed embeds                                  |
| `GOOGLE_SEARCH_API_KEY` + `SEARCH_ENGINE_ID` | Legacy fallback for the `/search` command when the primary search method is unavailable              |
| `CHROMA_COLLECTION`                          | ChromaDB collection name for the knowledge base (default: `freesona`)                                |
| `CHROMA_PERSIST_DIRECTORY`                   | Local path for ChromaDB vector storage (default: `./.chroma`)                                        |
| `BOT_NAME`                                   | Display name used in startup messages and certain response contexts (default: `Freesona`)            |
| `HTTP_PORT`                                  | Port for the built-in health check and webhook server (default: `10000`)                             |

### File Paths

Freesona stores several mutable files: a runtime config file, a user memory database, a warnings database, and persona files. The correct paths depend on where you're hosting the bot.

| Variable               | Local default   | Cloud (Railway / Render) |
| ---------------------- | --------------- | ------------------------ |
| `CONFIG_FILE_PATH`     | `config.json`   | `/data/config.json`      |
| `MEMORY_FILE_PATH`     | `memory.db`     | `/data/memory.db`        |
| `WARNINGS_FILE_PATH`   | `warnings.db`   | `/data/warnings.db`      |
| `AI_PERSONA_FILE`      | `persona.txt`   | `/data/persona.txt`      |
| `AI_PERSONA_JSON_FILE` | `persona.json`  | `/data/persona.json`     |
| `AI_PERSONAS_FILE`     | `personas.json` | `/data/personas.json`    |

<Note>
  On cloud hosts without a persistent volume, file changes don't survive a redeployment — the container resets to the image state. Mount a persistent volume at `/data` and switch to the `/data/` paths in your `.env` to keep your config, memory, warnings, and persona across deploys.
</Note>

***

## Runtime Config

The `/config` command group lets the bot owner inspect and adjust tunable behavior values while the bot is running. Changes take effect immediately — no restart needed.

These commands require you to be the **bot owner** (the account that owns the Discord application in the Developer Portal).

### Commands

```text theme={null}
/config list
/config show [key]
/config set <key> <value>
/config reset <key>
```

* **`/config list`** — Prints all configurable keys with their descriptions and current defaults.
* **`/config show [key]`** — Shows the current value and default for one key, or all keys if you omit the argument.
* **`/config set <key> <value>`** — Updates a key to a new value immediately. The bot converts the value to the correct type (int, float, bool, or string) based on the key's default type.
* **`/config reset <key>`** — Removes the override and restores the key to its compiled-in default.

### Configurable Keys

These are the configurable keys and the defaults the bot ships with.

| Key                               | Type  | Default | Description                                                                                           |
| --------------------------------- | ----- | ------- | ----------------------------------------------------------------------------------------------------- |
| `mvsep_poll_interval`             | int   | `10`    | Seconds between MVSEP API polling checks while waiting for a stem separation task                     |
| `mvsep_poll_timeout`              | int   | `600`   | Maximum seconds to wait for an MVSEP task before giving up                                            |
| `ytdlp_subprocess_timeout`        | int   | `300`   | Maximum seconds for a yt-dlp subprocess to complete before it is killed                               |
| `ytdlp_compress_target_mb`        | float | `9.5`   | Target file size in MB when compressing video for Discord upload                                      |
| `generation_split_min_length`     | int   | `280`   | Minimum character length before a long AI response is split into multiple messages                    |
| `generation_split_delay_base`     | float | `1.2`   | Base delay in seconds between consecutive message segments                                            |
| `generation_split_delay_per_char` | float | `0.012` | Additional delay added per character in a segment (creates natural pacing for longer chunks)          |
| `generation_split_delay_max`      | float | `3.5`   | Maximum delay in seconds between any two segments, regardless of length                               |
| `generation_rate_limit`           | float | `5`     | Minimum seconds between successive AI generation calls (per-bot rate limit)                           |
| `debounce_seconds`                | float | `1.2`   | Seconds to wait after a user's last message before generating a reply (collapses rapid-fire messages) |
| `autonomy_cooldown_seconds`       | int   | `120`   | Per-channel cooldown in seconds before the bot can autonomously respond in that channel again         |
| `autonomy_user_cooldown`          | int   | `60`    | Per-user cooldown in seconds before the bot can autonomously respond to the same user again           |

### Example Usage

```text theme={null}
/config show mvsep_poll_interval
/config set generation_rate_limit 2.0
/config reset ytdlp_compress_target_mb
```

<Tip>
  Use `/dumpconfig` to see the full contents of your current `config.json` in one shot — useful for verifying the state of all settings at once.
</Tip>

***

## config.json

`config.json` is the bot's runtime state file. Freesona reads it on startup and writes to it whenever you use commands that change persistent settings. You don't need to edit this file manually — the Discord commands are the intended interface.

A fresh `config.json` starts from `config.sample.json` and contains only:

```json config.json theme={null}
{
  "prefix": "~",
  "chat_channel_id": null
}
```

As you use the bot, it accumulates additional fields:

| Field                         | Set by                               | Description                                                      |
| ----------------------------- | ------------------------------------ | ---------------------------------------------------------------- |
| `prefix`                      | `~prefix <new_prefix>`               | The active prefix for all prefix commands (max 5 characters)     |
| `chat_channel_id`             | `/setchannel`                        | Channel where the bot responds to general (non-mention) messages |
| `conversation_response_mode`  | `/chatmode`                          | How the bot decides to respond: `all`, `mentions`, or `smart`    |
| `autonomy_*` settings         | `/autonomy`                          | Whether autonomy mode is on, and its frequency setting           |
| `enabled_modules`             | `/module enable` / `/module disable` | Per-module on/off state persisted across restarts                |
| `provider` / `provider_model` | `/provider set` / `/model set`       | Active AI provider and model overrides                           |
| `timezone`                    | `/settimezone`                       | IANA timezone string for time-sensitive features                 |
| `rss_feeds`                   | `/rss add` / `/rss remove`           | Configured RSS/Atom feed subscriptions                           |

<Note>
  You don't edit `config.json` directly. Use the Discord commands — `~prefix`, `/setchannel`, `/autonomy`, `/module`, `/provider`, `/model`, `/settimezone`, and `/rss` — to change these values. The bot writes the file automatically.
</Note>
