Skip to Content
Haven Documentation is the shared home for product guides, plugin setup, and release docs.
PluginsAIO AgentConfiguration

Configuration

AIO Agent is configured through aio_agent. If the Athena dashboard is enabled, use the dashboard first because the live config may be stored in MongoDB instead of only reading configuration/aio_agent.json5.

AIO Agent can run Discord actions for trusted users. Set owner_id, review every user ID list, and keep destructive actions confirmed before using it on a customer server.

How Values Are Entered

Most customer-specific fields are free text in the dashboard so you can enter real values instead of being limited to a dropdown. This includes model names, API base URLs, docs URLs, knowledgebase paths, prompt file names, timezone values, locale values, and the forum thread header template.

Dropdowns are used only for true fixed choices such as mode, llm_provider, permission tiers, personality, moderation mode, moderation sensitivity, boolean toggles, and other enum-style settings.

Use Discord snowflake IDs for users, roles, and channels. Enable Developer Mode in Discord, right-click the item, then copy the ID.

Addon Configuration

Customer-specific addon configuration belongs under:

plugins/aio_agent/data/addons/<addon-id>/config.json5

Addon defaults are applied only when the normal AIO config does not already set that value. Dashboard/config values win over addon defaults. This lets updates keep customer addons intact while still letting server owners override settings from the normal AIO config.

See Addons for the addon manifest, API, and update rules.

Core

OptionTypeDefaultDescription
enabledbooleanfalseMaster switch. When false, AIO Agent ignores all events.
modeenum"general"Feature mode: general, chat, support, or owner_only.
permissions.aio_commandstring"management"Athena permission level required for /aio. Must match configuration/permission.json5.

mode behavior:

ModeWhat runs
generalTickets, chat, owner/admin pings, moderation, member events, FAQ, and anti-raid.
chatChat replies only. No tickets, owner tools, moderation, or member automation.
supportTicket/support flows only. Owner pings only work inside support context.
owner_onlyOnly owner_id can talk to the agent. No tickets, chat, or automation.

LLM Provider

OptionTypeDefaultDescription
llm_providerenum"gemini"Provider to use: gemini, openai, anthropic, openrouter, or custom.
llm_api_keystring""Provider API key. Leave blank to use environment variables.
llm_modelstring""Exact model name to send to the selected provider. Empty uses provider default.
llm_api_base_urlstring""Required for custom; optional override for OpenAI-compatible providers.
gemini_api_keystring""Legacy Gemini-only key. Used when provider is gemini and llm_api_key is blank.
gemini_modelstring"gemini-2.5-flash"Legacy Gemini model fallback. Used when provider is gemini and llm_model is blank.
llm_max_output_tokensnumber4096Maximum output tokens for owner/tool and ticket calls.
llm_temperature_ticketnumber0.7Creativity for ticket support replies.
llm_temperature_ownernumber0.8Creativity for owner/admin tool-calling replies.
llm_temperature_chatnumber0.9Creativity for general chat.
llm_temperature_moderationnumber0.2Moderation decision temperature. Keep low for consistency.
gemini_max_output_tokensnumber4096Legacy alias. New llm_max_output_tokens wins.
gemini_temperature_ticketnumber0.7Legacy alias. New llm_temperature_ticket wins.
gemini_temperature_ownernumber0.8Legacy alias. New llm_temperature_owner wins.
gemini_temperature_chatnumber0.9Legacy alias. New llm_temperature_chat wins.
gemini_temperature_moderationnumber0.2Legacy alias. New llm_temperature_moderation wins.
llm_retry_attemptsnumber2Number of retries for temporary provider failures such as 429, 500, 502, 503, and 504.
llm_retry_base_delay_msnumber800Base delay between retries. Delay increases by attempt number.
usage_pricing_input_per_millionnumber0.30Estimated input-token cost per 1M tokens for /aio usage.
usage_pricing_output_per_millionnumber2.50Estimated output-token cost per 1M tokens for /aio usage.

Separate reasoning profile

The reasoning profile can use a second provider, model, base URL, and API key for heavier tasks while normal chat and ticket replies continue using the primary profile. Blank provider/model/base URL values inherit the primary settings. A blank reasoning key uses AIO_AGENT_REASONING_API_KEY, the matching provider environment variable, or the primary key.

OptionTypeDefaultDescription
reasoning_llm.enabledbooleanfalseEnables the optional second LLM profile.
reasoning_llm.providerenum/string""gemini, openai, anthropic, openrouter, or custom. Empty inherits the primary provider.
reasoning_llm.api_keystring""Separate API key. Empty uses the environment/key fallback described above.
reasoning_llm.modelstring""Separate model. Empty inherits the primary model.
reasoning_llm.api_base_urlstring""Separate compatible endpoint. Empty inherits the primary base URL.
reasoning_llm.use_for_owner_toolsbooleantrueUses this profile for multi-step owner/admin agent tools.
reasoning_llm.use_for_self_improvementbooleantrueUses this profile to evaluate confirmed-memory proposals.
reasoning_llm.use_for_response_classifierbooleanfalseUses this profile for ambiguous Smart reply decisions.
reasoning_llm.use_for_knowledgebase_searchbooleantrueUses this profile for embedding-backed knowledgebase search when supported.

Prompt caching

Prompt caching depends on the provider and model. These options apply to the primary LLM and the optional reasoning profile according to the provider used for each request.

OptionTypeDefaultDescription
prompt_caching.enabledbooleanfalseLets AIO send or manage the provider-specific controls below. Turning it off does not disable implicit caching performed by the provider.
prompt_caching.openai.modeenum"automatic"automatic uses provider-managed breakpoints. explicit marks AIO’s system prompt and requires GPT-5.6 or later.
prompt_caching.openai.cache_keystring""Optional stable routing key for requests that share the same long prompt prefix.
prompt_caching.anthropic.modeenum"automatic"automatic follows the growing conversation. explicit caches the system prompt.
prompt_caching.anthropic.ttlenum"5m"Claude cache lifetime: 5m or 1h.
prompt_caching.gemini.modeenum"automatic"automatic uses Gemini implicit caching. explicit creates a managed cache for the stable system prompt and active tool definitions.
prompt_caching.gemini.ttl_secondsnumber300Gemini explicit-cache lifetime from 60 to 86400 seconds.

OpenAI uses a fixed 30-minute TTL for explicit caching. If explicit mode is selected with an older OpenAI model, AIO safely uses automatic caching instead. Gemini also falls back to an ordinary request when its provider rejects an explicit cache, including prompts below the model’s minimum cache size.

/aio usage shows cached-input and cache-write token counts. The dollar estimate uses the configured base input/output prices and does not include provider-specific cache discounts, write premiums, or cache-storage charges.

Environment variable priority:

  1. AIO_AGENT_LLM_API_KEY
  2. Provider-specific variable such as AIO_AGENT_OPENAI_API_KEY
  3. llm_api_key
  4. gemini_api_key when using Gemini

Provider-specific variables:

AIO_AGENT_LLM_API_KEY=... AIO_AGENT_GEMINI_API_KEY=... AIO_AGENT_OPENAI_API_KEY=... AIO_AGENT_ANTHROPIC_API_KEY=... AIO_AGENT_OPENROUTER_API_KEY=...

Recommended starting models:

ProviderModel exampleNotes
geminigemini-2.5-flashBest default for low-cost support and knowledgebase answers.
openaigpt-4o-miniGood OpenAI-compatible default.
anthropicclaude-3-5-haiku-latestFast Claude option.
openrouteropenai/gpt-4o-miniRoute to many providers with one key.
customprovider-specificUse the exact OpenAI-compatible model name required by your endpoint.

Never publish real API keys in screenshots, docs, support tickets, or Discord messages. Use environment variables for production whenever possible.

Identity And Branding

OptionTypeDefaultDescription
brand_namestring""Brand inserted into prompts as the brand_name placeholder. Empty uses the Discord server name where available.
owner_display_namestring""Friendly owner name inserted into prompts as the owner_display_name placeholder.
docs_urlstring"https://docs.iynxdev.com/"Public documentation link the bot returns when users ask where docs are.
owner_idstring""Discord user ID with full owner-level tool access. Required for privileged tool use.

Permission Tiers

AIO Agent resolves each speaker into one tier.

TierConfig sourceAccess
Ownerowner_idAll tools, including sensitive owner-only tools.
Adminadmin_usersMost server-management and moderation tools, excluding sensitive owner-only tools.
Moderatormoderator_usersModeration tools, role assignment/removal, channel lock/unlock, slowmode, nicknames, and ticket close when allowed.
Allowedallowed_usersConversation only. No tools.
Nonenot listedCannot use privileged owner-ping flows.
Blockedblocked_usersIgnored by AIO Agent.
OptionTypeDefaultDescription
admin_usersstring[][]Discord user IDs with admin tool access.
moderator_usersstring[][]Discord user IDs with moderator tool access.
allowed_usersstring[][]Discord user IDs allowed to chat without tool access.
blocked_usersstring[][]Discord user IDs the bot ignores everywhere.

Abuse Protection

OptionTypeDefaultDescription
max_message_lengthnumber1500User messages longer than this are truncated before the model sees them. Extreme lengths add abuse strikes.
max_requests_per_user_per_hournumber15Rolling hourly request cap for non-privileged users.

Repeated rate-limit, spam, or extreme-length strikes can automatically add a user to blocked_users.

Confirmations And Audit Logging

OptionTypeDefaultDescription
require_confirmation_forstring[]destructive defaultsTool names that always require an Approve/Cancel button before execution.
confirm_destructive_toolsbooleantrueAlso require confirmation for any tool marked destructive by the plugin.
confirmation_approver_user_idsstring[][]Extra Discord user IDs allowed to approve AI action confirmations.
confirmation_approver_role_idsstring[][]Role IDs allowed to approve AI action confirmations.
confirmation_timeout_secondsnumber30How long confirmation buttons remain valid.
action_audit_log_channel_idstring""Optional channel ID where AI tool attempts are logged.
action_audit_include_argsbooleantrueInclude tool arguments in audit logs.
action_audit_include_resultbooleantrueInclude tool result in audit logs.

Recommended confirmed tools:

require_confirmation_for: [ "ban_user", "unban_user", "kick_user", "delete_messages", "delete_role", "remove_warning", "set_channel_permissions", "delete_channel", "close_ticket", "run_athena_command" ]

For normal AI tool confirmations, only a valid button click approves the action. Plain text such as ok after a timeout does not approve an expired action.

Multi-Step Agent Limits

OptionTypeDefaultDescription
tool_execution.max_iterationsnumber12Maximum planning/tool rounds for one agent request.
tool_execution.max_actions_per_requestnumber40Maximum individual actions across all rounds in one request.

When a request reaches either limit, AIO stops safely and reports what it completed instead of claiming the entire task finished.

Personality And Context

OptionTypeDefaultDescription
personalityenum"professional_casual"Global personality: professional, professional_casual, casual, or custom.
custom_personalitystring""Free-form personality instructions when personality is custom.
max_context_messagesnumber30Recent channel messages included as model history. Workflow embeds and bot action messages are filtered out.

Reply Modes And Smart Gate

Chat and tickets can use separate reply modes:

ModeBehavior
smartIgnores normal conversation and acknowledgements, answers clear help and direct bot-name calls locally, and classifies only ambiguous questions. In tickets, it also stays quiet while another human is handling the customer.
alwaysAnswers every eligible message in a watched chat channel or every customer message in an active ticket.
mentionsAnswers only a real bot mention or a Discord reply to the bot. Typing the bot name or a configured alias does not count in this mode.

Smart is the default for both chat.response_mode and tickets.response_mode. It uses local rules first, so normal conversation, clear help, and direct calls using the bot’s username, nickname, or a configured alias do not require a classifier request. If an ambiguous message does need classification, AIO sends a short JSON-only request with limited history and fails closed when the provider is unavailable or unsure.

OptionTypeDefaultDescription
response_gate.use_llm_classifierbooleantrueAllows a small LLM check for ambiguous questions. When false, ambiguous messages are ignored.
response_gate.classifier_modelstring""Optional lower-cost model used only for the response gate. Empty uses the main configured model.
response_gate.context_messagesnumber8Recent messages included so the classifier can tell who a question is aimed at. Range: 2-20.
response_gate.confidence_thresholdnumber0.72Minimum confidence required before AIO joins an ambiguous conversation. Range: 0.5-0.95.
response_gate.max_output_tokensnumber80Maximum output tokens for the JSON-only decision. Range: 32-160.
response_gate.max_message_charsnumber1200Maximum characters from the latest message sent to the classifier. Range: 200-4000.
response_gate.cache_ttl_secondsnumber120How long a decision for the same Discord message is reused. Range: 10-600.
response_gate.max_checks_per_user_per_hournumber12Hourly cap on ambiguous-message classifier requests for each user. Range: 1-100.

Classifier calls are included in /aio usage. The normal chat request limit still applies after Smart decides to answer. Direct mentions and intentional bot-name calls bypass the channel cooldown so they are not dropped behind an earlier response; per-user limits still apply.

Knowledgebase

AIO Agent can load knowledge from three places:

  1. .md and .txt files in knowledgebase_dir
  2. Built-in AthenaBot docs when athenabot_brain_enabled is true
  3. Configured channel or forum snapshots from knowledgebase_channels

The plugin reads the sources on startup or /aio reload, stores them in memory, then builds a knowledgebase_block for each AI request. The request does not read the filesystem again unless you reload or restart.

OptionTypeDefaultDescription
knowledgebase_channelsstring[][]Channel IDs to ingest as extra knowledge. Forum threads are supported.
knowledgebase_dirstring"knowledgebase"Folder for .md and .txt files. Relative paths resolve under plugins/aio_agent/data/; absolute paths are allowed.
knowledgebase_recursivebooleanfalseScan subfolders under knowledgebase_dir.
knowledgebase_max_depthnumber8Maximum folder depth when recursive loading is enabled.
athenabot_brain_enabledbooleantrueLoads built-in AthenaBot documentation, config references, FAQ, and common errors.
forum_thread_header_templatestring--- Thread: &#123;&#123;thread_name&#125;&#125; | Author: &#123;&#123;author_name&#125;&#125; ---Header added before imported forum thread content. Supports thread_name and author_name placeholders.

Retrieval Mode

OptionTypeDefaultDescription
knowledgebase_modeenum"search"off, full, search, or hybrid.
knowledgebase_full_max_charsnumber120000Character cap for full mode.
knowledgebase_search_top_knumber6Number of chunks selected in search or hybrid mode.
knowledgebase_search_max_charsnumber12000Total character cap for selected chunks.
knowledgebase_search_min_scorenumber0.05Minimum local-search score before a chunk is included.
knowledgebase_search_fallback_fullbooleanfalseIf search finds nothing, fall back to full mode. Use carefully because this can be expensive.
knowledgebase_chunk_max_charsnumber1800Target maximum size for each searchable chunk.
knowledgebase_chunk_overlap_charsnumber150Character overlap between split chunks.
knowledgebase_always_include_sourcesstring[][]Source path/title substrings that are always included when matched. Useful for policies or pricing docs.

Mode guide:

ModeWhat gets sent to the modelUse when
offNo knowledgebase block.You want pure model behavior or only prompt files.
fullOne large block with all loaded knowledge, capped by knowledgebase_full_max_chars.Small knowledgebases where every request needs the same context.
searchOnly locally scored chunks relevant to the user’s latest request.Default choice for most customers. Lower cost than full mode.
hybridLocal search selects candidates, then embeddings rerank them when configured.Large or messy knowledgebases where word matching alone misses relevant pages.

Embeddings

Embeddings are optional. With the default config, search mode uses local token matching only and does not call a separate embedding API. Turn embeddings on when the knowledgebase is large enough that semantic matching is worth the extra API calls.

OptionTypeDefaultDescription
knowledgebase_embeddings_enabledbooleanfalseEnables embedding rerank in search or hybrid mode.
knowledgebase_embedding_providerenum/string"llm"llm, gemini, openai, openrouter, or custom. llm reuses llm_provider.
knowledgebase_embedding_modelstring""Exact embedding model name. Empty uses provider defaults.
knowledgebase_embedding_api_keystring""Optional embedding-specific API key. Empty reuses the effective LLM key.
knowledgebase_embedding_api_base_urlstring""Optional embedding-specific OpenAI-compatible base URL.
knowledgebase_embedding_candidate_countnumber30Number of local-search candidates to embed/rerank before selecting top chunks.
knowledgebase_embedding_max_charsnumber3000Max characters embedded per chunk/query.
knowledgebase_hybrid_local_weightnumber0.35Local-search score weight in hybrid rerank.
knowledgebase_hybrid_embedding_weightnumber0.65Embedding similarity score weight in hybrid rerank.

Default embedding models:

ProviderDefault embedding model
Geminitext-embedding-004
OpenAItext-embedding-3-small
OpenRoutertext-embedding-3-small unless your route requires another model
CustomYou should set knowledgebase_embedding_model

Embedding vectors are cached in plugins/aio_agent/data/cache/knowledgebase-embeddings.json. If the content changes, the source hash changes and stale cached vectors are not reused.

Recommended setups:

// Small knowledgebase, lowest complexity knowledgebase_mode: "full" // Normal customer knowledgebase knowledgebase_mode: "search" knowledgebase_search_top_k: 6 knowledgebase_search_max_chars: 12000 // Large knowledgebase with semantic rerank knowledgebase_mode: "hybrid" knowledgebase_embeddings_enabled: true knowledgebase_embedding_provider: "llm" knowledgebase_embedding_candidate_count: 30

Run this after changing files or channel knowledge:

/aio reload

Confirmed Memory

Confirmed memory lets authorized users say remember this, or lets AIO propose useful server facts from configured conversations. Every proposal is posted to the review channel and must be approved before it is written to the configured knowledgebase file. It only updates AIO’s own knowledge, terminology, personality, server facts, and support guidance; it cannot edit code, configuration, permissions, or unrelated systems.

OptionTypeDefaultDescription
self_improvement.enabledbooleanfalseEnables authorized remember-this requests and memory review.
self_improvement.auto_detectbooleanfalseAllows eligible chats to create review proposals. Nothing is saved automatically.
self_improvement.source_scopeenum"selected"Sources for automatic proposals: all, staff, or selected.
self_improvement.channel_idsstring[][]Channels included when scope is selected.
self_improvement.category_idsstring[][]Categories included when scope is selected.
self_improvement.excluded_channel_idsstring[][]Channels always excluded from automatic proposals.
self_improvement.review_channel_idstring""Required review/log channel for proposals, approvals, rejections, and save results.
self_improvement.approver_user_idsstring[][]Extra users allowed to approve or reject memory proposals.
self_improvement.approver_role_idsstring[][]Roles allowed to approve or reject memory proposals.
self_improvement.minimum_requester_tierenum"ADMIN"Minimum AIO tier allowed to request remember this.
self_improvement.memory_filestring"agent-memory.md"Safe .md or .txt file inside the AIO knowledgebase directory.
self_improvement.min_confidencenumber0.88Minimum confidence for automatic proposals.
self_improvement.max_entry_charsnumber1000Maximum saved characters per approved entry.
self_improvement.cooldown_secondsnumber60Per-channel automatic proposal cooldown.
self_improvement.max_proposals_per_hournumber10Global hourly automatic proposal limit.
self_improvement.review_timeout_minutesnumber30How long review buttons remain active.

After approval, AIO writes the memory safely and reloads its knowledgebase so new conversations can use it immediately.

Tickets

Ticket support requires AthenaBot’s tickets plugin.

OptionTypeDefaultDescription
tickets.enabledbooleantrueEnables AI responses inside ticket channels.
tickets.response_modeenum"smart"Ticket reply behavior: smart, always, or mentions. Smart avoids interrupting active staff.
tickets.auto_activatebooleantrueAutomatically starts an AI ticket session when a customer messages. Use /aio handle instead if you want manual activation.
tickets.auto_activate_categoriesarray[]Ticket category indexes that auto-activate. Empty means all categories.
tickets.external_ticket_fallback.enabledbooleanfalseAllows AIO to create a ticket session in third-party ticket bot channels when a customer mentions the bot and the channel matches configured markers.
tickets.external_ticket_fallback.require_bot_mentionbooleantrueRequire the customer to mention the AIO bot before external fallback starts a session.
tickets.external_ticket_fallback.channel_name_patternsstring[]["ticket", "order"]Channel name substrings or /regex/ patterns treated as external ticket channels.
tickets.external_ticket_fallback.recent_message_limitnumber12Number of recent messages scanned for external ticket form markers.
tickets.external_ticket_fallback.form_text_containsstring[]Tickets v2 form textText fragments that identify a third-party ticket form message.
tickets.human_phrasesstring[]common phrasesCustomer phrases that pause the AI and hand off to staff.
tickets.owner_stop_phrasesstring[]common phrasesOwner/admin phrases that pause the AI inside a ticket.
tickets.cooldown_secondsnumber2Minimum channel delay between ticket AI replies.
tickets.allow_ai_ticket_closebooleanfalseMaster switch for AI/staff-triggered ticket closing.
tickets.ticket_close_requires_confirmationbooleantrueRequire a Discord button flow before closing.
tickets.ticket_close_minimum_tierenum"MODERATOR"Minimum AIO tier allowed to request/approve AI ticket closing: OWNER, ADMIN, or MODERATOR.
tickets.ticket_close_allow_creatorbooleanfalseLets the ticket creator approve an AI close request through Athena’s native ticket close buttons.
tickets.ticket_close_commandsstring[]close aliasesAthena command names treated as ticket-close commands when using run_athena_command.
tickets.ticket_close_approver_role_idsstring[][]Role IDs that can approve AI ticket-close confirmations.
tickets.staff_notify_enabledbooleantrueAllows the AI to trigger a real staff notification marker instead of only saying it notified staff.
tickets.staff_notify_markerstring"[STAFF_NOTIFY]"Marker the AI emits when it wants staff notified.
tickets.staff_notify_channel_idstring""Channel ID for staff notifications. Empty posts in the ticket channel.
tickets.staff_notify_user_idsstring[][]User IDs mentioned on staff notification.
tickets.staff_notify_role_idsstring[][]Role IDs mentioned on staff notification.
tickets.staff_notify_fallback_to_ownerbooleantrueMention owner_id if no explicit staff users/roles are configured.
tickets.staff_notify_on_handoffbooleantrueNotify staff when a customer uses a human handoff phrase.
tickets.staff_notify_pause_sessionbooleantruePause the AI session after staff notification.
tickets.staff_notify_context_messagesnumber6Recent ticket messages included in staff notification embeds.
tickets.strict_workflow.enabledbooleantrueRuns deterministic ticket intake before the LLM.
tickets.strict_workflow.notify_requires_customer_approvalbooleantrueAfter the customer confirms the brief, ask separately before notifying staff.
tickets.strict_workflow.pause_after_notifybooleantruePause the ticket AI after a real staff notification is sent.
tickets.strict_workflow.use_llm_extractorbooleanfalseOptional JSON-only field extraction helper. Failed extraction falls back to asking the next configured field.
tickets.strict_workflow.required_fieldsarrayservice/title/description/deadline/budget/referencesRequired intake fields. Each field supports key, label, question, and aliases.
tickets.strict_workflow.repliesobjectbuilt-in strict repliesReply templates for checklist, missing fields, brief summary, confirmation request, notify approval, notify success, skipped notify, and failures.
tickets.category_settingsarray[]Per-ticket-category overrides. See below.
tickets.enable_spec_confirmation_flowbooleanfalseEnables marker-based commission/spec confirmation flow.
tickets.spec_confirmation_markerstring"[SPEC_CONFIRMED]"Marker emitted by the model when a spec is confirmed.
tickets.ticket_form_embed_title_containsstring[]["Ticket questions"]Embed title substrings used to detect new ticket form data.
tickets.catchup_enabledbooleanfalseOn startup, scan missed tickets and create sessions when needed.
tickets.catchup_min_channel_created_atstring""ISO timestamp limiting catch-up to newer channels. Empty uses current time on first boot.

Per-category overrides:

tickets: { category_settings: [ { category_index: 0, tone: "friendly", custom_tone: "", handoff_phrases: ["staff please"], staff_notify_channel_id: "123456789012345678", staff_notify_user_ids: [], staff_notify_role_ids: ["123456789012345678"], staff_notify_on_handoff: true, staff_notify_pause_session: true, allow_ai_ticket_close: true, ticket_close_requires_confirmation: true, ticket_close_minimum_tier: "MODERATOR", ticket_close_allow_creator: true, ticket_close_approver_role_ids: [] } ] }

Ticket close behavior:

SetupResult
allow_ai_ticket_close: falseAI can answer tickets but cannot close them.
allow_ai_ticket_close: true and ticket_close_requires_confirmation: true and ticket_close_allow_creator: trueA creator close request such as close ticket or !tclose uses Athena’s native close-request buttons.
allow_ai_ticket_close: true and ticket_close_requires_confirmation: true and creator close disabledAIO posts an AI action confirmation for staff/approved users.
allow_ai_ticket_close: true and ticket_close_requires_confirmation: falseThe ticket closes directly through the tickets plugin with reason [aio-agent] close_ticket.

Expired close prompts cannot be approved with plain text. A user must send a new explicit close intent or click a fresh native button.

Strict Workflow

Strict workflow keeps ticket intake and staff notification deterministic. The model may still help with normal support replies, but it does not decide whether a brief is complete, whether staff were notified, or whether a handoff happened.

Default flow:

  1. Customer asks what information is needed.
  2. AIO sends the configured checklist and asks the first missing field.
  3. Customer answers one field at a time or sends a larger brief.
  4. AIO stores answers in workflowData.fields.
  5. Once all required_fields are filled, AIO sends brief_summary.
  6. Customer confirms the brief.
  7. AIO asks whether to notify staff.
  8. Only explicit notify approval sends the real staff notification.
  9. If pause_after_notify is true, the AI pauses after notifying staff.

Example required field:

{ key: "deadline", label: "Deadline / urgency", question: "What is the deadline or urgency?", aliases: ["deadline", "urgency", "deadline / urgency", "due", "due date"] }

Example strict workflow config:

tickets: { strict_workflow: { enabled: true, notify_requires_customer_approval: true, pause_after_notify: true, use_llm_extractor: false, required_fields: [ { key: "service", label: "Service", question: "What type of service do you need?", aliases: ["service", "type of service"] }, { key: "title", label: "Project title or text", question: "What is the project title or exact text?", aliases: ["project title", "title", "text"] }, { key: "description", label: "Description", question: "Please describe the project, style, and important details.", aliases: ["description", "details", "theme", "style"] }, { key: "deadline", label: "Deadline / urgency", question: "What is the deadline or urgency?", aliases: ["deadline", "urgency"] }, { key: "budget", label: "Budget range", question: "What is the budget range?", aliases: ["budget", "budget range"] }, { key: "references", label: "References", question: "Do you have any references, links, or images?", aliases: ["references", "links", "images"] } ] } }

Plain answers are applied to the last field AIO asked for. For example, if AIO asks for deadline and the customer replies take your time, that becomes the deadline value.

External Ticket Bot Fallback

Use this only when another ticket system creates the ticket channel and AthenaBot’s native tickets plugin cannot resolve the channel.

tickets: { external_ticket_fallback: { enabled: true, require_bot_mention: true, channel_name_patterns: ["ticket", "order"], recent_message_limit: 12, form_text_contains: [ "Your order ticket has been created", "While you are waiting, please fill out this question form", "Question 1", "Question 2", "Question 3", "Powered by tickets.bot" ] } }

When enabled, AIO starts a session only when:

  • the message is from a human
  • the customer mentions the bot, unless require_bot_mention is false
  • the message looks related to the strict ticket workflow
  • the channel name or recent bot ticket form messages match the fallback config

The first matching human is treated as the ticket creator for the AIO session.

Chat

OptionTypeDefaultDescription
chat.enabledbooleanfalseEnables general chat mode.
chat.channelsstring[][]Channel IDs where the bot can chat without being mentioned.
chat.respond_to_mentionsbooleantrueAllows replies when the bot is mentioned outside configured chat channels.
chat.respond_to_namebooleantrueReplies immediately when someone directly calls the bot by its Discord username or server nickname. Ordinary references to the name remain ignored.
chat.wake_wordsstring[][]Optional extra bot names or phrases that count as direct calls in Smart mode.
chat.response_modeenum"smart"Chat reply behavior: smart, always, or mentions.
chat.personalitystring""Chat-only personality override. Empty inherits global personality.
chat.custom_personalitystring""Chat-only custom personality text.
chat.allowed_topicsstring""Optional topic boundary for chat.
chat.max_messages_per_user_per_hournumber20Chat-only hourly cap for non-admin users.
chat.cooldown_secondsnumber3Channel cooldown between chat replies.

Moderation

OptionTypeDefaultDescription
moderation.enabledbooleanfalseEnables AI moderation checks.
moderation.modeenum"ask"off, ask, or instant. Start with ask.
moderation.review_channel_idstring""Channel where review embeds are posted in ask mode.
moderation.server_rulesstring""Rules the AI evaluates against. Be specific.
moderation.enforce_discord_tosbooleantrueAlso enforce Discord ToS/community guidelines.
moderation.sensitivityenum"medium"low, medium, or high.
moderation.actions.warnbooleantrueAllows warnings through Athena’s moderation plugin, including its history, thresholds, notifications, and log.
moderation.actions.timeoutbooleantrueAllows timeouts.
moderation.actions.timeout_max_minutesnumber60Maximum timeout duration.
moderation.actions.kickbooleanfalseAllows kicks. Keep disabled until reviewed.
moderation.actions.banbooleanfalseAllows bans. Keep disabled until reviewed.
moderation.actions.delete_messagebooleantrueAllows deleting violating messages.
moderation.monitored_channelsstring[][]Empty means all channels except excluded channels.
moderation.excluded_channelsstring[][]Channels skipped by moderation.
moderation.immune_rolesstring[][]Role IDs exempt from moderation.
moderation.immune_usersstring[][]User IDs exempt from moderation.
moderation.min_confidencenumber0.75Minimum confidence required to act or request review.
moderation.review_timeout_minutesnumber10How long review embeds remain actionable.
moderation.cooldown_per_user_secondsnumber5Per-user moderation-call cooldown.
moderation.context_messagesnumber5Recent messages supplied to the moderation prompt.

Scam Detection

Scam detection is separate from text moderation and is disabled by default. It can scan image attachments, links, sender age, join age, roles, trust lists, and recent context before normal AIO replies.

OptionTypeDefaultDescription
scam_detection.enabledbooleanfalseEnables scam scanning.
scam_detection.modeenum"ask"off, ask, or instant. Start with ask.
scam_detection.min_confidencenumber0.82Minimum confidence required for review or action.
scam_detection.auto_delete_confidencenumber0.94High-confidence threshold for delete actions when allowed.
scam_detection.scan_imagesbooleantrueSends image attachments to a vision-capable model.
scam_detection.scan_linksbooleantrueChecks message links and domains.
scam_detection.scan_new_accounts_more_strictlybooleantrueApplies stricter judgment for new accounts and recent joins.
scam_detection.review_channel_idstring""Channel for scam review embeds. Empty uses the moderation review channel.
scam_detection.log_channel_idstring""Optional channel for scam evidence and decisions. Athena’s moderation plugin owns punishment history and moderation logs.
scam_detection.monitored_channelsstring[][]Empty means all non-excluded channels.
scam_detection.excluded_channelsstring[][]Channels skipped by scam scanning.
scam_detection.ignored_usersstring[][]User IDs skipped by scam scanning.
scam_detection.ignored_rolesstring[][]Role IDs skipped by scam scanning.
scam_detection.trusted_domainsstring[][]Domains that should not trigger scans by themselves.
scam_detection.trusted_usersstring[][]User IDs trusted by scam scanning.
scam_detection.trusted_image_hashesstring[][]SHA-256 image hashes ignored by future scans.
scam_detection.max_image_bytesnumber4194304Maximum image size sent to the model.
scam_detection.max_images_per_messagenumber2Maximum image attachments scanned per message.
scam_detection.context_messagesnumber6Recent messages supplied as context.
scam_detection.cache_ttl_minutesnumber360How long image hash scan results are reused.
scam_detection.review_timeout_minutesnumber30How long review buttons stay active.
scam_detection.actions.delete_messagebooleantrueAllows deleting scam messages.
scam_detection.actions.auto_delete_high_confidencebooleanfalseAllows high-confidence auto-delete while in ask mode.
scam_detection.actions.warnbooleantrueAllows warning users.
scam_detection.actions.timeoutbooleantrueAllows timing out users.
scam_detection.actions.timeout_minutesnumber60Timeout duration for scam actions.
scam_detection.actions.kickbooleanfalseAllows kicks. Keep disabled until reviewed.
scam_detection.actions.banbooleanfalseAllows bans. Keep disabled until reviewed.

Raw images are not stored locally. AIO stores image hashes, attachment URLs, domains, scores, decisions, and short evidence text in AIOScamScanLog.

See Scam Detection for setup steps, provider requirements, and review behavior.

Member Events

OptionTypeDefaultDescription
member_events.enabledbooleanfalseEnables welcome, goodbye, auto-role, and member log features.
member_events.welcome_channel_idstring""Channel for welcome messages.
member_events.welcome_messagestring""Template supporting username, user_mention, server_name, and member_count placeholders.
member_events.welcome_ai_personalizebooleanfalseUses the LLM to generate a short unique welcome.
member_events.welcome_ai_languagestring"English"Language for the AI continuation, such as Dutch or nl-NL. Blank uses English. Translate the prefix separately.
member_events.welcome_ai_prefixstring""Text before the AI continuation. Blank keeps the English greeting. Supports {{username}}, {{user_mention}}, {{server_name}}, and {{member_count}}.
member_events.welcome_mention_modeenum"user"user adds a safe user mention outside the AI text; none sends no mention.
member_events.welcome_delay_secondsnumber0Delay before sending welcome messages.
member_events.welcome_wait_for_any_rolebooleanfalseWait until the member receives any non-@everyone role before welcoming.
member_events.welcome_wait_for_role_idsstring[][]Specific role IDs that can unlock the welcome when any one is found.
member_events.welcome_wait_timeout_secondsnumber60Maximum time to wait for role requirements before skipping the welcome.
member_events.goodbye_channel_idstring""Channel for goodbye messages.
member_events.goodbye_messagestring""Goodbye template.
member_events.auto_rolesstring[][]Role IDs assigned when a member joins.
member_events.log_channel_idstring""Channel for join/leave log embeds. Empty disables logs.

Welcome Language

In v1.4.2, both dashboards expose AI Welcome Language and AI Welcome Prefix under Member Events. Enable AI Personalize Welcome to use them.

For Dutch welcomes, set the language to Dutch and the prefix to Welkom bij {{server_name}}!. The bot adds the member mention, then asks the AI for a short continuation in Dutch. The language setting affects only the AI sentence; it does not translate the prefix or change chat/ticket languages.

With AI Welcome Mention set to No mention, the bot does not add a mention, and a {{user_mention}} placeholder in the prefix becomes the username. Role and everyone mentions cannot notify anyone. If the provider fails or returns no usable text, the bot sends only the configured prefix.

Existing configurations keep the English defaults. For a fixed translated message, disable AI Personalize Welcome and edit Welcome Message instead. See the Dutch setup example.

Anti-Raid

OptionTypeDefaultDescription
anti_raid.enabledbooleanfalseEnables join-burst monitoring.
anti_raid.join_thresholdnumber10Number of joins required to trigger.
anti_raid.join_window_secondsnumber30Time window for the join threshold.
anti_raid.actionenum"alert"alert or lockdown. Lockdown delegates to Athena’s security plugin so its exclusions, snapshots, and recovery flow remain authoritative.
anti_raid.alert_channel_idstring""Channel where anti-raid alerts are sent.

FAQ

FAQ replies are matched before an LLM request. Use FAQ entries for fixed answers such as docs links, pricing links, or server IPs.

OptionTypeDefaultDescription
faq.enabledbooleanfalseEnables fast non-LLM FAQ replies.
faq.entriesarray[]Entries shaped as { triggers: [...], answer: "..." }.

Example:

faq: { enabled: true, entries: [ { triggers: ["docs", "documentation", "where are the docs"], answer: "You can find the docs at https://docs.havendevelopment.net/" } ] }

Prompt Files

Prompt files live under plugins/aio_agent/data/prompts/ unless you provide an absolute path. They are re-read when prompts are built, so reload/restart after editing them if you are unsure which config backend is active.

OptionDefaultDescription
prompt_files.ticket"ticket-system.md"Ticket support system prompt.
prompt_files.owner"owner-system.md"Owner/admin tool-calling prompt.
prompt_files.chat"chat-system.md"General chat prompt.
prompt_files.moderation"moderation-system.md"Moderation JSON decision prompt.
prompt_files.ticket_role_body"ticket-role-body-default.md"Ticket role/persona body when spec flow is enabled.
prompt_files.ticket_role_body_no_spec"ticket-role-body-no-spec.md"Ticket role/persona body without spec flow.
prompt_files.ticket_important_context"ticket-important-context-default.md"Extra ticket context block.
prompt_files.owner_ticket_role_body"owner-ticket-role-default.md"Owner assistant ticket context body.
prompt_files.security_preamble"security-preamble.md"Safety and anti-abuse prompt preamble.

Prompt Variables And Appends

OptionTypeDefaultDescription
prompt_variablesobject{}Custom string placeholders available inside prompt templates.
prompt_append_ticketstring""Text appended to the ticket system prompt.
prompt_append_ownerstring""Text appended to the owner system prompt.
prompt_append_chatstring""Text appended to the chat system prompt.

Built-in prompt variables include:

VariableMeaning
&#123;&#123;brand_name&#125;&#125;Configured brand or server name.
&#123;&#123;owner_display_name&#125;&#125;Configured owner display name.
&#123;&#123;docs_url&#125;&#125;Public docs URL.
&#123;&#123;current_datetime&#125;&#125;Current formatted time.
&#123;&#123;datetime_timezone&#125;&#125;IANA timezone.
&#123;&#123;datetime_timezone_label&#125;&#125;Human-readable timezone label.
&#123;&#123;knowledgebase_block&#125;&#125;Knowledgebase content selected for the current request.

Time And Locale

OptionTypeDefaultDescription
datetime_timezonestring"UTC"IANA timezone used in prompts, such as America/Winnipeg or Europe/London.
datetime_localestring"en-US"Locale used for formatted dates, such as en-US, en-CA, or fr-FR.
datetime_timezone_labelstring"UTC"Human-readable timezone label shown to the model, such as Central Time.

What To Restart Or Reload

ChangeWhat to do
API keys or environment variablesRestart AthenaBot.
Dashboard config valuesSave in dashboard, then restart if the feature does not update live.
Prompt caching settingsSave in dashboard; new LLM requests use the updated settings. Existing Gemini managed caches expire on their configured TTL.
Knowledgebase filesRun /aio reload.
Knowledgebase channels/forumsRun /aio reload; restart if channel permissions changed.
Prompt filesRun /aio reload or restart.
Plugin code or dependenciesRestart AthenaBot.