Architecture¶
This page is a quick tour for developers who want to dive in and extend the bot.
High-Level Flow¶
cli.py
parses flags, loadsConfig
(env) andPersonality
(YAML), then callsdiscord_bot.run
.discord_bot.py
wires Discord events and commands to generation:- Builds conversation context + environment snippets
- Uses OpenAI Responses API (via
openai_client.py
) to generate text - Streams bursts to Discord using
streaming.py
- Tracks costs via
costs.py
and persists state withmemory.py
Modules¶
openai_client.py
: Responses-first helpers_messages_to_responses_payload(messages)
: builds typed items (developer/user/assistant)_build_responses_kwargs(...)
: consistent kwargs for GPT‑5 (reasoning + text.verbosity)chat_complete_with_usage(...)
: returns text and usage; Chat Completions is a fallback when neededstreaming.py
: human-paced streamingstream_deltas(...)
: returns an async iterator of text chunks, immediately (true streaming)send_stream_as_messages(...)
: first burst ASAP, then ~2 lines per burst, with typing indicatorruntime_utils.py
: keepsdiscord_bot.py
lean_build_env_context(...)
,_effective_truncation(...)
,_effective_model_and_params(...)
,_maybe_alert_owner(...)
_chunk_message(...)
: Discord-safe chunking helperlistener.py
: passive listening- Heuristics gate (allow/deny, cooldowns, triggers), optional judge step
mark_intervened(...)
updates cooldowns after an interventionmemory.py
: JSON-backed store- Per-channel
ChannelContext
, per-guild settings, and globalBilling
costs.py
: token pricing and budgetingusd_cost(...)
, daily/monthly rollover, alert thresholdspersonality.py
: dataclasses + YAML loader- Persona drives prompts, environment, streaming pacing, and listen settings
Key Design Choices¶
- Responses API first: typed items and GPT‑5
reasoning
/text.verbosity
when supported. - Safe mentions: user mentions allowed; roles/everyone blocked; strips leading self-mention.
- Streaming UX: avoid edits; burst on boundaries; keep typing indicator; fallback gracefully.
- Separation of concerns: helpers moved to
runtime_utils.py
to keep event loop readable.
Extending¶
- Tools and function-calling: add new helpers in
openai_client.py
and wire them intodiscord_bot.py
. - More commands: define new
@bot.command
functions indiscord_bot.py
(or split into acommands.py
). - Tests: add unit tests under
tests/
— mock OpenAI and Discord objects where needed.