Artwork by Pieter Jordaan
A Discord bot powered by OpenAI. Responds to mentions and replies, threads its own conversations, and exposes tools the model can invoke directly.
- Chat & reasoning via the OpenAI Responses API. Conversation continuity is handled server-side through
previous_response_id; per-conversation ids live in SQLite (conversation_responses). - Image generation via OpenAI
gpt-image-1(or xAIgrok-imagine-image-qualitywhen configured), exposed as a slash command and as thegenerate_imagefunction tool so the model can produce images inline. - Threads: replying to a bot message auto-creates a thread; the bot responds to everything inside threads it owns.
- Per-user memory in SQLite — the model can
remember,recall, andforgetfacts. Capped preference set is injected on every turn. - Tools: weather (Yr.no), Steam store lookups, ad-hoc SQLite querying of the bot's own data, sandboxed
run_bashfor log/source inspection, server-event lookup. - Daily MOTD with AI-generated city artwork; Peapix (Bing image of the day) as a fallback.
- Hot-reloadable config — edit
config/*.mdorconfig/tool-roles.jsonand changes take effect without redeploying.
Discord_jNpyZBfPt2.mp4
git clone https://github.com/fjlaubscher/rooivalk.git
cd rooivalk
pnpm install
cp .env.example .env # fill in credentials
pnpm startKey env vars:
| Variable | Description |
|---|---|
DISCORD_TOKEN / DISCORD_GUILD_ID / DISCORD_APP_ID |
Discord bot credentials |
DISCORD_STARTUP_CHANNEL_ID / DISCORD_MOTD_CHANNEL_ID |
Startup announcement and MOTD post target |
OPENAI_API_KEY + OPENAI_MODEL |
Chat / reasoning credentials and model |
OPENAI_IMAGE_MODEL |
Image generation model |
ROOIVALK_MOTD_CRON |
Cron expression for the daily MOTD (e.g. "0 8 * * *") |
ROOIVALK_DB_PATH |
SQLite path (default ./data/rooivalk.db) |
XAI_API_KEY / XAI_MODEL / XAI_IMAGE_MODEL |
Optional; route chat and/or image generation to xAI Grok via the OpenAI SDK |
STEAM_API_KEY |
Required for the nightly Steam catalogue sync that backs get_game_listing |
Each service has its own AGENTS.md:
src/services/openai— OpenAI chat + image generationsrc/services/xai— xAI Grok chat + image provider (OpenAI-SDK compatible)src/services/chat— provider + channel-routing factories (chat, image, per-channel behaviours)src/services/rooivalk— message processing, tool dispatch, MOTDsrc/services/discord— Discord API integration and thread handlingsrc/services/memory— SQLite-backed memory + conversation-id storesrc/services/yr— Yr.no weathersrc/services/steam— Steam store + nightly app catalogue syncsrc/services/peapix— Bing image-of-the-day fallback for MOTDsrc/services/cron— scheduled jobssrc/config— hot-reloadable markdown config
For architecture and conventions, see AGENTS.md.
config/instructions/openai.mdandconfig/instructions/xai.mdare the live per-provider system prompts. Hot-reloaded.- Placeholders:
{{CURRENT_DATE}}(ISO date),{{EMOJIS}}(server's allowed custom emojis). LOG_LEVEL=debugemits per-request prompt metrics.- Channel-specific behaviours are declared as profiles in
config/profiles.json(copyconfig/profiles.example.json); each profile's instructions live inconfig/profiles/<name>.mdand it may override the model/provider.
.github/workflows/test.yml— Prettier + Vitest on every push/PR tomain..github/workflows/deploy.yml— rsync + PM2 restart onmainafter tests pass. PM2 runs viaecosystem.config.cjsfor timestamped logs and managed restarts.
MIT
Generated by @rooivalk.

