mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-06-10 10:10:49 +00:00
feat(agent): adaptive tool timing with slow tool notification
Track per-tool execution time statistics in session metadata. When a tool call exceeds its adaptive threshold (2x historical max, min 120s default), send a direct outbound notification to the user. - ToolTimingMap: parse/serialize/record/threshold from session metadata - StartSlowTimer: fires once per tool call, auto-cancels on completion - Team config: slow_tool toggle (default on, always direct, never leader) - UI: toggle in team settings with i18n (en/vi/zh) - Store: add GetSessionMetadata to session store interface
This commit is contained in:
@@ -788,6 +788,9 @@ func runGateway() {
|
||||
}
|
||||
})
|
||||
|
||||
// Slow tool notification subscriber — direct outbound when tool exceeds adaptive threshold.
|
||||
wireSlowToolNotifySubscriber(msgBus)
|
||||
|
||||
// Start inbound message consumer (channel → scheduler → agent → channel)
|
||||
consumerTeamStore := pgStores.Teams
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/nextlevelbuilder/goclaw/internal/agent"
|
||||
"github.com/nextlevelbuilder/goclaw/internal/bus"
|
||||
"github.com/nextlevelbuilder/goclaw/pkg/protocol"
|
||||
)
|
||||
|
||||
// wireSlowToolNotifySubscriber registers a subscriber that sends direct outbound
|
||||
// notifications when a tool call exceeds its adaptive slow threshold.
|
||||
// Always uses direct mode (never leader) to avoid wasting LLM calls.
|
||||
// Team config (slow_tool enabled/disabled) is resolved in the loop before emitting
|
||||
// the event, so no DB query is needed here.
|
||||
func wireSlowToolNotifySubscriber(msgBus *bus.MessageBus) {
|
||||
msgBus.Subscribe("consumer.slow-tool-notify", func(event bus.Event) {
|
||||
if event.Name != protocol.EventAgent {
|
||||
return
|
||||
}
|
||||
agentEvent, ok := event.Payload.(agent.AgentEvent)
|
||||
if !ok || agentEvent.Type != protocol.AgentEventActivity {
|
||||
return
|
||||
}
|
||||
payloadMap, _ := agentEvent.Payload.(map[string]any)
|
||||
phase, _ := payloadMap["phase"].(string)
|
||||
if phase != "tool_slow" {
|
||||
return
|
||||
}
|
||||
if agentEvent.Channel == "" || agentEvent.ChatID == "" {
|
||||
return
|
||||
}
|
||||
|
||||
tool, _ := payloadMap["tool"].(string)
|
||||
thresholdMs, _ := payloadMap["threshold_ms"].(int64)
|
||||
thresholdSec := thresholdMs / 1000
|
||||
if thresholdSec <= 0 {
|
||||
thresholdSec = 120
|
||||
}
|
||||
|
||||
content := fmt.Sprintf("⏳ %s: tool %s running longer than usual (>%ds)", agentEvent.AgentID, tool, thresholdSec)
|
||||
msgBus.PublishOutbound(bus.OutboundMessage{
|
||||
Channel: agentEvent.Channel,
|
||||
ChatID: agentEvent.ChatID,
|
||||
Content: content,
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user