Skip to content

Latest commit

 

History

History
82 lines (52 loc) · 4.9 KB

File metadata and controls

82 lines (52 loc) · 4.9 KB

AGENTS.md

This file provides guidance to Codex when working with code in this repository.

Hard Rule — Graphify is the Knowledge Base

When any question about EasyCord's architecture, module relationships, data flows, or cross-cutting patterns arises, query the knowledge graph before reading source files manually.

Graph location: graphify-out/graph.json (relative to repo root)

/graphify query "<question>"
/graphify path "NodeA" "NodeB"
/graphify explain "NodeName"

The graph is already built. Do not rebuild it unless explicitly asked. Do not read vault files at C:\Users\Tom\Desktop\Wiki — that system is deprecated.

Commands

# Install with dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest tests/

# Run a single test
pytest tests/test_memory_safety.py::test_conversation_memory_evicts_oldest_over_cap -v

# Blocking lint gate (critical errors only) + per-plugin test-count thresholds
ruff check easycord tests --select E9,F63,F7,F82
python scripts/verify_plugin_tests.py

# Build distribution package
python -m build

Tests use pytest-asyncio with asyncio_mode = "auto" — async tests need no manual event loop setup.

The CI PR gate (.github/workflows/tests.yml) runs, in order: critical-error ruff (blocking) → full ruff check . (advisory) → check_release_metadata.pyverify_plugin_tests.pypytest, across Python 3.10/3.11/3.12.

Architecture

EasyCord is a Discord bot framework layered as follows:

Bot corebot.py defines the Bot class via multiple inheritance: discord.Client + four mixins (_bot_commands.py, _bot_events.py, _bot_guild.py, _bot_plugins.py). Adding bot-level behavior means adding to one of these mixin files.

Contextcontext.py + _context_channels.py, _context_moderation.py, _context_ui.py. This is the user-facing API inside command handlers (ctx.respond(), ctx.send(), ctx.send_embed(), etc.).

Decoratorsdecorators.py provides @slash / @slash_command, @autocomplete, @on, @component, @modal, @message_command, @user_command, @task, @ai_tool, @cooldown, @require_permissions, @install_type, and @premium_required. These are the primary extension points for bot authors.

Interaction registryregistry.py is the authoritative EasyCord inventory for slash commands, context menus, components, modals, and autocomplete callbacks. discord.app_commands.CommandTree remains the Discord sync backend.

Plugin systemplugin.py defines Plugin. Bundled plugins live in plugins/. bot.load_builtin_plugins() loads the starter set (welcome, tags, polls, levels). Load additional plugins explicitly with bot.add_plugin(...).

Databasedatabase.py provides SQLiteDatabase and MemoryDatabase with per-guild namespacing. GuildRecord is the typed row abstraction.

AI orchestrationorchestrator.py routes across 9 LLM providers with FallbackStrategy. plugins/_ai_providers.py holds provider adapters. Tools are registered via ToolRegistry in tools.py and gated by ToolSafety permission checks. Per-tool rate limiting in tool_limits.py — all ToolLimiter methods are async, must be awaited.

Localizationi18n.py (LocalizationManager) handles locale auto-detection with fallback chains (user → guild → system → default). Three diagnostic modes: SILENT (production), WARN (dev), STRICT (CI).

Middlewaremiddleware.py provides cross-cutting concerns (logging, auth, rate limiting) applied around command dispatch.

Public API — everything re-exported from easycord/__init__.py is the stable surface. Internal modules prefixed with _ are not part of the public contract.

Key conventions

  • Bot mixins follow the _bot_<area>.py naming pattern; context mixins follow _context_<area>.py.
  • The @ai_tool decorator registers a function into ToolRegistry and requires explicit ToolSafety permission annotation.
  • Per-guild state always goes through the database layer — never stored on the Bot instance directly.
  • Localization keys are looked up via LocalizationManager; strings must not be hardcoded in plugin responses.
  • Use ctx.user / ctx.memberctx.author does not exist.
  • ctx.is_admin is a property, not a method — do not call it as ctx.is_admin().
  • Cooldown sentinels default to float("-inf"), not 0.0 — ensures first-message events pass on fresh runners.
  • CI workflows pin to actions/checkout@v7 and actions/setup-python@v5 (dependabot manages major bumps; keep in sync with .github/workflows/).

Branch / repo state

  • Verify current topology with git status --short --branch and git log --oneline -5 --decorate.
  • Current version: v5.57.0. Run python scripts/check_release_metadata.py to confirm version consistency.
  • Latest local verification: python -m compileall -q easycord tests passes. All core plugins and AI orchestration layers stabilized.