A discord bot for Vane
  • TypeScript 100%
Find a file
2026-06-23 22:46:19 +02:00
src fix: follow ups are not replies 2026-06-23 22:46:19 +02:00
.env.example Initial commit 2026-06-23 22:40:32 +02:00
.gitignore Initial commit 2026-06-23 22:40:32 +02:00
package-lock.json Initial commit 2026-06-23 22:40:32 +02:00
package.json Initial commit 2026-06-23 22:40:32 +02:00
README.md Initial commit 2026-06-23 22:40:32 +02:00
tsconfig.json Initial commit 2026-06-23 22:40:32 +02:00

vane-discord 🔍🤖

A Discord companion bot for Vane. Run /vane, type a question, optionally pick a mode (speed / balanced / quality), and the bot replies — pinging you — with a cited answer when Vane is done.

It talks to Vane purely over its public HTTP API (POST /api/search). Vane itself is never modified.

How it works

/vane  question: how do magnets work   mode: [quality ▾]
   ↓
bot defers ("Vane is thinking…")        ← acks instantly, 15-min window
   ↓  POST {VANE_API_URL}/api/search  (optimizationMode = quality, stream:false)
   ↓
@you 🔍 **how do magnets work** · _quality_
Magnets work because of aligned electron spins… [1](https://…) [2](https://…)

**Sources**
1. [Title of source one](https://…)
2. [Title of source two](https://…)
  • Models & sources are gated in .env — users only choose the mode.
  • Citations like [1] are rewritten to markdown links [1](url).
  • Answers over Discord's 2000-char limit are split across follow-up messages.

Prerequisites

  • Node.js ≥ 20 (tested on 24)
  • A running Vane instance reachable from this bot (default http://localhost:3000)
  • A Discord application + bot token

Setup

1. Create the Discord bot

  1. Go to https://discord.com/developers/applicationsNew Application.
  2. Bot tab → Reset Token → copy it → DISCORD_TOKEN. (No privileged intents needed — slash commands don't require Message Content.)
  3. General Information → copy Application IDDISCORD_CLIENT_ID.
  4. Invite the bot: OAuth2 → URL Generator, scopes bot + applications.commands, then open the generated URL and add it to your server.

2. Find your Vane model IDs

The bot needs a chat model and an embedding model. List what your Vane instance has configured:

curl http://localhost:3000/api/providers

Take a provider id (a UUID) and a model key (use the key, not the display name) for both a chat model and an embedding model.

3. Configure

cp .env.example .env
# then fill in DISCORD_TOKEN, DISCORD_CLIENT_ID, and the VANE_* model values

Set DISCORD_GUILD_ID to your server's ID while testing — guild commands appear instantly; global commands can take up to ~1 hour the first time.

4. Install & run

npm install
npm start        # or: npm run dev   (auto-restarts on file changes)

On startup the bot registers the /vane command and logs in.

Usage

In any channel the bot can see:

/vane question:<your question> [mode:speed|balanced|quality]

If you omit mode, it uses VANE_DEFAULT_MODE from your .env.

Configuration reference

Variable Required Default Notes
DISCORD_TOKEN Bot token
DISCORD_CLIENT_ID Application ID
DISCORD_GUILD_ID Set for instant command registration in one server
VANE_API_URL http://localhost:3000 Base URL of Vane
VANE_CHAT_PROVIDER_ID Provider UUID from /api/providers
VANE_CHAT_MODEL_KEY Chat model key
VANE_EMBEDDING_PROVIDER_ID Provider UUID from /api/providers
VANE_EMBEDDING_MODEL_KEY Embedding model key
VANE_SOURCES web Comma list: web, academic, discussions
VANE_DEFAULT_MODE balanced Used when the user omits mode
VANE_SYSTEM_INSTRUCTIONS Extra guidance sent on every query
VANE_TIMEOUT_MS 600000 Abort a search after this long (Discord cap is 900000)
VANE_APPEND_SOURCES true Append a numbered Sources list

Notes & limits

  • 15-minute ceiling. After deferring, Discord allows follow-ups for 15 minutes. Keep VANE_TIMEOUT_MS900000. A very long quality run could exceed this; if you hit it often, switch the client to streaming and edit the reply incrementally (the API supports stream: true).
  • No auth on Vane's API. Run the bot on the same host/LAN as Vane, or put Vane behind a reverse proxy — don't expose port 3000 publicly.
  • One question per command; conversation history isn't threaded (the API supports it via history if you want to add it later).