Skip to content

HiLleywyn/Framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bot Framework

The reusable Discord-bot framework extracted from Discoin — the runtime that actually runs a bot. It is bot-agnostic: the same framework powers Disco (the economy / NFT / game bot), Recycler (the ,clanker containment bot) and any future bot you build, and it routes every bot's AI through the Auren platform.

Nothing was removed when this was split out of Discoin — the framework was re-homed here and decoupled from the economy so it can be reused.

What's in here

This repository ships three importable top-level packages. Every bot installs this framework and imports them unchanged:

Package What it provides
core core.config.Config (env-driven settings), core.database (asyncpg pool + PgRow helpers) and the whole core.framework runtime
core.framework The bot itself: FrameworkBot, prefix routing, the cog loader, the embedded FastAPI server, the agent-tools engine, the AI bridge (core.framework.ai), error tracking, the live dashboard, charts/render, graceful shutdown — and core.framework.run.run(), the shared entrypoint
constants Shared UI colors + validation constants used across the runtime
security The behavioural threat-scoring / detection engine
database The shared data plane: asyncpg data-access layer (Database/PgDatabase + repos), the migration runner and schema.sql. Bots get a working DB out of the box; a bot can also inject its own via FrameworkBot(db_factory=...)

What it deliberately does not ship: game cogs (each bot's features), the domain services, shop catalogs, the dashboard frontend. Those belong to each concrete bot. The data plane is bundled here because the runtime is built on it; a bot that wants a slim, custom schema can still supply its own database.Database via db_factory.

How a bot uses it

A bot built on the framework is small. It provides:

  1. A cogs/ package with its own features.
  2. A database/ package exposing a Database class (its schema/repos).
  3. A auren.json manifest declaring its identity, cog list (features) and settings.
  4. A three-line main.py.
  5. A Dockerfile that installs this framework from its repo and runs the bot.

auren.json (the manifest)

One declarative file at the repo root is the contract a bot satisfies. The framework reads features (the cog list, which supersedes the old bot_manifest.COGS) and settings at boot; the Auren control plane reads the same file to deploy and manage the bot (see the managed-bots platform spec). Phase 1 wires only the framework side — bots still run as today.

{
  "manifest_version": "1",
  "bot": { "slug": "recycler", "name": "Recycler", "version": "1.0.0" },
  "channels": ["discord"],
  "runtime": { "dockerfile": "Dockerfile", "entrypoint": "main.py" },
  "credentials": [
    { "key": "DISCORD_TOKEN", "label": "Bot token", "secret": true }
  ],
  "provision": { "database": "postgres" },
  "settings": { "groups": [
    { "id": "clanktank", "label": "Clanktank", "fields": [
      { "key": "CLANK_ESCAPE_WAIT_MINUTES", "type": "number",
        "label": "Reflection wait (minutes)", "default": 8, "min": 1, "max": 120 }
    ]}
  ]},
  "features": ["cogs.clanktank"]
}

settings field types map to a dynamic-UI control and a validator: string · number · boolean · select (needs options) · secret (masked, vault-bound) · discord_channel · discord_role. An unknown type fails validation rather than rendering blank. Validate any manifest with:

python -m core.framework.manifest path/to/auren.json

main.py

from core.framework.run import run_manifest
from bot_manifest import COGS, APP_NAME

if __name__ == "__main__":
    # Boots from auren.json; falls back to the legacy cog list so the bot
    # still starts as before if the manifest is ever missing or invalid.
    run_manifest(fallback_cogs=COGS, fallback_app_name=APP_NAME)

That's it. run_manifest() loads + validates the manifest, then runs FrameworkBot off its features/identity with the same rate-limit-aware startup retry loop and graceful SIGTERM/SIGINT draining as before. FrameworkBot lazily imports the bot's own database.Database for its data layer (or pass db_factory=...).

Reading settings in a cog

The loaded, validated settings are exposed as bot.settings — a typed view that resolves each field from a control-plane override (Phase 2), then an env var named after the field key, then the field's default:

wait = self.bot.settings.get("CLANK_ESCAPE_WAIT_MINUTES")   # 8 by default
if "log_channel" in self.bot.settings:
    channel_id = self.bot.settings["log_channel"]

A bot booted from the legacy bot_manifest.COGS path (no manifest) still gets a usable, empty bot.settings, so cog code is identical either way.

The legacy run(cogs=COGS, app_name=APP_NAME) entrypoint still works unchanged; bot_manifest.py is kept as the fallback the manifest supersedes.

Dockerfile (build the framework from this repo)

FROM python:3.12-slim
WORKDIR /app
# Build + install the framework straight from the Framework repo:
RUN pip install "git+https://github.com/HiLleywyn/Framework.git@main"
COPY requirements.txt .
RUN pip install -r requirements.txt   # the bot's own extra deps
COPY . .
CMD ["python", "main.py"]

AI is routed through Auren

Every AI feature in every bot goes through core.framework.ai. When the bot sets AUREN_AI_BASE_URL (and the tenant token AUREN_AI_API_KEY), the AI client routes all chat completions through the Auren proxy gateway — the platform's AI controller, OpenAI-compatible at /v1/chat/completions with tenant auth, billing and risk checks — instead of calling OpenRouter directly. Flip those env vars and a whole bot's AI surface (e.g. the Recycler ,clanker AI) moves onto Auren with no code changes.

Env var Meaning
AUREN_AI_BASE_URL Base URL of the Auren deployment. Empty → call OpenRouter directly.
AUREN_AI_API_KEY Per-bot Auren tenant token.
AUREN_BOT_ID Stable id Auren uses to attribute this bot's AI usage.
APP_NAME Human name of the bot (presence + logs).

Reusability summary

The split that makes this reusable:

  • Cog registry decoupledFrameworkBot(cogs=[...]); no bot's cog list is baked into the framework.
  • Data layer injected — the framework lazily imports each bot's database.Database (or takes db_factory=); no economy schema baked in.
  • API server optional — the embedded HTTP/dashboard server only starts if the bot ships an api.v2 app; minimal bots skip it.
  • Economy-free configcore.config tolerates a missing economy configs.items_config, so a bot with no shop still boots.
  • AI controller pluggable — one env var routes AI through Auren.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors