feat: add context compression hooks for plugin extensibility -还未自测,但是修改内容不多,如果可以的话可以直接合并#5291
feat: add context compression hooks for plugin extensibility -还未自测,但是修改内容不多,如果可以的话可以直接合并#5291evpeople wants to merge 3 commits intoAstrBotDevs:masterfrom
Conversation
Add two new event types: - OnBeforeContextCompressionEvent: triggered before context compression - OnAfterContextCompressionEvent: triggered after context compression Plugins can now register handlers to execute custom logic during context compression, enabling features like logging, analytics, or preserving specific conversation history.
Summary of ChangesHello @evpeople, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the system's extensibility by introducing new event hooks around the context compression process. This allows external plugins to tap into critical stages of conversation context management, enabling custom functionalities such as logging, analytics, or specialized handling of conversation history before and after compression occurs. The changes provide a more flexible and modular architecture for managing conversational context. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Hey - 我发现了两个问题,并给出了一些高层次的反馈:
- 建议在
_run_compression中对call_event_hook的调用加一层 try/except,这样即使插件的 hook 失败,也不会破坏核心的上下文压缩逻辑。 - 在
tool_loop_agent_runner.step中,把hasattr(self.run_context.context, "event")这个检查换成getattr(self.run_context.context, "event", None)会更简洁、更清晰,用来在调用context_manager.process时传入 event。
给 AI Agents 的提示词
Please address the comments from this code review:
## Overall Comments
- Consider wrapping the `call_event_hook` invocations in `_run_compression` with a try/except so that plugin hook failures don’t break core context compression behavior.
- In `tool_loop_agent_runner.step`, the `hasattr(self.run_context.context, "event")` check could be simplified and made clearer with `getattr(self.run_context.context, "event", None)` when passing the event into `context_manager.process`.
## Individual Comments
### Comment 1
<location> `astrbot/core/agent/context/manager.py:141-147` </location>
<code_context>
# still need compress, truncate by half
messages = self.truncator.truncate_by_halving(messages)
+ # Trigger after compression hook
+ if event:
+ await call_event_hook(
+ event,
+ EventType.OnAfterContextCompressionEvent,
+ messages,
+ tokens_after_summary,
+ )
+
</code_context>
<issue_to_address>
**issue:** After-compression hook receives token count before truncation, which may be misleading.
Here `tokens_after_summary` is the count immediately after compression but before truncation, so if `truncator` halves the messages further, the final context can have many fewer tokens than reported to `OnAfterContextCompressionEvent` consumers. Either recompute the token count after all truncation steps and pass that, or clarify in the event/parameter naming that this is the post-compression, pre-truncation token count.
</issue_to_address>
### Comment 2
<location> `astrbot/core/agent/runners/tool_loop_agent_runner.py:298-304` </location>
<code_context>
# do truncate and compress
token_usage = self.req.conversation.token_usage if self.req.conversation else 0
self._simple_print_message_role("[BefCompact]")
+ event = (
+ self.run_context.context.event
+ if hasattr(self.run_context.context, "event")
+ else None
+ )
self.run_context.messages = await self.context_manager.process(
</code_context>
<issue_to_address>
**suggestion:** Simplify and make the event extraction more robust using getattr with a default.
Instead of the `hasattr` check and multiline conditional, use `event = getattr(self.run_context.context, "event", None)`. This is clearer and avoids issues if `context` overrides attribute access with side effects.
```suggestion
self._simple_print_message_role("[BefCompact]")
event = getattr(self.run_context.context, "event", None)
self.run_context.messages = await self.context_manager.process(
```
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进以后的 Review。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- Consider wrapping the
call_event_hookinvocations in_run_compressionwith a try/except so that plugin hook failures don’t break core context compression behavior. - In
tool_loop_agent_runner.step, thehasattr(self.run_context.context, "event")check could be simplified and made clearer withgetattr(self.run_context.context, "event", None)when passing the event intocontext_manager.process.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider wrapping the `call_event_hook` invocations in `_run_compression` with a try/except so that plugin hook failures don’t break core context compression behavior.
- In `tool_loop_agent_runner.step`, the `hasattr(self.run_context.context, "event")` check could be simplified and made clearer with `getattr(self.run_context.context, "event", None)` when passing the event into `context_manager.process`.
## Individual Comments
### Comment 1
<location> `astrbot/core/agent/context/manager.py:141-147` </location>
<code_context>
# still need compress, truncate by half
messages = self.truncator.truncate_by_halving(messages)
+ # Trigger after compression hook
+ if event:
+ await call_event_hook(
+ event,
+ EventType.OnAfterContextCompressionEvent,
+ messages,
+ tokens_after_summary,
+ )
+
</code_context>
<issue_to_address>
**issue:** After-compression hook receives token count before truncation, which may be misleading.
Here `tokens_after_summary` is the count immediately after compression but before truncation, so if `truncator` halves the messages further, the final context can have many fewer tokens than reported to `OnAfterContextCompressionEvent` consumers. Either recompute the token count after all truncation steps and pass that, or clarify in the event/parameter naming that this is the post-compression, pre-truncation token count.
</issue_to_address>
### Comment 2
<location> `astrbot/core/agent/runners/tool_loop_agent_runner.py:298-304` </location>
<code_context>
# do truncate and compress
token_usage = self.req.conversation.token_usage if self.req.conversation else 0
self._simple_print_message_role("[BefCompact]")
+ event = (
+ self.run_context.context.event
+ if hasattr(self.run_context.context, "event")
+ else None
+ )
self.run_context.messages = await self.context_manager.process(
</code_context>
<issue_to_address>
**suggestion:** Simplify and make the event extraction more robust using getattr with a default.
Instead of the `hasattr` check and multiline conditional, use `event = getattr(self.run_context.context, "event", None)`. This is clearer and avoids issues if `context` overrides attribute access with side effects.
```suggestion
self._simple_print_message_role("[BefCompact]")
event = getattr(self.run_context.context, "event", None)
self.run_context.messages = await self.context_manager.process(
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Wrap hook calls in try/except to prevent plugin failures from breaking core compression behavior - Recalculate token count after all truncation steps for accurate reporting - Simplify event extraction using getattr with default value
Move call_event_hook and EventType imports inside the hook functions to avoid circular import at module load time.
Add two new event types:
Plugins can now register handlers to execute custom logic during context compression, enabling features like logging, analytics, or preserving specific conversation history.
添加了对话压缩前后两个钩子 #5290
Modifications / 改动点
astrbot/core/star/star_handler.py 新加两个事件
astrbot/core/agent/runners/tool_loop_agent_runner.py 在context_manager.process中,新传入一个参数
astrbot/core/agent/context/manager.py 处理上文传入的参数
Screenshots or Test Results / 运行截图或测试结果
Checklist / 检查清单
requirements.txt和pyproject.toml文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations inrequirements.txtandpyproject.toml.