DisgoroQ is a Go Discord bot with AI chat, image-aware context, guild-scoped memory, reengage checks, manual horoscope delivery, scheduled Farting Friday posts, and optional voice chat.
ai.primary_providerlibdave, the STT sidecar, and the TTS serviceconfig.yaml is the source of truth for runtime behavior.config.yaml.Typical interpolated secrets:
DISCORD_TOKENGROQ_API_KEYOPENCODE_API_KEYOPENROUTER_API_KEYDB_URLDB_TOKENStart from config.example.yaml, then review config.yaml for runtime defaults like AI, memory, reengage, and voice.
For AI, ai.primary_provider defaults to groq. Set it to ollama and enable ai.ollama.enabled to run Ollama by default without requiring GROQ_API_KEY, set it to opencode and enable ai.opencode.enabled with OPENCODE_API_KEY to use OpenCode Go's OpenAI-compatible chat/completions endpoint, or set it to openrouter and enable ai.openrouter.enabled with OPENROUTER_API_KEY to use OpenRouter's OpenAI-compatible /api/v1/chat/completions endpoint.
When image attachments are present, DisgoroQ keeps raw attachment refs in chat context. If the selected provider is using the same supported multimodal model for chat and vision, attachments are sent inline to chat; otherwise the bot falls back to a separate vision-to-text description step before chat. Detached image descriptions and document summaries are cached in the database per attachment fingerprint, provider, model, and prompt version so repeated requests do not keep paying the same preprocessing cost.
Each AI provider section also exposes thinking_enabled:
ai.ollama.thinking_enabled maps directly to Ollama's think request flag.ai.groq.thinking_enabled keeps Groq's default reasoning behavior when true and sends a lower/no reasoning effort hint when false for supported models.ai.opencode.thinking_enabled keeps the provider default when true and sends reasoning_effort: none when false on OpenCode chat-completions requests.ai.openrouter.thinking_enabled keeps the provider default when true and sends OpenRouter's normalized reasoning: { effort: "none", exclude: true } when false.DisgoroQ now supports provider-agnostic tool calling for chat models. The built-in tools are:
web_fetch for fetching a known URL and converting its content into markdown-friendly text.web_search for zero-API-cost search through a self-hosted SearXNG instance.Typical bot-side config:
ai:
tools:
enabled: true
max_rounds: 3
max_calls_per_round: 2
max_calls_total: 4
timeout_ms: 10000
web:
enabled: true
search:
enabled: true
provider: "searxng"
base_url: "http://127.0.0.1:8888"
max_results: 5
default_language: "fr"
safe_search: 2
Recommended SearXNG tweaks for this bot:
server.bind_address: "127.0.0.1" when the bot runs on the same host. Keep 0.0.0.0 only if the bot must reach SearXNG from another container or machine.valkey enabled if available. It helps search responsiveness and reduces repeated upstream work.server.limiter: false is acceptable for a private bot-only instance. Turn it on if the instance is exposed beyond your local/private network./search?format=json, and SearXNG defaults to search.formats: [html], which causes 403 FORBIDDEN until json is allowed too:search:
safe_search: 2
formats:
- html
- json
search.safe_search is fine as a backend default, but DisgoroQ also sends its own ai.tools.search.safe_search value on each request. Keep them aligned if you want predictable behavior.server.image_proxy, search.autocomplete, and most UI plugins do not matter for DisgoroQ's JSON search flow.wikipedia, qwant, or startpage.Security note: keep server.secret_key private. If a real secret key was pasted into chat or another public place, rotate it.
make buildmake testgo run .go run . -localairgo run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.30.0 generatevoice in config.yaml.libdave pkg-config path used by the Makefile.voice_enabled settings.discord.dev_guild_ids from config.logger package.SYSTEMS.md.164 commits
1 commits
Go
60.9%
Python
37.9%
DisgoroQ is a Go Discord bot with AI chat, image-aware context, guild-scoped memory, reengage checks, manual horoscope delivery, scheduled Farting Friday posts, and optional voice chat.
ai.primary_providerlibdave, the STT sidecar, and the TTS serviceconfig.yaml is the source of truth for runtime behavior.config.yaml.Typical interpolated secrets:
DISCORD_TOKENGROQ_API_KEYOPENCODE_API_KEYOPENROUTER_API_KEYDB_URLDB_TOKENStart from config.example.yaml, then review config.yaml for runtime defaults like AI, memory, reengage, and voice.
For AI, ai.primary_provider defaults to groq. Set it to ollama and enable ai.ollama.enabled to run Ollama by default without requiring GROQ_API_KEY, set it to opencode and enable ai.opencode.enabled with OPENCODE_API_KEY to use OpenCode Go's OpenAI-compatible chat/completions endpoint, or set it to openrouter and enable ai.openrouter.enabled with OPENROUTER_API_KEY to use OpenRouter's OpenAI-compatible /api/v1/chat/completions endpoint.
When image attachments are present, DisgoroQ keeps raw attachment refs in chat context. If the selected provider is using the same supported multimodal model for chat and vision, attachments are sent inline to chat; otherwise the bot falls back to a separate vision-to-text description step before chat. Detached image descriptions and document summaries are cached in the database per attachment fingerprint, provider, model, and prompt version so repeated requests do not keep paying the same preprocessing cost.
Each AI provider section also exposes thinking_enabled:
ai.ollama.thinking_enabled maps directly to Ollama's think request flag.ai.groq.thinking_enabled keeps Groq's default reasoning behavior when true and sends a lower/no reasoning effort hint when false for supported models.ai.opencode.thinking_enabled keeps the provider default when true and sends reasoning_effort: none when false on OpenCode chat-completions requests.ai.openrouter.thinking_enabled keeps the provider default when true and sends OpenRouter's normalized reasoning: { effort: "none", exclude: true } when false.DisgoroQ now supports provider-agnostic tool calling for chat models. The built-in tools are:
web_fetch for fetching a known URL and converting its content into markdown-friendly text.web_search for zero-API-cost search through a self-hosted SearXNG instance.Typical bot-side config:
ai:
tools:
enabled: true
max_rounds: 3
max_calls_per_round: 2
max_calls_total: 4
timeout_ms: 10000
web:
enabled: true
search:
enabled: true
provider: "searxng"
base_url: "http://127.0.0.1:8888"
max_results: 5
default_language: "fr"
safe_search: 2
Recommended SearXNG tweaks for this bot:
server.bind_address: "127.0.0.1" when the bot runs on the same host. Keep 0.0.0.0 only if the bot must reach SearXNG from another container or machine.valkey enabled if available. It helps search responsiveness and reduces repeated upstream work.server.limiter: false is acceptable for a private bot-only instance. Turn it on if the instance is exposed beyond your local/private network./search?format=json, and SearXNG defaults to search.formats: [html], which causes 403 FORBIDDEN until json is allowed too:search:
safe_search: 2
formats:
- html
- json
search.safe_search is fine as a backend default, but DisgoroQ also sends its own ai.tools.search.safe_search value on each request. Keep them aligned if you want predictable behavior.server.image_proxy, search.autocomplete, and most UI plugins do not matter for DisgoroQ's JSON search flow.wikipedia, qwant, or startpage.Security note: keep server.secret_key private. If a real secret key was pasted into chat or another public place, rotate it.
make buildmake testgo run .go run . -localairgo run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.30.0 generatevoice in config.yaml.libdave pkg-config path used by the Makefile.voice_enabled settings.discord.dev_guild_ids from config.logger package.SYSTEMS.md.164 commits
1 commits
Go
60.9%
Python
37.9%