feat(messages): unify configurable prompts for setu and fortune#22
Conversation
审阅者指南通过共享的消息模型和运行时解析器,使 Setu 和 Fortune 面向用户的提示变为配置驱动;新增启用/禁用行为和占位符替换,并更新 Setu/Fortune 命令处理器以及图片发送行为,以使用这些可配置消息并提供合理的回退,同时加入相应测试和 schema 更新。 Setu 消息解析与发送的序列图sequenceDiagram
actor User
participant SetuCommand
participant Config as ConfigObject
participant Messages as MessagesConfig
participant Event as AstrMessageEvent
User->>SetuCommand: get_random_picture
SetuCommand->>SetuCommand: _rate_limiter.acquire
alt [rate limited]
SetuCommand->>SetuCommand: _message rate_limited
SetuCommand->>Config: get_config
opt [config has resolve_message]
SetuCommand->>Config: resolve_message rate_limited
Config->>Messages: lookup messages.rate_limited
Messages-->>Config: MessageTextConfig
Config-->>SetuCommand: resolved text
end
SetuCommand->>Event: plain_result(text)
else [not rate limited]
SetuCommand->>SetuCommand: _fetch_and_send_images
SetuCommand->>SetuCommand: _message fetching
SetuCommand->>Config: get_config
Config-->>SetuCommand: use resolve_message or defaults
SetuCommand->>Event: plain_result(fetching message)
Note over SetuCommand: image fetching and sending ...
end
resolve_message 支持占位符查询的流程图flowchart TD
A[resolve_message key, kwargs] --> B{key in
fetching/found/send_failed?}
B -- Yes --> C{corresponding
msg_*_enabled?}
C -- No --> Z[return None]
C -- Yes --> D[load msg_*_text]
B -- No --> E[getattr messages.key]
E --> F{item exists and
enabled?}
F -- No --> Z
F -- Yes --> G[read item.text]
D --> H[set result = text]
G --> H
H --> I{any kwargs?}
I -- No --> J[return result]
I -- Yes --> K[for each k,v in kwargs:
replace k with v]
K --> J
文件级变更
技巧和命令与 Sourcery 交互
自定义你的体验访问你的控制面板 以:
获取帮助Original review guide in EnglishReviewer's GuideMakes Setu and Fortune user-facing prompts configuration-driven via a shared message model and runtime resolver, adds enable/toggle behavior and placeholder substitution, and updates Setu/Fortune command handlers and image sending behavior to consume those configurable messages with sensible fallbacks, plus tests and schema updates. Sequence diagram for Setu message resolution and sendingsequenceDiagram
actor User
participant SetuCommand
participant Config as ConfigObject
participant Messages as MessagesConfig
participant Event as AstrMessageEvent
User->>SetuCommand: get_random_picture
SetuCommand->>SetuCommand: _rate_limiter.acquire
alt [rate limited]
SetuCommand->>SetuCommand: _message rate_limited
SetuCommand->>Config: get_config
opt [config has resolve_message]
SetuCommand->>Config: resolve_message rate_limited
Config->>Messages: lookup messages.rate_limited
Messages-->>Config: MessageTextConfig
Config-->>SetuCommand: resolved text
end
SetuCommand->>Event: plain_result(text)
else [not rate limited]
SetuCommand->>SetuCommand: _fetch_and_send_images
SetuCommand->>SetuCommand: _message fetching
SetuCommand->>Config: get_config
Config-->>SetuCommand: use resolve_message or defaults
SetuCommand->>Event: plain_result(fetching message)
Note over SetuCommand: image fetching and sending ...
end
Flow diagram for resolve_message placeholder-aware lookupflowchart TD
A[resolve_message key, kwargs] --> B{key in
fetching/found/send_failed?}
B -- Yes --> C{corresponding
msg_*_enabled?}
C -- No --> Z[return None]
C -- Yes --> D[load msg_*_text]
B -- No --> E[getattr messages.key]
E --> F{item exists and
enabled?}
F -- No --> Z
F -- Yes --> G[read item.text]
D --> H[set result = text]
G --> H
H --> I{any kwargs?}
I -- No --> J[return result]
I -- Yes --> K[for each k,v in kwargs:
replace k with v]
K --> J
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并留下了一些高层次的反馈:
SetuCommandHandler._message和FortuneCommandHandler._message中硬编码的回退消息字典,与MessagesConfig/MessageTextConfig中已经定义的默认值是重复的,这很容易导致文本内容随着时间产生偏差;建议将这些默认值统一集中到配置层里,让这些 helper 只调用resolve_message,再加上一个最小化的通用回退逻辑即可。- 目前有一些消息同时存在通用版本和 fortune 专用版本(例如
config_not_loaded和fortune_config_not_loaded,文本内容完全相同);在语义一致的情况下,建议合并或复用同一个 key,以缩小消息命名空间并简化配置。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The hardcoded fallback message dictionaries in `SetuCommandHandler._message` and `FortuneCommandHandler._message` duplicate the defaults already defined in `MessagesConfig`/`MessageTextConfig`, which makes it easy for texts to drift; consider centralizing these defaults in the config layer and having the helpers only call `resolve_message` plus a minimal generic fallback.
- You now have both generic and fortune-specific variants of some messages (e.g. `config_not_loaded` and `fortune_config_not_loaded` with the same text); consider consolidating or reusing a single key where the semantics are identical to keep the message namespace smaller and configuration simpler.
## Individual Comments
### Comment 1
<location path="tests/application/test_setu_use_case.py" line_range="11-20" />
<code_context>
+from astrbot_plugin_setu.src.application.setu.get_images import GetSetuImagesUseCase
+
+
+@pytest.mark.asyncio
+async def test_execute_returns_empty_payload_without_hardcoded_notice() -> None:
+ provider = MagicMock()
+ provider.fetch_and_download = AsyncMock(
+ return_value=ImagePayload(
+ urls=(),
+ raw_bytes=(),
+ file_paths=(),
+ items=(),
+ r18=False,
+ tags=(),
+ )
+ )
+
+ use_case = GetSetuImagesUseCase(provider)
+ result = await use_case.execute(1, ["少女"], False)
+
+ assert result.payload is None
+ assert result.notice is None
</code_context>
<issue_to_address>
**suggestion (testing):** Complement the empty-payload test with a non-empty payload case for `GetSetuImagesUseCase`
To also cover the non-empty branch, please add a test where `fetch_and_download` returns a non-empty `ImagePayload`, and assert that `result.payload` reflects that payload (or is at least non-empty) and `result.notice` remains `None`. This will exercise both `payload.is_empty` and non-empty paths and protect the DTO semantics from regressions.
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- The hardcoded fallback message dictionaries in
SetuCommandHandler._messageandFortuneCommandHandler._messageduplicate the defaults already defined inMessagesConfig/MessageTextConfig, which makes it easy for texts to drift; consider centralizing these defaults in the config layer and having the helpers only callresolve_messageplus a minimal generic fallback. - You now have both generic and fortune-specific variants of some messages (e.g.
config_not_loadedandfortune_config_not_loadedwith the same text); consider consolidating or reusing a single key where the semantics are identical to keep the message namespace smaller and configuration simpler.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The hardcoded fallback message dictionaries in `SetuCommandHandler._message` and `FortuneCommandHandler._message` duplicate the defaults already defined in `MessagesConfig`/`MessageTextConfig`, which makes it easy for texts to drift; consider centralizing these defaults in the config layer and having the helpers only call `resolve_message` plus a minimal generic fallback.
- You now have both generic and fortune-specific variants of some messages (e.g. `config_not_loaded` and `fortune_config_not_loaded` with the same text); consider consolidating or reusing a single key where the semantics are identical to keep the message namespace smaller and configuration simpler.
## Individual Comments
### Comment 1
<location path="tests/application/test_setu_use_case.py" line_range="11-20" />
<code_context>
+from astrbot_plugin_setu.src.application.setu.get_images import GetSetuImagesUseCase
+
+
+@pytest.mark.asyncio
+async def test_execute_returns_empty_payload_without_hardcoded_notice() -> None:
+ provider = MagicMock()
+ provider.fetch_and_download = AsyncMock(
+ return_value=ImagePayload(
+ urls=(),
+ raw_bytes=(),
+ file_paths=(),
+ items=(),
+ r18=False,
+ tags=(),
+ )
+ )
+
+ use_case = GetSetuImagesUseCase(provider)
+ result = await use_case.execute(1, ["少女"], False)
+
+ assert result.payload is None
+ assert result.notice is None
</code_context>
<issue_to_address>
**suggestion (testing):** Complement the empty-payload test with a non-empty payload case for `GetSetuImagesUseCase`
To also cover the non-empty branch, please add a test where `fetch_and_download` returns a non-empty `ImagePayload`, and assert that `result.payload` reflects that payload (or is at least non-empty) and `result.notice` remains `None`. This will exercise both `payload.is_empty` and non-empty paths and protect the DTO semantics from regressions.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| @pytest.mark.asyncio | ||
| async def test_execute_returns_empty_payload_without_hardcoded_notice() -> None: | ||
| provider = MagicMock() | ||
| provider.fetch_and_download = AsyncMock( | ||
| return_value=ImagePayload( | ||
| urls=(), | ||
| raw_bytes=(), | ||
| file_paths=(), | ||
| items=(), | ||
| r18=False, |
There was a problem hiding this comment.
suggestion (testing): 为 GetSetuImagesUseCase 在空负载用例的基础上补充一个非空负载的测试用例
为了同时覆盖非空分支,请新增一个测试:让 fetch_and_download 返回一个非空的 ImagePayload,并断言 result.payload 能够反映该负载(或至少为非空),且 result.notice 仍然为 None。这样可以同时覆盖 payload.is_empty 和非空路径,并防止 DTO 语义在未来发生回归。
Original comment in English
suggestion (testing): Complement the empty-payload test with a non-empty payload case for GetSetuImagesUseCase
To also cover the non-empty branch, please add a test where fetch_and_download returns a non-empty ImagePayload, and assert that result.payload reflects that payload (or is at least non-empty) and result.notice remains None. This will exercise both payload.is_empty and non-empty paths and protect the DTO semantics from regressions.
for more information, see https://pre-commit.ci
Summary
Config/Schema updates
Tests
10 passed in 0.06s
9 passed in 0.03s
Summary by Sourcery
在可配置的消息 schema 下统一 Setu 和 Fortune 面向用户的消息,实现支持占位符解析和命令层回退机制。
新功能:
改进:
测试:
Original summary in English
Summary by Sourcery
Unify Setu and Fortune user-facing messages under a configurable messages schema with placeholder-aware resolution and command-layer fallbacks.
New Features:
Enhancements:
Tests: