mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-06-02 00:57:41 +08:00
126 lines
4.0 KiB
Python
126 lines
4.0 KiB
Python
"""
|
|
Agent Event Handler - Handles agent events and thinking process output
|
|
"""
|
|
|
|
from common import const
|
|
from common.log import logger
|
|
|
|
# Cap intermediate thinking messages on weixin to stay within send quota.
|
|
WEIXIN_THINKING_INSTANT_MAX = 7
|
|
|
|
|
|
class AgentEventHandler:
|
|
"""
|
|
Handles agent events and optionally sends intermediate messages to channel
|
|
"""
|
|
|
|
def __init__(self, context=None, original_callback=None):
|
|
self.context = context
|
|
self.original_callback = original_callback
|
|
|
|
self.channel = None
|
|
if context:
|
|
self.channel = context.kwargs.get("channel") if hasattr(context, "kwargs") else None
|
|
|
|
self.current_content = ""
|
|
self.turn_number = 0
|
|
|
|
channel_type = ""
|
|
if context and hasattr(context, "kwargs"):
|
|
channel_type = context.kwargs.get("channel_type", "") or ""
|
|
self._is_weixin = channel_type == const.WEIXIN
|
|
self._thinking_sent_count = 0
|
|
self._merged_buf: list[str] = []
|
|
|
|
def handle_event(self, event):
|
|
event_type = event.get("type")
|
|
data = event.get("data", {})
|
|
|
|
if event_type == "turn_start":
|
|
self._handle_turn_start(data)
|
|
elif event_type == "message_update":
|
|
self._handle_message_update(data)
|
|
elif event_type == "message_end":
|
|
self._handle_message_end(data)
|
|
elif event_type == "reasoning_update":
|
|
pass
|
|
elif event_type == "tool_execution_start":
|
|
self._handle_tool_execution_start(data)
|
|
elif event_type == "tool_execution_end":
|
|
self._handle_tool_execution_end(data)
|
|
elif event_type == "agent_end":
|
|
self._handle_agent_end(data)
|
|
|
|
if self.original_callback:
|
|
self.original_callback(event)
|
|
|
|
def _handle_turn_start(self, data):
|
|
self.turn_number = data.get("turn", 0)
|
|
self.current_content = ""
|
|
|
|
def _handle_message_update(self, data):
|
|
delta = data.get("delta", "")
|
|
self.current_content += delta
|
|
|
|
def _handle_message_end(self, data):
|
|
tool_calls = data.get("tool_calls", [])
|
|
|
|
if tool_calls:
|
|
if self.current_content.strip():
|
|
logger.info(f"💭 {self.current_content.strip()[:200]}{'...' if len(self.current_content) > 200 else ''}")
|
|
self._send_to_channel(self.current_content.strip())
|
|
else:
|
|
if self.current_content.strip():
|
|
logger.debug(f"💬 {self.current_content.strip()[:200]}{'...' if len(self.current_content) > 200 else ''}")
|
|
# Drain weixin buffer before final reply leaves chat_channel
|
|
self._flush_merged_now()
|
|
|
|
self.current_content = ""
|
|
|
|
def _handle_agent_end(self, data):
|
|
self._flush_merged_now()
|
|
|
|
def _handle_tool_execution_start(self, data):
|
|
pass
|
|
|
|
def _handle_tool_execution_end(self, data):
|
|
pass
|
|
|
|
def _send_to_channel(self, message):
|
|
if self.context and self.context.get("on_event"):
|
|
return
|
|
if not self.channel:
|
|
return
|
|
|
|
if not self._is_weixin:
|
|
self._do_send(message)
|
|
return
|
|
|
|
if self._thinking_sent_count < WEIXIN_THINKING_INSTANT_MAX:
|
|
self._do_send(message)
|
|
self._thinking_sent_count += 1
|
|
return
|
|
|
|
self._merged_buf.append(message)
|
|
|
|
def _flush_merged_now(self):
|
|
if not self._merged_buf:
|
|
return
|
|
merged = "\n\n".join(self._merged_buf)
|
|
count = len(self._merged_buf)
|
|
self._merged_buf = []
|
|
logger.debug(f"[AgentEventHandler] Flushing {count} merged thinking msgs, len={len(merged)}")
|
|
self._do_send(merged)
|
|
self._thinking_sent_count += 1
|
|
|
|
def _do_send(self, message):
|
|
try:
|
|
from bridge.reply import Reply, ReplyType
|
|
reply = Reply(ReplyType.TEXT, message)
|
|
self.channel._send(reply, self.context)
|
|
except Exception as e:
|
|
logger.debug(f"[AgentEventHandler] Failed to send to channel: {e}")
|
|
|
|
def log_summary(self):
|
|
pass
|