3.4 KiB
3.4 KiB
AGENTS.md
Single Python package vibe_bot: a Discord bot (discord.py, ! prefix) with SQLite RAG chat history, Kokoro TTS, and image gen/edit via OpenAI-compatible APIs. Python 3.13, managed with uv. Everything lives in vibe_bot/.
Commands
- Setup:
uv sync --extra dev— plainuv syncalready installs thedevdependency group (ruff, pyright); thedevextra adds black/debugpy/mypy - Run bot:
uv run python -m vibe_bot.main— this logs the real bot into Discord with the token from.env; don't run it as a smoke test - Tests:
uv run pytest vibe_bot/tests/ -v; single test:uv run pytest vibe_bot/tests/test_main.py::test_name - Checks:
uv run ruff check vibe_bot/,uv run mypy vibe_bot/(strict),uv run pyright vibe_bot/(strict),uv run black --check vibe_bot/ - Container:
./build.sh(podman). CI (.gitea/workflows/build-push.yml, Gitea) only builds/pushes the image on main/release — lint and tests are not gated; run them locally
Setup requirements
- A repo-root
.envis required even to run tests:config.pycallsload_dotenv()and raisesRuntimeErrorat import time if any required var is missing. Placeholder values suffice for the mocked suite. Never commit it. - PortAudio is a required system library (kokoro-tts → sounddevice). Without it, ~60 tests in
test_main/test_ttserror at import time. On this host:sudo dnf install portaudio(the Containerfile installsportaudio19-dev). - TTS needs
kokoro-v1.0.onnxandvoices-v1.0.binin the repo root (baked into the container image). The bot runs without them; only!speakdegrades.
Test suite gotchas
- Baseline: everything passes except
test_llama_wrapper.py::test_chat_completion_thinkand::test_chat_completion_instruct. Those two are unmocked live calls to the realCHAT_ENDPOINTfrom.envand fail without network access to that API. test_config.pyhardcodessys.path.insert(0, "/var/home/ducoterra/Projects/vibe_discord_bots")(a stale repo path). The test only passes because pytest's cwd fallback finds the package — run tests from the repo root.- If
uv run <tool>suddenly fails withModuleNotFoundErroror "bad interpreter", the.venvshebangs are stale from a repo move:rm -rf .venv && uv sync --extra dev.
Code map
main.py— entrypoint. The bot is created at module import (module-levelcommands.Bot(...)),bot.run()only under__main__. Custom-bot "commands" (!<bot_name> ...) are matched inon_messageagainst the database, not registered withbot.command.config.py— env loading + import-time validation, voice catalog.database.py—ChatDatabase(embeddings stored as float32 blobs, cosine-similarity RAG, schema auto-migrates on startup) andCustomBotManager.llama_wrapper.py— thin OpenAI-compatible clients for chat / image gen / image edit / embeddings, each with its own endpoint, key, and model.tools.py—get_channel_membersis a no-op LangChain@toolstub used only for name/description/schema; the real implementation isget_channel_members_impl(channel), wired into the tool executor inmain.py.
Style
- All four checks (ruff, mypy strict, pyright strict, black) are declared gates and currently pass; keep new code clean under all of them.
- ruff is a dev dependency (installed via
uv add --dev) with config inpyproject.toml; it runs with the default ruleset of the locked version.