Skip to content

jthingelstad/elixir-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

632 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Elixir Bot

Elixir is an LLM-powered Discord bot for the POAP KINGS Clash Royale clan (#J2RGCRVG).

It is not a generic chat bot and not a single-feed narrator. Elixir is a channel-native clan agent with:

  • Discord channel lanes like river-race, clan-events, leader-lounge, and ask-elixir
  • executable agents/workflows for awareness, conversation, clanops, memory synthesis, content, and specialist tasks
  • a central recurring activity registry for scheduled work
  • scoped memory for public vs leadership context
  • GitHub-backed publishing for poapkings.com

AGENTS.md is the repository source of truth for architecture and operating notes. This README is the best high-level introduction to the project.

Useful companion docs:

What Elixir Does

Elixir currently handles four main kinds of work:

  1. Discord conversation Elixir answers questions in the right channel with the right lane behavior. #ask-elixir is open conversation and screenshot help, #clan-chat is mention-driven, and #leaders is private clan operations.

  2. Signal-driven clan updates Elixir detects roster, war, and progression signals, then fans one source event into one or more destination-specific outcomes. A new member join can become:

    • a public welcome in #clan-events
    • a factual leadership note in #leaders
  3. Scheduled recurring activities Elixir runs recurring activities like the v5-reactive-tick proactive heartbeat, war-poll, player-progression, weekly-recap, promotion-content, and the daily #ask-elixir hidden-fact post.

  4. POAP KINGS website publishing Elixir generates and publishes structured data for poapkings.com, pushes it to GitHub, and reports publish outcomes in #website-updates.

Current Channel Model

Elixir uses channel lanes instead of one overloaded public stream. A lane is a Discord destination contract: channel id, audience, allowed topics, reply policy, memory scope, and voice. Lanes are not independent agents; they are the rooms where one Elixir speaks.

Primary public/proactive lanes:

  • #river-race for River Race scoreboards, recaps, and meaningful war momentum
  • #player-highlights for curated player milestones and non-war battle pushes
  • #clan-events for joins, promotions, anniversaries, and clan recognitions
  • #announcements for the weekly recap and important clan-wide Elixir updates
  • #recruiting for recruiting copy members can reuse
  • #website-updates for website publish visibility

Primary interactive lanes:

  • #ask-elixir for open conversation with Elixir
  • #clan-chat for mention-driven general questions
  • #welcome for onboarding and identity verification
  • #leaders for leadership and clan operations

The live channel contract lives in prompts/DISCORD.md.

Recurring Activities

Recurring automated work is defined in runtime/activities.py. This is the canonical schedule registry.

See runtime/activities.py for the exact keys, schedules, and enabled state. The shape today:

  • v5-reactive-tick The proactive heartbeat. Runs the Event Core engine (ingest → detections → recommendations/cases → communication intents → confirmed Discord delivery). This replaced the old clan-awareness / war-awareness ticks.
  • war-poll Hourly live war ingest + River Race snapshot pipeline.
  • player-progression Refreshes player profiles and battle logs, then emits curated member highlights.
  • daily-clan-insight Daily #ask-elixir hidden fact when the data supports a genuinely interesting insight.
  • weekly-recap Weekly public recap in #announcements, plus members-page sync for the website.
  • promotion-content Weekly recruiting content for #recruiting and the website.
  • Plus api-sentinel, card-catalog-sync, award-detection, weekly-discord-invite-relay, memory-synthesis, clan-wars-intel, and db-maintenance.

Quick Start

python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Create a .env file with the required secrets:

DISCORD_TOKEN=your_discord_bot_token
CLAUDE_API_KEY=your_anthropic_api_key
CR_API_KEY=your_clash_royale_api_key
ELIXIR_LOG_WEBHOOK_URL=optional_discord_webhook_url_for_elixir_log

Start the bot locally:

venv/bin/python elixir.py

See SETUP.md for production setup, launchd, optional site publishing config, and operational guidance.

Running Tests

venv/bin/python -m pytest tests/ -v

Tests use in-memory SQLite and mocked external services. No API keys are needed for the test suite.

Project Structure

Core entrypoints:

  • elixir.py Main bot runtime entrypoint.
  • elixir_agent.py Stable public LLM entrypoint for replies, updates, and site generation.
  • heartbeat.py API-driven signal detection for clan, war, and progression events.
  • cr_api.py Clash Royale API client.

Prompt and behavior stack:

Runtime architecture:

Persistence and intelligence:

  • db/ SQLite schema and query helpers.
  • storage/ Identity, memory, analytics, and message persistence.
  • agent/ LLM prompt composition, workflow contracts, tool policy, and chat loop.

Modules:

Prompt Model

Principle: prompts define what Elixir says and why. Code defines when, where, and how.

The current prompt stack is:

  • SOUL.md Who Elixir is.
  • PURPOSE.md What Elixir is for.
  • GAME.md Stable Clash Royale knowledge.
  • CLAN.md POAP KINGS-specific reality.
  • DISCORD.md Server and channel contract.
  • lanes/*.md Destination-lane behavior.
  • agents/*.md Workflow/agent instructions that are not tied to one Discord channel.

This split matters. It keeps one consistent Elixir identity across very different channels without collapsing everything into one noisy system prompt.

Memory Model

Elixir uses two memory layers.

Conversational memory:

  • user, member, and channel conversation state
  • recent channel history
  • message summaries and episodes

Durable scoped memory:

  • public
  • leadership
  • system_internal

Important rules:

  • public lanes only read public durable memory
  • leader-lounge can read public plus leadership durable memory
  • reception should stay focused on onboarding context
  • multi-outcome signals share a source identity, but public and leadership durable memories stay separated so private copy cannot overwrite public memory

POAP KINGS Website Integration

Elixir owns the dynamic site data written to poapkings.com:

  • elixirClan.json
  • elixirRoster.json
  • elixirHome.json
  • elixirMembers.json
  • elixirPromote.json

GitHub-backed site publishing lives in modules/poap_kings/site.py.

When a real publish happens, Elixir reports it in #website-updates with:

  • success or failure
  • commit SHA
  • direct GitHub commit URL
  • repo and branch
  • changed content types when useful

No-change publishes stay quiet.

Admin and Operations

Elixir's operator commands live in Discord #leaders; routine runtime notices go to #elixir-log when ELIXIR_LOG_WEBHOOK_URL is configured.

Use slash commands under /elixir ....

Examples:

/elixir system status
/elixir activity show activity:v5-reactive-tick
/elixir integration publish integration:poap-kings target:data preview:true
/elixir member set member:Ditika field:join-date value:2026-03-07
/elixir signal show view:recent limit:5

The command model is object-first and grouped around:

  • system
  • clan
  • member
  • memory
  • signal
  • activity
  • integration

Useful operational docs:

  • SETUP.md Installation, launchd, deploy/update flow, and logs.
  • AGENTS.md Deeper architecture and repository conventions.

Reviewing Prompt Failures

Elixir stores failed or unusable Discord prompt attempts in the local prompt_failures table.

Review the latest failures with:

venv/bin/python scripts/review_agent_feedback.py --limit 20
venv/bin/python scripts/review_agent_feedback.py --workflow clanops --json

Use --json when you want to hand the failure set to another model for diagnosis.

Cleanup

venv/bin/python scripts/clean.py
venv/bin/python scripts/clean.py --db

Default cleanup removes caches like __pycache__ and .pytest_cache.

--db also removes local runtime files like elixir.db and elixir.pid.

Portability

The project is designed so a new clan can fork it and mostly rewrite:

The shared Elixir identity in SOUL.md, PURPOSE.md, and the game knowledge in GAME.md should remain broadly portable.

About

LLM-powered, channel-native Discord agent for the POAP KINGS Clash Royale clan — event-sourced reactive engine, scoped public/leadership memory, and GitHub-backed poapkings.com publishing.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors