Release v2.1.0 - #28
Conversation
There was a problem hiding this comment.
Sorry @FlanChanXwO, your pull request is larger than the review limit of 150000 diff characters
|
Warning Review limit reached
More reviews will be available in 31 minutes and 20 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthrough本 PR 将插件版本升至 v2.1.0,核心变更包括:将自动撤回从布尔 R18 开关扩展为 Changesv2.1.0 功能升级主干
Sequence Diagram(s)sequenceDiagram
participant SetuPlugin as SetuPlugin.initialize
participant heal_astrbot_plugin_config
participant ImageSender
participant split_send_batches
participant _send_one_batch
participant RevokeScheduler
participant OneBot as OneBot bot_client
SetuPlugin->>heal_astrbot_plugin_config: raw_config (含旧键迁移)
heal_astrbot_plugin_config-->>SetuPlugin: healed_config
rect rgba(100, 149, 237, 0.5)
Note over ImageSender,split_send_batches: 发送流程
ImageSender->>ImageSender: _compress_chain (可选)
ImageSender->>split_send_batches: base64_sizes, mode
split_send_batches-->>ImageSender: batches[]
end
rect rgba(144, 238, 144, 0.5)
Note over ImageSender,OneBot: 逐批发送与回退
loop 每批
ImageSender->>_send_one_batch: batch_chain, options
_send_one_batch->>OneBot: send_group_msg (本地/流式/直发)
OneBot-->>_send_one_batch: send_result (含 message_ids)
end
end
rect rgba(255, 165, 0, 0.5)
Note over ImageSender,RevokeScheduler: 撤回调度
ImageSender->>RevokeScheduler: schedule_revoke(event, message_id, delay)
RevokeScheduler->>OneBot: delay 秒后 delete_msg(message_id)
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Poem
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/infrastructure/astrbot/commands/setu.py (1)
109-111:⚠️ Potential issue | 🟠 Major | ⚡ Quick win将“配置未加载”统一改为配置消息解析路径。
这里仍直接
yield event.plain_result("配置未加载"),会绕过消息配置与覆写机制。建议改为与其他分支一致,使用_message("config_not_loaded")+_plain(...)。💡 建议修复
config = get_config() if not config: - yield event.plain_result("配置未加载") + if result := self._plain(event, self._message("config_not_loaded")): + yield result return @@ config = get_config() if not config: - yield event.plain_result("配置未加载") + if result := self._plain(event, self._message("config_not_loaded")): + yield result returnAs per coding guidelines, "All user-visible prompts and messages must be retrieved through
MessagesConfig/resolve_message()function, do not hardcode message text in handler code".Also applies to: 183-186
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/infrastructure/astrbot/commands/setu.py` around lines 109 - 111, The hardcoded message string "配置未加载" in the yield statement at lines 109-111 violates the coding guideline that all user-visible messages must be retrieved through the MessagesConfig/resolve_message() function. Replace the hardcoded string with a call to _message("config_not_loaded") combined with _plain(...) to ensure the message is resolved through the configuration system. This same issue also appears at lines 183-186 in the same file where another hardcoded message is used instead of the message configuration system. Apply the same fix pattern to both locations to maintain consistency with the codebase guidelines.Source: Coding guidelines
src/infrastructure/sending/image_sender.py (1)
867-889:⚠️ Potential issue | 🟠 Major | ⚡ Quick win用户可见文案仍有硬编码,违反消息配置约束
Line [881]-Line [882] 与 Line [888] 直接返回硬编码中文文案。按仓库规范,这类用户可见消息应统一走
MessagesConfig/resolve_message(),避免多语言与配置覆盖失效。建议修复(示例)
def _format_found_message( @@ if config and hasattr(config, "format_found_message"): return config.format_found_message(count, revoke_delay, scope, r18) - if revoke_delay and revoke_delay > 0: - return f"找到 {count} 张图,将在 {revoke_delay} 秒后撤回" - return f"找到 {count} 张图" + return self._resolve_message( + "found", + count=count, + revoke_delay=revoke_delay, + scope=scope, + r18=r18, + ) def _send_failed_message(self) -> str | None: config = self._config if config and hasattr(config, "resolve_message"): return config.resolve_message("send_failed") - return "图片发送失败,请稍后再试。" + return self._resolve_message("send_failed")As per coding guidelines, “All user-visible prompts and messages must be retrieved through
MessagesConfig/resolve_message()function, do not hardcode message text in handler code”; if message keys/placeholders change, also updatesrc/shared/config/models.py.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/infrastructure/sending/image_sender.py` around lines 867 - 889, The _format_found_message method contains hardcoded Chinese user-visible messages on lines 881-882 and 888 that violate the coding guideline requiring all user-visible messages to be retrieved through MessagesConfig resolve_message() function. Replace the hardcoded return statements with calls to config.resolve_message() similar to how _send_failed_message handles its message retrieval, passing appropriate message keys that correspond to the different scenarios (with revoke_delay versus default). Also update src/shared/config/models.py to define the message keys needed for these resolved messages.Source: Coding guidelines
🧹 Nitpick comments (3)
_conf_schema.json (1)
282-287: 💤 Low value
stream_chunk_kbslider 上限 4096 KiB 可能过大。NapCat
upload_file_stream的chunk_data字段传输 base64 字符串,4096 KiB 原始数据对应约 5.5 MiB base64,可能超过某些 WebSocket 实现的单帧限制。根据上下文,该功能本身是为了绕开大体积限制,建议将 slider max 调低至更保守的值(如 512 或 1024),或在 hint 中补充说明较大分块可能导致的风险。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@_conf_schema.json` around lines 282 - 287, The stream_chunk_kb slider configuration has a max value of 4096 KiB, which when base64-encoded for transmission could exceed WebSocket frame limits (approximately 5.5 MiB). Either reduce the slider max property in the stream_chunk_kb field to a more conservative value such as 512 or 1024 KiB to prevent WebSocket transmission issues, or enhance the hint property to warn users that larger chunk sizes may cause transmission failures on certain WebSocket implementations.src/shared/config/models.py (1)
857-874: 💤 Low value
r18参数类型签名包含bool | str,但传递给resolve_message时未做类型统一。
r18参数声明为bool | str = "",但在调用resolve_message时直接传递,当调用者传入True/False时占位符会变成"True"/"False"字符串。如果模板中需要基于此显示中文提示(如"是/否"),当前行为可能不符合预期。建议明确该参数的预期用途:若仅用于调试/日志,当前实现可接受;若用于用户可见文案,考虑在此处统一转换。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/shared/config/models.py` around lines 857 - 874, The `r18` parameter in the `format_found_message` method is typed as `bool | str` but is passed directly to `resolve_message` without type normalization. When callers pass boolean values (True/False), they get stringified as "True"/"False" which may not be appropriate for user-facing templates. Before passing the `r18` parameter to the `resolve_message` call, add logic to convert boolean values to an appropriate string representation (such as an empty string, a localized yes/no value, or other suitable convention) while preserving string values as-is, ensuring consistent placeholder substitution regardless of whether the parameter is passed as a boolean or string.src/infrastructure/config/legacy_migration.py (1)
8-8: 💤 Low value
_TRUE_VALUES与keys.py中的TRUE_VALUES存在重复且不一致。
keys.py中的TRUE_VALUES包含更多变体(如"y","yes","enable","enabled","是"),而此处的_TRUE_VALUES缺少这些值。这可能导致迁移行为与运行时规范化行为不一致。建议复用
keys.py中的逻辑或常量,以保持一致性:♻️ 建议修改
-from copy import deepcopy +from copy import deepcopy from typing import Any +from ...application.session_config.keys import TRUE_VALUES as _TRUE_VALUES -_TRUE_VALUES = {"1", "true", "yes", "on", "enable", "enabled", "开", "开启", "启用"}或者直接导入并调用
_normalize_bool:+from ...application.session_config.keys import _normalize_bool + +def _legacy_revoke_bool_to_scope(value: Any) -> str: + """Map the old bool-ish R18 revoke toggle to the new scope enum.""" + try: + return "r18" if _normalize_bool(value) else "none" + except Exception: + return "none"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/infrastructure/config/legacy_migration.py` at line 8, The `_TRUE_VALUES` constant in legacy_migration.py is duplicated and inconsistent with the `TRUE_VALUES` constant in keys.py, which contains additional boolean variants like "y", "是", etc. This inconsistency causes migration behavior to differ from runtime normalization behavior. Remove the duplicate `_TRUE_VALUES` definition and instead import the `_normalize_bool` function from keys.py (or import `TRUE_VALUES` directly from keys.py), then use it consistently throughout the migration logic to ensure both migration and runtime normalization handle the same set of boolean values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/infrastructure/sending/dto.py`:
- Around line 40-54: The current implementation of the `success` and
`pending_delivery` classmethods treats string message IDs as iterables, causing
"123" to be split into ["1", "2", "3"]. Fix this by normalizing the message_ids
parameter handling in both methods: check if message_ids is a string and treat
it as a single ID, otherwise iterate normally, and filter out any empty or
whitespace-only values. Apply this normalization logic consistently in both
classmethods before creating the tuple.
In `@src/infrastructure/sending/image_sender.py`:
- Around line 229-289: The batch aggregation logic only updates state variables
when send_result.accepted is True, meaning failed batches (when accepted is
False) are silently ignored. This causes the code to incorrectly report overall
success when some batches fail. Add a new variable to track failed batches
(e.g., any_failed) and set it to True whenever send_result.accepted is False in
the loop starting at line 229. Then update the aggregation logic after the loop
to handle the partial failure case: when any batches failed but not all failed
(both any_failed and not all_failed are true), log an appropriate warning and
yield a result that reflects the partial failure rather than reporting success
via the post-delivery messages at line 262 onwards.
---
Outside diff comments:
In `@src/infrastructure/astrbot/commands/setu.py`:
- Around line 109-111: The hardcoded message string "配置未加载" in the yield
statement at lines 109-111 violates the coding guideline that all user-visible
messages must be retrieved through the MessagesConfig/resolve_message()
function. Replace the hardcoded string with a call to
_message("config_not_loaded") combined with _plain(...) to ensure the message is
resolved through the configuration system. This same issue also appears at lines
183-186 in the same file where another hardcoded message is used instead of the
message configuration system. Apply the same fix pattern to both locations to
maintain consistency with the codebase guidelines.
In `@src/infrastructure/sending/image_sender.py`:
- Around line 867-889: The _format_found_message method contains hardcoded
Chinese user-visible messages on lines 881-882 and 888 that violate the coding
guideline requiring all user-visible messages to be retrieved through
MessagesConfig resolve_message() function. Replace the hardcoded return
statements with calls to config.resolve_message() similar to how
_send_failed_message handles its message retrieval, passing appropriate message
keys that correspond to the different scenarios (with revoke_delay versus
default). Also update src/shared/config/models.py to define the message keys
needed for these resolved messages.
---
Nitpick comments:
In `@_conf_schema.json`:
- Around line 282-287: The stream_chunk_kb slider configuration has a max value
of 4096 KiB, which when base64-encoded for transmission could exceed WebSocket
frame limits (approximately 5.5 MiB). Either reduce the slider max property in
the stream_chunk_kb field to a more conservative value such as 512 or 1024 KiB
to prevent WebSocket transmission issues, or enhance the hint property to warn
users that larger chunk sizes may cause transmission failures on certain
WebSocket implementations.
In `@src/infrastructure/config/legacy_migration.py`:
- Line 8: The `_TRUE_VALUES` constant in legacy_migration.py is duplicated and
inconsistent with the `TRUE_VALUES` constant in keys.py, which contains
additional boolean variants like "y", "是", etc. This inconsistency causes
migration behavior to differ from runtime normalization behavior. Remove the
duplicate `_TRUE_VALUES` definition and instead import the `_normalize_bool`
function from keys.py (or import `TRUE_VALUES` directly from keys.py), then use
it consistently throughout the migration logic to ensure both migration and
runtime normalization handle the same set of boolean values.
In `@src/shared/config/models.py`:
- Around line 857-874: The `r18` parameter in the `format_found_message` method
is typed as `bool | str` but is passed directly to `resolve_message` without
type normalization. When callers pass boolean values (True/False), they get
stringified as "True"/"False" which may not be appropriate for user-facing
templates. Before passing the `r18` parameter to the `resolve_message` call, add
logic to convert boolean values to an appropriate string representation (such as
an empty string, a localized yes/no value, or other suitable convention) while
preserving string values as-is, ensuring consistent placeholder substitution
regardless of whether the parameter is passed as a boolean or string.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 904278e5-7f3a-4e6d-abb7-e58c556501aa
⛔ Files ignored due to path filters (5)
assets/img_ob_preview.pngis excluded by!**/*.pngassets/jrys_preview.pngis excluded by!**/*.pngassets/merge_send_preview.pngis excluded by!**/*.pngassets/tag_search_preview.pngis excluded by!**/*.pnglogo.pngis excluded by!**/*.png
📒 Files selected for processing (51)
.github/PULL_REQUEST_TEMPLATE.mdCHANGELOG.mdREADME.md_conf_schema.jsonassets/img_ob_preview.webpassets/jrys_preview.webpassets/merge_send_preview.webpassets/tag_search_preview.webpdocs/dev/testing.mddocs/project/architecture.mddocs/project/sending-limits.mddocs/usage/commands.mddocs/usage/configuration.mddocs/usage/plugin-pages.mdmain.pymetadata.yamlpages/dashboard/app.jspages/dashboard/index.htmlskills/get-setu/SKILL.mdsrc/application/session_config/__init__.pysrc/application/session_config/keys.pysrc/application/session_config/service.pysrc/application/settings.pysrc/infrastructure/astrbot/commands/fortune.pysrc/infrastructure/astrbot/commands/setu.pysrc/infrastructure/config/__init__.pysrc/infrastructure/config/legacy_migration.pysrc/infrastructure/config/schema_healer.pysrc/infrastructure/persistence/session_config_json_repository.pysrc/infrastructure/providers/__init__.pysrc/infrastructure/providers/sexnyan.pysrc/infrastructure/sending/__init__.pysrc/infrastructure/sending/dto.pysrc/infrastructure/sending/image_compressor.pysrc/infrastructure/sending/image_sender.pysrc/infrastructure/sending/revoke_scheduler.pysrc/infrastructure/sending/send_batching.pysrc/infrastructure/sending/send_strategies.pysrc/shared/config/__init__.pysrc/shared/config/models.pysrc/shared/logging.pytests/conftest.pytests/domain/test_value_objects.pytests/infrastructure/test_image_compressor.pytests/infrastructure/test_image_sender.pytests/infrastructure/test_provider_init_from_config.pytests/infrastructure/test_send_batching.pytests/infrastructure/test_session_config_repo.pytests/infrastructure/test_sexnyan_provider.pytests/shared/test_config_models.pytests/test_main_config_source.py
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/infrastructure/sending/image_sender.py (1)
909-913: 💤 Low value硬编码兜底消息与编码规范存在轻微冲突
根据编码规范,所有用户可见消息应通过
MessagesConfig/resolve_message()获取。第 913 行的硬编码兜底文案"图片发送失败,请稍后再试。"严格来说违反此规范。作为防御性编程这是可以理解的,但如果希望完全符合规范,可考虑返回
None或空字符串,让调用方决定是否需要兜底。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/infrastructure/sending/image_sender.py` around lines 909 - 913, The _send_failed_message method in image_sender.py contains a hard-coded Chinese fallback message that violates the coding standard requiring all user-visible messages to come from MessagesConfig via resolve_message(). Remove the hard-coded string "图片发送失败,请稍后再试。" and instead return None or an empty string as the fallback value, allowing the calling code to handle the fallback behavior appropriately rather than enforcing it at this layer.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/infrastructure/sending/image_sender.py`:
- Around line 909-913: The _send_failed_message method in image_sender.py
contains a hard-coded Chinese fallback message that violates the coding standard
requiring all user-visible messages to come from MessagesConfig via
resolve_message(). Remove the hard-coded string "图片发送失败,请稍后再试。" and instead
return None or an empty string as the fallback value, allowing the calling code
to handle the fallback behavior appropriately rather than enforcing it at this
layer.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 91274775-6f9f-4924-a064-d3c246b9e693
📒 Files selected for processing (16)
CHANGELOG.md_conf_schema.jsondocs/usage/plugin-pages.mdpages/dashboard/app.jspages/dashboard/css/components.csspages/dashboard/css/dashboard.csspages/dashboard/index.htmlsrc/infrastructure/astrbot/commands/setu.pysrc/infrastructure/config/legacy_migration.pysrc/infrastructure/sending/dto.pysrc/infrastructure/sending/image_sender.pysrc/shared/config/models.pytests/domain/test_value_objects.pytests/infrastructure/test_image_sender.pytests/shared/test_config_models.pytests/test_main_config_source.py
✅ Files skipped from review due to trivial changes (2)
- CHANGELOG.md
- docs/usage/plugin-pages.md
🚧 Files skipped from review as they are similar to previous changes (7)
- src/infrastructure/config/legacy_migration.py
- tests/domain/test_value_objects.py
- src/infrastructure/astrbot/commands/setu.py
- _conf_schema.json
- tests/infrastructure/test_image_sender.py
- tests/shared/test_config_models.py
- src/shared/config/models.py
提升 Setu 在 NapCat / OneBot 场景下的大图发送可靠性,并补齐自动撤回范围、SexNyan 配置、Plugin Pages iframe 加载、访问控制页面可用性和 2.1.0 发布说明。
Modifications / 改动点
新增 NapCat 平台传输模板,支持 stream 分块大小、本地
file://直通模式与额外共享目录配置。新增可信本地文件直通、发送前压缩和自动分批,降低大图与多图触发 base64 / WebSocket 限制的概率。
将自动撤回升级为
none/sfw/r18/all范围枚举,并补齐旧全局配置与旧会话覆盖迁移。新增撤回调度器,在 direct、stream、
file://、HTML fallback、forward、R18 Docx 等可拿到message_id的发送路径中调度撤回。补齐 SexNyan provider 模板与
proxy/uid/keyword参数传递。修复 Dashboard Plugin Pages bridge 注入竞态,确保 iframe 场景下能正常加载。
将访问控制新增/编辑记录表单改为 modal,对主视图保留模式设置、筛选和记录表格,减少页面拥挤。
处理 release review findings:修正 message_id 归一化、部分批次失败聚合、配置消息解析、legacy bool 迁移一致性、stream 分块风险提示和
{r18}占位符格式。更新 README、配置文档、命令文档、Plugin Pages 文档、测试文档、发送限制文档、changelog,并将
metadata.yaml提升到v2.1.0。This is NOT a breaking change. / 这不是一个破坏性变更。
Screenshots or Test Results / 运行截图或测试结果
浏览器验证:
http://127.0.0.1:8787/pages/dashboard/index.html。field-target-id,按 Escape 可关闭。target_id=10001,点击“取消”可关闭。Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed them with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txt./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by CodeRabbit
发布说明 v2.1.0
New Features
platform_transports:支持 NapCat/OneBot 流式分块上传与本地file://直通能力配置。Changed
Documentation