Skip to content
pieeg-clubPublic

About

A Discord companion for the PiEEG / BCI community.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

26 Commits

Folders and files

Repository files navigation

PiEEG-bot

A Discord companion for the PiEEG / BCI community. It answers questions about PiEEG hardware, software and setup using a lightweight RAG (retrieval-augmented generation) pipeline over the existing PiEEG documentation and website markdown — and always links back to the source pages.

How it works

PiEEG-docs + PiEEG-com  ──git clone──▶  chunk by heading  ──embed──▶  data/index.json
                                                                            │
Discord / REST  ──ask──▶  cosine top-k  ──▶  one LLM call (grounded)  ─────┘

No vector database. The corpus is a few dozen markdown files, so the whole index is a single JSON file loaded into memory and searched with cosine similarity in NumPy. Embeddings are computed locally with fastembed (ONNX on CPU — free, no API key), and answers are generated by Claude Haiku from the retrieved excerpts only. If the docs don't cover a question, the bot says so and points to the community Discord instead of guessing.

Sources indexed (see pieeg_bot/config.py):

  • PiEEG Docs — PiEEG-docs/content → https://pieeg.com/docs/...
  • PiEEG News — PiEEG-com/content/news → https://pieeg.com/news/...

Adding another repo is a one-line entry in SOURCES.

Usage

Requires Python 3.10+ and git on the PATH.

pip install .
cp .env.example .env   # fill in ANTHROPIC_API_KEY and DISCORD_TOKEN

# 1. Build the index (clones the docs repos, embeds locally, writes data/index.json)
#    No API key needed — embeddings run on-device via fastembed.
pieeg-bot ingest

# 2. Try it locally — no Discord required (reads ANTHROPIC_API_KEY from .env)
pieeg-bot ask "How do I attach the electrodes?"   # one-shot
pieeg-bot ask "..." --scores                        # also print retrieval scores
pieeg-bot chat                                       # interactive REPL

# 3. Run the bot on Discord
export ANTHROPIC_API_KEY=sk-ant-...
export DISCORD_TOKEN=...
pieeg-bot run

ask and chat exercise the exact same retrieval + prompt pipeline the Discord bot uses (pieeg_bot/engine.py), so they're the fastest way to sanity-check the index, tune PIEEG_TOP_K / PIEEG_MIN_SCORE, or demo answers without a token. All commands auto-load a local .env, so exporting the variables by hand is optional.

In Discord:

  • /ask <question> — slash command, works anywhere the bot is installed.
  • @PiEEG-bot <question> — mention it in any channel it can read.

REST API

The Fly deployment exposes the same answer engine through POST /ask. The FastAPI server and Discord client run in one process and share one in-memory index, embedding model, and Anthropic client; requests from either transport use the same retrieval and grounding pipeline.

Set a separate API key for applications that call the REST endpoint:

export ANTHROPIC_API_KEY=sk-ant-...
export DISCORD_TOKEN=...
export PIEEG_API_KEY=replace-with-a-long-random-secret
uvicorn pieeg_bot.api:app --host 0.0.0.0 --port 8080

This command starts both the HTTP server and the existing Discord bot. The pieeg-bot run command is still available when only Discord is needed.

Ask a question from another server-side application:

curl -X POST http://localhost:8080/ask \
    -H "Content-Type: application/json" \
    -H "X-API-Key: replace-with-a-long-random-secret" \
    -d '{"question":"How do I attach the electrodes?"}'

The response is structured JSON so clients do not need to parse Discord Markdown:

{
    "answer": "...",
    "grounded": true,
    "sources": [
        {"title": "...", "url": "https://docs.pieeg.com/..."}
    ]
}

GET /health is public for Fly health checks. POST /ask requires the API key in the X-API-Key header. Keep this key on the calling application's server; the endpoint does not enable browser CORS and is not intended to expose a secret from frontend JavaScript.

Configuration

All settings have sensible defaults; override via environment variables (see .env.example):

Variable Default Purpose
ANTHROPIC_API_KEY — (required) Chat answers (Claude)
DISCORD_TOKEN — (required for Discord) Discord bot token
PIEEG_API_KEY — (required for REST) Secret accepted by POST /ask
PIEEG_CHAT_MODEL claude-haiku-4-5 Answer model
PIEEG_MAX_TOKENS 1024 Max answer length
PIEEG_EMBED_MODEL BAAI/bge-small-en-v1.5 Local embedding model (fastembed)
PIEEG_TOP_K 5 Chunks retrieved per question
PIEEG_MIN_SCORE 0.30 Minimum cosine score to keep a chunk

pieeg-bot ingest needs no API key — embeddings are computed locally.

Connect it to Discord

A one-time setup to create the bot account and invite it to your server.

1. Create the application and bot

  1. Go to the Discord Developer Portal and click New Application. Name it PiEEG-bot.
  2. Open the Bot tab → Add Bot.
  3. Under Privileged Gateway Intents, enable Message Content Intent. This is required for the @PiEEG-bot mention trigger; without it only /ask works.
  4. Click Reset Token, copy the token, and put it in your .env as DISCORD_TOKEN. Treat it like a password — never commit it.

2. Invite it to your server

  1. Open OAuth2 → URL Generator.
  2. Under Scopes, tick bot and applications.commands.
  3. Under Bot Permissions, tick Send Messages, Read Message History, and Use Slash Commands.
  4. Copy the generated URL, open it in a browser, pick your server, and Authorize. You need Manage Server permission on that server.

3. Run it

With data/index.json built (pieeg-bot ingest) and .env filled in:

pieeg-bot run

On startup the bot registers its slash commands and connects to the Discord gateway. Give slash commands a minute to propagate the first time, then try /ask what sample rate does the PiEEG board use? or @PiEEG-bot in any channel it can see. To keep it online continuously, deploy to Fly.io (below).

Keeping the index fresh

The nightly GitHub Action rebuilds data/index.json, commits it when it changes, and (optionally) redeploys to Fly.io. Ingestion embeds locally, so no API key secret is required — only FLY_API_TOKEN if you want auto-deploy. You can also trigger it manually via Run workflow.

Deployment (Fly.io)

One always-on 512mb Fly machine runs both the HTTP service and Discord gateway client. The extra headroom is for the fastembed ONNX runtime (see fly.toml). The committed index is baked into the image at build time, and Fly checks the public /health endpoint.

fly launch --no-deploy       # first time only
fly secrets set ANTHROPIC_API_KEY=sk-ant-... DISCORD_TOKEN=... PIEEG_API_KEY=...
fly deploy

The production endpoint is https://pieeg-bot.fly.dev/ask unless the Fly app name or custom domain is changed. Generate PIEEG_API_KEY with a password manager or python -c "import secrets; print(secrets.token_urlsafe(32))" and give it only to applications allowed to consume the API.

Development

pip install -e ".[dev]"   # editable install with pytest + pytest-asyncio
python -m pytest -v

The retrieval tests run offline (local embeddings, no key). The live grounded- answer test in tests/test_pipeline.py calls Claude and runs only when ANTHROPIC_API_KEY is set (loaded from .env automatically); it is skipped otherwise, so CI stays green without secrets.

License

CC BY-NC 4.0 — see LICENSE.

About

A Discord companion for the PiEEG / BCI community.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages