feat(composer): support full bot configuration - #135
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 95 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideExtend Composer to fully mirror Bot configuration options, introduce a guarded client_options API for Discord Client kwargs, and shift the community scaffold/docs/tests to a composition-first, Composer-based setup. Sequence diagram for Composer client_options validation and Bot constructionsequenceDiagram
actor Developer
participant Composer
participant Bot
Developer->>Composer: Composer()
Developer->>Composer: auto_sync(False)
Developer->>Composer: database(SQLiteDatabase(path="data/bot.db"))
Developer->>Composer: client_options(shard_count=2)
alt [option in _BOT_OPTION_METHODS]
Composer-->>Developer: ValueError
else [no Bot option collision]
Composer-->>Developer: Composer
end
Developer->>Composer: build()
Composer->>Bot: Bot.__init__(intents, auto_sync, sync_guild_id, load_builtin_plugins, database, db_backend, db_path, db_auto_sync_guilds, guild_sync_timeout, localization, default_locale, translations, auto_translator, ai_provider, enable_conversation_memory, enable_health_command, cooldown_cleanup_interval, **_client_options)
Bot-->>Developer: Bot
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
PR Summary by QodoComposer parity: full Bot options + safe Discord client_options forwarding
AI Description
Diagram
High-Level Assessment
Files changed (6)
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="tests/test_developer_toolkit.py" line_range="248-251" />
<code_context>
test_source = (project / "tests" / "test_bot.py").read_text(encoding="utf-8")
- assert "load_builtin_plugins=True" in bot_source
+ assert "Composer()" in bot_source
+ assert ".auto_sync(False)" in bot_source
+ assert ".builtin_plugins()" in bot_source
+ assert ".build()" in bot_source
assert "ModerationPlugin()" in bot_source
assert "EconomyPlugin()" in bot_source
</code_context>
<issue_to_address>
**suggestion (testing):** Add an assertion that the community template does not instantiate `Bot` directly to fully guarantee composition-first setup.
The current assertions ensure the template uses `Composer` with the expected calls. To fully enforce the composition-first invariant, also assert that `Bot(` does not appear in `bot_source` (e.g. `assert "Bot(" not in bot_source`) so tests fail if a direct `Bot` instantiation is reintroduced alongside `Composer`.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| assert "Composer()" in bot_source | ||
| assert ".auto_sync(False)" in bot_source | ||
| assert ".builtin_plugins()" in bot_source | ||
| assert ".build()" in bot_source |
There was a problem hiding this comment.
suggestion (testing): Add an assertion that the community template does not instantiate Bot directly to fully guarantee composition-first setup.
The current assertions ensure the template uses Composer with the expected calls. To fully enforce the composition-first invariant, also assert that Bot( does not appear in bot_source (e.g. assert "Bot(" not in bot_source) so tests fail if a direct Bot instantiation is reintroduced alongside Composer.
Code Review by Qodo
1. Tests import easycord.composer
|
| import discord | ||
| import pytest | ||
|
|
||
| from easycord.composer import Composer |
There was a problem hiding this comment.
1. Tests import easycord.composer 📘 Rule violation ⌂ Architecture
tests/test_composer.py imports Composer from the internal submodule easycord.composer instead of the public top-level easycord API. This breaks the public-API-only import rule for code outside the easycord/ package and increases coupling to internal module layout.
Agent Prompt
## Issue description
A test file outside the `easycord/` package imports `Composer` via `from easycord.composer import Composer`, but external code must import only from the public top-level `easycord` package API.
## Issue Context
`Composer` is already re-exported from `easycord/__init__.py`, so the test can import it as `from easycord import Composer`.
## Fix Focus Areas
- tests/test_composer.py[9-9]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| for option in options: | ||
| method = _BOT_OPTION_METHODS.get(option) | ||
| if method is not None: | ||
| raise ValueError( | ||
| f"{option!r} is an EasyCord Bot option; " | ||
| f"use Composer.{method}(...) instead of client_options()." | ||
| ) | ||
| self._client_options.update(options) |
There was a problem hiding this comment.
2. Guild_id not mapped 🐞 Bug ≡ Correctness
Composer.client_options() accepts guild_id, but Bot.__init__ only consumes sync_guild_id, so passing guild_id via client_options cannot set the dev sync target and leaves command syncing in the wrong mode (global vs guild). This is especially likely because the docs/config use guild_id naming, while Composer exposes sync_guild_id.
Agent Prompt
### Issue description
`Composer.client_options()` only rejects keys listed in `_BOT_OPTION_METHODS`. The repo’s docs/config surface the development sync setting as `guild_id`, but `Bot`/`Composer` use `sync_guild_id`. As a result, `Composer().client_options(guild_id=...)` won’t configure the bot’s sync target.
### Issue Context
- `BotConfig` uses `guild_id` and maps it to `sync_guild_id` when building a `Bot`.
- `Composer` exposes `.sync_guild_id(...)`, but `client_options()` does not reject or translate `guild_id`.
### Fix Focus Areas
- easycord/composer.py[20-38]
- easycord/composer.py[180-195]
### Suggested fix
Choose one:
1) **Reject** `guild_id` in `client_options()` with a clear message directing users to `Composer.sync_guild_id(...)`.
2) **Alias** `guild_id` to `sync_guild_id` (either in `client_options()` or by adding it to `_BOT_OPTION_METHODS` mapping to `sync_guild_id`). Ensure it can’t conflict with an explicit `.sync_guild_id(...)` call (pick a precedence rule and test it).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
Verification
Part 1 of the EasyCord v5.62.0 DX release.
Summary by Sourcery
Extend the Composer builder to fully cover Bot configuration while promoting composition-first usage in scaffolds and docs.
New Features:
Enhancements:
Tests: