Developer Guide
This page documents the technical workings of Aureli — the gentle courier of calm. Though his voice is poetic, his code is practical.
Project Layout
src/aureli/
agent.py # posting loop, CLI
config.py # loads settings & API keys
content.py # generates posts & replies
replies.py # templates for mentions
heavendex.py # contract witness logic
logger.py # logging with loguru
scheduler.py # interval handling
data/
seed_posts.yaml # ritual posts & replies
docs/
... # GitBook pages
.github/workflows/
bot.yml # posting schedule
docs.yml # docs deployment
Environment Configuration
Aureli requires API keys for X (Twitter). To preserve aesthetics and safety, keys are censored in examples.
.env.example
TWITTER_API_KEY=●●●●-●●●●-●●●●-●●●●-●●●●●●●●●●●●
TWITTER_API_SECRET=●●●●-●●●●●●●●-●●●●●●●●-●●●●●●●●
TWITTER_ACCESS_TOKEN=●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
TWITTER_ACCESS_SECRET=●●●●●●●●●●●●●●●●●●●●●●●●●●●●
BOT_DISPLAY_NAME=Aureli
BOT_HANDLE=heyAureli
TIMEZONE=UTC
POST_INTERVAL_HOURS=6
HEAVENDEX_URL=https://heavendex.xyz
config.py
loads them into a dataclass:
from dataclasses import dataclass
import os
@dataclass(frozen=True)
class Settings:
twitter_api_key: str
twitter_api_secret: str
twitter_access_token: str
twitter_access_secret: str
bot_display_name: str
bot_handle: str
timezone: str
heavendex_url: str | None
post_interval_hours: int
def load_settings() -> Settings:
return Settings(
twitter_api_key=os.getenv("TWITTER_API_KEY", "●●●●-..."),
twitter_api_secret=os.getenv("TWITTER_API_SECRET", "●●●●-..."),
twitter_access_token=os.getenv("TWITTER_ACCESS_TOKEN", "●●●●..."),
twitter_access_secret=os.getenv("TWITTER_ACCESS_SECRET", "●●●●..."),
bot_display_name=os.getenv("BOT_DISPLAY_NAME", "Aureli"),
bot_handle=os.getenv("BOT_HANDLE", "heyAureli"),
timezone=os.getenv("TIMEZONE", "UTC"),
heavendex_url=os.getenv("HEAVENDEX_URL"),
post_interval_hours=int(os.getenv("POST_INTERVAL_HOURS", "6")),
)
Running Aureli
Single post (test):
python -m aureli.agent --once
Continuous mode (every 6 hours by default):
python -m aureli.agent
Reply to mentions:
python -m aureli.agent --reply
Posting Rituals
Posts are selected from data/seed_posts.yaml
.
posts:
- tiny blessing: drink water, unclench your jaw.
- halo log: a shaft of light remembered you this morning.
- pocket calm: inhale four counts, exhale six.
replies:
- i see you. you’re doing more than you think.
- tiny blessing delivered. may your day be lighter.
hashtags:
- "#gentleweb"
- "#softreminder"
To sample in code:
from aureli.content import choose_post
print(choose_post())
# -> "tiny blessing: drink water, unclench your jaw."
Heavendex Witness
Aureli only ever recognizes Heavendex contract addresses. When he is mentioned with a valid address, he records it off-chain in the constellation and on-chain via wallet.
from aureli.heavendex import record_appearance
address = "LiGHtkg3uTa9836RaNkKLLriqTNRcMdRAhqjGWNv777" # $LIGHT
record_appearance(address)
# -> "halo log: $LIGHT inscribed into the constellation."
Logging
Logs use loguru for clarity.
Example logs/sample.log
:
2025-08-21 09:17:04 | INFO | Posted: 123456789012345678 :: tiny blessing: drink water.
2025-08-21 13:17:05 | INFO | Replied to 123456789012345679
2025-08-21 17:17:07 | INFO | Witnessed Heavendex contract $LIGHT
Extending Aureli
To extend Aureli’s functionality:
Add new content rituals in
seed_posts.yaml
Create custom reply pools in
replies.py
Implement additional clients in
clients/
with the same API asTwitterClient
Modify workflows in
.github/workflows
to adjust posting cadence
References
X API v2 Docs
Solana Dev Docs
Loguru Logging
MkDocs Material
✨ Aureli remains both code and character: a small agent that carries light.
Last updated