# Volvox.Bot Changelog and Release Notes Source: https://docs.volvox.bot/changelog Release notes for Volvox.Bot covering new features, dashboard improvements, AI moderation updates, and bug fixes for the Discord bot platform. ## New features **Web search now available for supported AI providers** — The AI responder can now search the web for current or external information when a question needs up-to-date data. Supported providers in the catalog are **Z.AI** and **OpenRouter**; MiniMax, Moonshot, and Fireworks remain disabled until their endpoints have a verified compatible tool path. Z.AI uses its Coding Plan MCP web-search server, while OpenRouter uses its documented provider-exported server tool. Search is triggered automatically when the classification pass detects a question that needs fresh information, gated per-guild by the configured responder model. See [Search guardrails](/features/ai-conversations#search-guardrails). ## New features **Reputation dashboard for the Members page** — Tracking your server's XP economy used to mean clicking into one member profile at a time and squinting at the numbers. The new **Reputation** sub-tab on **Members** lives at `/dashboard/members?tab=reputation` and answers the operational questions in one view: total XP awarded, how members are distributed across levels, the current leaderboard, and who most recently earned XP. The **Directory** sub-tab still owns searchable member lookups with XP, levels, activity, warnings, and links into each member profile. See [Reputation dashboard](/features/community#reputation-dashboard). **AI Usage ops dashboard for deployment operators** — Global admins get a new operator-only **AI Usage** page at `/dashboard/ai-usage` that rolls up AI activity across every server the deployment runs. It surfaces input, output, and total tokens; cache read and cache-creation tokens with read/write rates; estimated cost in USD; average and p95 latency plus generated tokens per second; provider, model, and request-type comparisons; the top servers by AI usage (with server names when the bot can resolve them); and recent expensive or slow requests. Filter by `24h`, `7d`, `30d`, or `90d` ranges and narrow by provider, model, or request type. Visibility is scoped to `BOT_OWNER_IDS`; server admins still see their own server's spend under **Analytics -> Messages**. See [AI usage ops dashboard](/features/analytics#ai-usage-ops-dashboard). **Deployment-wide AI usage dashboard for operators** — A new operator-only **AI Usage** page lands at **Dashboard -> AI Usage** for global admins. It rolls up input, output, cache read, and cache creation tokens across every server, plus estimated cost in USD, average and p95 latency, and tokens-per-second throughput. Provider, model, and request-type filters let you slice the data; the top-servers list and recent expensive/slow requests surface the outliers worth investigating. Range picker covers `24h`, `7d`, `30d`, and `90d`. Per-server admins still see their own usage under **Dashboard -> Analytics -> Messages** — this page is for deployment operators with `BOT_OWNER_IDS` access. See [AI usage ops dashboard](/features/analytics#ai-usage-ops-dashboard). ## Improvements **Audit Log gets a refresh button and a proper header** — The **Audit Log** page now leads with a consistent **System Ops** header and a one-click **Refresh** button so you can re-pull the table without reloading the page or changing a filter to nudge it. Same filters, same data — just less futzing. See [Audit log](/features/audit-log). **Bot health moved next to Performance** — The bot health panel (heap, RSS, CPU, uptime) now lives on the operator-only **Performance** page alongside the rest of the runtime metrics, instead of sharing the **Logs** page. The Logs view stays focused on the live log stream and its filters. The standalone restart history log has been retired — restart events still surface in [Audit log](/features/audit-log) where the rest of operational history already lives. ## New features **Voice activity tracking, plus voice XP that lives with the rest of reputation** — Voice has always been the half of your server that didn't show up on the leaderboard. That changes now. **Voice Session Tracking** is on by default under **Settings -> Onboarding & Growth -> Engagement**, feeding voice joins and session duration into Live Insight so the **Voice Tracking** analytics tab finally has data behind it — it only collects while the top-level **Engagement** toggle is on, so opting out is one switch. Separately, **Voice XP** has moved into the reputation system under **Settings -> Onboarding & Growth -> Reputation**, where it belongs with the rest of your XP settings. Flip it on and members earn whole XP per completed voice minute — defaults to **2 XP/min** — running through the same cooldowns, level curve, and level-up actions as message XP. Existing servers are migrated in place; nothing about message XP changes. See [Voice tracking](/features/analytics) and [Community settings](/features/community#settings). **Reputation dashboard on the Members page** — Answering "how healthy is the XP economy right now?" used to mean clicking through individual member profiles and reading tea leaves. The new **Reputation** sub-tab on the Members page — at `/dashboard/members?tab=reputation` — puts the operational view in one place. You get total XP awarded across the server, level distribution, top members by XP, and the most recent XP earners. The existing **Directory** sub-tab still handles searchable per-member lookups with XP, levels, activity, warnings, and links into member detail. Nothing to enable — the sub-tab shows up automatically alongside Directory. See [Reputation dashboard](/features/community#reputation-dashboard). ## Bug fixes **Per-channel AI mode stops showing empty categories** — The **Per-Channel AI Mode** picker under **Settings -> AI & Automation -> AI Chat** used to list every category in the server, even ones with nothing for the bot to talk in. Lots of headers, lots of scrolling, zero payoff. Empty categories are now hidden, so you only see the ones you can actually configure. See [Channel modes](/features/ai-conversations#channel-modes). ## New features **Contextual docs button in the dashboard** — Hunting through the documentation to figure out what a setting actually does was always one tab too many. Every dashboard page now ships a **question-mark button** in the header that opens the matching documentation right where you are — Analytics deep-links into the sub-tab you're on, Settings deep-links into the feature you're configuring, and the rest of the dashboard hands you the page you'd otherwise have to guess at. Same docs, zero search. Read the full mapping under [Settings tabs](/configuration/bot-settings#settings-tabs). ## Improvements **Redesigned settings, with breathing room** — The settings dashboard got a serious haircut. Every category page now opens with a bigger, calmer page title and a single column of consistent **label / description / control** rows, so the eye doesn't have to renegotiate the layout every time you switch tabs. Section enable/disable toggles are now full-width cards with a tactile pill switch — the kind that makes it obvious what's actually on. The step rail on the left reacts to your cursor, the **Weekly Activity Heatmap** plays a tasteful entrance animation on first render, and the **Logs** panel now wraps long audit-log lines instead of trailing them off the page. Behavior is unchanged — same settings, same routes, just a layout that earns its rent. **Embed builder polish** — The visual embed editor across welcome, ticket panels, and level-up actions got tightened up. Description fields now show real placeholder text instead of empty boxes, the accent color picker labels each swatch for screen readers, and the timestamp toggle is finally labeled correctly. Saved embeds render the same; the editing surface is just less fiddly to use. See [Welcome message embed format](/features/welcome) and [Tickets](/features/tickets#configuration). **Analytics sub-tab switcher returns to the header** — The **Messages**, **Voice Tracking**, and **Community Engagement** switcher is back at the top of the Overview, where it's easier to flip between views without scrolling the sidebar. The sidebar entries still work and the `?tab=` URL parameter still drives both, so bookmarks and deep links from earlier this month don't lose their place. See [Analytics](/features/analytics#share-or-bookmark-a-sub-tab). **Tidier dashboard chrome** — A handful of small cuts across the dashboard: the always-on "Live" pill next to the page title is gone (the data is live; you knew), the server selector in the sidebar now matches the surrounding column width instead of nudging out a few pixels too far, and the audit-log table stops escaping its container on long entries. No setting to change — log back in and the surface area just feels less twitchy. ## New features **Curve Builder for reputation progression** — Hand-typing twenty XP thresholds to find the one shape that doesn't feel like a part-time job is officially over. The new **Curve Builder** on **Settings -> Onboarding & Growth -> Reputation** generates the whole progression from three inputs — total **Levels**, **Level 1 XP**, and **Final XP** — plus a shape. **Balanced** spaces levels evenly, **Early wins** front-loads progress so newcomers feel traction, and **Slow burn** stiffens the early climb for servers that want long-haul regulars. Select **Apply curve** and every row in the **Progression Steps** editor below updates in place; nudge individual levels by hand afterward if you want to break the pattern. Up to 100 levels, thresholds still have to strictly increase, and existing curves are left alone until you apply a new one. See [Level progression](/features/community#level-progression). ## New features **Reputation Curve Builder reshapes level progression in one click** — Tuning a 20-level XP curve by editing every threshold by hand was busywork that nobody enjoyed, especially when all you really wanted was "make the early levels faster" or "stretch the grind to Level 20." The Reputation editor now ships a **Curve Builder** that regenerates the whole progression from three inputs — total **Levels**, **Level 1 XP**, and **Final XP** — plus a curve shape. Pick **Balanced** for even spacing, **Early wins** to front-load faster early levels and push XP into the tail, or **Slow burn** for heavier early requirements that soften near the end. Select **Apply curve** to regenerate, then fine-tune any individual level inline. Thresholds must strictly increase, at least one level is required, and the editor supports up to 100 progression steps. Configure it under **Settings -> Onboarding & Growth -> Reputation**. See [Level progression](/features/community#level-progression). **Incident ping roles for Content Safety** — Posting an AI auto-moderation incident report into a busy staff channel only helps if the right humans actually see it, and "@everyone in #mod-reports" was never going to be the answer. Content Safety now ships an **Incident Ping Roles** setting that mentions the staff roles you pick whenever the bot posts a flagged incident to your **Incident Report Channel**. That covers Flag & Log reports plus the combined reports that also queue Hard Delete, Issue Warning, Temporary Timeout, Server Kick, or Permanent Ban. Mentions are scoped to the report channel post only — no extra pings in member DMs, moderation case embeds, audit logs, or operator logs. The bot also builds an explicit role allowlist, so a stray `@everyone` in the report body can't escape. Configure it under **Settings -> Moderation & Safety -> Content Safety**, or set numeric Discord role IDs directly on `aiAutoMod.incidentMentionRoleIds`. See [Incident ping roles](/features/moderation#incident-ping-roles). ## New features **GLM 5.1 is the new default AI model — and the bouncer finally checks IDs at the door** — Every AI surface that used to default to MiniMax M2.7 — Content Safety, triage classify and respond, and TL;DR — now defaults to Z.AI's **GLM 5.1**. New servers pick it up automatically. Existing servers still parked on `minimax:MiniMax-M2.7` are migrated to `z-ai:glm-5.1` on upgrade, and TL;DR routing is force-migrated to GLM 5.1 across the board to fix a stale-config edge case that was leaving summary jobs pointed at the old default. Custom model picks you actually chose are left alone. At the same time, the **premium tier stopped being theoretical** — MiniMax, Moonshot (Kimi), Fireworks, OpenRouter, and GLM 5 Turbo are now premium-only and the dashboard dropdowns hide them on free-tier servers instead of letting you save a model and fail at runtime. GLM 5.1 stays free for everyone. Self-hosters opt specific servers into the premium catalog by listing their guild IDs in the new `PREMIUM_GUILD_IDS` env var. Pick your model under **Settings -> AI**, **Settings -> Moderation & Safety -> Content Safety**, **Settings -> AI & Automation -> Triage**, or **Settings -> Community Tools -> TL;DR**. See [Available models](/features/ai-conversations#available-models). ## Improvements **Per-action thresholds show up in the operator log stream** — The classification log line was still quoting old single-threshold percentages even after action ladders shipped, which made tuning the new per-action confidence settings a guessing game. Every Content Safety scoring pass now writes per-action threshold percentages — one per **Flag & Log**, **Hard Delete**, **Issue Warning**, **Temporary Timeout**, **Server Kick**, and **Permanent Ban** rung — alongside the legacy category numbers, plus each score as a percentage of the action threshold it would trip. Tune the ladder under **Settings -> Moderation & Safety -> Content Safety** with actual numbers instead of vibes. See [AI auto-moderation configuration](/features/moderation#configuration). **Compact AI log lines that don't punish your scrollback** — Operator log entries for AI auto-moderation and AI triage have been put on a diet. Classification now writes a single `AI automod classified: ...` line with the clean/flagged verdict, the selected action, and the top category scores as `score%/threshold%`; triage writes matching `AI triage classified: ...` and `AI triage skipped: ...` lines with confidence and relevance side by side. Expanded metadata still carries the full per-action ladder for the strongest categories, so you keep the depth without drowning the **Logs** view. No configuration changes — applies to every server the next time the bot processes a message. See [AI auto-moderation configuration](/features/moderation#configuration). ## New features **GLM 5.1 is the new default AI model** — New servers now ship with `z-ai:glm-5.1` selected across [AI conversations](/features/ai-conversations), AI triage, [Content Safety](/features/moderation), and [TL;DR](/features/tldr) instead of the previous MiniMax default. Existing servers using the old default are migrated automatically the next time the bot starts, and the prior value is backed up so support can restore it if you ask. Custom picks on AI, triage, and Content Safety are left alone — only saved values that matched the previous default are swapped. **TL;DR is the one exception**: the summary model is force-migrated to GLM 5.1 for every server so `/tldr` routing stays consistent with the rest of the bot. Open **Settings -> Community Tools -> TL;DR** and pick a different model if you want to override it. Self-hosters need `ZHIPU_API_KEY` set in `.env` to keep GLM 5.1 working; the bot otherwise falls back through your configured models. See [Available models](/features/ai-conversations#available-models). **Per-action thresholds for Content Safety** — One threshold per category was always a blunt instrument: pick 75% and you either flag, delete, warn, *and* timeout at the same line in the sand, or you tuned the knob down and watched the bot get trigger-happy on borderline messages. Each Content Safety category now carries its own action ladder with independent confidence percentages for **Flag & Log**, **Hard Delete**, **Issue Warning**, **Temporary Timeout**, **Server Kick**, and **Permanent Ban**. Flag at 55%, delete at 70%, warn at 75%, timeout at 88%, leave kick and ban off entirely — or wire any other shape that matches your server's tolerance. Smarter defaults ship with every category: standard categories follow the 55/70/75/88 ladder, self-harm only flags for review, and doxxing plus child endangerment start stricter and can escalate to a ban at high confidence. Existing configs are migrated automatically — your old single-threshold tuning keeps working until you open the redesigned ladder under **Settings -> Moderation & Safety -> Content Safety** and dial each action in on its own. See [AI auto-moderation configuration](/features/moderation#configuration). ## Fixes **Dashboard server list no longer lies during bot startup** — If you opened the dashboard while the bot was still finishing its Discord handshake, the `/api/guilds` endpoint would happily hand back an empty cache, which the picker dutifully rendered as "you have no servers." The server list now returns `503 Discord client is not ready` until the gateway connection is actually live, so the dashboard can show a real loading state instead of gaslighting you into thinking your invites evaporated. No action needed; the fix kicks in for everyone the next time the bot restarts. ## New features **Z.AI joins the provider roster** — Z.AI is now a first-class provider for [AI conversations](/features/ai-conversations), AI triage, [AI auto-moderation](/features/moderation), and [TL;DR](/features/tldr). Two GLM models ship visible by default on the free tier: **GLM 5.1** (`z-ai:glm-5.1`) and **GLM 5 Turbo** (`z-ai:glm-5-turbo`). Both speak thinking mode and carry their own per-token pricing for input, output, and cache reads. Self-hosters flip on Z.AI by dropping `ZHIPU_API_KEY` into `.env`; the bot routes requests through the Z.AI Coding Plan endpoint at `https://api.z.ai/api/coding/paas/v4`. Managed users on volvox.bot get the new models in the dashboard pickers automatically — no restart, no fiddling. Select a Z.AI model under **Settings -> AI**, **Settings -> Moderation & Safety -> Content Safety**, **Settings -> AI & Automation -> Triage**, or **Settings -> Community Tools -> TL;DR**. ## Fixes **Safety guardrail spend stops sneaking past the budget** — Output Safety Guardrail calls were happily classifying away without their cost showing up anywhere it counted. Safety classifier calls — including the recheck after a constrained retry — now post to AI usage, the per-model cost rollup, *and* the daily budget limit alongside the classifier and response models. Translation: if you're running the guardrail at a hot threshold, it can now actually trip the budget cap it was already drafting against. The default for budget tracking flips to include safety spend; nothing to configure. See [Analytics](/features/analytics) and [Output Safety Guardrail](/features/ai-conversations#output-safety-guardrail). **One flaky provider no longer takes everyone down with it** — The AI circuit breaker kept a single, shared failure tally across every provider, so one provider's bad afternoon could trip the breaker for *all* of them and quietly defeat the gateway fallback you set up for exactly this scenario. Failure state is now keyed per provider, so OpenAI hiccuping doesn't drag Anthropic, Fireworks, or anyone else into the penalty box with it. Mid-stream errors also count properly instead of being recorded as a success at the moment the stream opened. See [AI conversations](/features/ai-conversations). **SSRF protection learns that IPv6 also exists** — The dashboard's SSRF guard only checked IPv4 dotted-quad hostnames, which meant `http://[::1]` and the IPv4-mapped IPv6 form `http://[::ffff:127.0.0.1]` could stroll past it and hit loopback or internal services. The validator now strips the brackets the URL parser leaves on IPv6 hosts, routes any IP literal — v4 or v6 — to the block check, decodes compressed IPv4-mapped addresses back to dotted-quad, and explicitly blocks the IPv6 unspecified address (`::`) and the unique-local range (`fc00::/7`). No configuration changes; the patch applies to every outbound URL the dashboard validates. **Live log filtering and stream layout settle down** — The operator-only **Logs** tab had two rough edges. The in-page text filter quietly dropped messages whose casing or whitespace didn't match exactly, and self-hosted browsers could fail to upgrade the log WebSocket when the dashboard couldn't guess the bot's public origin. Filter matching now normalizes case and whitespace so partial matches behave the way the input box suggests, and unmatched WebSocket upgrade requests close cleanly instead of hanging. The Logs viewer also streams across all servers in one feed for operators. Self-hosters set the new `BOT_PUBLIC_URL` env var to the public bot origin (for example, your Railway bot service URL) so the browser can reach `/ws/logs`; managed users on volvox.bot need no changes. See [Logs](/dashboard#operator-only-sections). ## Fixes **Analytics sub-tabs stop showing up twice** — The Overview dashboard was rendering its **Messages**, **Voice Tracking**, and **Community Engagement** switcher in both the header *and* the sidebar — same buttons, two homes, zero added value. The header pills are gone, and the sub-tabs now live only in the sidebar where the rest of the navigation already lives. Bookmarks, deep links, and the `?tab=` URL parameter all keep working exactly as before. See [Analytics](/features/analytics#share-or-bookmark-a-sub-tab). ## New features **Setup wizard for new servers** — Inviting Volvox.Bot now drops you into a guided, page-based setup wizard instead of a blank dashboard. Pick a server, then step through focused pages for welcome messages, content safety, protected roles, warning rules, tickets, reputation, starboard, command prefix, TL;DR summaries, and dashboard roles. A single AI provider/model pick drives chat, triage, content safety, and TL;DR routing together — no need to wire each one up separately. Toggle any section off, jump between steps, save when you're done. The bot picks up the new config without a restart. Skipping the wizard is fine; reopen it any time from **Settings -> Setup wizard** in the dashboard sidebar. No AI credentials yet? The wizard still saves the non-AI defaults, and you can wire AI up later from the dashboard. See [Run the setup wizard](/getting-started#run-the-setup-wizard). ## New features **Output Safety Guardrail for AI triage** — Neural Chat can now run a lightweight AI classifier on every bot-generated triage response before it posts to Discord. Responses flagged as unsafe are silently dropped and logged to Sentry, giving you a second pass on edge cases your system prompt didn't catch. Toggle it on under **Settings -> AI & Automation -> Triage -> Behavior -> Output Safety Guardrail**. Off by default. Self-hosters tune the classifier model, timeout, and fail-closed behavior through `SAFETY_GUARDRAIL_*` environment variables; managed users on volvox.bot get safe defaults. The AI usage ledger logs safety check cost under the `safety` type so you can keep an eye on the bill. See [Output Safety Guardrail](/features/ai-conversations#output-safety-guardrail). **Excluded channels for AI auto-moderation** — Content Safety now takes a per-channel ignore list. Pick channels under **Settings -> Moderation & Safety -> Content Safety -> Excluded Channels** and the bot skips scoring, thresholds, and every response action for messages posted there. Threads inherit their parent's setting, so excluding `#vent` covers every thread under it without extra clicks. Useful for venting channels, staff rooms quoting flagged content, or gradual Content Safety rollouts. Manual moderation, the Link filter, and classic auto-mod rules are unaffected. See [Excluded channels](/features/moderation#excluded-channels). ## Removed **Standalone auto-delete toggles retired** — Two global delete switches are gone: **Instant Enforcement** under **Settings -> Moderation & Safety -> Content Safety**, and the separate **Auto-Delete** toggle under **Settings -> Moderation & Safety -> Moderation**. Deletion is now driven entirely by the per-category **Hard Delete** response action and the **Spam Response** picker under **Spam Detection**. Pick `delete` on the categories that should actually remove messages, and leave it off everywhere you only want to flag, warn, or log — no more master switch quietly overruling your per-category choices. Existing configs are migrated automatically: the old toggles are dropped and every response action you already tuned keeps working. See [AI auto-moderation configuration](/features/moderation#configuration). ## Fixes **API keys and base URLs hidden from `/config`** — `/config view` used to happily dump the raw guild config into Discord, provider API keys and base URLs included — the same secrets the dashboard and API are careful to mask. Four fields — `triage.classifyApiKey`, `triage.respondApiKey`, `triage.classifyBaseUrl`, and `triage.respondBaseUrl` — are now stripped from `/config view`, rejected by `/config set` with a clear error, and hidden from path autocomplete. Descendant paths like `triage.classifyApiKey.foo` are blocked too, so nothing sneaks through a nested write. Manage these from **Settings -> AI** in the dashboard. Every other field behaves exactly as before. **Protected roles also skip the in-channel triage nudge** — Protected-role members were already exempt from formal moderation logs, but the lighter in-channel "hey, knock it off" nudge from AI triage was still sliding through. That nudge now respects the same protected-role list, so admins and trusted roles stop getting publicly side-eyed by their own bot. If the role check can't resolve cleanly, the nudge is skipped instead of sent. No configuration change needed — your existing Protect Roles selection takes effect immediately. See [Protected roles](/features/moderation#protected-roles). **Mass pings no longer hijack the AI** — Neural Chat used to treat `@everyone`, `@here`, and role pings as direct mentions, so a server-wide announcement could yank the bot into a reply it was never asked for. Mention detection now ignores mass pings by default — only an explicit `@Bot` mention (or a reply to the bot) triggers a response. A new **Ignore mass pings** toggle lives under **Settings -> AI -> Chat**; turn it off if you want the bot to chime in on mass pings again. See [AI conversations](/features/ai-conversations#configuration). **TL;DR dashboard toggle reflects the on-by-default behavior** — TL;DR has shipped enabled out of the box for a while now. But the **Settings -> Community Tools -> TL;DR** toggle and the **Community Features** summary switch could still display as off when a guild's saved config didn't include an explicit `enabled` flag. The dashboard now treats a missing flag as enabled — matching what the bot already does at runtime — so the UI and `/tldr` finally stop contradicting each other. Flip the toggle off if you want to disable summaries; everything else is unchanged. See [TL;DR](/features/tldr). **`/tldr` cooldown is now per user, per server** — The `/tldr` rate limit used to apply per channel, so one person's summary blocked everyone else in the same channel for the full cooldown window. The cooldown is now keyed by `(server, user)` instead — each member gets their own timer, and it spans the whole server rather than a single channel. The default is still 300 seconds, and you can tune it under **Settings -> Community Tools -> TL;DR**. The rate-limit message now reads "before using /tldr again on this server." See [TL;DR](/features/tldr). **Threads hidden from dashboard channel pickers** — Channel selectors across the dashboard no longer list threads as pickable options. Threads were never a useful target anyway — Content Safety excluded channels, AI chat allowlists, and the rest all inherit from the parent channel. Pickers now show only text, voice, announcement, forum, media, and category channels. Any thread IDs already saved in your configuration stick around quietly, with a one-click control to clear them if you want a clean slate. No action needed for existing setups. **Server-side telemetry stays grouped by Discord server** — Operational Amplitude events for bot installs, slash command usage, and AI usage are now keyed by Discord server ID instead of a shared anonymous device. Usage stays grouped by server rather than blending across guilds, and events without a resolvable server ID are dropped instead of falling back to an anonymous identifier. The properties sent are unchanged — command name, AI token and cost totals, member-count bucket, and the large-server flag. Discord user IDs, message content, raw channel IDs, channel names, and server names are still never sent. See [What analytics covers](/security#what-analytics-covers). ## Improvements **Shareable analytics sub-tabs** — The Overview dashboard's **Messages**, **Voice Tracking**, and **Community Engagement** views now live behind a `?tab=` URL parameter. Bookmark a view, send a teammate a direct link to **Voice Tracking**, or refresh the page without bouncing back to **Messages**. Selecting a sub-tab from the dashboard sidebar updates the URL in place — no full reload. See [Analytics](/features/analytics#share-or-bookmark-a-sub-tab). **Refreshed dashboard, settings, and layout polish** — A broad UI refresh lands across the dashboard. The page header picks up subtle motion, and animated pill switchers replace the old tab bars in the header, sidebar, and ticket panel format selector. **AI Triage** now pairs Engine & Routing with Role Filtering, and Limits & Tuning with Behavior, in side-by-side rows. **Support & Integrations** does the same for Ticket Routing and Operational Limits. Inputs share one consistent style with the number-spinner arrows hidden, and the Discord Markdown editor gets a thinner scrollbar. **Content Safety -> Spam Response** also moves to a searchable multi-select popover with checkmarks and removable action badges, so picking several response actions feels less fiddly. No behavior changes — same fields, cleaner edges. ## Improvements **Triage now scores certainty and usefulness separately** — The AI triage classifier used to roll "am I sure what this message is?" and "should I actually say something?" into a single confidence number, which led to the bot either over-talking or sitting on its hands. Triage now produces two scores — **confidence** (label certainty) and **relevance** (response value) — with independent thresholds. The result: fewer drive-by chime-ins on messages the model only half-understands, and more thoughtful replies when something genuinely warrants one. Classification logs surface both numbers so you can tune each on its own. Technical frustration is also now a valid chime-in trigger, so a member rage-typing about a broken build no longer gets ignored for being off-topic. See [AI conversations](/features/ai-conversations#configuration). **Web search gated on provider capability** — Providers that can't actually browse the web no longer get asked to. When the selected model lacks search, the bot injects a `SEARCH_UNAVAILABLE` directive and hedges on time-sensitive claims instead of making things up. System prompt facts — who built the bot, where to find the invite, your house rules — stay authoritative either way, so "who made you?" no longer triggers an existential crisis. See [AI conversations](/features/ai-conversations). **MiniMax thinking mode enabled** — MiniMax models now use their thinking capability for triage and responses, trading a few extra tokens for noticeably steadier answers on multi-step questions. No configuration needed — pick a `minimax:*` model and you get the upgrade automatically. See [Available models](/features/ai-conversations#available-models). **Softer classifier prompts** — Hard "never" and "always" rules in the classifier have been rewritten as "favor" guidance. The model now treats edge cases as judgment calls instead of bouncing off rigid rails, which translates to fewer obviously-wrong skips and fewer over-eager replies. Existing thresholds carry over; only the prompt tone changed. **Smarter memory extraction** — The memory pipeline got a thorough scrub. Discord markup (mentions, roles, channels, custom emoji) is now stripped before anything reaches mem0, so memories read like sentences instead of raw markup soup. Mentions resolve to `displayName [userId: id]` so the model can tell two `@Alex`es apart. Assistant replies are excluded from extraction to stop the bot from remembering its own echoes as facts. Multiple facts per message get captured together instead of only the first one. Updates to existing memories replace stale info instead of stacking duplicates. See [AI conversations](/features/ai-conversations). **Optional solo-user confidence boost** — When only one human is actively chatting, the bot can now lower its confidence and relevance thresholds slightly so a 1:1 conversation doesn't feel like pulling teeth. Enabled by default; flip it off in AI Automation config if you'd rather keep the bot at arm's length in quiet channels. ## Fixes **Debug footer shows human-readable model names** — Discord embeds from AI features were quietly leaking raw model paths like `accounts/fireworks/models/deepseek-v4-pro` into debug footers, which is exactly as readable as it looks. Footers now render as `Fireworks / DeepSeek V4 Pro` by resolving the friendly name from the provider registry. Unknown models fall back to a clean strip-prefix instead of dumping the full path. See [AI conversations](/features/ai-conversations#available-models). **Memory extraction dedup bug squashed** — When multiple messages from the same user landed in the same extraction batch, only the first one was being sent to mem0 and the rest got dropped on the floor. All target messages per user are now joined and extracted together, so the bot stops forgetting half of what you just told it. ## Fixes **Buffered messages stop falling into the void** — Under sustained chatter, the AI triage buffer could quietly drop messages, direct @mentions included, once its internal re-evaluation hit a recursion cap. No follow-up timer meant the work never resumed. Re-evaluation now hands off to a short timer instead of stacking calls on itself. Rapid-fire messages coalesce into a single pass, and nothing gets orphaned when a busy channel hits the limit. Direct @mentions arriving during the delay still cancel the timer and evaluate immediately on the fast path. See [AI conversations](/features/ai-conversations). ## New features **Custom command prefixes** — Admins can now set a text command prefix like `.`, `!`, or `?` under **Settings -> Community Tools -> Commands**. Every slash command is mirrored as a prefix command using the same name, options, and permission gates — `/ban @user spam` and `!ban @user spam` route to the same handler, so a member who can't use `/ban` still can't use `!ban`. Prefixes accept one to five non-space characters and skip `/`, `@`, `#`, `<`, `>`, and backticks to avoid colliding with mentions or Markdown. Leave the field blank to keep slash-only behavior. See [Command prefix](/configuration/bot-settings#command-prefix). **Ticket panels publish themselves** — Configuring a ticket panel no longer means copying a message into a channel and praying. Save a **Panel Destination** and **Panel Message** under **Settings -> Tickets** and the dashboard posts the panel for you the moment the save succeeds. Switch destinations and the old panel cleans itself up before the new one drops in — no orphaned buttons lurking in last week's announcements channel. The embed editor also got a tidy: template variables (`{{username}}`, `{{mention}}`, `{{serverName}}`) are now limited to the description, where they actually belong. See [Tickets](/features/tickets#configuration). **Saved ticket panel publishing** — Ticket panels are finally part of your dashboard save, no more copy-paste rituals. Select a **Panel Destination** under **Settings -> Tickets**, edit the **Panel Message** as **Text**, **Embed**, or **Both**, then select **Save**. The bot quietly cleans up the previously tracked panel message, posts a fresh one in the saved channel, and remembers the new message ID so the next edit replaces the right post. If the publish trips on missing channel access, **Send Messages**, or **Embed Links**, the failure is recorded so you can fix permissions and retry without losing your config. See [Ticket panel publishing](/features/tickets#ticket-panel-publishing). **Welcome message embed format** — Welcome messages now ship in **Text**, **Embed**, or **Both** flavors, matching the ticket panel and level-up message editors. Configure title, description, color, thumbnail (none, server icon, custom, or user avatar), fields, footer, image, and timestamp under **Settings -> Onboarding & Growth -> Welcome**. The plain-text `message` field still works, so servers that never switch to embed mode keep their current copy untouched. ## Improvements **Welcome publish accepts a target channel override** — The welcome publish endpoint (`POST /guilds/:id/welcome/publish/:panelType`) now accepts an optional `channelId` in the request body. Dashboards and integrations can publish the rules panel to a specific channel without first updating the saved config. Requests without `channelId` continue to publish to the configured channel, and invalid IDs are rejected with a 400 response. ## Removed **Temp roles retired** — The temp roles feature leaves the bot end to end. The `/temprole` command, the **Temp Roles** dashboard page, and the **Settings -> Temp Roles** settings panel are gone. The **Temp roles** category also drops out of [audit log](/features/audit-log) filters. The upgrade clears any existing temp role assignments along with it. If you leaned on time-limited roles, pair Volvox.Bot with a dedicated role-scheduling bot or lean on Discord's native role management. Permanent role assignments through Discord stay untouched. **Directed onboarding DM sequence retired** — The multi-step welcome DM sequence under **Settings -> Onboarding & Growth -> Welcome** is gone. Volvox.Bot no longer pings new members with scripted follow-up DMs after they join. The welcome flow now sticks to context-aware welcome messages in your configured channel plus optional rules verification. The upgrade drops any existing `dmSequence` config automatically, and the **Welcome DM Sequence** advanced panel and its search entry leave the dashboard with it. The `welcome_onboarding` source also stops appearing on `notifications.dm_failed` audit entries. If you leaned on staged onboarding DMs, hand the job to Discord's native **Onboarding** flow — it walks new members through rules and role choices without the bot in the loop. ## Fixes **AI auto-mod reasons no longer end mid-thought** — Mod log embeds, DM notifications, and case records were quietly chopping AI auto-mod reasons off at 512 characters, which is roughly the length it takes the model to clear its throat. Reasons now use the full 1024-character embed field limit, and the model has more tokens to actually explain itself. Case reasons sent to Discord's audit log get capped cleanly at 512 instead of bouncing off the API. Long reasons in the dashboard also wrap properly instead of trailing off the page. See [AI auto-moderation](/features/moderation). **Ticket support role picker remembers Discord exists** — When the bot's role cache was cold, the **Support Staff Roles** dropdown on **Settings -> Tickets** would shrug and show nothing. It now fetches roles directly from Discord on demand, caches the result, and stops hammering the API with repeat empty lookups. New servers and freshly restarted bots can configure tickets without waiting for the cache to warm up. **Dashboard access stays in sync with Discord** — Promoting or demoting a moderator in Discord now reflects in the dashboard on the next page load instead of clinging to a stale snapshot. Server membership and role lookups refresh before access is granted, so newly promoted admins can manage and ex-moderators can't. **Community Activity Over Time graph stops gaslighting you** — The new [Activity Over Time](/features/analytics#activity-over-time) chart on the Community Engagement tab had mislabeled series and axis ticks that didn't quite line up with the data. Labels and series now match what you're actually looking at. **Quieter DM failure logs** — When a DM bounced — common when a user has DMs disabled — multiple subsystems would each file their own audit entry for the same event. DM delivery failures now flow through a single helper, so the [audit log](/features/audit-log) records the event once instead of three times. **Configured providers API is scoped to your server** — The `GET /api/v1/providers/configured` endpoint now requires a `guildId` query parameter and only returns data to admins of that server. Requests without `guildId`, with a malformed Discord snowflake, or from a non-admin caller are rejected with a 400 or 403 response. Dashboards already pass the current server's ID; integrations that call the endpoint directly need to add `?guildId=` and authenticate as a server admin. The dashboard hook also caches results per server for 30 seconds and keeps the previous data on screen during revalidation, so switching pages no longer blanks the model picker. See [Providers API](/features/ai-conversations#providers-api). ## New features **Fireworks AI provider** — Fireworks just joined the roster as a first-class provider for [AI conversations](/features/ai-conversations), [AI auto-moderation](/features/moderation), AI triage, and [TL;DR](/features/tldr). Nine serverless models ship visible by default: **DeepSeek V4 Flash**, **Kimi K2.6**, **Kimi K2.5**, **Qwen 3.6 Plus**, **Qwen3 VL 30B A3B Instruct**, **MiniMax M2.7**, **MiniMax M2.5**, **GPT-OSS 120B**, and **GPT-OSS 20B** — each with its own per-token pricing for input, output, and cache reads. Self-hosters enable Fireworks by setting `FIREWORKS_API_KEY` in `.env` and selecting a `fireworks:*` model in any AI dropdown. Managed users see the new models in the dashboard pickers automatically. Under the hood, Volvox.Bot now dispatches to the matching Vercel AI SDK factory per provider based on each provider's declared `apiShape`. Future providers no longer have to speak the Anthropic Messages wire protocol to play nice. Select a Fireworks model under **Settings -> AI**, **Settings -> Moderation & Safety -> Content Safety**, **Settings -> AI & Automation -> Triage**, or **Settings -> Community Tools -> TL;DR**. **Doxxing and child endangerment safety categories** — Content Safety just got two new line items it should have had all along. **Doxxing** flags personal contact info, addresses, and identity details shared without consent, and **Child endangerment** targets content that sexualizes or grooms minors. Both ship with the same defaults as every other Content Safety category: a 75% sensitivity threshold plus **Flag & Log**, **Hard Delete**, and **Issue Warning**. They start working the moment the migration runs. Any category you've already hand-tuned keeps your settings; only categories left at the old defaults get bumped to the new ones. Adjust thresholds and response actions under **Settings -> Moderation & Safety -> Content Safety**. See [Content Safety](/features/moderation#configuration). **Activity Graph with rolling and custom ranges** — The Messages sub-tab on the Overview dashboard now leads with an **Activity Graph** that plots community message volume over time. One-click buttons cover `1d`, `7d`, `14d`, `30d`, `60d`, `90d`, `6 month`, and `1 year` rolling windows. **Custom** opens **Start** and **End** date pickers, and **Apply** stays disabled until both dates are valid and in order. Custom ranges can now span up to **366 days** — the legacy 90-day cap is gone — so year-over-year comparisons stop requiring duct tape and multiple queries. The selected range stays highlighted and feeds the surrounding KPIs and breakdowns, so you can pivot between Messages, Voice Tracking, and Community Engagement without losing context. See [Activity Graph](/features/analytics#activity-graph). **Send channel message level-up action** — Level-up actions now include a **Send Channel Message** type that posts publicly into a server channel when a member reaches a level. Pick **Current Channel** to celebrate in the channel that triggered the level-up, or **Specific Channel** to route every announcement to a fixed milestones channel. Pick text, embed, or both formats, and drop in the usual template variables (`{{username}}`, `{{mention}}`, `{{level}}`, `{{serverName}}`) anywhere in the message body. Configure it under **Settings -> Community -> XP -> Level-up actions**. See [Level-up actions](/features/community#level-up-actions). **Activity Over Time graph** — The **Community Engagement** tab now opens with a combined **Activity Over Time** graph that plots messages and voice minutes on the same chart so you can see when chat and voice rise together. The graph has its own range picker — `1d`, `7d`, `14d`, `30d`, `60d`, `90d`, `6 month`, `1 year`, or `Custom` — independent from the dashboard-wide range. `1d` buckets are hourly; everything else is daily. Custom ranges are capped at 366 days. Dashboard analytics queries now also stretch from 90 days up to **1 year**. See [Activity Over Time](/features/analytics#activity-over-time). ## Changed **Settings dashboard restricted to owners and admins** — The keys to the settings dashboard now belong strictly to owners and admins. Moderators keep every in-Discord superpower they had — moderation, tickets, audit log — but the **Manage** button no longer winks at them. The server picker quietly files moderator-only servers under viewer-only. Need a moderator to tweak config? Promote them to admin. See [Permissions](/configuration/permissions#dashboard-access). ## Improvements **20-level XP progression with a per-level editor** — New servers now ship with a smoother **20-level** reputation curve, climbing from 100 XP at Level 1 to 12,000 XP at Level 20. That gives long-term regulars somewhere to keep climbing without making the early levels feel like a second job. The **Progression Steps** editor at **Settings -> Onboarding & Growth -> Reputation (XP)** is rebuilt around one row per level. Edit any threshold inline, select **Add Step** to append a level, or select the **✕** to drop one. Thresholds must strictly increase, and at least one level is required. Existing servers keep their current thresholds — only the out-of-the-box default changed. See [Level progression](/features/community#level-progression). **Dedicated Spam Detection tab** — Spam controls finally have their own room at **Settings -> Moderation & Safety -> Spam Detection**, instead of squatting in the Moderation and Content Safety tabs. **Enable Spam Detection** flips both phrase-pattern checks and the AI spam category with a single switch. **Spam threshold** tunes the AI spam category, and **Spam response** picks any combination of flag, delete, warn, timeout, kick, or ban. The standalone spam confidence input is retired — the threshold slider on this tab is the only source of truth now. Turn the master toggle off and Volvox.Bot skips both classic and AI spam checks while the other Content Safety categories keep running. Existing configurations carry over automatically. See [Configuration](/features/moderation#configuration). **AI model dropdowns now hide what you can't use** — Every AI model picker in the dashboard — **Settings -> AI**, **Settings -> Moderation & Safety -> Content Safety**, **Settings -> AI & Automation -> Triage**, and **Settings -> Community Tools -> TL;DR** — only lists models whose provider has a configured API key and whose tier matches your server's entitlement. No more selecting a provider you don't have credentials for and discovering the failure at runtime. Saved models that fall out of availability still surface as **Current saved model: `provider:model`**; if the provider has no key, the entry is flagged with **⚠ provider not configured** so you know to pick a replacement. When no provider has credentials, the dropdown shows **No configured models available** and goes read-only. A new `GET /api/v1/providers/configured` endpoint returns the same data — `configuredProviders` and `guildTier` — for integrations that render their own model pickers. See [Available models](/features/ai-conversations#available-models). **Server-agnostic default AI system prompt** — New installs now ship with a generic Neural Chat system prompt that adapts to any Discord server instead of cosplaying as a developer-community mascot. The default voice stays friendly, concise, and respectful. The `@everyone` and `@here` ping bans are still in force, and the bot is told to ask for context when an answer depends on server-specific policy. If you've already customized the system prompt under **Settings -> AI**, your value is preserved — only the out-of-the-box default changed. Edit the prompt anytime to dial in tone, topics, or house rules. See [AI Conversations](/features/ai-conversations#configuration). **Simpler Weekly Activity Heatmap** — The Community Engagement heatmap is now labeled **Weekly Activity Heatmap** and renders weekday names in your browser locale. When the selected range is a week or shorter, each row also shows the matching calendar date so you can tell repeated weekdays apart. See [Weekly Activity Heatmap](/features/analytics#weekly-activity-heatmap). **Session replay on the dashboard, opt-in only** — Dashboard analytics can now record sampled session replays so the team can spot UX rough edges. Recording only runs when you've accepted **Analytics** cookies, sample rates and masking are managed remotely in Amplitude, and turning **Analytics** off in **Cookie Preferences** stops recording immediately. Essential cookies are unaffected. See [What analytics covers](/security#what-analytics-covers). ## Fixes **Tighter spam presets and a calmer custom editor** — All three message spam presets now share the same 10 messages / 10 seconds rate limit. They differ only in how quickly repeated hits escalate to a timeout. **Standard** (the new default) times out after 2 hits in 3 minutes, **Strict** times out on the first hit for 10 minutes, and **Relaxed** keeps the previous 3-hits-in-5-minutes behavior. The **Custom** option hides its advanced controls until you select it. The custom editor also resets when you switch servers, reload the page, or toggle spam protection off and on, so stale values from one server never carry over to another. Enabling defaults seeds the Standard preset, and partial custom configs keep their existing fields instead of silently dropping back to defaults. See [Configuration](/features/moderation#configuration). **Manual XP adjustments now trigger level-up actions** — Push a member over a level threshold from the dashboard or API and Volvox.Bot now runs the same level-up actions it would for organic XP gains. Role grants, DMs, channel messages, XP bonuses, reactions, and nickname updates all fire as expected. Rewards already granted at lower levels are not replayed, so re-adjusting a member's XP won't double up on role grants or DMs. See [Level-up actions](/features/community#level-up-actions). **DM delivery failures now show up in the audit log** — When Discord refuses a member DM — moderation notice, level-up action, or welcome onboarding step — Volvox.Bot writes a `notifications.dm_failed` audit entry instead of failing quietly. Each entry records the target member, the source feature, the Discord error, and source-specific details like the moderation action or onboarding step. Filter by **Category -> Notifications** and **Action -> Notifications: DM failed** to find members whose DMs aren't landing. The original moderation, level-up, or onboarding action still runs. See [DM delivery failures](/features/audit-log#dm-delivery-failures). ## New features **Dedicated Warnings dashboard page** — Warning records now have their own home at **Dashboard -> Warnings**, so you can review and triage warnings without paging through every other case type. The page leads with totals for warnings, active warnings, high-severity active warnings, and the current top user by active warning points. Inventory filters narrow records by severity, active state, or Discord user ID, and every row keeps a deep link into the broader moderation case for that warning. The old **User history** lookup on the Moderation page is gone. Start from **Dashboard -> Members -> \[member]** when you're investigating one person, or **Dashboard -> Moderation** when you want the broader case table and filters. See [Manage warning records](/features/moderation#manage-warning-records). **Warning Rules tab with expiry and point escalation** — Warning tuning moved out of the general Moderation tab into its own home at **Settings -> Moderation & Safety -> Warning Rules**. Set **Warning expiry days** to control how long warnings stay active (`30` is the new default, down from `90`; `0` disables expiry), assign **Severity points** so low, medium, and high warnings carry different weight (defaults: `1`, `2`, `3`), and define **Warning thresholds** that fire when a member's active points cross a line. Each threshold takes a point total, a lookback window in days, and an action (`timeout` requires a duration like `1h` or `7d`; `ban` does not). When multiple thresholds match, Volvox.Bot applies the highest point threshold first, so a 5-point ban isn't masked by a 3-point timeout. Existing configs that used the old `warns` field on escalation thresholds are automatically read as `points`. The `/warn` slash command now replies with a rich embed showing case number, severity, the point progression (for example, `2 points -> 3 points`), and direct links to the case and member profile in the dashboard. See [Warning expiry and escalation](/features/moderation#warning-expiry-and-escalation). **Classic spam detection controls in the dashboard** — Phrase-pattern spam detection is now a first-class toggle under **Settings -> Moderation & Safety -> Moderation -> Classic spam detection**. It defaults to on, runs before AI scoring, and honors the Content Safety spam **Hard Delete** and **Instant Enforcement** settings when AI auto-moderation is enabled. Spam alerts and spam actions are decoupled — if you leave the log channel unset, Volvox.Bot still applies the configured spam action and just skips the Discord alert post. Every detection writes a `spam.detect` audit-log entry with the alert/delete outcome, message link, channel ID, and a redacted content preview. Filter on it under **Dashboard -> Audit Log**. See [Classic spam detection](/features/moderation#configuration) and [Audit log](/features/audit-log#what-it-logs). **Link filter UI in the dashboard** — You can now manage blocked link domains directly from **Settings -> Moderation & Safety -> Moderation -> Link filter**. Paste hostnames, full URLs, or even Markdown links and the dashboard normalizes them to a clean hostname (so `https://www.example.com/path` becomes `example.com`) before saving. Bulk-add by separating entries with spaces, commas, semicolons, or new lines. Invalid entries are rejected inline so your blocklist stays clean. The Link filter has its own toggle that runs independently from the parent auto-mod switch, so you can enforce domain blocks without turning on every other classic rule. See [Link filter](/features/moderation#link-filter). **Quiet mode for Neural Chat** — A new `/quiet` slash command temporarily silences AI replies in a single channel without disabling Neural Chat server-wide. `/quiet on` mutes the current channel for the default duration (30 minutes), and `duration:1h` or `duration:30m` sets a custom window that's clamped between 1 minute and the configured maximum. Pass `channel:#support` to target another channel, `/quiet off` to resume early, or `/quiet status` to check what's active. Quiet mode also pauses vibe-mode triage accumulation for the muted channel so the bot fully steps out of the conversation. Permissions default to moderators and can be widened to `any`, narrowed to `admin`, or pinned to specific role IDs via `quietMode.allowedRoles`. Members can also mention the bot — for example, `@Volvox quiet for 30 minutes` or `@Volvox unquiet`. See [Quiet mode](/features/ai-conversations#quiet-mode). **Voice session tracking lands in the Overview** — Analytics on the Overview page now splits cleanly into **Messages**, **Voice Tracking**, and **Community Engagement** sub-tabs, so voice chatter stops getting buried under message charts. Voice Tracking covers joins, active sessions, unique participants, total and average voice time, and top channels ranked by session count and duration. A recent sessions feed flags rooms still live when analytics last refreshed. Overlapping sessions in the same channel are counted instead of quietly discarded, so simultaneous calls finally show up in the totals. The date range picker and 90-day window apply as usual. See [Analytics](/features/analytics). ## Improvements **Settings tabs finally have addresses** — The dashboard's **Config** screens now keep the URL in sync with the active tab. Switching tabs appends a `?tab=` query parameter, so you can bookmark **Moderation & Safety -> Link filter** or paste a link to a teammate and land on the exact tab you opened. Browser back and forward walk through your tab history. Existing settings links still work — they redirect to each category's first tab. **Calmer status rotation** — Volvox.Bot's presence used to swap status messages every five minutes, which turned the member list into a low-key strobe light. The default rotation interval is now **30 minutes**, so **Watching**, **Listening**, **Playing**, and **Competing** each get room to land before the next one swaps in. Servers that customized the interval keep their setting; everyone else picks up the new default automatically. ## Removed **Command aliases have left the chat** — The `/alias` command and the entire custom-alias system are retired. Aliases that remapped one slash command to another stop resolving on the next bot restart, so reach for Discord's built-in slash commands instead. Nothing to clean up on your end — the underlying table is dropped automatically when migrations run. **Snippets, polls, code reviews, and announcements are gone** — The `/snippet`, `/poll`, `/review`, and `/announce` commands and their dashboard toggles are retired. The **Post Announcement** action in the level-up action builder is gone too. Discord's native polls cover voting, threads and code blocks cover review and snippet sharing, and plain channel messages cover announcements. Saved configuration for these features is dropped automatically when migrations run, and existing level-up actions of type **Post Announcement** stop firing. **TL;DR moved to Community Tools** — The TL;DR settings tab now lives under **Settings -> Community Tools** alongside **Starboard**, instead of under **Onboarding & Growth**. The `/tldr` command and every setting (model, message limits, cooldown, system prompt) work exactly the same — only the dashboard location changed. See [TL;DR](/features/tldr). **Reaction roles retired** — The `/reactionrole` command and its `create`, `add`, `remove`, `delete`, and `list` subcommands have been removed, along with the underlying reaction-role menu storage. Volvox.Bot no longer assigns or revokes roles when members react to menu messages. Existing menu messages stay in your channels as ordinary posts until you delete them — they just won't hand out roles anymore. Stored reaction-role menus and their emoji-to-role mappings were dropped as part of the upgrade. For self-assigned roles, use Discord's native **Onboarding** flow or a button-based role picker from another bot. The rest of your configuration is untouched. ## Fixes **Bot presence is always online** — Volvox.Bot now stays **online** at all times. Any **idle**, **do not disturb**, or **invisible** value left over from older configs is ignored. The availability dot no longer drifts out of sync with whether the bot is actually running. Custom status text and rotation messages still work exactly as before; only the availability dot is locked. **`discord.gg` invites are blockable again** — Adding `discord.gg` (or any other Discord invite host) to the Link filter blocklist now reliably deletes matching messages, including ones posted by members with the Discord **Administrator** permission. The raw Administrator permission no longer auto-exempts users from the Link filter — your configured admin, moderator, and protected roles still bypass it as expected. Other moderation paths continue to treat the Administrator permission as an exemption. ## Improvements **Status messages that actually flex** — Volvox.Bot's Discord presence rotation got a glow-up. The old lineup — "Watching servers", "Listening to members", "Playing with /help" — read like placeholder copy from a 2017 starter template. The new rotation cycles through **Watching**, **Listening**, **Playing**, and a fresh **Competing** status. Each one pairs member counts with server counts, so the numbers do the bragging. Nothing to configure; your bot will start showing off the next time it reconnects. ## New features **Full moderation history on member profiles** — The member profile in the dashboard now shows the complete case history for that member instead of just recent warnings. Cases are paginated 10 per page, and a quick breakdown at the top tallies warnings, timeouts, kicks, and bans so you can size up a member at a glance. Select **View full history** to jump to the Moderation page with that member's user ID preloaded — handy when you need filters, search, or the wider tools on that page. You can also share the preloaded view directly: `https://volvox.bot/dashboard/moderation?userId=`. See [Moderation](/features/moderation#review-a-members-moderation-history). ## Improvements **Case log messages link straight to Discord** — Open any case in the dashboard and the **Log Message** field is now a clickable link. It opens the original log post in Discord in a new tab, as long as the bot has the channel and message ID for that case. Older cases without a stored channel ID still display the message ID as plain text. Nothing to configure — new cases pick this up automatically. See [Moderation](/features/moderation#jump-to-the-discord-log-message). **Cookie preferences are now yours to decide** — First-time visitors to the website and dashboard get a consent banner that sorts cookies into two honest buckets. **Essential** stays on so sign-in and saved state actually work. **Analytics** (Amplitude) stays off until you opt in. Pick **Accept all**, **Reject non-essential**, or **Customize** to flip analytics on its own. Changed your mind? The **Cookie Preferences** link in the footer is there for exactly that, and switching analytics off clears the Amplitude identifiers and cookies stored while you were opted in. Your choice sticks for 365 days per browser. See [Cookie preferences](/security#cookie-preferences). **Add to Server lands you on the dashboard** — Selecting **Add to Server** on the landing page used to pop Discord open in a new tab and leave you to find your own way back. The flow now starts the invite in the same window and returns you straight to the dashboard after you approve, so onboarding is one continuous trip instead of a tab-juggling exercise. The dashboard's **Add Bot** button already worked this way; the landing page now matches it. See [Getting started](/getting-started#add-volvox-bot-to-your-server). **Tidier AI auto-mod case reasons** — Case reasons from [AI auto-moderation](/features/moderation) used to read like a model's stream-of-consciousness, occasionally truncating into the void. They now follow a compact format: `AI Auto Mod: Toxicity 82%, Harassment 64% / delete and warn`. Categories appear with their confidence scores, the actions taken are listed plainly, and case tables stop wrapping into wall-of-text territory. Existing cases keep their original reasons; new cases adopt the new format automatically. **Less noisy AI model picker** — Models offered through OpenRouter no longer carry a redundant **(via OpenRouter)** suffix in dashboard model pickers. The provider is already obvious from the section it lives in, and the cleaner labels make scanning the list a lot faster. See [AI automation](/features/ai-conversations). **Audit log filters and details, expanded** — The **Audit Log** page now groups actions by category (Moderation, AI and triage, Config, Members, Tickets, Temp roles) and adds **Target ID** and **Channel ID** filters alongside the existing user and date filters. Each row leads with a plain-language summary — for example, "Mod#0001 banned BadUser#1234" or "AI auto-mod timed out SpamBot#0001" — so you can scan the table without decoding action codes. Expand any entry to see structured panels for moderation cases (case number, action, reason) and AI auto-mod decisions (model, category scores, thresholds, skipped actions, message link), with the raw JSON still available underneath. See [Audit log](/features/audit-log). ## Removed **GitHub feed feature retired** — The `/github` command, the GitHub feed module, and its **Settings -> Support & Integrations** panel have been removed. It saw vanishingly little use and the maintenance tax wasn't worth it. If you relied on GitHub-to-Discord notifications, Discord's built-in webhook integration covers the same ground in about thirty seconds of setup. Stored GitHub feed configuration has been dropped as part of the upgrade; nothing else in your config was touched. **Reminders retired** — The `/remind` command, its scheduler, and the **Reminders** section in **Config** have all been removed. The bot no longer delivers personal or channel reminders, and any pending reminders have been cleared. If you leaned on this for routine pings, Discord's scheduled events or a lightweight webhook-driven cron are the closest replacements. The rest of your configuration is untouched. **Backup and restore retired** — Config backup and restore — including the export and import endpoints and any scheduled automatic backups — have been removed. Usage was minimal and the surface area carried real risk: an accidental restore could clobber a live config in a single click. Your live configuration is unaffected and stays editable from the dashboard or the `/config` command. If you want a snapshot before a big change, copy the relevant settings out of the dashboard manually before editing. **Memory opt-out subcommand removed** — The `/memory optout` subcommand has been retired. To clear what the bot remembers about you, use `/memory forget`. To turn memory off for everyone, a server admin can disable it under **Settings -> AI & Automation**. Existing memories stay put and keep following the server's memory settings. **Outbound webhook notifications retired** — The **Notifications** panel for managing outbound webhook endpoints, the **Webhook** action under **XP Level-Up Actions** and **Default Moderation Actions**, and the webhook delivery log have all been removed. Volvox.Bot no longer fans events out to third-party URLs, and any stored webhook endpoints, secrets, and delivery history were dropped during the upgrade. If you forwarded events to another service, switch to Discord's native channel webhooks or your own listener built against the dashboard. The **Notifications** category and `notifications.*` action types no longer appear in [Audit log](/features/audit-log) filters. **`/help` knowledge base retired** — The `/help` slash command and its per-server FAQ are gone, along with the `view`, `add`, `edit`, `remove`, and `list` subcommands moderators used to curate topics. Usage was minimal and the format never quite kept pace with Discord's own forum and pinned-message tooling. Stored help topics have been dropped as part of the upgrade; nothing else in your config was touched. For server documentation, a pinned message, a forum channel, or a ticket category covers the same ground without a custom command surface. Looking for product support instead? The [Help](/help) page still lists every way to reach us. ## Fixes **Direct @mentions no longer trip over themselves** — The lower-latency mention path shipped on 2026-05-11 occasionally raced against the standard triage flow and aborted the very response it was trying to speed up. Direct mentions and replies to the bot now complete reliably instead of silently bailing mid-evaluation. See [Moderation](/features/moderation). ## Removed **Showcase, Challenges, and Role Menus have left the building** — Three features that weren't pulling their weight have been retired so the dashboard and bot can focus on what people actually use: * **Showcase** — the `/showcase` command and its community gallery pages are gone. Submissions and votes have been cleared from storage. * **Challenges** — the legacy `/challenge` command, scheduler, and prompt library have been removed. No more weekly prompts firing into channels nobody opted into. * **Role menus** — the role menu builder under **Settings -> Onboarding & Growth** and the `/rolemenu` command have been removed. If you handed out roles this way, swap to Discord's native onboarding before your next member wave. Existing data for these features has been dropped as part of the upgrade. Nothing else in your configuration was touched. ## Fixes **Starboard config now refuses nonsense values** — The Starboard section was the lone holdout without a validation schema. The API would cheerfully accept a string where a threshold should be, or persist an emoji field long enough to qualify as a novella. All six Starboard fields are now type- and range-checked, and the emoji field is capped at a sane length. See [Starboard](/features/community#starboard). **Starboard emoji wildcard saves correctly on autosave** — Picking **Any** as your reaction emoji could previously persist the Unicode heavy asterisk (✱) instead of the intended wildcard (`*`) if autosave fired before the field lost focus. The normalization now runs on every change, so **Any** means **any** the moment you select it. ## Improvements **Protected roles now skip automated moderation, too** — Roles you select under **Settings -> Moderation & Safety -> Moderation -> Protect Roles** used to only shield members from manual mod actions, leaving them awkwardly exposed to Active Sentry's automated side. They now also exempt members from AI auto-moderation, spam rate limiting, and link filters. Your existing selections take effect immediately — no migration, no resaving, no fuss. See [Moderation](/features/moderation#protected-roles). **Cleaner Starboard embeds** — Starboard posts now lead with a clickable title — for example, **⭐ 7 stars in #general** — that jumps straight to the original message. The old **Source**, **Stars**, and **Jump** fields have been retired, leaving more room for the message content and any attached image. Star counts still update in place as members react. Nothing to configure; existing posts pick up the new layout the next time their star count changes. See [Community](/features/community#starboard). ## New features **Dashboard server picker for first-time setup** — Logging in without the bot installed used to dump you into a hauntingly empty dashboard. Now the [dashboard](/dashboard) opens a proper server picker that lists every Discord server you can manage. Each card shows whether Volvox.Bot is already present (**Manage**) or still needs an invite (**Add Bot**), with member counts so you pick the right one. Select **Refresh server list** when Discord takes its sweet time catching up after an invite. See [Getting started](/getting-started) for the full walkthrough. **Inline "Add Bot" flow** — Inviting Volvox.Bot from the dashboard now returns you to the server picker after Discord's OAuth handshake, instead of stranding you on a permissions screen. Fewer tabs, fewer "wait, where did it go?" moments. ## Fixes **Dashboard no longer greets new users with a void** — Accounts whose servers don't yet have Volvox.Bot installed previously landed on a blank dashboard with nothing to click. The new welcome flow routes those users straight to the server picker so onboarding actually has a starting point. ## Improvements **Multiple support staff roles for tickets** — The **Support role** picker on **Settings -> Tickets** is now **Support Staff Roles** and accepts as many roles as you need. The bot grants ticket access to every selected role. It dedupes members across roles when adding them to thread tickets, and skips roles that no longer exist. Existing single-role setups continue to work unchanged. See [Tickets](/features/tickets). ## Improvements **Step-by-step AI auto-mod DMs** — Active Sentry now sends a separate pre-action DM for each destructive step in a sequence (for example, warn -> kick -> ban). Each DM lists **Actions taken** so far and the single **Actions planned** step coming next. Members see exactly where they are in the sequence instead of getting one combined list. Follow-up DMs use a new title like **Moderation action update in ``**. The new title makes it clear that this is the same ongoing incident. DM toggles in **Settings -> Moderation & Safety -> Content Safety -> User DM Notifications** still control which actions notify members. Members never receive duplicate DMs for the same action. See [Moderation](/features/moderation). ## New features **Triage performance controls** — AI Automation now exposes triage latency controls in the dashboard. `responseCooldownMs` defaults to `0` ms and remains clamped with `triageDebounceMs` and `memoryTimeoutMs`; fast direct replies are enabled by default and you can toggle them from Operational Modes. See [Moderation](/features/moderation). ## Improvements **Lower-latency mentions** — Direct @mentions and replies to the bot now trigger immediate triage evaluation and bypass the response cooldown for mentioned messages. They still run through the classifier and responder flow. Safety and relevance checks remain in place. See [Moderation](/features/moderation). **Documented triage defaults** — The default response cooldown is `0` ms. New server config uses 5 recent context messages by default; runtime triage only falls back to 10 when that value is unset. **Stricter triage model validation** — The dashboard now rejects unsupported or malformed `provider:model` strings when you save a triage config, so misconfigurations surface up front instead of failing at runtime. The bot still falls back gracefully if a legacy stored value drifts out of the supported list. ## Improvements **Community features on by default** — TL;DR summaries, engagement tracking, and the reputation XP system now ship enabled out of the box. New servers see leaderboards, badges, and `/tldr` working immediately. You can still toggle each feature off from the dashboard. See [Community](/features/community) and [TL;DR](/features/tldr). **No more pre-seeded channel IDs** — Welcome, moderation alert, and triage moderation log channels start empty until you select a channel for your server. Earlier defaults referenced channels from a single test server, which could surface confusing errors on first install. Configure each channel from **Settings -> Onboarding & Growth** and **Settings -> Moderation & Safety**. ## New features **Community Hubs surface in the server selector** — The dashboard server selector now lists every server with Community Hubs enabled under a dedicated **Community Hubs** section. Members see those entries even without admin or moderator roles. Selecting a hub opens the read-only public view. Servers without hubs enabled stay hidden from members who lack management permissions. See [Community](/features/community) for details. **Owner access level** — Server owners now consistently get full admin access on the dashboard, regardless of role permissions. The dashboard and API access enum is now `[owner, admin, moderator, viewer]`. See [Permissions](/configuration/permissions) for the role breakdown. **Engagement metrics on Analytics** — The Analytics overview shows **Active users**, **Avg messages per user**, **Lifetime reactions given**, and **Lifetime reactions received**. The page also adds a **Recent events** feed (last 10 messages and slash command uses) and a per-model **AI usage** breakdown. The breakdown shows requests, prompt and completion tokens, and cost in USD when usage data is available. See [Analytics](/features/analytics). ## Improvements **Clearer welcome personalization toggle** — The "Engine Intelligence" toggle on **Settings -> Onboarding & Growth** is now labeled **AI-Powered Personalization**. The new label explains that the bot uses server context — active channels, member milestones — to personalize welcome messages. Highlight and Exclude channel pickers also stop showing the same channel in both lists, so the two settings can't conflict. **Tidier dashboard chrome** — The configuration search now closes automatically when you select a result or interact elsewhere on the page. The **Variables** lists in welcome and XP-level editors collapse to save vertical space. The **AI Chat** entry has moved out of the sidebar — use **Conversations** for AI history instead. ## New features **Customizable onboarding panel messages** — Tailor the copy on your rules, role menu, and introduction panels directly from the [dashboard](/dashboard) under Onboarding & Growth. Each panel has its own Discord markdown editor (up to 2000 characters), so you can match your server's tone instead of relying on the defaults. **Introduction prompt variables** — The new introduction prompt supports template variables: `{{user}}` mentions the new member, `{{username}}` prints their plain name without a ping, and `{{server}}` inserts your server's name. Combine them to write a warm, personal welcome — for example, `Welcome {{user}}! Tell {{server}} a bit about yourself.` **Dedicated role menu publishing** — `/welcome setup` and the dashboard now publish the rules and role menu panels independently, with per-panel status feedback. Publish a single panel without touching the other, and see clear success, warning, or failure messages for each. ## Improvements **More reliable welcome publishing** — Welcome publish routes now rate-limit requests and validate channels per server, so misconfigured publishes fail fast with a useful error. The dashboard also surfaces persistence warnings when Discord delivery succeeds but the bot can't save state, so you know to retry. **Friendlier timezone inputs** — Challenge schedule timezones now accept UTC/GMT offsets like `GMT+3` or `UTC-05`, in addition to IANA names like `America/New_York`. Offsets normalize to their canonical IANA equivalent (for example, `GMT+3` -> `Etc/GMT-3`) when you save. ## Fixes **Stricter timezone validation** — The dashboard now rejects unsupported timezone strings up front with a clear error (`expected a valid IANA timezone or UTC/GMT offset`). This stops bad values from reaching the scheduler. Existing servers fall back to a supported timezone automatically, so daily challenges keep posting on time. **Steadier server list** — The dashboard server selector no longer drops servers when a single server lookup fails. Loading falls back to bot-side data so admins still see and manage every server they have access to. ## Improvements **Dark mode by default** — The [dashboard](/dashboard) and the documentation site now load in dark mode on first visit, matching the rest of the Volvox.Bot brand. You can still switch to light mode or follow your system preference from the theme toggle. Your choice persists across sessions. Charts, toasts, and other themed surfaces pick up the new default automatically. ## Fixes **New member counts that actually update** — Analytics on the [dashboard](/dashboard) now refresh new-member counts on every load, instead of holding onto stale numbers from a cached payload. Welcome the newcomers, count them properly, and stop wondering why your "new this week" tile looked suspiciously frozen. ## Improvements **Global admin access for ops pages** — Only global admins (configured via `BOT_OWNER_IDS`) can now access the dashboard's **Logs** and **Performance** pages. Server admins and moderators continue to manage their servers as usual, while operators keep infrastructure-level views to themselves. See [Permissions](/configuration/permissions) for the full role breakdown. **Cleaner access levels** — Server access roles are now consistently `admin`, `moderator`, or `viewer` across the dashboard and API. The dashboard surfaces global admin status separately, so sidebar navigation and protected pages reflect the correct permissions for every user. ## Fixes **More reliable AI auto-moderation** — [AI auto-moderation](/features/moderation) now parses model responses more robustly. The bot scores and acts on messages correctly, even when the model buries its verdict in extra text or nested formatting. Fewer skipped messages, fewer "no decision" outcomes. **Stronger link filter and phishing detection** — The link filter now extracts URLs more accurately from messages, catching more obfuscated and disguised links. Phishing detection resists common evasion tricks (extra punctuation, mixed casing, embedded characters), so the filter flags suspicious links even when posters try to sneak them past. ## Improvements **Stronger phishing and link filtering** — The link filter now catches malicious URLs hidden inside markdown links (`[click here](https://...)`), angle-bracket links (``), and links wedged against punctuation. It also detects phishing keywords in URL query strings (for example, `?gift=nitro` on a `.xyz` domain). See [moderation](/features/moderation) for the full set of safeguards. **Better reliability monitoring** — Volvox.Bot now tracks dashboard errors and performance issues in the background, so the team finds and fixes problems faster. It scrubs sensitive data — Discord IDs, message content, tokens, query params, headers, and request bodies — before anything leaves your browser. Your server's data stays private by default. ## Fixes **More reliable AI auto-moderation** — [AI auto-moderation](/features/moderation) now parses provider responses correctly, even when they arrive wrapped in extra text or nested braces. Unparseable responses route to "needs review" instead of slipping through. Fewer missed flags, fewer surprises. ## New features **Branded 404 page** — Missing pages on [volvox.bot](https://volvox.bot) now serve a polished, on-brand 404 with quick links back into the [dashboard](/dashboard) and docs, instead of the generic browser error. ## Improvements **Audit trail for AI triage moderation** — [AI automation](/features/ai-conversations) now writes its moderation actions to the audit log. Moderators can trace exactly which AI decisions led to deletes, warnings, timeouts, kicks, or bans. The bot also throttles triage budget alerts, so usage-limit notifications stop duplicating noisily. ## Fixes **Dashboard activity chart dates** — The activity chart on the [dashboard](/dashboard) overview now plots dates correctly. Daily message and command counts line up with the right day in your server's timezone. **Documentation link in profile dropdown** — The "Documentation" link in the profile dropdown menu works again across the [dashboard](/dashboard), opening the docs in a new tab as expected. ## New features **AI auto-moderation** — Active Sentry now scores incoming messages with AI across toxicity, spam, harassment, hate speech, sexual content, violence, and self-harm. Select a detection model and set per-category sensitivity thresholds. Configure response actions — ignore, delete, flag, warn, timeout, kick, or ban — including multiple actions per violation. Volvox.Bot logs AI auto-moderation actions alongside classic moderation cases. Configure it under **Settings -> Moderation & Safety -> Content Safety** in the [dashboard](/dashboard). See the [moderation docs](/features/moderation) for details. **Configurable model for `/tldr`** — You can now select which provider/model the [TL;DR command](/features/tldr) uses to generate summaries, right from the dashboard. MiniMax M2.7 is the new default. **MiniMax provider** — MiniMax is now a first-class AI provider, with models like **MiniMax M2.7** and **MiniMax M2.7 Highspeed** available across [AI automation](/features/ai-conversations) and [TL;DR](/features/tldr). **Welcome panel publishing from the dashboard** — Publish, update, and remove your welcome and rules panels directly from the [dashboard](/dashboard) under Onboarding & Growth. Channel changes automatically clean up stale panel messages, and publish actions show clear success/failure feedback. **Dedicated role menu channel** — Onboarding & Growth now exposes a separate **Role Menu Channel** picker. Your self-serve role menu can live in its own channel, apart from rules and welcome. ## Improvements **Cleaner model selectors** — Dashboard provider/model pickers now hide models that aren't available to your server, so you only see options you can actually use. The dashboard preserves saved selections with `provider:model` IDs, including ones containing colons. **Streamlined dashboard overview** — The AI cost tile is gone from the dashboard overview, keeping the page focused on activity and health metrics. ## Fixes **Auto-mod flag embeds** — Flag embeds now show the global actions that ran for an auto-mod violation, so moderators can see which actions ran at a glance. **Welcome publish reliability** — Welcome-panel publishing now handles several edge cases gracefully: split payloads, status mismatches, persistence gaps, channel-change cleanup, and rate-limited publish routes. **AI auto-moderation stability** — Prompt handling, action reporting, and case/flag log writes are now more resilient, so AI auto-moderation behaves predictably under unusual server conditions. ## New features **Custom returning member welcome message** — When someone rejoins your server, you can now send them a tailored greeting instead of the default copy. Toggle the **Returning member message** option in the [dashboard](/dashboard) under Onboarding & Growth. Then write your own message with full Discord markdown support and welcome variables like `{{user}}`. ## Improvements **Landing page navigation and feedback polish** — In-page navigation on [the landing page](https://volvox.bot) now scrolls smoothly to each section. It also respects reduced-motion preferences and lines up correctly under the sticky navbar. The footer, feature grid, pricing table, and stats sections also got visual refinements. The result is cleaner spacing, contrast, and interactive states. ## Fixes **Disable milestone interval messages** — Setting the welcome milestone interval to `0` in the [dashboard](/dashboard) now correctly disables interval-based milestone callouts in welcome messages. Notable milestones (like 100, 500, 1000 members) still appear, so you can opt out of the regular cadence without losing the big moments. ## New features **More AI providers** — Moonshot and OpenRouter are now first-class providers for [AI automation](/features/ai-conversations) and [TL;DR](/features/tldr). Select models from these providers in your AI settings using the `provider:model` format (for example, `moonshot:kimi-k2.6`). **TL;DR is now front and center** — `/tldr` now gets top billing on the landing page, with a [dedicated docs page](/features/tldr) covering setup, configuration, and examples. ## Improvements **Faster dashboard selectors** — Role and channel pickers across the dashboard load faster and refresh without a full page reload when Discord updates. New roles and channels appear sooner, and switching between pages reuses cached data. **Starboard moved to Community Tools** — Starboard settings now live under **Community Tools** in the [dashboard](/dashboard) instead of **Moderation & Safety**, grouping them with other member-facing utilities. **Version label in the dashboard** — The dashboard sidebar and landing footer now display the current Volvox.Bot version, making it easier to confirm which build you're on. ## Fixes **Welcome message channel selector** — You can now select, directly from the [dashboard](/dashboard), the channel where the bot posts welcome messages. The Onboarding & Growth settings page exposes a dedicated **Message Channel** picker alongside the Rules, Roles, and Support channel selectors. ## New features **Level-up action builder** — Configure automated actions that trigger when members reach specific XP levels. From the dashboard, set up actions like granting or removing roles, sending DMs, or posting announcements in a channel. You can also award bonus XP, add reactions, set nickname prefixes or suffixes, and fire webhooks. Each action supports Discord markdown messages, rich embeds, and template variables like `{{username}}` and `{{level}}`. Assign multiple actions per level to build customized level-up experiences for your server. ## New features **Role-based triage filtering** — You can now control which members the AI responds to by role. Set allowed roles (allowlist) or excluded roles (denylist) in your AI Automation settings. The triage filter automatically ignores bot, webhook, and system messages. **Configurable level-up DMs** — You can now set custom DM messages sent to members when they level up. Supports per-level message overrides, a live Discord-style preview, and built-in rate limiting to prevent spam. **Discord markdown editor** — The dashboard now includes a new rich-text editor for Discord-formatted messages. It ships with a formatting toolbar, variable inserter, split raw/preview mode, character counter, and keyboard shortcuts. **Visual embed builder** — Create Discord embeds visually in the dashboard with a color picker, field management, thumbnail selector, and a live embed preview. **Dashboard permission controls** — The dashboard now enforces role-based access. Viewers get read-only access, moderators can manage moderation features, and admins have full control. **Server-scoped log viewer** — The log viewer now shows logs scoped to your current server. A new channel filter lets you narrow the live log stream to specific Discord channels. ## Improvements **Landing page redesign** — The landing page now sports a new visual style, with interactive feature previews in a bento-box grid, animated stats, and a redesigned pricing section. **Dashboard polish** — Tables now have row hover highlighting, KPI counters animate, and heatmap tooltips are visible. Member rows are clickable, XP progress bars now display correctly, and the dashboard shows a live commands-served counter. Inputs and dropdowns now use thin scrollbars for a cleaner look. **Identity resolution** — Conversation replays now show real Discord profile icons. Volvox.Bot resolves mentions to actual usernames, and audit logs display rich user identity (display name + username). **Improved AI reliability** — The AI triage system now includes retry logic, timeout handling, and per-role budget support. You can configure separate models for classification vs. responding to optimize costs. **Mobile experience** — The settings save toolbar, header, and sidebar are now fully responsive on smaller screens. Every animated component now supports reduced-motion preferences. **OpenGraph previews** — Sharing Volvox.Bot links now shows rich previews on social media, Discord, and Slack. A sitemap and robots.txt are now in place for better search engine discoverability. **Branding update** — Visible branding now uses "Volvox.Bot" consistently across the product. ## Fixes **More reliable bot responses** — Reminders, moderation, reaction roles, and other features now handle command-response failures gracefully (for example, blocked DMs or deleted channels) instead of failing silently. **Removed the Bot Owners setting** — The "Bot Owners" editor is gone from dashboard Permissions settings. You now manage bot ownership via environment configuration only. # Bot Settings and Dashboard Settings Source: https://docs.volvox.bot/configuration/bot-settings Configure Volvox.Bot for your Discord server from the web dashboard, with per-feature settings, role access, and no config files or restarts. # Bot settings All server configuration lives in the dashboard under **Settings**. No config files, no environment variables, no restarts. ## How it works You can edit server settings through the dashboard. The dashboard saves changes through the bot API, and the bot picks up new config on the next config refresh. Use the dashboard search to quickly find a specific setting. ## Shareable tab URLs Every settings category and feature tab has its own URL. Bookmark or share a link to open the dashboard on the exact tab you want. Switching tabs updates the address bar with a `?tab=` query parameter, and browser back and forward walk through your tab history. The URL pattern is: ```text theme={null} https://volvox.bot/dashboard/settings/?tab= ``` For example, the Link filter is inside the **Moderation** tab at `/dashboard/settings/moderation-safety?tab=moderation`. Open `/dashboard/settings` and Volvox.Bot redirects you to the default **AI & Automation** category. ## Settings tabs | Section | What you can configure | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **AI & Automation** | AI chat, per-channel AI modes, triage, model routing, and memory | | **Onboarding & Growth** | Welcome messages, rules verification, introductions, XP, level-up actions, and engagement badges | | **Moderation & Safety** | Content safety, spam detection, moderation actions, warning rules, permissions, protected roles, and audit log retention | | **Community Tools** | Command prefix, starboard highlights, and TL;DR summaries | | **Support & Integrations** | Ticket mode, ticket panels, staff roles, limits, and transcript channels | | Dashboard tab | Route | Feature docs | | ------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------- | | AI & Automation -> AI Chat | `/dashboard/settings/ai-automation?tab=ai-chat` | [AI Chat settings](/features/ai-conversations#ai-chat-settings) | | AI & Automation -> Triage | `/dashboard/settings/ai-automation?tab=triage` | [AI triage settings](/features/moderation#ai-triage-settings) | | AI & Automation -> Memory | `/dashboard/settings/ai-automation?tab=memory` | [Memory settings](/features/ai-conversations#memory-settings) | | Onboarding & Growth -> Welcome | `/dashboard/settings/onboarding-growth?tab=welcome` | [Welcome settings](/features/welcome#welcome-settings) | | Onboarding & Growth -> Engagement | `/dashboard/settings/onboarding-growth?tab=engagement` | [Engagement settings](/features/community#engagement-settings) | | Onboarding & Growth -> Reputation | `/dashboard/settings/onboarding-growth?tab=reputation` | [Reputation settings](/features/community#reputation-settings) | | Onboarding & Growth -> Level Actions | `/dashboard/settings/onboarding-growth?tab=xp-level-actions` | [Level-up actions](/features/community#level-up-actions) | | Moderation & Safety -> Content Safety | `/dashboard/settings/moderation-safety?tab=ai-automod` | [AI auto-moderation settings](/features/moderation#ai-auto-moderation-settings) | | Moderation & Safety -> Spam Detection | `/dashboard/settings/moderation-safety?tab=spam-detection` | [Spam detection settings](/features/moderation#spam-detection-settings) | | Moderation & Safety -> Moderation | `/dashboard/settings/moderation-safety?tab=moderation` | [Classic moderation settings](/features/moderation#classic-moderation-settings) | | Moderation & Safety -> Warning Rules | `/dashboard/settings/moderation-safety?tab=warning-rules` | [Warning expiry and escalation](/features/moderation#warning-expiry-and-escalation) | | Moderation & Safety -> Permissions | `/dashboard/settings/moderation-safety?tab=permissions` | [Permissions settings](/configuration/permissions#permissions-settings) | | Moderation & Safety -> Audit Log | `/dashboard/settings/moderation-safety?tab=audit-log` | [Audit Log settings](/features/audit-log#audit-log-settings) | | Community Tools -> Commands | `/dashboard/settings/community-tools?tab=commands` | [Command prefix](#command-prefix) | | Community Tools -> Starboard | `/dashboard/settings/community-tools?tab=starboard` | [Starboard](/features/community#starboard) | | Community Tools -> TL;DR | `/dashboard/settings/community-tools?tab=tldr` | [TL;DR settings](/features/tldr#tldr-settings) | | Support & Integrations -> Tickets | `/dashboard/settings/support-integrations?tab=tickets` | [Ticket settings](/features/tickets#ticket-settings) | ## Command prefix Set a text command prefix under **Settings -> Community Tools -> Commands**. A prefix can be one to five non-space characters, such as `.`, `!`, or `?`. Leave the field blank to disable prefix commands and keep slash-only behavior. Prefix commands are an alias layer over slash commands — they reuse the exact same command names, options, and permission gates. A member who cannot run `/ban` also cannot run `!ban`, and a moderator who can run `/timeout` can run it either way. ### When to use a prefix * Members on mobile or older clients prefer typing over the slash command picker. * You want quick, one-handed moderation actions during a raid. * Your community already uses a familiar prefix from a previous bot. ### Allowed characters * One to five characters * No spaces, `/`, `@`, `#`, `<`, `>`, or backticks. Those collide with mentions, channels, or Markdown. * Common examples: `.`, `!`, `?`, `$`, `!!`, `..` ### Example With the prefix set to `!`, both calls below run the same handler and produce the same result: ```text theme={null} /ban user:@spammer reason:advertising !ban @spammer advertising ``` Quote arguments with spaces, just like a shell: ```text theme={null} !timeout @spammer 10m "spamming invite links" ``` If a member runs a prefix command they don't have permission for, the bot replies with the same permission error it sends for slash commands. ## Saving changes Settings are per-server. Each Discord server you add Volvox.Bot to has its own independent configuration. When you change settings, the dashboard shows a save bar with the pending changes. Save when you are ready, or discard changes to return to the last saved config. The legacy `/dashboard/config` route redirects to `/dashboard/settings`. # Discord Bot Permissions and Dashboard Access Control Source: https://docs.volvox.bot/configuration/permissions Discord permissions Volvox.Bot requests for moderation and logging, plus dashboard access roles and per-feature role restrictions you can configure. # Permissions ## Discord permissions When you add Volvox.Bot to your server, the default invite requests these permissions: | Permission | Why it's needed | | -------------------- | ------------------------------------------------------- | | Kick Members | Moderation actions | | Ban Members | Moderation actions | | Manage Channels | Create and permission-lock channel-mode support tickets | | View Channels | Access channels for logging and AI conversations | | Send Messages | Bot responses, notifications | | Manage Messages | Auto-mod message deletion | | Read Message History | Access prior messages for AI context and search | | Moderate Members | Moderation timeouts | Volvox.Bot only uses permissions when performing an action. It doesn't read or store messages unless a feature requires it. Channel-mode tickets require **Manage Channels** because Discord treats creating the ticket channel and applying its private permission overwrites as channel management. ## Optional role permissions Welcome verification and level-up role rewards require Discord role management to succeed. The bot's highest role must be above any role it assigns or removes. If a role workflow fails, check Discord's role hierarchy before changing Volvox.Bot settings. ## Dashboard access Discord roles control dashboard access. By default, server owners and users with the **Administrator** permission can manage dashboard settings for their server. When you first open the dashboard, the server picker only exposes settings management actions for servers where you're the owner or an admin. Those cards show **Manage** when Volvox.Bot is already installed and **Add Bot** when it still needs to be invited. Moderator-only and viewer-only servers stay read-only and don't expose settings or invite controls. Configure Volvox.Bot's admin and moderator role IDs in **Settings -> Moderation & Safety -> Permissions**. Viewer access is derived from membership and is not a configurable role picker: * **Owner** — Server owners always get full admin access, regardless of role permissions. * **Admin** — Full access to all dashboard features, including settings (granted by the **Administrator** Discord permission or admin role). * **Moderator** — Can act on moderation and tickets where the dashboard or Discord command allows it, but can't open or change server settings on the dashboard. Promote a moderator to admin if they need to edit configuration. * **Viewer** — Read-only member-level access. Viewer access does not expose server settings. Only owners and admins can open the settings dashboard for a server. If a moderator needs to update configuration, an owner or admin must either make the change for them or grant them the **Administrator** Discord permission. ## Per-feature permissions You can restrict commands to permission levels through **Settings -> Moderation & Safety -> Permissions**. Prefix commands and slash commands use the same permission checks. ## Permissions settings The **Permissions** settings tab at `/dashboard/settings/moderation-safety?tab=permissions` controls dashboard admin roles, moderator roles, and per-command permission levels for prefix commands and slash commands. ## Global admin access Some dashboard pages expose infrastructure-level data that isn't tied to a single server. Only **global admins** — operators of the Volvox.Bot deployment itself, not server admins — can access these pages. ### What requires global admin Only global admins can access the following dashboard pages and APIs: * **Performance** (`/dashboard/performance`) — Bot uptime, latency, and resource trends across all servers. * **Logs** (`/dashboard/logs`) — Live log stream across all servers, server/channel filtering controls, and the underlying log-stream WebSocket ticket endpoint. Self-hosted dashboards need `BOT_PUBLIC_URL` set to the public bot origin so the browser can reach `/ws/logs`. If you aren't a global admin, the sidebar hides these entries, and visiting their URLs redirects you back to the dashboard. All other dashboard features (moderation, tickets, AI, analytics, configuration) continue to follow your per-server role. Self-hosted deployments with separate web and bot services need `BOT_PUBLIC_URL` set to the public HTTPS bot origin for live Logs. Keep `BOT_API_URL` private for server-side dashboard proxy calls. ### Configuring global admins Set global admins via the `BOT_OWNER_IDS` environment variable on the server running the bot and dashboard. Provide a comma-separated list of Discord user IDs: ```bash theme={null} BOT_OWNER_IDS=123456789012345678,987654321098765432 ``` Each ID must be a Discord user ID for an account that logs in to the dashboard with Discord OAuth2. Changes take effect after you restart every process or container that reads `BOT_OWNER_IDS`. This includes both the bot and dashboard when they run separately. Global admin status is independent of any server's roles. If you're listed in `BOT_OWNER_IDS`, you only gain access to the operator-only pages above. Normal Discord permissions still govern what you can do in your servers. # Manage Your Discord Server from the Volvox.Bot Dashboard Source: https://docs.volvox.bot/dashboard Tour of the Volvox.Bot web dashboard, including analytics, conversations, moderation, warnings, members, tickets, audit log, AI usage, and settings sections. # Dashboard overview The dashboard at [volvox.bot](https://volvox.bot) is your control center. Log in with Discord, select a server, and manage everything from the sidebar. If Volvox.Bot is not installed in any server you can manage, the dashboard opens the server picker. Servers you can manage show **Manage** when the bot is installed and **Add Bot** when it still needs to be invited. Use the question-mark button in the dashboard header to open documentation for the current page, analytics sub-tab, or settings tab. ## Sections Message, voice, community, AI usage, and health metrics. Sub-tabs live at `?tab=messages`, `?tab=voice`, and `?tab=community`. View, search, and manage AI conversation history Cases, warnings, bans, timeouts, auto-mod rules Active warning inventory, severity filters, and member warning records Member stats, roles, XP, moderation history, and CSV export Open and closed tickets, transcripts, settings Dashboard changes, moderation actions, automation events, and raw details Feature toggles, welcome flow, moderation rules, AI settings, tickets, and community tools Guided setup for welcome, safety, tickets, reputation, starboard, TL;DR, roles, and AI model selection Operator-only bot health, response times, triage latency, and resource usage Operator-only deployment-wide token, cache, cost, provider, model, and server usage Operator-only live bot logs across all servers for debugging, with filters for server, channel, level, module, and message text. ## Dashboard links | Dashboard surface | Route | Documentation | | -------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------ | | Analytics - Messages | `/dashboard?tab=messages` | [Messages dashboard](/features/analytics#messages-dashboard) | | Analytics - Voice Tracking | `/dashboard?tab=voice` | [Voice Tracking dashboard](/features/analytics#voice-tracking-dashboard) | | Analytics - Community Engagement | `/dashboard?tab=community` | [Community Engagement dashboard](/features/analytics#community-engagement-dashboard) | | Moderation | `/dashboard/moderation` | [Moderation dashboard](/features/moderation#moderation-dashboard) | | Warnings | `/dashboard/warnings` | [Warnings dashboard](/features/moderation#warnings-dashboard) | | Members | `/dashboard/members` | [Member details dashboard](/features/moderation#member-details-dashboard) | | Conversations | `/dashboard/conversations` | [Conversations dashboard](/features/ai-conversations#conversations-dashboard) | | Tickets | `/dashboard/tickets` | [Tickets dashboard](/features/tickets#tickets-dashboard) | | Audit Log | `/dashboard/audit-log` | [Audit Log dashboard](/features/audit-log#audit-log-dashboard) | | AI Usage | `/dashboard/ai-usage` | [AI usage ops dashboard](/features/analytics#ai-usage-ops-dashboard) | | Performance | `/dashboard/performance` | [Performance dashboard](/features/analytics#performance-dashboard) | | Logs | `/dashboard/logs` | [Operator-only sections](#operator-only-sections) | | Settings | `/dashboard/settings/?tab=` | [Settings tabs](/configuration/bot-settings#settings-tabs) | | Setup wizard | `/dashboard/setup` | [Run the setup wizard](/getting-started#run-the-setup-wizard) | ## Operator-only sections **AI Usage**, **Performance**, and **Logs** are only visible to global admins who operate the Volvox.Bot deployment. AI Usage shows global token, cache, cost, model/provider, and top-server usage from the shared `ai_usage` telemetry table. Performance owns deployment health, resource trends, and latency diagnostics. Logs stream across all servers by default, and operators can narrow the live stream by server before using server-specific channel filters. Normal server owners and admins manage their own server through the other dashboard sections. If a self-hosted logs tab repeatedly reconnects or reports WebSocket frame errors, restart the bot/API process and confirm the browser can reach `BOT_PUBLIC_URL`. # Volvox.Bot Frequently Asked Questions Source: https://docs.volvox.bot/faq Answers to common Volvox.Bot questions about pricing, hosting, data security, Discord permissions, dashboard access, exports, and support. # Frequently asked questions Yes. The standard plan includes the bot and dashboard features. Paid tiers are mainly for higher limits, premium model access, and priority support. See the [pricing page](https://volvox.bot#pricing) for the current plan details. No. Volvox.Bot is fully hosted. Add it to your Discord server and everything runs on managed infrastructure. No servers to manage, no updates to install. Yes. Volvox.Bot encrypts all connections and stores your data securely. Authentication uses Discord OAuth2, so the bot receives a temporary token instead of your credentials. The bot never receives or stores your Discord password. See the [security page](/security) for full details. The install flow includes the `applications.commands` OAuth scope so slash commands can be registered. Discord guild permissions control runtime actions like moderation, messages, and channel-mode tickets; role-based workflows also require the bot's role to sit above the role it grants. See the [permissions page](/configuration/permissions) for the full list. Yes. Each server has its own independent configuration. Add the bot to as many servers as you need. Join the [Discord community](https://discord.gg/8ahXACdamN) for help, or open an issue on [GitHub](https://github.com/VolvoxLLC/volvox-bot/issues). See the [help page](/help) for all support channels. Volvox.Bot runs on high-availability infrastructure with automatic recovery. If the bot goes offline, it restarts automatically and resumes normal operation. Yes. The dashboard includes focused exports for member lists, analytics, and audit-log data. Contact support if you need a broader account or server export. Yes. Slash commands always work, and you can set a text command prefix under **Settings -> Community Tools -> Commands**. Prefixes like `.`, `!`, and `?` reuse the same command permissions as slash commands. # AI Conversations with Neural Chat Source: https://docs.volvox.bot/features/ai-conversations Neural Chat lets Discord members talk to AI with mention-aware replies, per-channel modes, quiet mode, memory, history search, and flagging. # AI conversations (Neural Chat) Neural Chat lets your server members interact with AI directly in Discord. Members can mention the bot, reply to it, or use channels you configure for AI responses. The dashboard stores conversation history for review. ## What it does * **AI chat** — Members talk to the bot through mentions, replies, and configured channel modes * **Per-channel modes** — Set channels to Off, Mention, or Vibe * **Conversation history** — Replay, search, and review AI conversations * **Flagging** — Flag inappropriate AI responses for review * **Search** — Search across all conversations by keyword or member * **Response control** — Use quiet mode, blocked channels, cooldowns, and daily budgets to keep replies under control ## Settings location | Feature area | Dashboard location | | ----------------------------------------------------------------------------------- | ------------------------------------------ | | AI chat behavior, system prompt, blocked channels, and per-channel modes | **Settings -> AI & Automation -> AI Chat** | | Classifier, response model, role filters, budgets, cooldowns, and performance knobs | **Settings -> AI & Automation -> Triage** | | Memory retrieval depth and automatic memory extraction | **Settings -> AI & Automation -> Memory** | ## How to use 1. Enable AI chat in **Settings -> AI & Automation -> AI Chat**. 2. Set the global channel mode: **Off**, **Mention**, or **Vibe**. 3. Add per-channel overrides where you want different behavior. 4. Block any channels where AI should never respond. 5. Review conversation history under **Dashboard -> Conversations**. 6. Flag and filter conversations as needed. AI conversations may occasionally produce unexpected responses. Use flagging to catch and review issues. ## Conversations dashboard The **Conversations** page at `/dashboard/conversations` is the review surface for Neural Chat history. It lists AI conversations, participants, channels, status, flags, and recent activity. Opening a conversation detail page shows the replay for that thread. Use it to search conversation history, review flagged replies, inspect context around an AI response, and decide whether a prompt or moderation setting needs tuning. ## AI chat settings The **AI Chat** settings tab at `/dashboard/settings/ai-automation?tab=ai-chat` controls core Neural Chat behavior: enablement, model routing, system prompt, channel response mode, blocked channels, mass-ping handling, and per-channel overrides. ## Quiet mode Quiet mode temporarily stops Neural Chat from replying in one channel. It also pauses vibe-mode triage accumulation for that channel, so the bot stays out of the conversation until quiet mode expires or a moderator turns it off. | Command | What it does | | ----------------------------------------- | -------------------------------------------------- | | `/quiet on` | Quiet the current channel for the default duration | | `/quiet on duration:1h` | Quiet the current channel for a custom duration | | `/quiet on channel:#support duration:30m` | Quiet another channel | | `/quiet off` | Resume AI replies in the current channel | | `/quiet status` | Check whether quiet mode is active | Quiet mode is per-channel, not server-wide. The default duration is 30 minutes, and durations are clamped between 1 minute and the configured maximum. By default, moderators can change quiet mode; servers can configure `quietMode.allowedRoles` for `any`, `admin`, `moderator`, or specific role IDs. Members can also mention the bot with commands like `@Volvox quiet for 30 minutes` or `@Volvox unquiet`. ## Channel modes Set channel behavior under **Settings -> AI & Automation -> AI Chat -> Per-Channel AI Mode**. | Mode | Behavior | | ------- | ---------------------------------------------------------------- | | Off | The bot does not respond in the channel | | Mention | The bot responds to direct mentions and replies | | Vibe | The bot watches the channel context and decides when to chime in | The **Global Fallback Mode** applies to channels without an override. Use per-channel overrides for support, announcements, off-topic channels, or any place that needs different AI behavior. ## Configuration | Setting | Description | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AI enabled | Toggle AI conversations | | System prompt | Custom instructions for the AI | | Per-channel AI mode | Configure Off, Mention, or Vibe behavior globally and per channel | | Response boundaries | Select channels where AI should never respond | | Ignore mass pings | When on (default), only direct `@Bot` mentions trigger a reply — `@everyone`, `@here`, and role pings are ignored. Turn off to let the bot respond to mass pings too. | | Triage | Configure classifier and response models, role filters, budgets, cooldowns, and status/debug behavior | | Output Safety Guardrail | Run a classifier on every bot triage response and block unsafe output before it reaches Discord | | Memory | Set retrieval depth and automatic memory extraction | | Quiet mode | Temporarily suppress AI replies in a channel | ## Memory settings The **Memory** settings tab at `/dashboard/settings/ai-automation?tab=memory` controls how much user and channel context Neural Chat can retrieve and whether the bot extracts memories from conversations automatically. Keep memory conservative for privacy-sensitive communities. Increase retrieval only when long-running personalized context is worth the extra latency and provider cost. ## Output safety guardrail The Output Safety Guardrail runs a lightweight AI classifier on every triage response the bot is about to post. If the classifier flags the response as unsafe, the bot silently drops it instead of sending it to Discord. Unsafe verdicts are logged to Sentry so you can review them later. Turn it on when you want a second pass on bot output — for example, in larger servers, communities with younger members, or anywhere a single off-tone reply is worse than no reply at all. ### When to use it * You run a moderated community and want belt-and-suspenders coverage on AI replies. * You've tightened your system prompt but still see occasional edge-case responses you'd rather not ship. * You're rolling out Neural Chat to a new audience and want extra caution while you tune thresholds. The classifier only inspects bot output. Member messages and moderation actions are unaffected. ### Enable it 1. Open **Settings -> AI & Automation -> Triage**. 2. In the **Behavior** section, toggle **Output Safety Guardrail** on. 3. Save. The bot starts classifying triage responses immediately — no restart required. The toggle is off by default. Safety check usage is recorded in the AI usage ledger under the `safety` type so you can track its cost alongside classify, respond, and Content Safety `automod` calls. ### Operational tuning (self-hosters) The per-server toggle controls whether the guardrail runs. Model selection and runtime behavior are set per deployment through environment variables: ```bash .env theme={null} # Classifier model (default: z-ai:glm-5.2) SAFETY_GUARDRAIL_MODEL=z-ai:glm-5.2 # Request timeout in milliseconds (default: 5000) SAFETY_GUARDRAIL_TIMEOUT_MS=5000 # Maximum tokens for the classifier verdict (default: 128) SAFETY_GUARDRAIL_MAX_TOKENS=128 # Block responses when the classifier errors or times out (default: true) # Set to "false" to let responses through on classifier failure. SAFETY_GUARDRAIL_FAIL_CLOSED=true ``` The default classifier model — `z-ai:glm-5.2` — requires `ZHIPU_API_KEY`. Select any chat-completion model from a provider you have credentials for. With `SAFETY_GUARDRAIL_FAIL_CLOSED=true`, the bot treats classifier timeouts and errors as unsafe and drops the response. Set it to `false` if you'd rather let responses through when the classifier is unavailable. Managed users on volvox.bot get safe defaults — just flip the toggle. Self-hosters tune the env vars above and restart the bot. ## Search guardrails When triage decides a prompt needs fresh or external information, Neural Chat only attaches web-search tools for providers with a verified compatible implementation. The current supported provider paths are: | Provider | Search path | | ---------- | ---------------------------------------------------- | | Z.AI | Coding Plan MCP web-search server | | OpenRouter | OpenRouter provider-exported `webSearch` server tool | MiniMax, Moonshot, and Fireworks stay search-disabled in the provider catalog until their endpoints have a verified tool shape. If a server selects a model without search support, the prompt receives a `SEARCH_UNAVAILABLE` directive so the bot avoids pretending to have live web access. ## Available models Every AI model dropdown in the dashboard lists only models you can actually use right now. The same filtering applies across AI Chat, Content Safety, Triage, and TL;DR settings. Two gates run before a model shows up: * **Credential gate** — The model's provider must have an API key configured on the bot. If `OPENAI_API_KEY`, `FIREWORKS_API_KEY`, or another provider key is missing, every model from that provider is hidden. * **Tier gate** — The model's tier must match your server's entitlement. `z-ai:glm-5.2` is the free default for every server, and the Z.AI GLM family is available on the free tier. Models marked `premium` show only for paid-tier servers. The config API, dashboard webhook, and Discord `/config set` command enforce the same tier gate when saving model settings, so direct writes cannot assign paid-tier models to a free server. Global config writes are treated as free-tier defaults; use per-server config for paid-tier overrides. Self-hosters grant premium model access by setting `PREMIUM_GUILD_IDS` on the bot/API process to a comma-separated list of Discord server IDs, then restarting: ```bash .env theme={null} PREMIUM_GUILD_IDS=123456789012345678,987654321098765432 ``` If your saved model is no longer available — for example, the provider key was rotated out or the model moved to premium — the dropdown still surfaces it as **Current saved model: `provider:model`**. The value stays stored so you don't lose it. When the provider has no configured key, the entry is prefixed with **⚠** and labeled **provider not configured**. At runtime, free-tier servers fall back to `z-ai:glm-5.2` instead of sending traffic to paid-tier saved models. Select any visible option to replace the saved value. If the dropdown is empty and shows **No configured models available**, no provider has credentials configured on this deployment. Self-hosters can fix this by adding a provider key to `.env` and restarting: ```bash .env theme={null} # Enable any one of these to populate the model dropdowns OPENAI_API_KEY=sk-... ANTHROPIC_API_KEY=sk-ant-... FIREWORKS_API_KEY=fw_... ZHIPU_API_KEY=... ``` Z.AI models (`z-ai:glm-5.2`, `z-ai:glm-5.1`, and `z-ai:glm-5-turbo`) authenticate with `ZHIPU_API_KEY` and route through the Z.AI Coding Plan endpoint at `https://api.z.ai/api/coding/paas/v4`. GLM 5.2 is the free-tier default, and GLM 5.1 plus GLM 5 Turbo are also free-tier options. These models support thinking mode, which lets the provider spend extra reasoning effort before producing the final answer. For triage, set `triage.thinkingTokens` above `0` to enable thinking, or `0` to disable it; Z.AI treats that value as an enable/disable switch. Managed users on volvox.bot don't need to do anything — the hosted deployment keeps provider keys in place, and the dropdown reflects whichever providers are live. ### Providers API Dashboards and integrations can read the same availability data from the bot API: ```http theme={null} GET /api/v1/providers/configured?guildId=123456789012345678 Authorization: Bearer ``` ```json Response theme={null} { "configuredProviders": ["z-ai"], "guildTier": "free" } ``` `configuredProviders` lists every provider that has an API key set and at least one visible model matching the server's tier. `guildTier` is `free` or `premium`. Pair this with the static model catalog to apply the same filtering anywhere you render a model picker. `guildId` is required and must be a Discord snowflake. The caller must be an admin of that server — requests without the parameter are rejected with a 400, and non-admin callers receive a 403. The dashboard hook caches each server's response for 30 seconds and keeps the previous data visible during revalidation, so model pickers don't flicker when you switch config pages. # Real-Time Discord Server Analytics with Live Insight Source: https://docs.volvox.bot/features/analytics Live Insight tracks Discord server activity in real time with charts for messages, active members, command usage, response times, and uptime. # Analytics (Live Insight) Live Insight gives you a real-time view into your server's health and activity. The Overview dashboard groups analytics into Messages, Voice Tracking, and Community Engagement sub-tabs. ## What it does * **Message volume** — Track messages over time by channel and member * **Engagement metrics** — Active users, average messages per user, and lifetime reaction totals * **Activity Over Time** — Compare message volume with voice minutes on a single graph with its own range picker (1d, 7d, 14d, 30d, 60d, 90d, 6 month, 1 year, or Custom) * **Weekly Activity Heatmap** — Message density by day of week and hour, with weekday labels that follow your browser locale * **Voice sessions** — Tracked joins, active sessions, unique participants, total voice time, average duration, top voice channels, and recent session activity * **AI usage breakdown** — Per-model request counts, prompt and completion tokens, and estimated spend in USD * **Recent events feed** — The 10 most recent messages and slash command uses, sourced from your live conversation history * **Bot usage** — How often members run commands and start AI conversations * **Performance** — Bot response times, AI triage phase latency, and resource usage * **Server health** — Overall server health score ## Settings location Analytics does not have a dedicated Settings tab. Use the dashboard controls on **Dashboard -> Analytics** for date ranges and exports. Voice session collection is controlled by **Settings -> Onboarding & Growth -> Engagement -> Voice Session Tracking**. It is on by default, but it only records sessions while the top-level **Engagement** setting is enabled. Voice reputation rewards are configured separately under **Settings -> Onboarding & Growth -> Reputation -> Voice XP**, where you can enable or disable voice XP and set whole XP per minute. Related AI triage performance settings are in **Settings -> AI & Automation -> Triage -> Performance**. ## How to use 1. Open the dashboard -> **Overview** for your server snapshot and analytics sub-tabs. 2. Use **Messages** for message volume, top channels, AI usage, and command telemetry. 3. Use **Voice Tracking** for voice joins, duration, live rooms, top channels, and recent sessions. 4. Use **Community Engagement** for active members, reaction totals, XP economy, and activity heatmaps. 5. Use the **Activity Graph** range buttons on the Messages sub-tab to zoom in or out on community activity. 6. Use the date range picker to focus on specific periods. 7. Check **Performance** for technical health metrics. Analytics queries support a custom range of up to 366 days. Rolling presets cover everything from the last 24 hours up to the last year. Dashboard analytics dates, times, chart labels, and heatmap buckets display in the viewer's local browser time. Exports keep ISO timestamps where a machine-readable value is required. ## Activity graph The Activity Graph on the **Messages** sub-tab plots community message volume over time so you can spot growth, lulls, and traffic spikes at a glance. The chart shares its range with the rest of the dashboard, so switching the range here also updates the surrounding KPIs and breakdowns. ### Select a range Use the range buttons above the chart to switch between rolling windows or set a custom range: | Button | Window | | --------- | ------------------------------------------------- | | `1d` | Last 24 hours | | `7d` | Last 7 days | | `14d` | Last 14 days | | `30d` | Last 30 days | | `60d` | Last 60 days | | `90d` | Last 90 days | | `6 month` | Last 183 days | | `1 year` | Last 365 days | | `Custom` | Select exact start and end dates (up to 366 days) | Select **Custom** to reveal date inputs, select a **Start** and **End** date, then select **Apply** to load the range. The Apply button stays disabled until both dates are filled in and **Start** is on or before **End**. The currently selected range button stays highlighted so you always know which window you're looking at. The dashboard remembers your selected range while you navigate between sub-tabs, so you can compare voice and engagement metrics across the same window without re-selecting it. ## Share or bookmark a sub-tab The Overview dashboard tracks the active sub-tab in the URL through a `tab` query parameter. You can bookmark, refresh, or share a direct link to the view you want a teammate to land on. | Sub-tab | URL | | -------------------- | -------------------------- | | Messages | `/dashboard?tab=messages` | | Voice Tracking | `/dashboard?tab=voice` | | Community Engagement | `/dashboard?tab=community` | When you select a sub-tab from the dashboard sidebar, the URL updates in place without a full page reload. Open `/dashboard` without a `tab` parameter to land on **Messages** by default. ## Messages dashboard The **Messages** sub-tab is the default Analytics view at `/dashboard?tab=messages`. It shows message volume, active users, average messages per user, channel activity, AI usage, recent events, command usage, and dashboard-wide date range controls. Use this tab when you need the quick server pulse: who is talking, where activity is happening, which commands are being used, and whether AI usage or spend changed during the selected range. ## Voice tracking dashboard The **Voice Tracking** sub-tab lives at `/dashboard?tab=voice`. It focuses on voice joins, active sessions, total voice time, average duration, top voice channels, and recent session activity. Use it to spot active voice rooms, review participation patterns, and confirm whether voice tracking is producing fresh session data. ## Community engagement dashboard The **Community Engagement** sub-tab lives at `/dashboard?tab=community`. It shows active members, reaction totals, XP economy signals, weekly activity heatmaps, and the Activity Over Time graph for messages and voice minutes. Use it for longer-term engagement review, activity rhythm, and XP/community health checks. ## Available metrics | Metric | Description | | --------------------------- | ----------------------------------------------------------------- | | Messages per day | Total message count over time | | Active users | Unique members who sent messages in the selected range | | Avg messages per user | Mean messages per active user | | Lifetime reactions given | All-time reactions sent by tracked members in the server | | Lifetime reactions received | All-time reactions received by tracked members in the server | | Voice sessions | Voice channel sessions started in the selected range | | Active voice sessions | Voice sessions still open when analytics last refreshed | | Voice time | Total and average voice duration from tracked sessions | | Top voice channels | Voice rooms ranked by session count and total duration | | Recent voice sessions | Latest voice sessions with duration and active status | | AI usage by model | Requests, prompt and completion tokens, and cost in USD per model | | Recent events | Latest messages and slash command uses across tracked channels | | Command usage | Bot command frequency | | Response time | Average bot response latency | | Triage latency | Recent AI triage evaluation timing by outcome and phase | | Uptime | Bot and service uptime percentage | AI usage and cost figures appear when the bot has recorded usage data for the selected range. If no usage data exists, the dashboard reports the AI usage source as unavailable instead of showing zeros. ## Activity over time The **Activity Over Time** graph on the **Community Engagement** tab plots messages and voice minutes side by side. You can see when chat and voice spike together, or when one carries the server while the other goes quiet. * **Messages** plot in the primary Volvox green, stacked behind voice * **Voice minutes** plot in neon orange on top * Hover any point to see the bucket label, message count, and voice time formatted as `Hh Mm` * Buckets switch to hourly resolution for **1d** ranges and daily resolution everywhere else ### Range presets The graph has its own range picker, separate from the dashboard-wide date range: | Preset | Window | | --------- | --------------------------------------------- | | `1d` | Last 24 hours, hourly buckets | | `7d` | Last 7 days | | `14d` | Last 14 days | | `30d` | Last 30 days | | `60d` | Last 60 days | | `90d` | Last 90 days | | `6 month` | Last 6 months | | `1 year` | Last 12 months | | `Custom` | Select any start and end date, up to 366 days | Selecting **Custom** opens a date picker. Ranges longer than 366 days are clamped to keep the graph readable. ## Triage latency The **Triage latency** widget on the Performance sub-tab breaks down recent AI triage evaluations so you can see where time is spent before the bot replies. Each evaluation runs through several internal phases, including context fetch, classification, memory lookup, and response generation. The widget surfaces the timing for each phase. Use it when: * AI replies feel slow and you want to see which phase is the bottleneck * You're tuning `memoryTimeoutMs` or other triage performance knobs in **Settings -> AI & Automation -> Triage -> Performance** * You want to confirm mem0 cache hits are landing instead of paying full API latency on every message ### Summary cards | Card | What it shows | | ------------ | ----------------------------------------------------------------------------------- | | Triage p95 | 95th percentile total triage time across recent evaluations | | Classify Avg | Average classifier phase time, with the latest provider call duration | | Memory Avg | Average time spent waiting on user memory, with cache hits on the latest evaluation | | Respond Avg | Average responder phase time, with the latest provider call duration | ### Phase averages chart The bar chart plots the average duration of each triage phase across recent samples: | Phase | Description | | ------------- | ----------------------------------------------------------------- | | Budget | Per-guild budget and rate-limit checks | | Context | Loading recent channel messages for the prompt | | Classify Prep | Building the classifier prompt | | Classify | Classifier model call (decides whether to reply, search, or skip) | | Memory | Waiting on mem0 user memory lookup (capped by `memoryTimeoutMs`) | | Respond Prep | Building the responder prompt | | Respond | Responder model call that generates the reply | | Stats | Recording usage and analytics for the evaluation | | Discord | Sending the final reply through the Discord API | ### Recent evaluations table The recent evaluations panel lists the last 20 triage runs with: * **Time** — When the evaluation finished * **Outcome** — Whether triage replied, skipped, or hit an error, plus the classification or skip reason * **Slowest** — The phase that took the longest in that evaluation * **Total** — End-to-end triage duration in milliseconds * **Memory** — Memory wait time, cache hits, and live mem0 API searches Outcome chips above the table show the count of each outcome (for example `replied: 12`, `skipped: 7`) so you can tell at a glance how often the bot is choosing to reply. The widget only shows data once the bot has run triage in your server. If you see "No triage samples yet", trigger an AI conversation in any channel where triage is enabled and refresh the page. ## Performance dashboard The operator-only **Performance** page at `/dashboard/performance` shows runtime health across the deployment: bot health, heap and RSS memory trends, CPU utilization, uptime, average and percentile latency, and recent AI triage phase timings. Only global admins can see this page. Server owners and server admins keep using the server-scoped Analytics tabs unless they also operate the deployment. ## AI usage ops dashboard The operator-only **AI Usage** page at `/dashboard/ai-usage` shows deployment-wide AI usage across every server. It is visible only to global admins configured through `BOT_OWNER_IDS`. Use **System Ops -> AI Usage** when you need to inspect: * input, output, and total tokens * cache read and cache creation tokens, including cache read/write rates * estimated AI cost in USD * average latency, p95 latency, and generated tokens per second * provider, model, and request-type comparisons * top servers by AI usage, with server names when the bot can resolve them * recent expensive or slow AI requests The page supports `24h`, `7d`, `30d`, and `90d` ranges plus provider, model, and request-type filters for `classify`, `respond`, `safety`, and `automod` calls. It uses the global `ai_usage` telemetry table, so it is meant for deployment operators rather than per-server admins. Server-scoped AI usage remains on **Dashboard -> Analytics -> Messages**. The AI Usage ops page is global and may expose cross-server usage patterns, so keep `BOT_OWNER_IDS` restricted to trusted operators. ## Weekly activity heatmap The **Weekly Activity Heatmap** shows message density across day of week and hour of day, using the same Community Engagement range as the rest of that tab. Weekday labels follow your browser locale. When the selected range is a week or shorter, each row also shows the matching calendar date so you can tell `Mon 12 May` apart from `Mon 19 May` at a glance. # Discord Bot Actions and Config Changes Audit Log Source: https://docs.volvox.bot/features/audit-log Review Volvox.Bot moderation actions, config changes, AI auto-mod decisions, DM delivery failures, and triage alerts with 90-day retention. # Audit log Volvox.Bot records important bot and dashboard actions in the audit log. Use it to review what happened, who triggered it, and what was affected. ## What it logs * **Moderation actions** — Warns, bans, kicks, timeouts, unbans, temp bans, and soft bans * **Classic spam detections** — Alert/delete outcomes, message links, channel IDs, and redacted content previews * **Config changes** — Who changed what setting, with before/after config details when available * **AI auto-mod decisions** — Action taken, model, scores, thresholds, skipped actions, message link, and case number * **Triage alerts** — Moderation flags and budget-limit alerts * **DM delivery failures** — Member DMs the bot could not deliver for moderation notifications or level-up actions * **Dashboard/API mutations** — Successful mutating dashboard requests with masked request details ## Settings location Audit Log settings are in **Settings -> Moderation & Safety -> Audit Log**. ## How to use 1. Open the dashboard -> **Audit Log** for your server. 2. Filter by category, action, user, target, channel, or date range. 3. Select any entry for human-readable details and raw JSON. You can also export filtered audit-log data as CSV or JSON when you need offline review or handoff evidence. Volvox.Bot retains audit logs for 90 days. Contact support if you need longer retention. ## Audit log dashboard The **Audit Log** page at `/dashboard/audit-log` is the dashboard reader for audit entries. It includes category, action, user, target, channel, and date filters, plus expandable structured details for each entry. Use it when you need evidence for a moderation action, config change, ticket event, AI auto-mod decision, triage alert, or failed DM notification. ## Audit log settings The **Audit Log** settings tab at `/dashboard/settings/moderation-safety?tab=audit-log` controls audit-log retention for moderation evidence and dashboard/API mutation history. ## Filtering | Filter | Description | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | Category | Moderation, AI and triage, Config, Members, Tickets, or Notifications | | Action type | Exact actions such as `mod.ban`, `spam.detect`, `ai_automod.timeout`, `ai_automod.case_failed`, `notifications.dm_failed`, or `config.update` | | User | Filter by who performed the action | | Target | Filter by who or what the action targeted | | Channel | Filter spam, AI auto-mod, and triage entries by channel | | Date range | Focus on a specific time period | Selecting a **Category** narrows the **Action** dropdown to just the actions in that category, so you can drill from "AI and triage" down to `ai_automod.timeout`, `ai_automod.case_failed`, or `ai_automod.provider_failed` without scrolling the full list. ## Reading an entry Each row leads with a plain-language summary so you can scan the table without decoding action codes. Examples: `Mod#0001 banned BadUser#1234`, `Spam detected from SpamBot#0001`, or `AI auto-mod timed out SpamBot#0001`. Expand a row to see structured panels tailored to the action type: * **Moderation entries** show the case number, the action taken, and the reason. * **Spam entries** show whether the bot alerted moderators, deleted the message, and where the original message lived. * **AI auto-mod entries** show the model used, the categories that flagged the message with their scores, and the configured thresholds. They also include any skipped actions, a link to the original Discord message, and the case number. * **Config changes** list the keys that changed in the summary line, so you can spot which setting moved without opening the row. The raw JSON for the entry is always available underneath the structured panels if you need the full payload. ## DM delivery failures Volvox.Bot DMs members for configured moderation notices (`warn`, `timeout`, `kick`, and `ban`) and level-up actions. Discord sometimes refuses the delivery because the member has server DMs disabled, has blocked the bot, or shares no other mutual server. When that happens, the bot records a `notifications.dm_failed` entry instead of swallowing the error. The original action — the ban or the level-up role grant — still runs. Each entry captures: * **Target** — the member the bot tried to DM * **Source** — `moderation_dm_notification` or `level_up_action` * **Error** — the Discord error message returned for the failed delivery * **Details** — source-specific context, such as the moderation action and reason or the level reached Use these entries to spot patterns: a member who never receives moderation DMs or a level-up reward whose announcements never land. Filter by **Category -> Notifications** and **Action -> Notifications: DM failed** to scope the table to delivery problems only. # Discord Community Engagement with XP and Leaderboards Source: https://docs.volvox.bot/features/community Boost Discord engagement with Volvox.Bot community features: XP, leaderboards, activity badges, level rewards, and Starboard highlights. # Community Community features help members see their activity, earn XP, and surface the best messages in your server. Engagement tracking and reputation are on by default; Starboard starts off until you select a channel. ## What it does * **XP and ranks** — Members earn XP from message and optional voice activity, then check progress with `/rank` * **Leaderboards** — `/leaderboard` shows the top members by XP * **Reputation dashboard** — The Members page shows XP totals, level distribution, top members, and recent XP earners * **Engagement profiles** — `/profile` shows message, reaction, and activity badge stats * **Voice tracking** — Track voice joins and duration for Live Insight analytics * **Activity badges** — Recognize members by tenure, such as newcomer, regular, veteran, or custom tiers * **Level-up actions** — Reward levels with roles, messages, DMs, reactions, XP bonuses, or nickname changes * **Starboard** — Repost popular messages to a dedicated channel once reactions reach your threshold ## Settings location | Feature area | Dashboard location | | ----------------------------------------------------- | ---------------------------------------------------- | | Activity tracking, voice tracking, and profile badges | **Settings -> Onboarding & Growth -> Engagement** | | XP rates, cooldowns, voice XP, and level thresholds | **Settings -> Onboarding & Growth -> Reputation** | | Level-up rewards and automations | **Settings -> Onboarding & Growth -> Level Actions** | | Starboard highlights | **Settings -> Community Tools -> Starboard** | ## How to use 1. Members earn XP from message activity, and from voice minutes when Voice XP is enabled. 2. Members can use `/rank`, `/leaderboard`, and `/profile` in Discord. 3. Open **Settings -> Onboarding & Growth -> Engagement** to manage message, reaction, voice tracking, and badges. 4. Open **Settings -> Onboarding & Growth -> Reputation** to tune XP rates, cooldowns, and level progression. 5. Open **Settings -> Onboarding & Growth -> Level Actions** to configure rewards. 6. Open **Members -> Reputation** to review the server XP economy and recent XP gainers. 7. Open **Settings -> Community Tools -> Starboard** to enable community highlights. ## Engagement settings The **Engagement** settings tab at `/dashboard/settings/onboarding-growth?tab=engagement` controls profile activity tracking, activity badges, and the engagement signals surfaced in the dashboard and `/profile`. Use it when you want the bot to recognize activity tiers without changing XP math or level rewards. ## Reputation settings The **Reputation** settings tab at `/dashboard/settings/onboarding-growth?tab=reputation` controls XP awards, cooldowns, and progression thresholds. Use it when members are leveling too quickly, not quickly enough, or when you want to reshape the level curve before adding rewards. ## Reputation dashboard The **Reputation** sub-tab on the Members page lives at `/dashboard/members?tab=reputation`. It shows the server's XP economy without opening individual member profiles. Use it when you need to answer operational questions quickly: * How much XP has been awarded across the server? * What is the distribution of members across levels? * Who leads the leaderboard right now? * Who most recently earned XP? The regular **Directory** sub-tab at `/dashboard/members?tab=directory` still lists searchable members with XP, levels, activity, warnings, and member-detail links. ## Level-up actions Level-up actions can grant or remove roles, send DMs, post messages, add reactions, award bonus XP, and update nickname prefixes or suffixes. Channel messages can post back into the channel where the member leveled up, or into a fixed channel you select in the dashboard. ## Level progression New servers ship with a 20-level reputation curve that climbs from 100 XP at Level 1 to 12,000 XP at Level 20. Edit thresholds under **Settings -> Onboarding & Growth -> Reputation** using the **Progression Steps** editor. Use the **Curve Builder** when you want to reshape the whole progression without editing every level by hand: 1. Set **Levels** to the total number of levels in the curve. 2. Set **Level 1 XP** to the first threshold members should reach. 3. Set **Final XP** to the XP required for the last level. 4. Pick a curve shape. 5. Select **Apply curve**. 6. Fine-tune any generated level inline below the builder. | Curve shape | Best for | | ----------- | ------------------------------------------------------------- | | Balanced | Even spacing from the first threshold to the final threshold | | Early wins | Faster early levels with more XP pushed into the later levels | | Slow burn | Heavier early requirements with a softer climb near the end | Select **Add Step** to append a single level, or select the remove button to drop one. Thresholds must strictly increase, at least one level is required, and the dashboard editor supports up to 100 progression steps. ## Starboard Starboard reposts popular messages into a dedicated channel once they collect enough reactions. Use it to spotlight memes, highlights, or community wins without anyone needing to pin them by hand. ### When to use it * You want a "hall of fame" channel that fills itself based on community reactions. * You want members to curate content with reactions instead of relying on moderators. * You want a single emoji (for example, ⭐) to act as a vote, or you want any emoji over the threshold to qualify. ### Set it up 1. Open **Settings -> Community Tools -> Starboard**. 2. Toggle **Enabled** on. 3. Select a **Destination channel** where reposts will land. Use a channel different from where members usually chat. 4. Set the **Reaction threshold** — the number of reactions a message needs before it's reposted. 5. Select an **Emoji**: a specific emoji (like ⭐) or **Any** to count every emoji. 6. Save your changes. ### How it works * Starboard reacts to live reaction events. Messages that already met the threshold before you enabled Starboard or changed the threshold are not backfilled. To trigger a repost on an older message, remove and re-add a qualifying reaction, or add another one. * React to messages in normal channels, not in the Starboard destination channel itself. Messages posted in the destination channel are skipped so the bot doesn't repost its own entries back into the same channel. * Each qualifying message is reposted only once. Additional reactions after the first repost don't create duplicates. ### Configuration reference | Setting | Description | Default | | ------------------- | -------------------------------------------------------- | ------- | | Enabled | Turn Starboard on or off | Off | | Destination channel | Channel where popular messages are reposted | None | | Reaction threshold | Number of reactions needed to qualify | 3 | | Emoji | Specific emoji to count, or **Any** to count every emoji | Any | | Allow Self-Star | Allow members to qualify their own messages | Off | | Ignored Channels | Channels Starboard should ignore | None | ### What a Starboard post looks like Each Starboard post is an embed with a clickable title that jumps to the original message. The title shows the reaction emoji, the live star count, and the source channel — for example, **⭐ 7 stars in #general**. The embed also includes the original author, message content, any attached image, and the message timestamp. The star count updates in place as members react. ## Configuration | Setting | Description | Default | | ------------------- | ------------------------------------------------------------------------------------ | ---------------------------------- | | Engagement tracking | Track messages and reactions for XP and badges | On | | Voice tracking | Track voice sessions for analytics; disabled whenever Engagement tracking is off | On | | Reputation (XP) | Award XP per message, reaction, and event | On | | Voice XP | Award reputation XP for completed voice minutes | Off, 2 XP/min when enabled | | Activity badges | Labels shown by `/profile` based on member activity history | Newcomer, Regular, Veteran, Legend | | XP range | Random XP awarded per message | 5-15 XP | | XP cooldown | Minimum time between XP gains | 60 seconds | | XP system | Configure level thresholds and rewards - see [Level progression](#level-progression) | 20 levels, ending at 12,000 XP | | Starboard | Repost messages that reach your reaction threshold | Off | # Active Sentry Discord Auto-Moderation and Case Management Source: https://docs.volvox.bot/features/moderation Active Sentry handles Discord auto-moderation with AI content safety scoring, warnings, bans, timeouts, escalation rules, and full case management. # Moderation (Active Sentry) Active Sentry is Volvox.Bot's moderation engine. It runs automatically, and you can tune each safety layer from the dashboard. ## What it does * **Auto-mod** — The bot detects spam, blocked links, invite links, and AI safety issues, then runs your configured actions * **Spam Detection** — Classic phrase patterns and the AI spam category share one dashboard tab for thresholds and response actions * **Content Safety** — AI scores incoming messages across toxicity, harassment, doxxing, hate speech, sexual content, violence, self-harm, and child endangerment. Spam is handled separately in **Spam Detection**. The bot runs your configured actions when a category crosses its threshold * **Warnings** — Warnings accumulate and trigger escalating actions * **Bans and kicks** — Full ban and kick support with reason tracking * **Timeouts** — Discord native timeouts with configurable durations * **Cases** — Every moderation action creates a case with full context ## Settings location | Feature area | Dashboard location | | ------------------------------------------------------------------------- | ----------------------------------------------------- | | AI content safety model, thresholds, and actions | **Settings -> Moderation & Safety -> Content Safety** | | Spam detection and spam response actions | **Settings -> Moderation & Safety -> Spam Detection** | | Classic moderation, link filter, protected roles, logs, and notifications | **Settings -> Moderation & Safety -> Moderation** | | Warning expiry, severity points, and escalation | **Settings -> Moderation & Safety -> Warning Rules** | | Command access and role-based permissions | **Settings -> Moderation & Safety -> Permissions** | | Audit-log retention for moderation evidence | **Settings -> Moderation & Safety -> Audit Log** | | AI triage classifier and responder models | **Settings -> AI & Automation -> Triage** | ## How to use 1. Open the dashboard -> **Moderation** for your server. 2. Review active cases, filter by type or member. 3. Use **Settings -> Moderation & Safety -> Moderation** to set up classic auto-mod rules. 4. Use **Settings -> Moderation & Safety -> Spam Detection** to tune classic spam detection, spam threshold, and spam response actions. 5. Use **Settings -> Moderation & Safety -> Warning Rules** to configure warning expiry, severity points, and escalation actions. 6. Use **Settings -> Moderation & Safety -> Content Safety** to select the detection model, thresholds, and actions for other safety categories. 7. Use **Settings -> AI & Automation -> Triage** to select the supported classifier and response models for AI triage. ## Moderation dashboard The **Moderation** page at `/dashboard/moderation` is the case-management view. It shows moderation stats, recent cases, action filters, member filters, active state filters, and case details. Use it when you need the full moderation timeline for a server, including warnings, timeouts, kicks, bans, AI auto-mod cases, spam detections, and manual actions. ## Review a member's moderation history Open **Dashboard -> Members -> \[member]**. The **Moderation History** panel lists every case for that member, paginated 10 per page. A breakdown at the top tallies warnings, timeouts, kicks, and bans. Use **Dashboard -> Moderation** when you need the broader case table, action filters, and member ID filter across all cases. ## Member details dashboard The **Members** page at `/dashboard/members` lists server members with searchable identity, roles, XP, activity, and moderation signals. Opening a member detail page shows member profile data plus their moderation history. Use it when you need to inspect one member before taking action, export member data, or jump from a warning/case into that member's broader history. ## Warnings dashboard Open **Dashboard -> Warnings** to review warning records without digging through the broader case table. The page shows total warnings, active warnings, high-severity active warnings, and the current top user by active warning points. Use the inventory filters to narrow records by severity, active state, or Discord user ID. Each warning row keeps the case link available so moderators can jump into the broader moderation history when needed. ### Jump to the Discord log message When you open a case, the **Log Message** field links straight to the original log post in Discord. The link appears whenever the bot still has the channel and message ID for that case. Select it to open Discord in a new tab at the exact log message. Cases logged before the bot started recording channel IDs still show the message ID as plain text — those cases stay readable but aren't clickable. Configure escalation rules so that repeated warnings automatically escalate to timeouts or bans. ## Configuration ### Classic moderation settings Core moderation settings are in **Settings -> Moderation & Safety -> Moderation**: | Setting | Description | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Auto-mod enabled | Toggle automatic moderation | | Classic spam detection | Toggle phrase-pattern spam detection before AI moderation runs | | Message spam protection | Select Relaxed, Standard, Strict, or Custom message-spam thresholds. Every hit deletes the excess message, and repeated hits can timeout the member | | Link filter | Add or remove blocked domains for link enforcement. Runs whenever the Link filter toggle is on, even if the parent auto-mod toggle is paused. See [Link filter](#link-filter) | | Invite blocking | Block Discord invite hosts (for example, `discord.gg`) by adding them to the Link filter blocklist | | Log channel | Where the bot posts moderation actions | Message spam protection uses presets by default so most servers only select a sensitivity: **Relaxed**, **Standard**, or **Strict**. Strict allows 10 messages in 10 seconds; the first hit over that threshold deletes the hit message and applies a timeout. Use **Custom** only when you need to tune the message window, timeout trigger count, trigger tracking window, or timeout length. | Preset | Rate limit | Timeout escalation | | ------------------ | ----------------- | --------------------------------------------------- | | Relaxed | 10 messages / 10s | Timeout after 3 hits in 5 minutes, 5-minute timeout | | Standard (default) | 10 messages / 10s | Timeout after 2 hits in 3 minutes, 5-minute timeout | | Strict | 10 messages / 10s | Timeout on the first hit, 10-minute timeout | Every hit deletes the offending message even before a timeout applies. Select **Custom** to expand the advanced controls and tune the message window, timeout trigger count, trigger tracking window, or timeout length yourself. The custom controls stay collapsed on a preset and reset when you switch servers or reload the page. ### Spam detection settings Spam settings are in **Settings -> Moderation & Safety -> Spam Detection**. This is where AI spam controls live; **Content Safety** covers the other AI safety categories listed above. | Setting | Description | | --------------------- | --------------------------------------------------------------------------------------- | | Enable Spam Detection | Toggle both phrase-pattern spam detection and the AI spam scoring category | | Spam threshold | Tune the AI spam category threshold | | Spam response | Select any combination of flag, delete, warn, timeout, kick, or ban for spam detections | Spam Detection defaults to on and can be disabled in the dashboard. When it is off, Volvox.Bot skips both classic phrase-pattern spam checks and the AI spam category. When Spam Detection is on, classic spam runs before AI scoring. If AI auto-moderation is also enabled, classic spam honors the **Hard Delete** spam response under **Settings -> Moderation & Safety -> Spam Detection**. Classic spam actions run independently of the log channel. If you leave the log channel unset, Volvox.Bot still applies the configured spam action; it just skips the Discord alert post. Delete only runs when the spam response includes `delete`. Every classic spam detection writes a `spam.detect` audit-log entry and a redacted debug-log entry with the alert/delete outcome, message ID, channel ID, and user ID. ### Warning expiry and escalation Use **Settings -> Moderation & Safety -> Warning Rules** to tune how warning pressure decays and when it becomes a stronger action. * **Warning expiry days** controls how long warning records count as active. `30` keeps the default 30-day window. `0` disables automatic expiry. * **Severity points** set how much each warning severity contributes. Low, medium, and high warnings default to `1`, `2`, and `3` points. * **Warning thresholds** define the active warning points, lookback window, and action. Timeout thresholds require a duration like `1h`, `30m`, or `7d`; ban thresholds don't use a duration. * When multiple thresholds match, Volvox.Bot applies the highest point threshold first, so a 5-point ban is not masked by an earlier 3-point timeout rule. Example warning rules config: ```json moderation.warnings + escalation theme={null} { "moderation": { "warnings": { "expiryDays": 30, "severityPoints": { "low": 1, "medium": 2, "high": 3 } }, "escalation": { "enabled": true, "thresholds": [ { "points": 3, "withinDays": 7, "action": "timeout", "duration": "1h" }, { "points": 5, "withinDays": 30, "action": "ban" } ] } } } ``` If your config still uses the older `warns` field on escalation thresholds, Volvox.Bot reads it as `points` for backward compatibility. No manual migration is required, but use `points` for new entries. ### Warning replies in Discord When a moderator runs `/warn`, the bot responds in-channel with an embed instead of a plain confirmation line. The reply includes: * The case number with a direct link to **Dashboard -> Moderation** filtered to that case. * The warned member's tag, mention, and a link to **Dashboard -> Members -> \[member]**. * The severity (Low, Medium, or High) and how many points that warning contributed. * The member's active point progression — for example, `2 points -> 3 points` — so moderators can see at a glance how close they are to the next threshold. * The reason text the moderator supplied, truncated if it would overflow the embed field limit. The dashboard links use the `DASHBOARD_URL` environment variable when set, and fall back to `https://volvox.bot`. ### AI auto-moderation settings AI auto-moderation settings are in **Settings -> Moderation & Safety -> Content Safety**: | Setting | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Detection model | The supported provider/model used to score incoming messages | | Incident report channel | Where the bot posts flagged AI auto-moderation reports | | Incident ping roles | Staff roles pinged when Content Safety posts an incident report | | Action ladders | Each category has its own ladder of **Flag & Log**, **Hard Delete**, **Issue Warning**, **Temporary Timeout**, **Server Kick**, and **Permanent Ban**. Turn an action off, or set the confidence percentage required before that specific action runs. | | Excluded channels | Channels where Content Safety skips scoring, thresholds, and response actions | | User DM notifications | Select whether AI auto-moderation warnings, timeouts, kicks, and bans send a direct message to the affected member. If you haven't set AI-specific DM preferences, Content Safety follows your existing moderation DM notification settings. | `warn` creates a warning record, sends the warning DM when enabled, and applies your escalation rules. If multiple action thresholds are met for the same category, Volvox.Bot queues every enabled action once for the incident. Every Content Safety scoring pass writes a compact `AI automod classified: ...` entry to the operator log stream and records an `automod` row in the AI usage ledger. The visible log line includes the clean/flagged decision, selected action, and the top category scores as `score%/threshold%`. Expanded metadata keeps the same summary plus the strongest action-ladder threshold rows, so operators can tune ladders without exposing raw message content. Provider failures fail open by default so messages are not punished because an AI provider is down. Those failures are recorded as throttled `ai_automod.provider_failed` audit entries. If Discord accepts a timeout, kick, or ban but the moderation case cannot be created, Volvox.Bot records `ai_automod.case_failed` alongside the successful action audit so operators can repair the missing case trail. ### Investigation mode Investigation mode adds a pre-enforcement trust and fact-check pass for punitive Content Safety actions (`warn`, `timeout`, `kick`, and `ban`). It profiles the member's message history, active unexpired warnings, and tenure; trusted-member cases can optionally run a web-search fact-check before punitive actions execute. High-confidence `skip` or `downgrade` recommendations can suppress punitive actions, but low-confidence suppressive suggestions are ignored so enforcement proceeds. Investigation mode is off by default until dashboard controls are available. Self-hosters can opt in through config by setting `aiAutoMod.investigation.enabled` to `true`, tuning `minMessagesTrusted` and `minDaysActive`, and optionally setting `aiAutoMod.investigation.model`. Leave `model` as `null` to reuse the guild's Content Safety detection model. ### Incident ping roles Use **Incident Ping Roles** when Content Safety incident reports should notify staff reviewers. Content Safety pings the selected roles whenever it posts an incident report to the configured **Incident Report Channel**. **Flag & Log** actions generate these reports, including combined reports that also queue **Hard Delete**, **Issue Warning**, **Temporary Timeout**, **Server Kick**, or **Permanent Ban**. Incident pings only happen in the incident report channel post. They do not ping roles in member DMs, moderation case embeds, audit-log entries, or operator logs. If no incident report channel is configured, Volvox.Bot has nowhere to post the report and no roles are pinged. **When to use it** * You want immediate staff notifications for Content Safety incidents that post to the incident report channel. * You have dedicated moderation roles that should review flagged content in real time. * You route incident reports into an escalation or audit workflow that depends on role mentions. **How to configure** 1. Open **Settings -> Moderation & Safety -> Content Safety**. 2. Set **Incident Report Channel** to the staff channel that should receive AI auto-moderation reports. 3. Use **Incident Ping Roles** to select the staff roles that should be mentioned on those reports. 4. Save your changes. The next incident report uses the selected roles. For direct config updates, store numeric Discord role IDs in `aiAutoMod.incidentMentionRoleIds`: ```json aiAutoMod.incidentMentionRoleIds theme={null} { "aiAutoMod": { "incidentMentionRoleIds": ["123456789012345678", "234567890123456789"] } } ``` ### Action ladders Action ladders let you set a separate confidence threshold for every response action in every Content Safety category. Instead of one sensitivity number per category, you pick the score at which the bot should flag, delete, warn, timeout, kick, or ban. Turn off any actions you don't want for that category. If a message clears more than one threshold, the bot queues each enabled action once for the incident. **When to use it** * You want soft actions (flag, delete) to trigger early but only escalate to a timeout or ban on very high confidence. * A category needs a different posture than the rest — for example, treating self-harm as review-only or letting doxxing auto-ban at high confidence. * You're tuning false positives in one category without loosening every other category at the same time. **How to configure** 1. Open **Settings -> Moderation & Safety -> Content Safety**. 2. Expand the category you want to tune (for example, **Toxicity**). 3. For each action in the ladder, toggle it on and drag the slider to the confidence percentage that should trigger it. Toggle an action off to disable it for that category. 4. Save your changes. The next scored message uses the new thresholds. **Defaults** New servers and unmigrated categories start with these thresholds: * **Standard categories** (toxicity, spam, harassment, hate speech, sexual content, violence): flag at 55%, delete at 70%, warn at 75%, timeout at 88%. Kick and ban are off. * **Self-harm**: flag only at 30%. All destructive actions are off so the bot routes incidents to human review. * **Doxxing**: flag at 35%, delete at 60%, warn at 70%, timeout at 82%, ban at 92%. * **Child endangerment**: flag at 25%, delete at 50%, warn at 65%, timeout at 78%, ban at 85%. Existing servers keep their previous per-category sensitivity and selected actions. The migration converts each enabled action to the category's old threshold so behavior matches your current setup until you tune individual rungs. ```json moderation.aiAutoMod.actionThresholds theme={null} { "moderation": { "aiAutoMod": { "actionThresholds": { "toxicity": { "flag": 0.55, "delete": 0.7, "warn": 0.75, "timeout": 0.88, "kick": null, "ban": null }, "selfHarm": { "flag": 0.3, "delete": null, "warn": null, "timeout": null, "kick": null, "ban": null } } } } } ``` Use `null` (or omit the key) to disable that rung. Values are decimals between `0` and `1` representing model confidence. ### Excluded channels Excluded channels let you carve specific channels out of AI auto-moderation entirely. Messages posted in an excluded channel skip Content Safety scoring, thresholds, and every response action. Threads inherit their parent channel's setting, so excluding `#vent` also excludes every thread under it without you adding each one by hand. **When to use it** * You run a venting, debate, or roleplay channel where stricter Content Safety responses cause more friction than they're worth. * You have a staff-only channel where moderators discuss flagged content and don't want the bot scoring their own quotes. * You're rolling out Content Safety gradually and want to opt specific channels in (or out) before turning it on server-wide. **How to configure** 1. Open **Settings -> Moderation & Safety -> Content Safety**. 2. Under **Excluded Channels**, select one or more channels from the picker. 3. Save your changes. Exclusions take effect on the next message. To resume scoring a channel, remove it from the list and save. Manual moderation commands, the Link filter, and classic auto-mod rules are unaffected — only AI Content Safety honors this list. ```json moderation.aiAutoMod theme={null} { "moderation": { "aiAutoMod": { "enabled": true, "excludedChannelIds": ["123456789012345678", "987654321098765432"] } } } ``` ### Link filter The Link filter blocks messages that link to domains you've added to your blocklist. Use it to stop ad spam, phishing links, competitor invites, or unwanted referral URLs without enabling the rest of classic auto-mod. Once a message matches, the bot deletes it and notifies your configured moderator channel. The Link filter has its own toggle nested under classic moderation, so it runs even when the parent **Auto-mod enabled** toggle is paused. You can keep aggressive spam rules off while still enforcing your domain blocklist. **When to use it** * You want to block specific Discord invite hosts (for example, `discord.gg`) or shorteners (`bit.ly`). * You're rolling out moderation gradually and only need URL enforcement right now. * You need to add or remove a domain quickly without touching other auto-mod rules. **How to configure** 1. Open **Settings -> Moderation & Safety -> Moderation -> Link filter**. 2. Turn on the **Link filter** toggle. 3. In the domain input, paste one or more domains. You can separate entries with spaces, commas, semicolons, or new lines. URLs and Markdown links are normalized to their hostname automatically — `https://www.example.com/path` becomes `example.com`. 4. Select **Add** to save the entries. Invalid entries are rejected with an inline error and won't be added. 5. To remove a domain, select the **×** next to it in the blocked list. **Who is exempt** The Link filter respects your configured admin and moderator roles, plus any role listed under **Protect Roles**. The raw Discord `Administrator` permission alone does *not* grant a bypass for the Link filter — this lets server owners block links posted by other administrators when needed. Manual moderation actions and other auto-mod rules still treat the `Administrator` permission as an exemption. **Example blocklist** ```text Example blocked domains theme={null} discord.gg bit.ly example-phishing.com ``` Entries are stored as normalized hostnames in your server config: ```json moderation.linkFilter theme={null} { "moderation": { "linkFilter": { "enabled": true, "blockedDomains": ["discord.gg", "bit.ly", "example-phishing.com"] } } } ``` ### Protected roles Use **Settings -> Moderation & Safety -> Moderation -> Protect Roles** to mark roles whose members should never be moderated. Members with any selected role are exempt from: * Manual moderation commands and dashboard actions (warn, timeout, kick, ban, tempban). * AI auto-moderation responses from Content Safety. * Spam rate limiting and link/invite filters. * AI triage moderation nudges (the in-channel warning the bot posts when triage flags a message for moderation). Use this for staff, partnered creators, or other accounts that should bypass every automated and manual moderation path. Removing the role restores normal moderation immediately on the next message. ### How the bot sends AI auto-mod DMs When the bot queues multiple destructive actions for the same message (for example, warn -> kick -> ban), each destructive step sends its own DM right before that action runs: * **Actions taken** lists actions the bot has already applied in this incident. * **Actions planned** lists the single next destructive action. * **Triggered categories** and **Reason** show what the model flagged and why. The first DM in an incident uses a title like **Moderation actions planned in ``**. Follow-up DMs that include actions already taken use a title like **Moderation action update in ``**. The updated title helps members recognize this is the same ongoing incident. The bot tracks which actions a DM has already covered and never sends a duplicate for the same action. The bot only sends DMs for actions you have enabled under **User DM Notifications**. The bot records every triggered AI auto-moderation response in the audit log, with one entry per action that actually runs. Classic spam detections are logged as `spam.detect`. Legacy configs that still cross a category threshold without a selected action record a "no action" entry for auditability. New action-ladder configs only trigger when at least one enabled action threshold is met. ### AI auto-mod case reason format Cases opened by Content Safety use a compact, structured reason so case tables stay scannable. Each reason follows this shape: ```text theme={null} AI Auto Mod: %, % / , ``` * **Categories and scores** list every category that crossed its threshold, with the model's confidence as a percentage. * **Actions** list every response action that ran for the incident (for example, `delete`, `warn`, `timeout`, `kick`, `ban`), separated by commas. For example, a message that tripped two categories and led to a delete plus a warning would record: ```text theme={null} AI Auto Mod: Toxicity 82%, Harassment 64% / delete, warn ``` You don't need to configure anything. New cases adopt this format automatically. Existing cases keep their original reason text so historical context isn't rewritten. ### AI triage settings Triage model settings are in **Settings -> AI & Automation -> Triage**. The classifier and response engines use the same supported model dropdown as Content Safety. The dashboard validates `provider:model` strings when you save, so it rejects unsupported or malformed selections up front. If a stored config still contains an invalid value at runtime, the bot logs a warning. It falls back through your configured models in order. When none are supported, it uses the default AI model. ### Triage latency tuning These are advanced tuning knobs; defaults work for most servers. The dashboard exposes these fields under **Settings -> AI & Automation -> Triage -> Performance**. Config loading normalizes each value and clamps it to the listed range. The runtime currently enforces `responseCooldownMs` and `memoryTimeoutMs`. | Setting | Description | Default | Range | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | --------- | | `responseCooldownMs` | Minimum gap between bot replies in the same channel. Set to `0` to allow replies as fast as the model and other gates permit. Direct mentions bypass this cooldown when fast direct replies are enabled. | 0 | 0-60000 | | `triageDebounceMs` | Reserved for a future debounce feature; has no effect today. The current channel evaluation timer still uses `triage.defaultInterval`. | 500 | 0-2000 | | `memoryTimeoutMs` | Maximum time triage waits for user memory context before continuing without memory. This keeps mem0 latency from blocking classification or response generation. | 2000 | 500-30000 | ### Triage classification tuning Each classifier call returns two independent scores. **Confidence** measures how certain the model is about the label it picked (for example, `chime-in` vs. `skip`). **Relevance** measures how much value a reply would add to the conversation. Both scores must clear their threshold before triage proceeds to the response stage. Direct @mentions bypass these gates when fast direct replies are enabled, and safety-critical classifications always bypass them. Set these knobs in the `triage` config block. Defaults work for most servers; raise the thresholds to make the bot pickier, lower them to make it chime in more often. | Setting | Description | Default | Range | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | --------- | | `confidenceThreshold` | Minimum label certainty required before the bot acts on a classification. Classifications below this score are dropped. | 0.6 | 0-1 | | `relevanceThreshold` | Minimum response-value score required before the bot generates a reply. A high-confidence label with low relevance is treated as a skip. | 0.4 | 0-1 | | `soloUserBoost` | Lowers both thresholds when the recent channel context contains exactly one non-bot participant, since a solo speaker is implicitly addressing the bot. Only applies to `chime-in` classifications. | `true` | boolean | | `soloUserBoostAmount` | How much to subtract from each threshold while the solo-user boost is active. Effective thresholds are clamped at 0, so large values reduce — but never invert — the gate. | 0.15 | 0-1 | | `maxMessageChars` | Hard cap on the number of characters from each newly buffered Discord message passed into the classifier. Recent channel history is truncated separately before the prompt is built. | 1000 | 100-10000 | | `maxReplyChars` | Hard cap on the number of characters copied from a referenced Discord reply into the classifier context. Longer referenced messages are truncated before the prompt is built. | 500 | 100-5000 | Example triage block in your server config: ```json config.json theme={null} { "triage": { "confidenceThreshold": 0.6, "relevanceThreshold": 0.4, "soloUserBoost": true, "soloUserBoostAmount": 0.15, "maxMessageChars": 1000, "maxReplyChars": 500 } } ``` Triage classification logs use compact `AI triage classified: ...` and `AI triage skipped: ...` entries with both `confidence` and `relevance` alongside the picked label, so you can spot-check threshold behavior before adjusting either knob. ### Provider capability gating Triage checks provider capabilities before building the responder prompt. When the selected triage model can't search the web, triage appends a `SEARCH_UNAVAILABLE` directive to the responder prompt. The bot then hedges claims about current events, prices, or other time-sensitive facts instead of inventing answers. System prompt information — the bot's identity, team, and invite links — stays authoritative regardless. To restore live search, select a model whose provider supports web search for triage responses. **MiniMax M2.7** now also advertises thinking support, so reasoning traces appear when the underlying model emits them. New server config uses `contextMessages: 5` by default. Runtime triage only falls back to 10 recent messages when you leave `contextMessages` unset. Fast direct replies are enabled by default. With that toggle on, direct @mentions and replies to the bot force immediate triage evaluation and bypass the response cooldown for mentioned messages. Classification still runs before the responder, so safety and relevance checks remain in place. Settings changes apply on reload or the next config refresh. You don't need to restart the bot process. # Discord Support Tickets and Transcripts Source: https://docs.volvox.bot/features/tickets Run a Discord support ticket system with Volvox.Bot: ticket panels, private threads or channels, staff roles, limits, transcripts, and dashboard tools. # Tickets A built-in support ticket system for your Discord server. Your members can open tickets, and your team can manage them from Discord or the dashboard. ## What it does * **Ticket creation** — Your members open tickets via a panel or command * **Ticket location** — The bot creates a private thread or a dedicated private channel depending on your ticket mode * **Transcripts** — The bot saves a transcript automatically when a ticket closes ## Settings location Ticket settings are in **Settings -> Support & Integrations -> Tickets**. ## How to use 1. Open **Settings -> Support & Integrations -> Tickets**, select a **Panel Destination**, edit the **Panel Message** if needed, then save your changes. After the save succeeds, the dashboard publishes the ticket panel. 2. Your members select a ticket panel option or use the command to open a ticket. 3. The bot creates a private thread or channel for the conversation. 4. Staff respond and close the ticket when resolved. 5. The bot saves the transcript so you can view it in the dashboard. Select support staff roles, transcript channel, and ticket workflow before publishing the panel. Channel mode also needs a ticket root category. Channel-mode tickets require the bot's **Manage Channels** permission. Without it, Discord rejects ticket channel creation even if the bot can see and send messages in the category. ## Tickets dashboard The **Tickets** page at `/dashboard/tickets` lists open and closed tickets for the selected server. It supports ticket status filtering, search, and direct navigation into ticket detail pages. Use it when staff need to review support volume, inspect a closed ticket, or open a saved transcript from the dashboard. ## Ticket settings The **Tickets** settings tab at `/dashboard/settings/support-integrations?tab=tickets` controls ticket mode, panel publishing, panel destination, support staff roles, transcript channel, auto-close timing, and ticket welcome copy. ## Ticket modes Volvox.Bot supports two ticket modes. Select the one that fits how your team works. * **Channel mode** — The bot creates a dedicated private channel for each ticket under your ticket category. Permission overwrites lock access to the opener and your support staff roles. Use this mode when you want long-lived tickets, deeper channel-level integrations, or per-ticket permission control. * **Thread mode** — The bot opens a private thread in your ticket category. Threads are lighter weight and ideal for high-volume servers where each ticket is short-lived. Channel-mode tickets require the bot's **Manage Channels** permission. Thread-mode tickets don't. ## Configuration | Setting | Description | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Ticket mode | Channel mode (dedicated channels) or thread mode (private threads) | | Panel destination | Text channel where the dashboard publishes the ticket panel after you save. Saving a new channel deletes the previously tracked panel message and posts a fresh one in the new channel. | | Panel message | Text, embed, or text + embed content shown above the ticket button. Saving panel message changes deletes the previously tracked panel message and posts a fresh one to the saved destination. | | Ticket root category | Root category where the bot creates ticket channels in channel mode | | Auto-close | Automatically close stale tickets after N hours | | Transcript channel | Where the bot posts transcripts | | Support staff roles | One or more roles that can see and manage tickets | | Welcome message | The message the bot sends automatically when a ticket opens | ## Ticket panel publishing The dashboard publishes the ticket panel for you. Once you select a **Panel Destination** and save, the bot posts the panel to that channel and tracks the message it sent. The panel is an embed (or text, or both) with a button members select to open a ticket. When you save changes to either the **Panel Destination** or the **Panel Message**, the bot: 1. Deletes the previously tracked panel message, if one exists. 2. Posts a fresh panel message to the saved destination. 3. Records the new channel and message ID so future updates replace the right post. If the publish fails — for example, the bot can't see the channel or lacks **Send Messages** — saving still persists your config. The panel status records the error so you can retry after fixing permissions. ### Panel message format Select **Text**, **Embed**, or **Both** for the panel message: * **Text** — A plain message with the button below it. * **Embed** — A configurable embed (title, description, color, thumbnail, fields, footer, image, timestamp) with the button below. * **Both** — A text message above the embed, with the button below. Embed **Thumbnail** options are **None**, **Server Icon**, or **Custom URL**. User avatar isn't available for ticket panels because the panel is server-wide, not per-member. ### Permissions required to publish Grant the bot the following in the panel destination channel: * **View Channel** * **Send Messages** * **Embed Links** (when the panel uses embed or both formats) * **Manage Messages** (so the bot can delete the old panel when you change channels or update the message) ## Support staff roles Tickets support multiple staff roles. You can grant access to several teams — for example, **Support**, **Senior Support**, and **Moderators** — without merging them into one role. * Open **Settings -> Support & Integrations -> Tickets** and use the **Support Staff Roles** picker to add every role that should see new tickets. * The bot grants ticket access to all selected roles. In channel-mode tickets, each role gets a permission overwrite. In thread-mode tickets, the bot adds members of every selected role only once, even if they hold multiple roles. * The bot automatically skips stale role IDs (roles that no longer exist on the server). * Discord caps channel permission overwrites at 100. The bot reserves three for `@everyone`, the ticket opener, and itself. That leaves up to **97 support roles** per channel-mode ticket; the bot ignores any extras. Configurations that previously stored a single **Support role** continue to work. The legacy field stays in sync with the first entry in **Support Staff Roles**. Existing setups keep their staff access without changes. # AI Channel Summaries with the /tldr Command Source: https://docs.volvox.bot/features/tldr Use the /tldr Discord command to summarize recent channel messages by count or hours, extracting key topics, decisions, action items, and links with AI. # TL;DR The `/tldr` command uses AI to summarize recent channel messages into a structured summary with key topics, decisions, action items, and notable links. ## What it does * **Instant summaries** — Use `/tldr` to summarize the last 50 messages (configurable) * **Time-based** — Use `/tldr hours:24` to summarize the last 24 hours * **AI-powered** — Your selected model extracts key topics, decisions, action items, and links * **Rich embeds** — Cleanly formatted summaries right in Discord * **Configurable** — Custom system prompts, cooldowns, and message limits ## Settings location TL;DR settings are in **Settings -> Community Tools -> TL;DR**. ## TL;DR settings The **TL;DR** settings tab at `/dashboard/settings/community-tools?tab=tldr` controls whether `/tldr` is enabled, which model summarizes messages, the default and maximum message counts, per-user cooldown, and custom summary instructions. ## How to use 1. Use `/tldr` in any channel to summarize recent messages. 2. Optionally adjust TL;DR in **Settings -> Community Tools -> TL;DR**. 3. Optionally specify `count` (1–200 messages) or `hours` (1–168 hours). 4. The AI returns a structured summary with topics, decisions, actions, and links. ## Example Using `/tldr hours:2` in a busy channel: > **📋 TL;DR Summary** — Summarized **87** messages in #general > > 🗝️ **Key Topics**: Feature roadmap discussion, community event planning, bug triage > ✅ **Decisions Made**: Moving to weekly releases, adopting new CI pipeline > 📌 **Action Items**: @dev team: update docs by Friday, @mods: set up event channel > 🔗 **Notable Links**: design mockup, CI migration guide ## Configuration | Setting | Description | Default | | ------------------ | ------------------------------------------- | ----------------------- | | Enabled | Toggle the `/tldr` command | On | | Model | Supported provider/model used for summaries | `z-ai:glm-5.2` | | Default messages | Messages to summarize | 50 | | Max messages | Hard cap on message count | 200 | | Cooldown (seconds) | Per-user cooldown per server | 300 | | System prompt | Custom AI instructions | Built-in summary prompt | # Discord Welcome Messages and Onboarding Source: https://docs.volvox.bot/features/welcome Set up Volvox.Bot welcome messages, returning-member greetings, rules verification, introduction prompts, and dynamic onboarding context from the dashboard. # Welcome and onboarding Volvox.Bot can greet new members, point them to useful channels, help with rules verification, and prompt introductions. Configure it from **Settings -> Onboarding & Growth -> Welcome**. ## What it does * **Welcome messages** — Send a message when a member joins your server * **Text, embed, or both** — Use plain text, a Discord embed, or a combined message * **Dynamic context** — Add member-count milestones, time-aware greetings, and suggested active channels * **Returning-member greetings** — Show a different message when someone rejoins * **Rules verification** — Publish a rules prompt and assign a verified role when members accept it * **Introduction prompts** — Send members toward an intro channel with a customizable prompt ## Settings location Welcome settings are in **Settings -> Onboarding & Growth -> Welcome**. ## Welcome settings The **Welcome** settings tab at `/dashboard/settings/onboarding-growth?tab=welcome` controls join messages, embed/text mode, dynamic welcome context, rules verification, introduction prompts, and returning-member greetings. ## How to use 1. Open **Settings -> Onboarding & Growth -> Welcome**. 2. Turn **Welcome** on. 3. Select the **Message Channel** where join messages should appear. 4. Write the welcome message, or switch the editor to **Embed** or **Text + Embed**. 5. Optionally configure **Rules Channel**, **Verification Role**, and **Introductions**. 6. Save changes. Use `{{user}}` when you want to mention the new member. Use `{{username}}` when you want plain text without a ping. ## Message variables Welcome messages support double-brace variables only. Single braces are treated as normal text. | Variable | What it inserts | | ------------------- | ---------------------------------- | | `{{user}}` | Member mention | | `{{username}}` | Member display name without a ping | | `{{server}}` | Server name | | `{{memberCount}}` | Current member count | | `{{greeting}}` | Time-aware greeting | | `{{milestoneLine}}` | Member-count milestone text | | `{{vibeLine}}` | Current server activity context | | `{{ctaLine}}` | Suggested channels call-to-action | | `{{timeOfDay}}` | Time-of-day label | | `{{activityLevel}}` | Current activity level | | `{{topChannels}}` | Active or highlighted channels | ## Dynamic welcomes Dynamic welcomes use server context to make join messages less generic. When enabled, Volvox.Bot can include active channels, member milestones, time of day, and activity level in the generated message variables. You can tune: | Setting | Description | | ------------------ | -------------------------------------------------------------------------------------- | | Milestone interval | How often member-count milestone text appears. Set `0` to disable interval milestones. | | Highlight channels | Channels Volvox.Bot should prefer when suggesting where to go next. | | Exclude channels | Channels Volvox.Bot should never suggest in welcome copy. | ## Rules verification Rules verification uses the **Rules Channel**, **Verification Role**, and **Rules agreement message** fields. After you save the setup, publish or refresh the rules panel from the dashboard or with `/welcome setup`. Role assignment requires the bot's Discord role to be above the role it grants. If verification fails, check the bot role position and Discord role permissions first. ## Introduction prompts Set an **Introductions** channel and customize the **Introduction prompt**. The prompt can mention the new member with `{{user}}` or use `{{username}}` for plain text. ## Returning members Enable **Returning member message** to greet members differently when they rejoin. This is useful when someone leaves briefly and comes back; the bot can avoid treating them like a brand-new member. # Add Volvox.Bot to Your Discord Server Source: https://docs.volvox.bot/getting-started Add Volvox.Bot to your Discord server, log in to the dashboard with OAuth2, and configure welcome messages, moderation, AI chat, tickets, and community tools. # Getting started No installation required. No hosting. No config files on your machine. ## Add Volvox.Bot to your server Go to [volvox.bot](https://volvox.bot) and select **Add to Server**. The landing-page button starts the Discord invite flow, lets you select a server, and returns you to a setup wizard after approval. The bot requests only the permissions it needs. Review them and approve. You need **Manage Server** permission in the target Discord server to add bots. ## Run the setup wizard The Add to Server flow opens a skippable, page-based setup wizard. Focused sections cover welcome messages, content safety, protected roles, warning rules, tickets, reputation, Starboard, command prefix, TL;DR summaries, dashboard roles, and AI provider/model selection. Setup starts with a server selection page that uses the same workspace selector as the dashboard. Select the server first, then start setup. The wizard locks that server while you work so channel and role selectors stay scoped to the right Discord server. To configure a different server, use **Back to server selection**, select the server, and start again. Turn off any section you don't need, and jump to any step from the wizard step list. Fill in the required choices for the sections you keep on, then save the checklist. The AI provider/model selection applies to AI chat, triage, content safety, and TL;DR routing together. If no AI provider credentials are available yet, the wizard still saves the non-AI defaults. You can add provider credentials later and finish the AI pieces from the dashboard. Skipping setup isn't permanent. Open **Settings** in the dashboard sidebar, then select **Setup wizard** to return to the setup server selector. ## Open the dashboard If you come back later, go to [volvox.bot](https://volvox.bot), select **Login with Discord**, and authorize the OAuth2 connection. Once logged in, the dashboard opens a server picker when Volvox.Bot isn't yet installed in one of your manageable servers. Server cards show **Manage** when the bot is already present and **Add Bot** when it still needs to be invited. The dashboard **Add Bot** flow returns you to the setup wizard after Discord approval. Use **Refresh server list** if Discord hasn't caught up after an invite. ## Configure your server Open **Settings** in the dashboard sidebar. Here you can: * Toggle features on and off * Set welcome messages, rules verification, and introduction prompts * Set moderation rules and thresholds * Configure AI conversation settings * Set up ticket panels, staff roles, and transcript channels * Customize XP, leaderboards, Starboard, and activity badges No restarts needed. The bot picks up new config on the next config refresh. ## That's it Your bot is live. Explore the dashboard to see analytics, manage moderation, set up tickets, review conversations, and tune settings. Learn your way around the dashboard Set up AI auto-moderation and moderation rules Build your onboarding flow Common questions answered # Get Volvox.Bot Help and Support Source: https://docs.volvox.bot/help Get Volvox.Bot support through the Discord community or GitHub Issues, learn how to file useful bug reports, and request new features for the Discord bot. # Help and support ## Support channels Get help from the team and other members. Fastest response times. Report bugs and track fixes. Good for technical issues. ## Bug reports When reporting a bug, include: 1. **What happened** — The unexpected behavior 2. **What you expected** — What should have happened 3. **Steps to reproduce** — How to trigger the bug 4. **Screenshots** — If applicable Don't include server IDs or other private identifiers in public GitHub issues. Share those privately with support if requested. You can report bugs via [GitHub Issues](https://github.com/VolvoxLLC/volvox-bot/issues) or in the `#bug-reports` channel on the Volvox.Bot Discord. ## Feature requests Submit feature requests via: * [GitHub Issues](https://github.com/VolvoxLLC/volvox-bot/issues) with the `feature-request` label * The `#suggestions` channel on Discord Check existing issues before submitting — your request might already be tracked. ## Contact * **General support** — [Discord](https://discord.gg/8ahXACdamN) * **Security issues** — [security@volvox.bot](mailto:security@volvox.bot) * **Business inquiries** — Contact us through Discord # Hosted Discord Bot for AI Chat, Moderation, and Tickets Source: https://docs.volvox.bot/introduction Volvox.Bot is a fully hosted Discord bot for AI chat, welcome messages, moderation, analytics, tickets, leaderboards, and audit logs. # Welcome to Volvox.Bot Volvox.Bot is a fully hosted Discord bot platform. Add it to your Discord server, log in with Discord, and manage the bot from the web dashboard. Volvox.Bot handles hosting, updates, and infrastructure. You focus on your community. ## What it does | Feature | What it gives you | | -------------- | --------------------------------------------------------------------------------------- | | **AI chat** | Mention-aware AI replies, channel modes, quiet mode, memory, and conversation review | | **Welcome** | Join messages, returning-member greetings, rules verification, and introduction prompts | | **Moderation** | Manual actions, warning rules, spam protection, link filtering, and AI content safety | | **Analytics** | Message, voice, engagement, AI usage, and performance dashboards | | **Tickets** | Thread or channel support tickets with panels, limits, staff roles, and transcripts | | **Community** | XP, ranks, leaderboards, activity badges, and Starboard highlights | | **Audit log** | Searchable history of dashboard changes, moderation actions, and automation events | ## How it works 1. **Add the bot** to your server in one step 2. **Open the dashboard** at [volvox.bot](https://volvox.bot) and log in with Discord 3. **Configure** features under **Dashboard -> Settings** 4. **Done** — updates and maintenance happen automatically Everything runs on managed infrastructure. Your bot stays online even when your computer is off. Add Volvox.Bot to your server in under a minute Explore the dashboard and all available features Configure onboarding and first messages # Volvox.Bot Security and Privacy Practices Source: https://docs.volvox.bot/security How Volvox.Bot secures your data with TLS encryption, Discord OAuth2 login, encrypted managed storage, retention windows, and deletion on request. # Security and privacy ## Data encryption * **In transit** — Connections to the dashboard and bot use HTTPS/TLS * **At rest** — Data lives in a managed database with hosting-provider encryption at rest ## Authentication Volvox.Bot uses Discord OAuth2 for authentication and never sees or stores your Discord password. When you log in, Discord confirms your identity and issues a temporary token. ## Data retention | Data type | Retention | | ---------------------- | ---------------------------------------------------------- | | Moderation cases | Duration of server membership | | AI conversations | 30 days (a cleanup job deletes them automatically) | | Audit logs | 90 days by default, configurable in Settings | | Server configuration | Duration of server membership | | Community stats and XP | Duration of server membership unless deletion is requested | You can request deletion of your data at any time by contacting support. ## Infrastructure * **Hosting** — Managed infrastructure with automated deployments * **Updates** — Bot and platform updates apply automatically * **Recovery** — Automatic restart on failure with health monitoring ## Privacy Volvox.Bot follows these privacy principles: * Volvox.Bot only collects data necessary to function * Volvox.Bot shares data only with service providers essential to running the platform (for example, Discord for authentication) * You can request a full export or deletion of your data at any time For full details, see the [Privacy Policy](https://volvox.bot/privacy). ## Cookie preferences The website and dashboard split cookies and local storage into two categories so you stay in control of optional tracking. | Category | Purpose | Default | | --------- | ---------------------------------------------------------------------------- | -------------------- | | Essential | Login, security, and saved dashboard state | Always on | | Analytics | Amplitude product analytics and session replay for aggregate dashboard usage | Off until you opt in | ### Set your preferences A consent banner appears the first time you visit [volvox.bot](https://volvox.bot). You can: * **Accept all** — turn on essential and analytics cookies * **Reject non-essential** — keep only essential cookies * **Customize** — open the preferences dialog and toggle analytics individually Your browser stores your choice for 365 days. After that, the banner reappears so you can confirm or change your decision. ### Change your mind later Open **Cookie Preferences** from the website footer at any time to switch analytics on or off. Turning analytics off stops session replay recording and clears any Amplitude identifiers and cookies that were set while you were opted in. ### What analytics covers When you opt in, Volvox.Bot uses Amplitude to collect: * **Product analytics** — aggregate dashboard usage like page views, navigation, and feature interactions * **Session replay** — a sampled recording of dashboard interactions (clicks, navigation, and scrolling) so the team can diagnose UX issues. Amplitude manages sample rates and masking remotely, and recording stops the moment you opt out Volvox.Bot also records server-side operational events for bot installs, slash command usage, and AI usage. These events use the Discord server ID as the Amplitude user so activity stays grouped by server. If a server ID is unavailable, the event is skipped instead of falling back to an anonymous device. Events send aggregate properties only — for example, command name, AI token/cost totals, member-count bucket, and whether a server is flagged as large. Discord member user IDs, message content, raw channel IDs, channel names, and server names are not sent to Amplitude. Cookie preferences are per browser. If you log in from a different browser or device, set your preferences again there. ## Reporting security issues If you discover a security vulnerability, report it responsibly to [security@volvox.bot](mailto:security@volvox.bot). The team acknowledges reports within 24 hours and works to resolve issues as quickly as possible. # 2026 05 21 setup wizard Source: https://docs.volvox.bot/superpowers/plans/2026-05-21-setup-wizard # Setup Wizard Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development > (recommended) or superpowers:executing-plans to implement this plan task-by-task. **Goal:** Build a skippable `/dashboard/setup` wizard that lets admins configure each first-run section directly, always includes AI provider/model selection, and stores setup completion in guild config. **Architecture:** Add a guild-scoped `setup` config section, a pure web section/patch builder, and a dashboard setup route that reuses `ConfigProvider` and the existing guild config `PUT` endpoint. The welcome server picker routes install callbacks into setup; the Settings sidebar exposes setup as an optional workflow that can be rerun later. **Tech Stack:** Node 22, pnpm 11, Next.js 16 App Router, React 19, TypeScript, Tailwind 4, Vitest 4, Express config API, existing dashboard UI primitives. *** ## Task 1: Setup Config Section **Files:** * Modify: `config.json` * Modify: `src/api/utils/configAllowlist.js` * Modify: `src/api/utils/configValidation.js` * Modify: `web/src/types/config.ts` * Modify: `web/src/components/dashboard/config-editor-utils.ts` * Test: `tests/api/utils/configAllowlist.test.js` * Test: `tests/api/utils/configValidation.test.js` * Test: `web/tests/components/dashboard/config-editor-utils.test.ts` * [x] Add failing allowlist, schema, and web type-guard tests for `setup`. * [x] Add `setup` defaults, safe/readable allowlist entries, schema validation, web types, and `isGuildConfig()` support. * [x] Verify the focused config tests pass. ## Task 2: Provider Option Helper and Section Patch Builder **Files:** * Modify: `web/src/lib/provider-model-options.ts` * Create: `web/src/lib/setup-sections.ts` * Test: `web/tests/lib/provider-model-options.test.ts` * Test: `web/tests/lib/setup-sections.test.ts` * [x] Add provider filtering tests for configured provider and guild tier behavior. * [x] Add section patch-builder tests for enabled sections, disabled sections, AI unavailable, and skipped setup metadata. * [x] Implement `getAvailableProviderModelOptions()`. * [x] Implement `SETUP_SECTIONS`, `buildSetupSectionPatches()`, `buildSetupSkipPatches()`, and `validateSetupStep()`. * [x] Verify the focused helper tests pass. ## Task 3: Setup Wizard Component and Route **Files:** * Create: `web/src/app/dashboard/setup/page.tsx` * Create: `web/src/components/dashboard/setup-wizard.tsx` * Modify: `web/src/lib/page-titles.ts` * Test: `web/tests/app/dashboard/setup/page.test.tsx` * Test: `web/tests/components/dashboard/setup-wizard.test.tsx` * Test: `web/tests/lib/page-titles.test.ts` * [x] Add route/title tests for `/dashboard/setup` and `Setup`. * [x] Add component tests proving the wizard starts at Welcome, does not show server presets, blocks enabled required fields, allows disabled/unavailable AI paths, and saves or skips correctly. * [x] Implement the free-jump section stepper: 1. Welcome 2. Content safety 3. Protected roles 4. Warning rules 5. Tickets 6. Reputation 7. Starboard 8. Commands 9. TL;DR 10. Dashboard roles 11. AI 12. Review * [x] Use the shared dashboard `ServerSelector` on the setup start page and broadcast server switches through the shared guild-selection bus before the wizard starts. * [x] Lock the selected server inside setup step pages so channel and role selectors stay scoped to the route `guildId`. * [x] Use the shared dashboard `AiModelSelect` and fan the selected model out to AI chat, triage, content safety, and TL;DR config. * [x] Split setup into route-backed step pages under `/dashboard/setup/{step}` so each section can grow without being cramped into one in-memory panel. * [x] Save via `fetch('/api/guilds/${guildId}/config', { method: 'PUT', body: JSON.stringify(patches) })`, refetch config on success, and show `Open dashboard`. * [x] Verify the focused route/component tests pass. ## Task 4: Welcome Redirect and Sidebar Entry **Files:** * Modify: `web/src/components/dashboard/welcome-server-picker.tsx` * Modify: `web/src/components/layout/sidebar.tsx` * Test: `web/tests/components/dashboard/welcome-server-picker.test.tsx` * Test: `web/tests/components/layout/sidebar.test.tsx` * [x] Add a welcome redirect test for installed selectable guilds going to `/dashboard/setup?guildId=`. * [x] Add a sidebar test for the Settings `Setup wizard` link to `/dashboard/setup`. * [x] Implement the redirect and sidebar entry. * [x] Verify the focused tests pass. ## Task 5: Docs and Final Verification **Files:** * Modify: `docs/getting-started.mdx` * Review: `AGENTS.md` * Review: `DESIGN.md` * [x] Update `docs/getting-started.mdx` to describe the skippable section-based setup wizard and later Settings `Setup wizard` entry. * [x] Update `DESIGN.md`, `AGENTS.md`, and this implementation plan for the setup start page, locked step server, free-jump setup rail, and expanded setup sections. * [x] Run focused backend and web tests. * [x] Run broad web typecheck/lint, root lint, and provider catalog sync check. * [x] Browser-check `/dashboard/setup` and `/dashboard/setup/welcome?guildId=...` at desktop and mobile sizes. # 2026 06 07 ai usage ops dashboard Source: https://docs.volvox.bot/superpowers/plans/2026-06-07-ai-usage-ops-dashboard # AI Usage Ops Dashboard Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Build an owner-only global AI usage dashboard backed by the existing `ai_usage` table. **Architecture:** Add a bot API route that validates `x-api-secret`, parses range/filter query params, queries global AI usage aggregates, and resolves guild names from the Discord client cache. Add a Next.js global-admin-gated proxy route and a dashboard page that renders summary cards, charts, and comparison tables using existing dashboard primitives. **Tech Stack:** Node 22, Express 5, PostgreSQL, Vitest, Next.js 16 App Router, React 19, TypeScript, Tailwind 4, Recharts via `StableResponsiveContainer`. *** ## Task 1: Backend AI Usage Aggregation **Files:** * Create: `src/api/repositories/aiUsageRepository.js` * Test: `tests/api/repositories/aiUsageRepository.test.js` * [x] **Step 1: Write failing repository tests** Add tests for: ```js theme={null} import { describe, expect, it, vi } from 'vitest'; import { fetchAiUsageOpsSnapshot, parseAiUsageOpsQuery, parseProviderFromModel, } from '../../../src/api/repositories/aiUsageRepository.js'; it('parses supported ranges and rejects invalid filters', () => { expect(parseAiUsageOpsQuery({ range: '24h' }).preset).toBe('24h'); expect(parseAiUsageOpsQuery({ range: '7d' }).interval).toBe('hour'); expect(parseAiUsageOpsQuery({ range: '30d' }).interval).toBe('day'); expect(() => parseAiUsageOpsQuery({ range: '999d' })).toThrow('Invalid range'); expect(() => parseAiUsageOpsQuery({ type: 'delete' })).toThrow('Invalid type'); }); it('parses provider from provider:model and groups bare models as unknown', () => { expect(parseProviderFromModel('z-ai:glm-5.1')).toEqual({ provider: 'z-ai', model: 'glm-5.1' }); expect(parseProviderFromModel('bare-model')).toEqual({ provider: 'unknown', model: 'bare-model' }); }); it('returns empty aggregates when ai_usage has no rows', async () => { const dbPool = { query: vi.fn().mockResolvedValue({ rows: [] }) }; const result = await fetchAiUsageOpsSnapshot({ dbPool, client: { guilds: { cache: new Map() } }, query: {} }); expect(result.summary.requests).toBe(0); expect(result.summary.cacheReadRate).toBeNull(); expect(result.byProvider).toEqual([]); }); it('aggregates totals, cache rates, weighted TPS, p95 latency, and guild names', async () => { const rows = [ { id: 1, guild_id: 'guild-1', channel_id: 'chan-1', type: 'respond', model: 'z-ai:glm-5.1', input_tokens: 1000, output_tokens: 250, cache_read_tokens: 300, cache_creation_tokens: 50, cost_usd: '0.012', duration_ms: 500, search_count: 2, created_at: '2026-06-07T10:00:00.000Z' }, { id: 2, guild_id: 'guild-2', channel_id: 'chan-2', type: 'safety', model: 'bare-model', input_tokens: 500, output_tokens: 100, cache_read_tokens: 0, cache_creation_tokens: 0, cost_usd: '0.002', duration_ms: 1000, search_count: 0, created_at: '2026-06-07T10:10:00.000Z' }, ]; const dbPool = { query: vi.fn().mockResolvedValue({ rows }) }; const client = { guilds: { cache: new Map([['guild-1', { name: 'Alpha' }]]) } }; const result = await fetchAiUsageOpsSnapshot({ dbPool, client, query: { range: '24h' } }); expect(result.summary.requests).toBe(2); expect(result.summary.totalTokens).toBe(1850); expect(result.summary.cacheReadRate).toBeCloseTo(0.2); expect(result.summary.avgTokensPerSecond).toBeCloseTo(1233.333, 2); expect(result.byProvider.map((row) => row.name)).toEqual(['z-ai', 'unknown']); expect(result.topGuilds[0]).toMatchObject({ guildId: 'guild-1', guildName: 'Alpha' }); }); ``` * [x] **Step 2: Run repository tests to verify RED** Run: `pnpm test -- tests/api/repositories/aiUsageRepository.test.js` Expected: fail because `src/api/repositories/aiUsageRepository.js` does not exist. * [x] **Step 3: Implement repository** Create `src/api/repositories/aiUsageRepository.js` with: * `parseAiUsageOpsQuery(query)` supporting `24h`, `7d`, `30d`, `90d`, and `type` in `classify/respond/safety`. * `parseProviderFromModel(modelString)` using the first colon. * `fetchAiUsageOpsSnapshot({ dbPool, client, query })` issuing one parameterized `SELECT` from `ai_usage` for the requested range and optional filters, then aggregating rows in JavaScript. * helper functions for totals, cache rates, weighted TPS, p95 latency, provider/model/type/guild grouping, time buckets, and recent expensive rows. * [x] **Step 4: Run repository tests to verify GREEN** Run: `pnpm test -- tests/api/repositories/aiUsageRepository.test.js` Expected: pass. * [x] **Step 5: Commit backend repository** ```bash theme={null} git add src/api/repositories/aiUsageRepository.js tests/api/repositories/aiUsageRepository.test.js git commit -m "feat(api): aggregate global ai usage" ``` ### Task 2: Bot API Route **Files:** * Create: `src/api/routes/aiUsage.js` * Modify: `src/api/index.js` * Test: `tests/api/routes/aiUsage.test.js` * [x] **Step 1: Write failing route tests** Add tests that build the Express app with a mocked pool and verify: ```js theme={null} it('returns 401 without x-api-secret', async () => { const res = await request(app).get('/api/v1/ai-usage'); expect(res.status).toBe(401); }); it('returns 400 for an invalid range', async () => { const res = await request(app).get('/api/v1/ai-usage?range=bad').set('x-api-secret', TEST_SECRET); expect(res.status).toBe(400); }); it('returns a snapshot with valid auth', async () => { const res = await request(app).get('/api/v1/ai-usage?range=24h').set('x-api-secret', TEST_SECRET); expect(res.status).toBe(200); expect(res.body).toHaveProperty('summary'); expect(res.body).toHaveProperty('byProvider'); expect(res.body.range.preset).toBe('24h'); }); ``` * [x] **Step 2: Run route tests to verify RED** Run: `pnpm test -- tests/api/routes/aiUsage.test.js` Expected: fail with 404 or missing route. * [x] **Step 3: Implement route and mount it** Create `src/api/routes/aiUsage.js` using `Router()`, `isValidSecret(req.headers['x-api-secret'])`, and `fetchAiUsageOpsSnapshot({ dbPool: req.app.locals.dbPool, client: req.app.locals.client, query: req.query })`. Mount it in `src/api/index.js` near `/performance`: ```js theme={null} import aiUsageRouter from './routes/aiUsage.js'; router.use('/ai-usage', aiUsageRouter); ``` * [x] **Step 4: Run route tests to verify GREEN** Run: `pnpm test -- tests/api/routes/aiUsage.test.js` Expected: pass. * [x] **Step 5: Commit bot route** ```bash theme={null} git add src/api/routes/aiUsage.js src/api/index.js tests/api/routes/aiUsage.test.js git commit -m "feat(api): expose owner ai usage snapshot" ``` ### Task 3: Web Proxy, Types, and Page Titles **Files:** * Create: `web/src/app/api/ai-usage/route.ts` * Create: `web/src/types/ai-usage.ts` * Modify: `web/src/lib/page-titles.ts` * Test: `web/tests/api/ai-usage-route.test.ts` * Test: `web/tests/lib/page-titles.test.ts` * [x] **Step 1: Write failing web API and title tests** Add route tests that mock `authorizeRequestGlobalAdmin` and `proxyBotApiEndpoint`: ```ts theme={null} it('returns the global admin auth error without proxying', async () => { mockAuthorizeRequestGlobalAdmin.mockResolvedValueOnce(NextResponse.json({ error: 'Forbidden' }, { status: 403 })); const response = await GET(new NextRequest('http://localhost/api/ai-usage')); expect(response.status).toBe(403); expect(mockProxyBotApiEndpoint).not.toHaveBeenCalled(); }); it('proxies range and filters to the bot API after owner auth', async () => { mockAuthorizeRequestGlobalAdmin.mockResolvedValueOnce(null); await GET(new NextRequest('http://localhost/api/ai-usage?range=24h&type=respond')); expect(mockProxyBotApiEndpoint).toHaveBeenCalledWith('/ai-usage?range=24h&type=respond', '[api/ai-usage]', 'Failed to fetch AI usage data'); }); ``` Update `web/tests/lib/page-titles.test.ts` to expect `AI Usage` and docs href for `/dashboard/ai-usage`. * [x] **Step 2: Run web API/title tests to verify RED** Run: `pnpm --filter volvox-bot-web test -- tests/api/ai-usage-route.test.ts tests/lib/page-titles.test.ts` Expected: fail because route/title wiring is missing. * [x] **Step 3: Implement web route, types, and title wiring** Create `web/src/app/api/ai-usage/route.ts` with `dynamic = 'force-dynamic'`, owner auth, URL search forwarding, and `proxyBotApiEndpoint`. Create `web/src/types/ai-usage.ts` matching the spec response. Add `/dashboard/ai-usage` title/docs matcher to `web/src/lib/page-titles.ts`. * [x] **Step 4: Run web API/title tests to verify GREEN** Run: `pnpm --filter volvox-bot-web test -- tests/api/ai-usage-route.test.ts tests/lib/page-titles.test.ts` Expected: pass. * [x] **Step 5: Commit web plumbing** ```bash theme={null} git add web/src/app/api/ai-usage/route.ts web/src/types/ai-usage.ts web/src/lib/page-titles.ts web/tests/api/ai-usage-route.test.ts web/tests/lib/page-titles.test.ts git commit -m "feat(web): proxy owner ai usage data" ``` ### Task 4: Dashboard AI Usage UI **Files:** * Create: `web/src/components/dashboard/ai-usage-dashboard.tsx` * Create: `web/src/app/dashboard/ai-usage/page.tsx` * Modify: `web/src/components/layout/sidebar.tsx` * Test: `web/tests/components/dashboard/ai-usage-dashboard.test.tsx` * Test: `web/tests/components/layout/sidebar.test.tsx` * [x] **Step 1: Write failing component and sidebar tests** Add component tests that mock `fetch` and verify loading, empty, populated, filter changes, and failed response states. Add sidebar expectations: ```ts theme={null} mockGlobalAdminStatus.value = { isGlobalAdmin: true, isLoading: false, status: 'allowed' }; expect(screen.getByRole('link', { name: /ai usage/i })).toHaveAttribute('href', '/dashboard/ai-usage'); mockGlobalAdminStatus.value = { isGlobalAdmin: false, isLoading: false, status: 'denied' }; expect(screen.queryByRole('link', { name: /ai usage/i })).not.toBeInTheDocument(); ``` * [x] **Step 2: Run UI tests to verify RED** Run: `pnpm --filter volvox-bot-web test -- tests/components/dashboard/ai-usage-dashboard.test.tsx tests/components/layout/sidebar.test.tsx` Expected: fail because component and nav item do not exist. * [x] **Step 3: Implement dashboard page and component** Create `AiUsageDashboard` with: * range/provider/model/type filter controls. * summary metric cards. * time-series chart using `StableResponsiveContainer`. * provider/model/type/top-guild/recent-request tables. * loading, empty, and error states. Create `web/src/app/dashboard/ai-usage/page.tsx` with metadata, `isDashboardGlobalAdmin()` redirect, `ErrorBoundary`, and ``. Add sidebar `AI Usage` with a lucide icon under System Ops and add `/dashboard/ai-usage` to `GLOBAL_ADMIN_ONLY_HREFS`. * [x] **Step 4: Run UI tests to verify GREEN** Run: `pnpm --filter volvox-bot-web test -- tests/components/dashboard/ai-usage-dashboard.test.tsx tests/components/layout/sidebar.test.tsx` Expected: pass. * [x] **Step 5: Commit UI** ```bash theme={null} git add web/src/components/dashboard/ai-usage-dashboard.tsx web/src/app/dashboard/ai-usage/page.tsx web/src/components/layout/sidebar.tsx web/tests/components/dashboard/ai-usage-dashboard.test.tsx web/tests/components/layout/sidebar.test.tsx git commit -m "feat(dashboard): add owner ai usage page" ``` ### Task 5: Docs, AGENTS Check, and Verification **Files:** * Modify: `docs/features/analytics.mdx` * Modify: `docs/dashboard.mdx` * Read/check: `AGENTS.md` * [x] **Step 1: Update docs** Document that global admins can use System Ops -> AI Usage for deployment-wide token, cache, cost, model/provider, and top-server usage. Do not edit `docs/changelog.mdx` except to repair generated output required by docs validation. * [x] **Step 2: Run targeted tests** Run: ```bash theme={null} pnpm test -- tests/api/repositories/aiUsageRepository.test.js tests/api/routes/aiUsage.test.js pnpm --filter volvox-bot-web test -- tests/api/ai-usage-route.test.ts tests/lib/page-titles.test.ts tests/components/dashboard/ai-usage-dashboard.test.tsx tests/components/layout/sidebar.test.tsx ``` Expected: all targeted tests pass. * [x] **Step 3: Run broader checks** Run: ```bash theme={null} pnpm lint pnpm test -- tests/docs/docs.test.js ``` Expected: both pass. Record any pre-existing warnings separately. * [x] **Step 4: Browser verification** Start local dev: ```bash theme={null} pnpm mono:dev ``` Use `agent-browser` to open `/dashboard/ai-usage`, verify owner access, desktop layout, mobile layout, filters, and no visible overflow. If browser tooling cannot run, state that plainly. * [x] **Step 5: Final commit** ```bash theme={null} git add docs/features/analytics.mdx docs/dashboard.mdx git commit -m "docs(dashboard): document owner ai usage ops" ``` # 2026 05 21 setup wizard design Source: https://docs.volvox.bot/superpowers/specs/2026-05-21-setup-wizard-design # Setup Wizard Design Date: 2026-05-21 Status: Updated during implementation ## Summary Add a dedicated setup wizard for Volvox.Bot at `/dashboard/setup`. It launches after the bot is added to a server, remains reachable later, and guides admins through the first settings without blocking access to the dashboard. The root route is a start page with the shared workspace selector; every step has a route at `/dashboard/setup/{step}` and requires a locked `?guildId=...`. The wizard uses a free-jump section checklist: 1. Welcome 2. Content safety 3. Protected roles 4. Warning rules 5. Tickets 6. Reputation 7. Starboard 8. Commands 9. TL;DR 10. Dashboard roles 11. AI 12. Review Each feature section has an enable/disable control. Disabled sections do not block progress. Enabled sections validate only the choices they need. The AI step is always present and can be completed even when no configured provider is available. Admins can click any step in the rail at any time; validation runs when advancing or saving enabled sections. ## Goals * Give new admins a polished first-run setup after the Discord invite flow returns them to the dashboard. * Let admins configure each setup area directly instead of choosing a broad server preset. * Save setup state in guild config so completion follows the server across browsers and admins. * Reuse the existing config fetch/save path instead of adding a parallel settings API. * Always include AI provider/model selection while allowing completion if no provider is available. * Keep the wizard accessible after first run from dashboard chrome. ## Non-Goals * Do not require setup completion before the dashboard opens. * Do not add provider secret entry to this wizard. * Do not replace the existing full settings workspace. * Do not add a separate database table for setup state. ## Entry Points ### First Run The Discord invite callback returns users to `/dashboard/welcome`, optionally with `guildId`. After the bot is detected in that guild and the guild is selectable, the welcome flow selects the guild and routes to `/dashboard/setup?guildId=`. The setup start page explains the flow and lets the admin confirm or change the server before starting `/dashboard/setup/welcome?guildId=`. If bot detection is delayed, `/dashboard/welcome` keeps the current server picker and refresh behavior. Do not claim setup is ready before the bot is actually present. ### Later Access Admins can reopen setup from a visible dashboard action: * Settings sidebar action named `Setup wizard` linking to `/dashboard/setup`. If `setup.completed === true`, the route still opens and allows rerunning the wizard. Rerunning saves a new completed state only after the review step succeeds. The setup start page uses the same `ServerSelector` as the dashboard. Switching servers must use the shared guild-selection bus so the dashboard config context reloads the selected guild before the wizard starts. Step pages do not expose a workspace selector; the selected guild is locked through `?guildId=...` so channel and role selectors stay scoped to one server. Step pages include a back-to-server-selection link, but they do not show the header-level server refresh action. Draft state persists in session storage per guild so moving between step pages does not discard previous choices. ## Config Model Add a guild-scoped `setup` config section: ```ts theme={null} interface SetupConfig { completed: boolean; completedAt: string | null; presetId: 'community' | 'support' | 'creator' | 'locked-down' | null; skippedAt: string | null; updatedAt: string | null; } ``` `presetId` remains nullable legacy metadata for compatibility. The section-based wizard writes `setup.presetId = null`. Required config surfaces: * Add `setup` defaults to `config.json`. * Add `setup` to `SAFE_CONFIG_KEYS` and `READABLE_CONFIG_KEYS`. * Add validation schema for all fields. * Add `setup` to `BotConfig`, `ConfigSection`, and `isGuildConfig()`. * Ensure masked config reads return setup state. Completion semantics: * `setup.completed = true` only after all required wizard fields validate and the review save succeeds. * `setup.skippedAt` records when the user chooses `Set up later`. * Skipping must not set `completed` or `completedAt`. * A later successful completion clears `skippedAt`. ## Section Patch Builder Section definitions live in `web/src/lib/setup-sections.ts`. The module is pure and testable: given enabled sections, selected channels, selected roles, and selected AI model availability, it returns the config patches to save. * Welcome enabled: set `welcome.enabled`, `welcome.channelId`, `welcome.rulesChannel`, welcome message, and rules message. * Welcome disabled: set `welcome.enabled = false`. * Content safety enabled: set `aiAutoMod.enabled`, one default threshold across all safety categories, per-category default safety actions, moderation log routing, spam checks, link filtering, and `auditLog.enabled`. * Content safety disabled: disable AI auto-mod, spam, link filtering, moderation logs, and audit log defaults written by setup. * Protected roles enabled: write owner/admin/mod protected-role behavior and selected role IDs. * Protected roles disabled: clear setup-managed protected-role defaults. * Warning rules enabled: write warning expiry and low/medium/high severity points. Setup clears legacy escalation thresholds instead of asking for them. * Warning rules disabled: clear setup-managed warning escalation behavior. * Tickets enabled: set `tickets.enabled`, `tickets.panelChannel`, `tickets.mode`, `tickets.category`, `tickets.supportRoles`, and legacy `tickets.supportRole`. * Tickets disabled: disable tickets and clear support role routing. * Reputation enabled: enable engagement, reputation, XP, XP min/max, and XP cooldown. * Reputation disabled: disable engagement, reputation, and XP. * Starboard enabled: set `starboard.enabled`, `starboard.channelId`, `starboard.threshold`, `starboard.emoji`, and `starboard.selfStarAllowed`. * Starboard disabled: disable starboard. * Commands enabled: write the command prefix and whether custom prefixes are enabled. * Commands disabled: disable setup-managed custom prefix behavior. * TL;DR enabled: write `tldr.enabled`, analysis window (`tldr.defaultMessages`), max message count, cooldown, and model. * TL;DR disabled: disable TL;DR. * Roles always write the dashboard permission model. * AI writes the selected `provider:model` to AI chat defaults, triage classify/respond models, TL;DR, and AI auto-mod/content-safety routing when a configured provider/model exists; otherwise AI-backed setup features are disabled. * Completion writes `setup.completed`, `setup.completedAt`, `setup.presetId = null`, `setup.skippedAt = null`, and `setup.updatedAt`. ## Wizard Steps ### Welcome Show a toggle for welcome setup. When enabled, require a welcome channel and allow an optional rules channel. ### Content safety Show a toggle for AI/content safety setup. When enabled, require a moderation log channel, set one threshold across all safety categories, and allow per-category default safety actions. ### Protected roles Show protected role selectors plus owner/admin/mod protection toggles. ### Warning rules Show warning expiry plus low, medium, and high severity point controls. Do not show escalation threshold controls in setup. ### Tickets Show a toggle for ticket setup. When enabled, require a ticket panel channel and allow ticket workflow, support staff roles, and root category selection. ### Reputation Show a toggle for reputation setup. When enabled, turn on engagement, reputation, and XP. Include XP min/max and cooldown controls. ### Starboard Show a toggle for starboard setup. When enabled, require a target channel and allow star threshold, watch emoji (including `*` for all), and self-star controls. ### Commands Show the custom command prefix and common prefix choices. ### TL;DR Show TL;DR analysis window, max messages, cooldown, and the shared AI model routing note. ### Roles Show role selectors for admin and moderator roles. Also provide a clear path to use Discord's native owner/admin permission checks without selecting roles. ### AI The AI step is always present. Behavior: * Fetch configured providers via the existing configured providers API. * Filter models by configured provider and guild tier using the existing provider catalog helpers. * Default to the first available model. * If no configured provider/model exists, show an unavailable state, disable AI-backed features, and allow completion. * Provider API failures behave like no configured provider: AI is unavailable and setup can continue with AI off. The wizard never asks for provider API keys. Provider secret management belongs outside this flow. ### Review Show a grouped review of the section choices before saving: * Feature sections enabled or skipped. * Channels and roles selected. * AI provider/model selected or AI unavailable state. * Setup completion metadata. Saving uses the existing `PUT /api/guilds/{guildId}/config` route with a patch array. On success, refetch config, mark setup complete in the UI, and show a clear `Open dashboard` action. ## UX Rules * Use the existing dashboard visual system: `Button`, `ChannelSelector`, `RoleSelector`, `ServerSelector`, `AiModelSelect`, dashboard cards, and Tailwind tokens. * Keep it skippable. `Set up later` saves skipped metadata but does not mark setup complete. * Do not hide the AI step even when no providers are configured. * Keep section copy short and operational. * Validate on next/save, not on every field focus. * Allow jumping to any step from the sidebar at any time. * Keep the mobile layout usable with the footer controls visible and no overlapping text. ## Tests * Config allowlist and validation for `setup`. * Web config type guard for `setup`. * Provider/model filtering by configured provider and guild tier. * Section-to-patch mapping for enabled and disabled sections. * Step validation only for enabled sections. * Setup start page uses the shared dashboard `ServerSelector`. * Setup step pages lock the selected server and do not expose workspace switching. * Step rail allows jumping to any step. * AI selection uses the shared dashboard model selector and fans out to AI chat, triage, content safety, and TL;DR model routing. * Wizard path with AI unavailable still reaches review and saves. * Skip path does not mark setup complete. * Welcome invite callback routes installed guilds to setup. * Settings exposes `Setup wizard` without adding a persistent dashboard setup prompt. # 2026 06 07 ai usage ops dashboard design Source: https://docs.volvox.bot/superpowers/specs/2026-06-07-ai-usage-ops-dashboard-design # AI Usage Ops Dashboard Design Date: 2026-06-07 Status: Approved for implementation planning ## Summary Add a global AI usage dashboard at `/dashboard/ai-usage` for Volvox.Bot operators. The page is part of the dashboard's System Ops area and is visible only to users listed in `BOT_OWNER_IDS`. It aggregates the existing `ai_usage` table across every server so bot owners can inspect token volume, cache usage, cost, latency, throughput, and model/provider mix without jumping between server-scoped Analytics tabs. The implementation should not add a new telemetry store. `ai_usage` already records `guild_id`, `channel_id`, request `type`, `model`, input/output tokens, cache read/write tokens, cost, duration, search count, user id, and timestamp. Provider names can be parsed from the stored `provider:model` string, and guild names can be resolved from the bot client's current guild cache with guild ID fallback. ## Goals * Show global AI usage for bot owners, not server admins. * Make spend spikes easy to trace by server, provider, model, and request type. * Include cache effectiveness and throughput metrics, not just prompt/completion totals. * Reuse the existing owner-only Performance/Logs access patterns. * Keep the first implementation query-driven with no schema migration. * Keep the page useful when there is no data or when some guild names cannot be resolved. ## Non-Goals * Do not expose this dashboard to server owners, server admins, moderators, or viewers. * Do not replace the server-scoped Analytics AI usage card. * Do not store guild names in `ai_usage`. * Do not add provider/model configuration controls to this page. * Do not manually edit `docs/changelog.mdx`; it is automation-owned except for repairs to generated output required to keep docs validation green. ## Access Model The dashboard page uses defense-in-depth checks: * `web/src/app/dashboard/ai-usage/page.tsx` calls `isDashboardGlobalAdmin()` and redirects non-owners to `/dashboard`. * `web/src/app/api/ai-usage/route.ts` calls `authorizeRequestGlobalAdmin()` before proxying. * The bot API route is mounted at `/api/v1/ai-usage` and accepts only `x-api-secret` traffic, matching the Performance route pattern. * The sidebar adds an `AI Usage` item under System Ops and includes it in the global-admin-only href set. ## Data Model Use the existing `ai_usage` columns: * `input_tokens` and `output_tokens` for total token volume. * `cache_read_tokens` and `cache_creation_tokens` for cache effectiveness. * `duration_ms` for latency and tokens-per-second calculations. * `cost_usd` for spend. * `type` for `classify`, `respond`, and `safety` request breakdowns. * `model` for model and provider grouping. * `guild_id`, `channel_id`, `user_id`, and `search_count` for drilldown context. * `created_at` for range filters and time-series buckets. Provider parsing should use the first colon in `model`. Values without a colon are grouped under provider `unknown` and preserve the raw model string. TPS should be derived as `(input_tokens + output_tokens) / greatest(duration_ms / 1000, 0.001)`. Rows with zero or missing duration should not divide by zero; aggregate TPS should use weighted tokens and duration rather than averaging per-row ratios blindly. Cache hit rate should be: ```text theme={null} cache_read_tokens / nullif(input_tokens, 0) ``` Cache write rate should be: ```text theme={null} cache_creation_tokens / nullif(input_tokens, 0) ``` ## API Shape Query parameters: * `range`: `24h`, `7d`, `30d`, or `90d`; default `7d`. * `provider`: optional exact provider filter. * `model`: optional exact model filter. * `type`: optional exact request type filter. Response shape: ```ts theme={null} interface AiUsageOpsSnapshot { range: { preset: '24h' | '7d' | '30d' | '90d'; from: string; to: string; interval: 'hour' | 'day'; }; summary: { requests: number; activeGuilds: number; inputTokens: number; outputTokens: number; totalTokens: number; cacheReadTokens: number; cacheCreationTokens: number; cacheReadRate: number | null; cacheWriteRate: number | null; costUsd: number; avgLatencyMs: number | null; p95LatencyMs: number | null; avgTokensPerSecond: number | null; searchCount: number; }; timeseries: Array<{ bucket: string; label: string; requests: number; inputTokens: number; outputTokens: number; totalTokens: number; cacheReadTokens: number; cacheCreationTokens: number; costUsd: number; avgLatencyMs: number | null; avgTokensPerSecond: number | null; }>; byProvider: AiUsageComparisonRow[]; byModel: AiUsageComparisonRow[]; byType: AiUsageComparisonRow[]; topGuilds: Array; recentExpensiveRequests: Array<{ id: number; createdAt: string; guildId: string; guildName: string | null; channelId: string; type: string; provider: string; model: string; inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheCreationTokens: number; costUsd: number; durationMs: number; tokensPerSecond: number | null; searchCount: number; }>; } interface AiUsageComparisonRow { name: string; requests: number; inputTokens: number; outputTokens: number; totalTokens: number; cacheReadTokens: number; cacheCreationTokens: number; cacheReadRate: number | null; cacheWriteRate: number | null; costUsd: number; avgLatencyMs: number | null; p95LatencyMs: number | null; avgTokensPerSecond: number | null; searchCount: number; } ``` ## UI The page follows the existing dashboard control-plane style from `DESIGN.md`. Sections: 1. Header with range and optional provider/model/type filters. 2. KPI row for requests, total tokens, input tokens, output tokens, cache read rate, cost, TPS, p95 latency, and active servers. 3. Time-series chart for requests, token volume, and cost. 4. Provider comparison table sorted by cost by default. 5. Model comparison table sorted by cost by default. 6. Request type mix for classify/respond/safety. 7. Top servers table showing server name when available and guild ID fallback. 8. Recent expensive or slow requests table for operator triage. Use `StableResponsiveContainer` for every Recharts chart. Empty states should say the selected range has no AI usage rows instead of displaying fake zeros. Loading, error, and unauthorized states should match the existing Performance/Logs tone. ## Error Handling * Invalid range or filter values return `400` from the bot API. * Database errors return `500` with a compact `{ error: string }` response and log through `src/logger.js`. * The web proxy returns existing global-admin auth failures for non-owners. * Missing guild names are not errors; return `guildName: null`. * Unknown provider/model strings stay visible as raw values and group provider as `unknown`. ## Tests Backend: * Repository/helper tests for range parsing and SQL parameterization. * Aggregation tests for totals, cache rates, weighted TPS, p95 latency, provider parsing, and unknown model strings. * Route tests for `x-api-secret` enforcement, bad filters, empty data, and populated responses. Web: * API route tests for `authorizeRequestGlobalAdmin()` gating and bot proxy path. * Sidebar test for `AI Usage` hidden from non-owners and visible to global admins. * Page/component tests for loading, empty, error, and populated states. * Page title test for `/dashboard/ai-usage`. Manual/browser: * Run the dashboard locally with dev login. * Verify `/dashboard/ai-usage` redirects for non-owner status. * Verify the owner view renders desktop and mobile without overflow. * Verify filters update the request URL and tables/charts. ## Implementation Notes * Prefer a new route file, `src/api/routes/aiUsage.js`, and a small repository module such as `src/api/repositories/aiUsageRepository.js`. * Mount `/ai-usage` near `/performance` in `src/api/index.js`. * Keep query SQL parameterized. Do not interpolate filter values. * Use `provider:model` parsing logic locally or a pure helper; do not import `aiClient.js` into API routes just to parse strings. * Do not add a migration unless implementation proves a query cannot be made efficient with the current indexes.