Compare commits

...

6 Commits

Author SHA1 Message Date
Soulter
81932f4a05 chore: ruff format 2026-04-14 18:47:29 +08:00
Soulter
6965a1d7d6 feat: rename event types to include 'Event' suffix for consistency 2026-04-14 18:46:43 +08:00
Soulter
b692674c52 Update astrbot/core/astr_agent_hooks.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-04-14 18:43:52 +08:00
Soulter
284f83bcb0 Update astrbot/core/star/star_handler.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-04-14 18:43:36 +08:00
Soulter
748ed1495b docs: add version requirement for event hooks in message event guide 2026-04-14 18:35:22 +08:00
Soulter
6e517ff096 feat: add on_agent_begin, on_using_llm_tool, on_llm_tool_respond, on_agent_done event hooks 2026-04-14 18:32:20 +08:00
9 changed files with 367 additions and 0 deletions

View File

@@ -14,6 +14,8 @@ from astrbot.core.star.register import register_command_group as command_group
from astrbot.core.star.register import register_custom_filter as custom_filter
from astrbot.core.star.register import register_event_message_type as event_message_type
from astrbot.core.star.register import register_llm_tool as llm_tool
from astrbot.core.star.register import register_on_agent_begin as on_agent_begin
from astrbot.core.star.register import register_on_agent_done as on_agent_done
from astrbot.core.star.register import register_on_astrbot_loaded as on_astrbot_loaded
from astrbot.core.star.register import (
register_on_decorating_result as on_decorating_result,
@@ -51,6 +53,8 @@ __all__ = [
"custom_filter",
"event_message_type",
"llm_tool",
"on_agent_begin",
"on_agent_done",
"on_astrbot_loaded",
"on_decorating_result",
"on_llm_request",

View File

@@ -12,6 +12,15 @@ from astrbot.core.star.star_handler import EventType
class MainAgentHooks(BaseAgentRunHooks[AstrAgentContext]):
async def on_agent_begin(
self, run_context: ContextWrapper[AstrAgentContext]
) -> None:
await call_event_hook(
run_context.context.event,
EventType.OnAgentBeginEvent,
run_context,
)
async def on_agent_done(self, run_context, llm_response) -> None:
# 执行事件钩子
if llm_response and llm_response.reasoning_content:
@@ -25,6 +34,12 @@ class MainAgentHooks(BaseAgentRunHooks[AstrAgentContext]):
EventType.OnLLMResponseEvent,
llm_response,
)
await call_event_hook(
run_context.context.event,
EventType.OnAgentDoneEvent,
run_context,
llm_response,
)
async def on_tool_start(
self,

View File

@@ -7,6 +7,8 @@ from .star_handler import (
register_custom_filter,
register_event_message_type,
register_llm_tool,
register_on_agent_begin,
register_on_agent_done,
register_on_astrbot_loaded,
register_on_decorating_result,
register_on_llm_request,
@@ -31,6 +33,8 @@ __all__ = [
"register_custom_filter",
"register_event_message_type",
"register_llm_tool",
"register_on_agent_begin",
"register_on_agent_done",
"register_on_astrbot_loaded",
"register_on_decorating_result",
"register_on_llm_request",

View File

@@ -460,6 +460,64 @@ def register_on_llm_response(**kwargs):
return decorator
def register_on_agent_begin(**kwargs):
"""当 Agent 开始运行时的事件
Examples:
```py
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@on_agent_begin()
async def test(
self,
event: AstrMessageEvent,
run_context: ContextWrapper[AstrAgentContext],
) -> None:
...
```
请务必接收两个参数event, run_context
"""
def decorator(awaitable):
_ = get_handler_or_create(awaitable, EventType.OnAgentBeginEvent, **kwargs)
return awaitable
return decorator
def register_on_agent_done(**kwargs):
"""当 Agent 运行完成后的事件
Examples:
```py
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
from astrbot.api.provider import LLMResponse
@on_agent_done()
async def test(
self,
event: AstrMessageEvent,
run_context: ContextWrapper[AstrAgentContext],
response: LLMResponse,
) -> None:
...
```
请务必接收三个参数event, run_context, response
"""
def decorator(awaitable):
_ = get_handler_or_create(awaitable, EventType.OnAgentDoneEvent, **kwargs)
return awaitable
return decorator
def register_on_using_llm_tool(**kwargs):
"""当调用函数工具前的事件。
会传入 tool 和 tool_args 参数。

View File

@@ -71,6 +71,22 @@ class StarHandlerRegistry(Generic[T]):
plugins_name: list[str] | None = None,
) -> list[StarHandlerMetadata[Callable[..., Awaitable[Any]]]]: ...
@overload
def get_handlers_by_event_type(
self,
event_type: Literal[EventType.OnAgentBeginEvent],
only_activated=True,
plugins_name: list[str] | None = None,
) -> list[StarHandlerMetadata[Callable[..., Awaitable[Any]]]]: ...
@overload
def get_handlers_by_event_type(
self,
event_type: Literal[EventType.OnAgentDoneEvent],
only_activated=True,
plugins_name: list[str] | None = None,
) -> list[StarHandlerMetadata[Callable[..., Awaitable[Any]]]]: ...
@overload
def get_handlers_by_event_type(
self,
@@ -213,6 +229,8 @@ class EventType(enum.Enum):
OnWaitingLLMRequestEvent = enum.auto() # 等待调用 LLM在获取锁之前仅通知
OnLLMRequestEvent = enum.auto() # 收到 LLM 请求(可以是用户也可以是插件)
OnLLMResponseEvent = enum.auto() # LLM 响应后
OnAgentBeginEvent = enum.auto() # Agent 开始运行
OnAgentDoneEvent = enum.auto() # Agent 运行完成
OnDecoratingResultEvent = enum.auto() # 发送消息前
OnCallingFuncToolEvent = enum.auto() # 调用函数工具
OnUsingLLMToolEvent = enum.auto() # 使用 LLM 工具

View File

@@ -79,6 +79,8 @@ class PluginRoute(Route):
EventType.AdapterMessageEvent: "平台消息下发时",
EventType.OnLLMRequestEvent: "LLM 请求时",
EventType.OnLLMResponseEvent: "LLM 响应后",
EventType.OnAgentBeginEvent: "Agent 开始运行时",
EventType.OnAgentDoneEvent: "Agent 运行完成后",
EventType.OnDecoratingResultEvent: "回复消息前",
EventType.OnCallingFuncToolEvent: "函数工具",
EventType.OnAfterMessageSentEvent: "发送消息后",

View File

@@ -289,6 +289,94 @@ async def on_llm_resp(self, event: AstrMessageEvent, resp: LLMResponse): # Note
> You cannot use yield to send messages here. If you need to send, please use the `event.send()` method directly.
#### On Agent Begin
> Requires AstrBot version > v4.23.1
When the Agent starts running, the `on_agent_begin` hook is triggered.
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@filter.on_agent_begin()
async def on_agent_begin(self, event: AstrMessageEvent, run_context: ContextWrapper[AstrAgentContext]): # Note there are three parameters
print("Agent started")
```
> You cannot use yield to send messages here. If you need to send, please use the `event.send()` method directly.
#### Before LLM Tool Call
> Requires AstrBot version > v4.23.1
When the Agent is about to call an LLM tool, the `on_using_llm_tool` hook is triggered.
You can obtain the `FunctionTool` object and tool call arguments.
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.tool import FunctionTool
@filter.on_using_llm_tool()
async def on_using_llm_tool(
self,
event: AstrMessageEvent,
tool: FunctionTool,
tool_args: dict | None,
):
print(tool.name, tool_args)
```
> You cannot use yield to send messages here. If you need to send, please use the `event.send()` method directly.
#### After LLM Tool Call
> Requires AstrBot version > v4.23.1
After the LLM tool call completes, the `on_llm_tool_respond` hook is triggered.
You can obtain the `FunctionTool` object, tool call arguments, and tool call result.
```python
from mcp.types import CallToolResult
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.tool import FunctionTool
@filter.on_llm_tool_respond()
async def on_llm_tool_respond(
self,
event: AstrMessageEvent,
tool: FunctionTool,
tool_args: dict | None,
tool_result: CallToolResult | None,
):
print(tool.name, tool_args, tool_result)
```
> You cannot use yield to send messages here. If you need to send, please use the `event.send()` method directly.
#### On Agent Done
> Requires AstrBot version > v4.23.1
After the Agent finishes running, the `on_agent_done` hook is triggered. This hook is triggered after `on_llm_response`.
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.api.provider import LLMResponse
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@filter.on_agent_done()
async def on_agent_done(self, event: AstrMessageEvent, run_context: ContextWrapper[AstrAgentContext], resp: LLMResponse): # Note there are four parameters
print(resp)
```
> You cannot use yield to send messages here. If you need to send, please use the `event.send()` method directly.
#### Before Sending Message
Before sending a message, the `on_decorating_result` hook is triggered.

View File

@@ -305,6 +305,94 @@ async def on_llm_resp(self, event: AstrMessageEvent, resp: LLMResponse): # 请
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
#### Agent 开始运行时
> 适用于 AstrBot 版本 > v4.23.1
在 Agent 开始运行时,会触发 `on_agent_begin` 钩子。
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@filter.on_agent_begin()
async def on_agent_begin(self, event: AstrMessageEvent, run_context: ContextWrapper[AstrAgentContext]):
print("Agent 开始运行")
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
#### LLM 工具调用前
> 适用于 AstrBot 版本 > v4.23.1
在 Agent 准备调用 LLM 工具时,会触发 `on_using_llm_tool` 钩子。
可以获取到 `FunctionTool` 对象和工具调用参数。
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.tool import FunctionTool
@filter.on_using_llm_tool()
async def on_using_llm_tool(
self,
event: AstrMessageEvent,
tool: FunctionTool,
tool_args: dict | None,
):
print(tool.name, tool_args)
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
#### LLM 工具调用后
> 适用于 AstrBot 版本 > v4.23.1
在 LLM 工具调用完成后,会触发 `on_llm_tool_respond` 钩子。
可以获取到 `FunctionTool` 对象、工具调用参数和工具调用结果。
```python
from mcp.types import CallToolResult
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.tool import FunctionTool
@filter.on_llm_tool_respond()
async def on_llm_tool_respond(
self,
event: AstrMessageEvent,
tool: FunctionTool,
tool_args: dict | None,
tool_result: CallToolResult | None,
):
print(tool.name, tool_args, tool_result)
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
#### Agent 运行完成时
> 适用于 AstrBot 版本 > v4.23.1
在 Agent 运行完成后,会触发 `on_agent_done` 钩子。这个钩子会在 `on_llm_response` 之后触发。本质上和 `on_llm_response` 一样。
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.api.provider import LLMResponse
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@filter.on_agent_done()
async def on_agent_done(self, event: AstrMessageEvent, run_context: ContextWrapper[AstrAgentContext], resp: LLMResponse):
print(resp)
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
#### 发送消息前
在发送消息前,会触发 `on_decorating_result` 钩子。

View File

@@ -507,6 +507,96 @@ async def on_llm_resp(self, event: AstrMessageEvent, resp: LLMResponse): # 请
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
##### Agent 开始运行时
> 适用于 AstrBot 版本 > v4.23.1
在 Agent 开始运行时,会触发 `on_agent_begin` 钩子。
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@filter.on_agent_begin()
async def on_agent_begin(self, event: AstrMessageEvent, run_context: ContextWrapper[AstrAgentContext]): # 请注意有三个参数
print("Agent 开始运行")
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
##### LLM 工具调用前
> 适用于 AstrBot 版本 > v4.23.1
在 Agent 准备调用 LLM 工具时,会触发 `on_using_llm_tool` 钩子。
可以获取到 `FunctionTool` 对象和工具调用参数。
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.tool import FunctionTool
@filter.on_using_llm_tool()
async def on_using_llm_tool(
self,
event: AstrMessageEvent,
tool: FunctionTool,
tool_args: dict | None,
):
print(tool.name, tool_args)
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
##### LLM 工具调用后
> 适用于 AstrBot 版本 > v4.23.1
在 LLM 工具调用完成后,会触发 `on_llm_tool_respond` 钩子。
可以获取到 `FunctionTool` 对象、工具调用参数和工具调用结果。
```python
from mcp.types import CallToolResult
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.core.agent.tool import FunctionTool
@filter.on_llm_tool_respond()
async def on_llm_tool_respond(
self,
event: AstrMessageEvent,
tool: FunctionTool,
tool_args: dict | None,
tool_result: CallToolResult | None,
):
print(tool.name, tool_args, tool_result)
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
##### Agent 运行完成时
> 适用于 AstrBot 版本 > v4.23.1
在 Agent 运行完成后,会触发 `on_agent_done` 钩子。这个钩子会在 `on_llm_response` 之后触发。
可以获取到 `LLMResponse` 对象,可以对其进行修改。
```python
from astrbot.api.event import filter, AstrMessageEvent
from astrbot.api.provider import LLMResponse
from astrbot.core.agent.run_context import ContextWrapper
from astrbot.core.astr_agent_context import AstrAgentContext
@filter.on_agent_done()
async def on_agent_done(self, event: AstrMessageEvent, run_context: ContextWrapper[AstrAgentContext], resp: LLMResponse): # 请注意有四个参数
print(resp)
```
> 这里不能使用 yield 来发送消息。如需发送,请直接使用 `event.send()` 方法。
##### 发送消息前
在发送消息前,会触发 `on_decorating_result` 钩子。