Skip to main content

Clanker9000

SDK-first Discord bot with chat, voice pipeline, shitposts, and a standalone CLI.

Clanker9000 separates a reusable SDK (clanker) from its Discord host (clanker_bot). Build multi-personality bots with LLM chat, voice transcription, TTS output, and meme generation — all with pluggable provider abstractions. Use the SDK standalone via the CLI without any Discord infrastructure.

Features

  • Multi-Persona Support - YAML-configured bot personalities with custom system prompts and voice settings
  • Voice Pipeline - Real-time voice activity detection (Silero VAD), chunking, idle flush, and speech-to-text
  • Voice Resilience - Keepalive packets, automatic reconnection, and actor-based voice management
  • CLI Interface - Chat, speak, transcribe, and generate memes from the command line
  • Provider Architecture - Pluggable adapters for LLM (OpenAI, Anthropic), STT (Whisper), TTS (ElevenLabs), and image generation (Memegen)
  • Shitpost Generator - Context-aware meme generation with ephemeral preview/post/regenerate workflow
  • VC Monitoring - Auto-leave when alone, nudge-to-join when humans gather
  • Feedback Persistence - Track user interactions (accepted/rejected/regenerated) with SQLite via sqlc
  • Structured Logging - File-based rotation, JSON format, voice-specific log levels

Discord Commands

Command Description
/chat <prompt> Chat with Clanker
/speak <prompt> Chat with TTS audio response
/shitpost [n] [guidance] Generate meme previews with Post/Regenerate/Dismiss buttons
/join Join your voice channel for transcription
/leave Leave the current voice channel
/transcript Show recent voice transcripts (ephemeral)

CLI Commands

clanker chat "What is the meaning of life?"    # Chat with the LLM
clanker speak "Hello world" -o hello.mp3       # Generate TTS audio
clanker transcribe audio.wav                   # Transcribe audio file
clanker shitpost --guidance "programming"       # Generate a shitpost
clanker meme --guidance "cats"                  # Generate a meme image
clanker config show                            # Show active configuration

Use --config path/to/config.yaml and --persona <id> to control persona selection.

Installation

Prerequisites

  • Python 3.12+
  • uv package manager

Install from GitHub

# Install the CLI tool (lightweight — SDK + CLI only)
uv tool install git+https://github.com/safurrier/clanker.git

# Install as a library
uv pip install git+https://github.com/safurrier/clanker.git

# Install with Discord bot support
uv pip install "clanker9000[bot] @ git+https://github.com/safurrier/clanker.git"

# Install with everything (bot + voice)
uv pip install "clanker9000[bot,voice] @ git+https://github.com/safurrier/clanker.git"

Local Development Setup

# Install all dependencies (including bot, voice, dev)
make setup

# Run quality checks
make check

Environment Variables

# Required for LLM and STT (when using OpenAI provider)
export OPENAI_API_KEY="sk-..."

# Required for LLM (when using Anthropic provider)
export ANTHROPIC_API_KEY="sk-ant-..."

# Required for Discord bot
export DISCORD_TOKEN="..."

# Required for TTS
export ELEVENLABS_API_KEY="..."

# Optional
export CLANKER_CONFIG_PATH="./config.yaml"   # Custom config path
export VOICE_DEBUG=1                          # Enable voice debug capture
export VOICE_DEBUG_DIR="./voice_debug"        # Debug output directory
export LOG_DIR="./logs"                       # Enable file logging (JSON, rotated)
export LOG_LEVEL="INFO"                       # Base log level
export VOICE_LOG_LEVEL="INFO"                 # Voice-specific log level
export DATABASE_URL="sqlite:///data/clanker.db"  # Database path
export USE_VOICE_ACTOR=1                      # Enable actor-based voice management

Quick Start

SDK Usage

from clanker.models import Context, Message, Persona
from clanker.providers.openai.llm import OpenAILLM
from clanker.respond import respond

# Create a persona
persona = Persona(
    id="assistant",
    display_name="Helper",
    system_prompt="You are a helpful assistant.",
)

# Build context
context = Context(
    request_id="req-001",
    user_id=0,
    guild_id=None,
    channel_id=0,
    persona=persona,
    messages=[Message(role="user", content="Hello!")],
    metadata={},
)

# Generate response
llm = OpenAILLM(api_key="sk-...")
response, audio = await respond(context, llm=llm)
print(response.content)

Voice Transcription

from clanker.providers.openai.stt import OpenAISTT

stt = OpenAISTT(api_key="sk-...")

with open("audio.wav", "rb") as f:
    audio_bytes = f.read()

transcript = await stt.transcribe(audio_bytes)
print(transcript)

Run the Discord Bot

Requires the [bot] extra (included by make setup):

make run

# Or directly:
python -m clanker_bot.main

# With custom config:
CLANKER_CONFIG_PATH=./my-config.yaml make run

Configuration

Create a config.yaml file:

providers:
  llm: openai    # or: anthropic
  stt: openai
  tts: elevenlabs
  image: memegen

personas:
  - id: clanker
    display_name: Clanker9000
    system_prompt: |
      You are Clanker9000, a witty and slightly sarcastic Discord bot.
      Keep responses concise and entertaining.
    tts_voice: "Rachel"

  - id: helper
    display_name: Helper Bot
    system_prompt: |
      You are a helpful assistant. Be clear and informative.
    tts_voice: "Alice"

default_persona: clanker

Project Structure

src/
  clanker/                  # Core SDK (no Discord dependencies)
    config/                 # Configuration loading (YAML)
    providers/              # Pluggable provider adapters
      openai/               # LLM (GPT) and STT (Whisper)
      anthropic/            # LLM (Claude)
      elevenlabs/           # TTS
      memegen/              # Meme image generation
      audio_utils.py        # Stereo-to-mono, resampling
      base.py               # Protocol definitions (LLM, STT, TTS, ImageGen)
      factory.py            # Provider construction with lazy env-var resolution
    shitposts/              # Template-based meme content generation
    voice/                  # Voice processing pipeline
      vad.py                # Voice activity detection (Silero/Energy)
      chunker.py            # Audio chunking with idle flush
      formats.py            # AudioFormat abstraction
      worker.py             # Transcription orchestration
      debug/                # Debug capture system
    models.py               # Domain models (Context, Persona, Message)
    respond.py              # Core response orchestration

  clanker_cli/              # Click-based CLI (consumes SDK)
    commands/               # chat, speak, transcribe, shitpost, meme, config
    main.py                 # CLI entry point and shared context

  clanker_bot/              # Discord bot host
    command_handlers/       # /chat, /speak, /shitpost, /join, /leave, etc.
    cogs/                   # Discord cogs (vc_monitor)
    persistence/            # Feedback persistence (sqlc-gen-python + SQLite)
    views/                  # Discord UI views (shitpost preview)
    voice_actor.py          # Actor-based voice management
    voice_ingest.py         # Voice receive integration
    voice_resilience.py     # Keepalive and reconnection
    logging_config.py       # Structured logging setup
    commands.py             # Slash command registration
    health.py               # Health endpoint
    main.py                 # Bot entry point

tests/                      # Test suite
  cli/                      # CLI command tests (CliRunner + fakes)
  network/                  # Integration tests (require API keys)
  test_*.py                 # Unit tests

Development

make check    # Run all checks (lint, format, test, typecheck)
make test     # Run tests (excludes network tests)
make lint     # Ruff linting with auto-fix
make format   # Ruff formatting
make ty       # Type checking with ty
make setup    # Install all dependencies with uv
make run      # Run the Discord bot

Voice Support

Voice features require additional dependencies:

uv pip install -e ".[voice]"

Two VAD implementations are available:

Implementation Accuracy Dependencies Size
SileroVAD (default) High (ML-based) torch, numpy ~500MB
EnergyVAD (fallback) Moderate (RMS) Built-in Minimal

Docker

See docker/README.md for full documentation.

docker-compose up -d

Documentation

Detailed guides in agent_docs/:

  • Architecture - System design, data flows, design decisions
  • Testing - Testing strategy, fixtures, fakes, markers
  • Voice Pipeline - End-to-end voice processing and debugging
  • Providers - Provider system and adding new providers

Additional docs in docs/:

License

MIT License - see LICENSE file for details.

Release files for clanker9000 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for clanker9000 0.3.0
File Size Uploaded
clanker9000-0.3.0.tar.gz 2.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for clanker9000 0.3.0
File Interpreter ABI Platform
clanker9000-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.5 MB

Release files / clanker9000-0.3.0.tar.gz

Download URL clanker9000-0.3.0.tar.gz
Size 2.3 MB
Tags Source
SHA-256 checksum
How to use checksums
64b56d6acc3d75612f2eb0233832b4bd790bd7c3e91371ab23cd5a125f3ea8f4
BLAKE2b-256 checksum
How to use checksums
6035cf48a0816b654d8b3df8700c0fc5cdda4aa0f30c6cb0fd30af83cf196b39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 1, 2026.

Transparency log

Release files / clanker9000-0.3.0-py3-none-any.whl

Download URL clanker9000-0.3.0-py3-none-any.whl
Size 190.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
92a605ee4ef0fd0dc49c3fa6488ba81ff19ce483b5a81fec1f4bdb19a3eb761b
BLAKE2b-256 checksum
How to use checksums
8848b802e4052ace928769f0386cd85ee0eac3162ae7c0e3c67b6edb05c3d940
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page