Skip to content

Conversation

anka-afk
Copy link
Member

@anka-afk anka-afk commented Sep 1, 2025

Motivation

之前的api有点乱, 并且命名和结构不是很规范(例如all里面并不是真的all)
因此进行api结构调整, 同时保留之前的全部api和结构以向后兼容

Modifications

去除了所有import *
加入大部分事件, 平台, 供应商api, 便于构造特定供应商的请求/特定平台的事件
提供了详尽的注释

正在慢慢撰写相应的api文档

Check

  • 😊 我的 Commit Message 符合良好的规范
  • 👀 我的更改经过良好的测试
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。
  • 😮 我的更改没有引入恶意代码

Sourcery 总结

标准化并模块化 AstrBot API 表面,通过显式导出、子包组织和丰富组件定义,同时保持向后兼容性。

增强功能:

  • 将顶级 API 重组为专用子包(event, platform, provider, star, util, tool),并消除通配符导入
  • 增强消息组件类型和类,提供详细的文档字符串和额外的平台特定枚举
  • 扩展 provider API,通过显式导入包含新的 TTS、嵌入和 LLM 源提供者
  • api.star.register 下模块化插件注册和事件过滤
  • 引入 README.md 文档,说明新的 API 结构

文档:

  • 在所有 API 模块中添加全面的文档字符串,并提供 README 概述标准化 API 布局
Original summary in English

Summary by Sourcery

Standardize and modularize the AstrBot API surface with explicit exports, subpackage organization, and enriched component definitions while preserving backward compatibility

Enhancements:

  • Reorganize top-level api into dedicated subpackages (event, platform, provider, star, util, tool) and eliminate wildcard imports
  • Augment message component types and classes with detailed docstrings and additional platforms-specific enums
  • Expand provider API to include new TTS, embedding, and LLM source providers via explicit imports
  • Modularize plugin registration and event filtering under api.star.register
  • Introduce README.md documenting the new API structure

Documentation:

  • Add comprehensive docstrings across API modules and a README overview of the standardized API layout

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你好 - 我已审阅了你的更改,它们看起来很棒!

AI 代理提示
请处理此代码审查中的评论:
## 独立评论

### 评论 1
<location> `astrbot/core/message/components.py:657` </location>
<code_context>
+    QQ 戳一戳
+    """
+
     type: str = ""
     id: T.Optional[int] = 0
     qq: T.Optional[int] = 0
</code_context>

<issue_to_address>
戳一戳类型被定义为 str 而不是 ComponentType。

这种不一致可能会影响类型检查和序列化。除非有特定原因,否则请更新“type”字段以使用“ComponentType”来匹配其他组件。
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    type: str = ""
=======
    type: ComponentType = "Poke"
>>>>>>> REPLACE

</suggested_fix>

### 评论 2
<location> `astrbot/core/message/components.py:452` </location>
<code_context>
+    """
+
     type: ComponentType = "Contact"
     _type: str  # type 字段冲突
     id: T.Optional[int] = 0
</code_context>

<issue_to_address>
'_type' 字段可能存在命名冲突。

建议重命名 '_type' 或添加清晰的文档,以防止混淆和潜在的序列化问题。
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    _type: str  # type 字段冲突
=======
    contact_type: str  # 原字段名为 _type,为避免与 type 冲突已重命名。用于标识推荐的好友或群类型。
>>>>>>> REPLACE

</suggested_fix>

### 评论 3
<location> `astrbot/core/message/components.py:987` </location>
<code_context>

+# 匹配消息用字典
 ComponentTypes = {
     "plain": Plain,
     "text": Plain,
</code_context>

<issue_to_address>
ComponentTypes 字典可能需要规范化键的大小写。

规范化字典键和输入值为一致的大小写,以防止因大小写差异导致的查找失败。

建议的实现:

```python
# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,

```

```python
# 用于安全查找组件类型,自动规范化输入键为小写
def get_component_type(key: str):
    return ComponentTypes.get(key.lower())

# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,

```

1. 将代码库中任何直接查找(如 `ComponentTypes[some_key]`)替换为 `get_component_type(some_key)` 以确保规范化。
2. 如果在其他地方向 `ComponentTypes` 添加键,请确保它们以小写形式添加。
</issue_to_address>

### 评论 4
<location> `astrbot/core/platform/astr_message_event.py:29` </location>
<code_context>

 @dataclass
 class MessageSesion:
+    """
+    消息会话
</code_context>

<issue_to_address>
类名拼写错误:'MessageSesion' 应为 'MessageSession'。

将类重命名为 'MessageSession' 以匹配其在其他地方的使用并保持一致性。

建议的实现:

```python
class MessageSession:
    """
    消息会话
    用于统一标识一个消息会话
    """

    platform_name: str
    message_type: MessageType
    session_id: str

```

如果代码库中存在任何 `MessageSesion` 的用法,也应将其更新为 `MessageSession` 以保持一致性。
</issue_to_address>

### 评论 5
<location> `astrbot/api/README.md:14` </location>
<code_context>
+astrbot.api.event: 包括了 AstrBot 事件以及相关类的导入
+astrbot.api.event.filter(将弃用): 包括了事件过滤器, 用于注册 Handler, 由 astrbot.api.star.register 统一注册来代替
+astrbot.api.event.message: 包括了 AstrBot 事件中, 所有有关消息的类
+astrbot.api.api.event.message.message_components: 包括了所有消息组件
+
+astrbot.api.platform: 包括了所有平台相关的导入
</code_context>

<issue_to_address>
可能存在拼写错误:'astrbot.api.api.event.message.message_components' 中 'api' 重复。

如果 'api' 的重复是无意的,请考虑将导入路径更新为 'astrbot.api.event.message.message_components'。
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
astrbot.api.api.event.message.message_components: 包括了所有消息组件
=======
astrbot.api.event.message.message_components: 包括了所有消息组件
>>>>>>> REPLACE

</suggested_fix>

### 评论 6
<location> `astrbot/api/provider/__init__.py:23` </location>
<code_context>
 )
+from astrbot.core.provider.manager import ProviderManager
+
+from astrbot.core.provider.sources.anthropic_source import ProviderAnthropic  # Claude
+from astrbot.core.provider.sources.azure_tts_source import (
+    OTTSProvider,
</code_context>

<issue_to_address>
考虑动态发现和导入提供者类,以避免手动样板导入。

您可以通过动态发现和导入提供者来消除几乎所有样板代码。例如,将 `astrbot/core/provider/sources/` 转换为一个 proper package(带有自己的 `__init__.py`),然后执行以下操作:

```python
# astrbot/core/provider/sources/__init__.py
import pkgutil
import importlib
from astrbot.core.provider.provider import BaseProvider  # or whatever your common parent is

__all__ = []

for finder, module_name, ispkg in pkgutil.iter_modules(__path__):
    module = importlib.import_module(f"{__name__}.{module_name}")
    for obj in vars(module).values():
        if isinstance(obj, type) and issubclass(obj, BaseProvider):
            globals()[obj.__name__] = obj
            __all__.append(obj.__name__)
```

然后您的顶级 `astrbot/api/provider/__init__.py` 可以简单地重新导出该子包中的所有内容:

```python
from astrbot.core.provider.provider import Provider, STTProvider, Personality, TTSProvider, EmbeddingProvider
from astrbot.core.provider.entities import (
    ProviderRequest, ProviderType, ProviderMetaData, LLMResponse,
    ToolCallsResult, AssistantMessageSegment, ToolCallMessageSegment,
)
from astrbot.core.provider.manager import ProviderManager

# pull in all providers dynamically
from astrbot.core.provider.sources import *

__all__ = [
    "Provider", "STTProvider", "Personality", "TTSProvider", "EmbeddingProvider",
    "ProviderRequest", "ProviderType", "ProviderMetaData", "LLMResponse",
    "ToolCallsResult", "AssistantMessageSegment", "ToolCallMessageSegment",
    "ProviderManager",
] + __all__  # append all the dynamically discovered provider class names
```

这使得每个提供者都在 `__all__` 中,但您不再需要手动维护数十行导入代码。
</issue_to_address>

Sourcery 对开源免费 - 如果您喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进您的评论。
Original comment in English

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `astrbot/core/message/components.py:657` </location>
<code_context>
+    QQ 戳一戳
+    """
+
     type: str = ""
     id: T.Optional[int] = 0
     qq: T.Optional[int] = 0
</code_context>

<issue_to_address>
Poke type is defined as str instead of ComponentType.

This inconsistency may affect type checking and serialization. Please update to use 'ComponentType' for 'type' to match other components, unless there's a specific reason for using 'str'.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    type: str = ""
=======
    type: ComponentType = "Poke"
>>>>>>> REPLACE

</suggested_fix>

### Comment 2
<location> `astrbot/core/message/components.py:452` </location>
<code_context>
+    """
+
     type: ComponentType = "Contact"
     _type: str  # type 字段冲突
     id: T.Optional[int] = 0
</code_context>

<issue_to_address>
Potential naming conflict with '_type' field.

Renaming '_type' or adding clear documentation is recommended to prevent confusion and potential serialization problems.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    _type: str  # type 字段冲突
=======
    contact_type: str  # 原字段名为 _type,为避免与 type 冲突已重命名。用于标识推荐的好友或群类型。
>>>>>>> REPLACE

</suggested_fix>

### Comment 3
<location> `astrbot/core/message/components.py:987` </location>
<code_context>

+# 匹配消息用字典
 ComponentTypes = {
     "plain": Plain,
     "text": Plain,
</code_context>

<issue_to_address>
ComponentTypes dictionary may need normalization for key casing.

Normalize dictionary keys and input values to a consistent case to prevent lookup failures due to casing differences.

Suggested implementation:

```python
# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,

```

```python
# 用于安全查找组件类型,自动规范化输入键为小写
def get_component_type(key: str):
    return ComponentTypes.get(key.lower())

# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,

```

1. Replace any direct lookup like `ComponentTypes[some_key]` elsewhere in the codebase with `get_component_type(some_key)` to ensure normalization.
2. If there are other places where keys are added to `ComponentTypes`, ensure they are added in lowercase.
</issue_to_address>

### Comment 4
<location> `astrbot/core/platform/astr_message_event.py:29` </location>
<code_context>

 @dataclass
 class MessageSesion:
+    """
+    消息会话
</code_context>

<issue_to_address>
Typo in class name: 'MessageSesion' should be 'MessageSession'.

Rename the class to 'MessageSession' to match its usage elsewhere and maintain consistency.

Suggested implementation:

```python
class MessageSession:
    """
    消息会话
    用于统一标识一个消息会话
    """

    platform_name: str
    message_type: MessageType
    session_id: str

```

If there are any usages of `MessageSesion` elsewhere in the codebase, those should also be updated to `MessageSession` for consistency.
</issue_to_address>

### Comment 5
<location> `astrbot/api/README.md:14` </location>
<code_context>
+astrbot.api.event: 包括了 AstrBot 事件以及相关类的导入
+astrbot.api.event.filter(将弃用): 包括了事件过滤器, 用于注册 Handler, 由 astrbot.api.star.register 统一注册来代替
+astrbot.api.event.message: 包括了 AstrBot 事件中, 所有有关消息的类
+astrbot.api.api.event.message.message_components: 包括了所有消息组件
+
+astrbot.api.platform: 包括了所有平台相关的导入
</code_context>

<issue_to_address>
Possible typo: 'astrbot.api.api.event.message.message_components' has 'api' twice.

Consider updating the import path to 'astrbot.api.event.message.message_components' if the repetition of 'api' is unintentional.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
astrbot.api.api.event.message.message_components: 包括了所有消息组件
=======
astrbot.api.event.message.message_components: 包括了所有消息组件
>>>>>>> REPLACE

</suggested_fix>

### Comment 6
<location> `astrbot/api/provider/__init__.py:23` </location>
<code_context>
 )
+from astrbot.core.provider.manager import ProviderManager
+
+from astrbot.core.provider.sources.anthropic_source import ProviderAnthropic  # Claude
+from astrbot.core.provider.sources.azure_tts_source import (
+    OTTSProvider,
</code_context>

<issue_to_address>
Consider dynamically discovering and importing provider classes to avoid manual boilerplate imports.

You can eliminate almost all of that boilerplate by discovering and importing your providers dynamically. For example, turn `astrbot/core/provider/sources/` into a proper package (with its own `__init__.py`), and do something like this:

```python
# astrbot/core/provider/sources/__init__.py
import pkgutil
import importlib
from astrbot.core.provider.provider import BaseProvider  # or whatever your common parent is

__all__ = []

for finder, module_name, ispkg in pkgutil.iter_modules(__path__):
    module = importlib.import_module(f"{__name__}.{module_name}")
    for obj in vars(module).values():
        if isinstance(obj, type) and issubclass(obj, BaseProvider):
            globals()[obj.__name__] = obj
            __all__.append(obj.__name__)
```

Then your top-level `astrbot/api/provider/__init__.py` can simply re-export everything in that subpackage:

```python
from astrbot.core.provider.provider import Provider, STTProvider, Personality, TTSProvider, EmbeddingProvider
from astrbot.core.provider.entities import (
    ProviderRequest, ProviderType, ProviderMetaData, LLMResponse,
    ToolCallsResult, AssistantMessageSegment, ToolCallMessageSegment,
)
from astrbot.core.provider.manager import ProviderManager

# pull in all providers dynamically
from astrbot.core.provider.sources import *

__all__ = [
    "Provider", "STTProvider", "Personality", "TTSProvider", "EmbeddingProvider",
    "ProviderRequest", "ProviderType", "ProviderMetaData", "LLMResponse",
    "ToolCallsResult", "AssistantMessageSegment", "ToolCallMessageSegment",
    "ProviderManager",
] + __all__  # append all the dynamically discovered provider class names
```

This keeps every provider on `__all__`, but you no longer have to hand-maintain dozens of import lines.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

QQ 戳一戳
"""

type: str = ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: 戳一戳类型被定义为 str 而不是 ComponentType。

这种不一致可能会影响类型检查和序列化。除非有特定原因,否则请更新“type”字段以使用“ComponentType”来匹配其他组件。

Suggested change
type: str = ""
type: ComponentType = "Poke"
Original comment in English

suggestion: Poke type is defined as str instead of ComponentType.

This inconsistency may affect type checking and serialization. Please update to use 'ComponentType' for 'type' to match other components, unless there's a specific reason for using 'str'.

Suggested change
type: str = ""
type: ComponentType = "Poke"

"""

type: ComponentType = "Contact"
_type: str # type 字段冲突
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: '_type' 字段可能存在命名冲突。

建议重命名 '_type' 或添加清晰的文档,以防止混淆和潜在的序列化问题。

Suggested change
_type: str # type 字段冲突
contact_type: str # 原字段名为 _type,为避免与 type 冲突已重命名。用于标识推荐的好友或群类型。
Original comment in English

suggestion: Potential naming conflict with '_type' field.

Renaming '_type' or adding clear documentation is recommended to prevent confusion and potential serialization problems.

Suggested change
_type: str # type 字段冲突
contact_type: str # 原字段名为 _type,为避免与 type 冲突已重命名。用于标识推荐的好友或群类型。


# 匹配消息用字典
ComponentTypes = {
"plain": Plain,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: ComponentTypes 字典可能需要规范化键的大小写。

规范化字典键和输入值为一致的大小写,以防止因大小写差异导致的查找失败。

建议的实现:

# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,
# 用于安全查找组件类型,自动规范化输入键为小写
def get_component_type(key: str):
    return ComponentTypes.get(key.lower())

# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,
  1. 将代码库中任何直接查找(如 ComponentTypes[some_key])替换为 get_component_type(some_key) 以确保规范化。
  2. 如果在其他地方向 ComponentTypes 添加键,请确保它们以小写形式添加。
Original comment in English

suggestion: ComponentTypes dictionary may need normalization for key casing.

Normalize dictionary keys and input values to a consistent case to prevent lookup failures due to casing differences.

Suggested implementation:

# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,
# 用于安全查找组件类型,自动规范化输入键为小写
def get_component_type(key: str):
    return ComponentTypes.get(key.lower())

# 匹配消息用字典,所有键统一为小写
ComponentTypes = {
    "plain": Plain,
    "text": Plain,
  1. Replace any direct lookup like ComponentTypes[some_key] elsewhere in the codebase with get_component_type(some_key) to ensure normalization.
  2. If there are other places where keys are added to ComponentTypes, ensure they are added in lowercase.

anka-afk and others added 3 commits September 1, 2025 13:39
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
@LIghtJUNction
Copy link
Contributor

Motivation

之前的api有点乱, 并且命名和结构不是很规范(例如all里面并不是真的all)
因此进行api结构调整, 同时保留之前的全部api和结构以向后兼容

Modifications

去除了所有import *
加入大部分事件, 平台, 供应商api, 便于构造特定供应商的请求/特定平台的事件
提供了详尽的注释

正在慢慢撰写相应的api文档

Check

  • 😊 我的 Commit Message 符合良好的规范
  • 👀 我的更改经过良好的测试
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。
  • 😮 我的更改没有引入恶意代码

Sourcery 总结

标准化并模块化 AstrBot API 表面,通过显式导出、子包组织和丰富组件定义,同时保持向后兼容性。

增强功能:

  • 将顶级 API 重组为专用子包(event, platform, provider, star, util, tool),并消除通配符导入
  • 增强消息组件类型和类,提供详细的文档字符串和额外的平台特定枚举
  • 扩展 provider API,通过显式导入包含新的 TTS、嵌入和 LLM 源提供者
  • api.star.register 下模块化插件注册和事件过滤
  • 引入 README.md 文档,说明新的 API 结构

文档:

  • 在所有 API 模块中添加全面的文档字符串,并提供 README 概述标准化 API 布局
Original summary in English

Summary by Sourcery

Standardize and modularize the AstrBot API surface with explicit exports, subpackage organization, and enriched component definitions while preserving backward compatibility

Enhancements:

  • Reorganize top-level api into dedicated subpackages (event, platform, provider, star, util, tool) and eliminate wildcard imports
  • Augment message component types and classes with detailed docstrings and additional platforms-specific enums
  • Expand provider API to include new TTS, embedding, and LLM source providers via explicit imports
  • Modularize plugin registration and event filtering under api.star.register
  • Introduce README.md documenting the new API structure

Documentation:

  • Add comprehensive docstrings across API modules and a README overview of the standardized API layout

请问你说的all是指的:__all__吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants