From 313275662334baaf9ea3b46fcf7788e2c5db5809 Mon Sep 17 00:00:00 2001 From: xj Date: Wed, 25 Feb 2026 22:26:23 -0800 Subject: [PATCH] fix(hooks): restore direct message callback when hooks disabled --- docs/hooks-plugin-examples.md | 1 + pkg/agent/loop.go | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/docs/hooks-plugin-examples.md b/docs/hooks-plugin-examples.md index 1e9d427ae..8626f8d67 100644 --- a/docs/hooks-plugin-examples.md +++ b/docs/hooks-plugin-examples.md @@ -134,4 +134,5 @@ Recommended ordering: - Hook panics are recovered internally; one bad hook does not crash the loop. - Hook errors are logged and execution continues unless `Cancel` is set. +- Observe-only hooks (`message_received`, `after_tool_call`, `llm_input`, `llm_output`, `session_start`, `session_end`) must treat events as read-only. - Keep hook handlers fast and non-blocking to avoid latency impact. diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 9bd9145bb..5c257539b 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -230,6 +230,17 @@ func (al *AgentLoop) SetHooks(h *hooks.HookRegistry) error { if agent, ok := al.registry.GetAgent(agentID); ok { if tool, ok := agent.Tools.Get("message"); ok { if mt, ok := tool.(*tools.MessageTool); ok { + if h == nil { + mt.SetSendCallback(func(_ context.Context, channel, chatID, content string) error { + al.bus.PublishOutbound(bus.OutboundMessage{ + Channel: channel, + ChatID: chatID, + Content: content, + }) + return nil + }) + continue + } mt.SetSendCallback(func(ctx context.Context, channel, chatID, content string) error { if sent, reason := al.sendOutbound(ctx, bus.OutboundMessage{ Channel: channel,