Skip to main content

A Discord chatbot that emulates the tone and typing style of provided example messages.

Project description

Faithful

Faithful is a Discord bot that reads example messages and mimics the author's tone and typing style. It responds when mentioned or replied to, and can optionally post on its own.

Features

  • Swappable backends:
    Backend Description Requirements
    openai-compatible Any OpenAI-compatible API via Chat Completions. (default) base_url (API key optional)
    openai OpenAI API key
    gemini Google Gemini API key
    anthropic Anthropic Claude API key
  • Web search: optionally searches the web for current information.
  • Memory: optionally remembers facts about users and channels across conversations
  • Reactions: optionally reacts to messages with emojis including custom ones
  • Random posts: optionally sends a few messages per day into a configured channel
  • Random replies: optionally replies to any message in configured channels

Prerequisites

  • A Discord bot with the Message Content privileged intent enabled
  • A LLM provider of your choice

Quick Start

pip install "faithful[all]"     # core plus all three backend SDKs
faithful                        # run the interactive setup wizard
faithful run                    # start the bot

The wizard writes ~/.faithful/config.toml. Run faithful doctor any time to check connectivity, or faithful info to see where things live.

If you want a slimmer install, the per-backend extras are [openai], [gemini], and [anthropic]. The OpenAI-compatible backend uses the openai package as well. Override paths with --config <path>, --data-dir <path>, or set FAITHFUL_HOME=/some/dir.

Commands

All commands are slash commands and only usable by users listed in admin_ids.

Command Description
/upload Upload a .txt file of example messages
/add_message <text> Add a single example message
/list_messages [page] View stored messages (paginated)
/remove_message <index> Remove a message by its index
/clear_messages Remove all example messages
/download_messages Download all messages as a .txt file
/generate_test <prompt> Manually trigger a response test
/status Show detailed configuration status
/memory list <target> [user] List memories for a user or channel
/memory add <target> <text> [user] Add a memory for a user or channel
/memory remove <target> <index> [user] Remove a memory by index
/memory clear <target> [user] Clear all memories for a user or channel

You can also right-click any message and use the Add to Persona context menu to add it directly as an example.

How It Works

The bot responds when pinged or in chat, ignoring replies to messages older than 5 minutes (configurable). The bot can react to messages with emoji, including server custom emoji. Reactions happen in two ways: If channels is configured under [scheduler], the bot sends messages at random intervals into one of those channels.

Example Messages Format

Create a .txt file with one message per line:

lol yeah thats what i was thinking
bruh no way
ok but have u considered... maybe not doing that

Upload via /upload or add individually with /add_message.

Configuration

The bot is configured via ~/.faithful/config.toml. The repo's config.example.toml documents every setting. Environment variables override their TOML equivalents:

Variable Overrides
DISCORD_TOKEN discord.token
ADMIN_USER_IDS (comma-separated) discord.admin_ids
API_KEY backend.api_key

[discord]

Key Description Default
token Your Discord bot token (Required)
admin_ids List of Discord user IDs who can manage the bot (Required)

[backend]

Key Description Default
active Backend to use: openai, openai-compatible, gemini, anthropic openai-compatible
api_key API key for the active LLM backend
model Model name for the active LLM backend (per-backend default)
base_url Endpoint URL, required for openai-compatible (e.g. http://localhost:11434/v1 for Ollama)

[llm]

Key Description Default
temperature Controls randomness (0.0-2.0) 1.0
max_tokens Maximum tokens per response 16000
sample_size Example messages to include in the system prompt 300

[behavior]

Key Description Default
persona_name The persona name used in system prompts faithful
reply_probability Chance of random unsolicited reply (0.0-1.0) 0.02
reaction_probability Chance of reacting to a message without replying (0.0-1.0) 0.05
debounce_delay Seconds to wait for multi-message bursts 3.0
conversation_expiry Seconds before a thread is considered stale 300.0
max_context_messages Number of previous messages to include 20
max_session_messages Per-channel session history window 50
enable_web_search Allow the LLM to search the web false
enable_memory Enable per-user and per-channel memory false
system_prompt Custom system prompt template ({name}, {examples}, {custom_emojis} placeholders) (built-in)

[scheduler]

Key Description Default
channels Channel IDs for unprompted messages []
min_hours Minimum hours between spontaneous messages 12
max_hours Maximum hours between spontaneous messages 24

Project Structure

faithful/
├── pyproject.toml              # dependencies and project metadata
├── config.example.toml         # reference config for hand-editors
├── README.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE
└── faithful/                   # main package
    ├── cli.py                  # argparse entry point and verb dispatch
    ├── verbs.py                # `info` and `run` verbs
    ├── wizard.py               # interactive setup wizard
    ├── doctor.py               # connectivity self-check
    ├── bot.py                  # Discord bot class
    ├── config.py               # TOML config loader (read-only at runtime)
    ├── paths.py                # config and data directory resolution
    ├── errors.py               # friendly user-facing exceptions
    ├── store.py                # example message storage
    ├── prompt.py               # prompt assembly and custom emoji
    ├── chunker.py              # message chunking, typing delays, reaction parsing
    ├── tools/                  # tool definitions and executors
    │   ├── definitions.py      # provider-agnostic tool schemas
    │   ├── executor.py         # dispatch (web search, web fetch, memory)
    │   └── memory.py           # MemoryExecutor for the file-based memory tool
    ├── backends/               # text-generation backends
    │   ├── base.py             # Backend ABC, GenerationRequest, session history, tool loop
    │   ├── openai.py           # OpenAI Responses API
    │   ├── openai_compat.py    # OpenAI-compatible Chat Completions API
    │   ├── gemini.py           # Google Gemini
    │   └── anthropic.py        # Anthropic Claude
    └── cogs/                   # Discord command and event modules
        ├── admin.py            # admin slash commands and memory management
        ├── chat.py             # message handling, responses, reactions
        ├── onboarding.py       # welcome DM and `/help`
        └── scheduler.py        # spontaneous message scheduler

License

AGPL-3.0-or-later. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

faithful-1.0.1.tar.gz (66.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

faithful-1.0.1-py3-none-any.whl (63.6 kB view details)

Uploaded Python 3

File details

Details for the file faithful-1.0.1.tar.gz.

File metadata

  • Download URL: faithful-1.0.1.tar.gz
  • Upload date:
  • Size: 66.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for faithful-1.0.1.tar.gz
Algorithm Hash digest
SHA256 ead64147e77126ea9a6fa13a986e13d7e0796b263b56d47d1db94fb551bc9164
MD5 6262c0a183647e2f25e95e8f1db8ba58
BLAKE2b-256 24ffadab11dffe74c5b9885b8fb715668848199ee0ed4605c48d5a63636c681b

See more details on using hashes here.

Provenance

The following attestation bundles were made for faithful-1.0.1.tar.gz:

Publisher: release.yml on a9lim/faithful

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file faithful-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: faithful-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 63.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for faithful-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ffb5e39a333a72fd52210f3fa35482c5109ea796eb64035d81341d73226383f1
MD5 90a27375ae6101c722b39fd8271ea872
BLAKE2b-256 85ac11b701e00947fb77271abb2e17fffbdec88fcc9bfbb7baabae70c56782dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for faithful-1.0.1-py3-none-any.whl:

Publisher: release.yml on a9lim/faithful

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page