Skip to main content

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

Project description

Faithful

CI PyPI Downloads License: AGPL v3 Python 3.10+

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.2.tar.gz (67.0 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.2-py3-none-any.whl (63.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: faithful-1.0.2.tar.gz
  • Upload date:
  • Size: 67.0 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.2.tar.gz
Algorithm Hash digest
SHA256 3114b1fa2acbcfba4ae4756da95d41ac73ae277fa18309f7b61c74d1fbea1a36
MD5 79b8ffda2759386d52515747a53856fb
BLAKE2b-256 eeaff2a6f43d519f4ccf8f326f8c918f6a6b1e94a72222ee282363caeebe032d

See more details on using hashes here.

Provenance

The following attestation bundles were made for faithful-1.0.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: faithful-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 63.7 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 97a9c736ee6f387c1d913e90412abc057292743d7fd765e4fe7abe70b44b314b
MD5 9a799f235809746e9f603a377af4e621
BLAKE2b-256 bf5bddf235631417b2f4b2c42cc55b9a2781d6724576bece6ef3b9f78eedae90

See more details on using hashes here.

Provenance

The following attestation bundles were made for faithful-1.0.2-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