mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-18 10:14:49 +00:00
feat: enhance agent tool loop detection sensitivity, add Markdown to HTML conversion for Telegram media captions, and refine trace detail dialog UI styling.
This commit is contained in:
1 parent
45ea0ee9a4
commit
26067d2432
4 files changed
+15
-9
No files matched your search
@@ -10,9 +10,9 @@ import (
|
||||
|
||||
// Tool loop detection thresholds (per-run, not per-session).
|
||||
const (
|
||||
toolLoopHistorySize = 30
|
||||
toolLoopWarningThreshold = 5 // inject warning into conversation
|
||||
toolLoopCriticalThreshold = 10 // force stop the iteration loop
|
||||
toolLoopHistorySize = 30
|
||||
toolLoopWarningThreshold = 3 // inject warning into conversation
|
||||
toolLoopCriticalThreshold = 5 // force stop the iteration loop
|
||||
)
|
||||
|
||||
// toolLoopState tracks recent tool calls within a single agent run
|
||||
|
||||
@@ -5,8 +5,8 @@ import "testing"
|
||||
func TestToolLoopDetection_NoLoop(t *testing.T) {
|
||||
var s toolLoopState
|
||||
|
||||
// 4 identical calls with same result → below threshold, no detection
|
||||
for i := 0; i < 4; i++ {
|
||||
// 2 identical calls with same result → below threshold, no detection
|
||||
for i := 0; i < 2; i++ {
|
||||
h := s.record("list_files", map[string]interface{}{"path": "."})
|
||||
s.recordResult(h, "access denied")
|
||||
level, _ := s.detect("list_files", h)
|
||||
@@ -77,7 +77,8 @@ func TestToolLoopDetection_MixedTools(t *testing.T) {
|
||||
var s toolLoopState
|
||||
|
||||
// Alternate between two tools with same result → each tool only hit ~half
|
||||
for i := 0; i < 15; i++ {
|
||||
// With 8 iterations, each tool is called 4 times → below critical (5)
|
||||
for i := 0; i < 8; i++ {
|
||||
toolName := "list_files"
|
||||
if i%2 == 1 {
|
||||
toolName = "read_file"
|
||||
@@ -85,7 +86,7 @@ func TestToolLoopDetection_MixedTools(t *testing.T) {
|
||||
h := s.record(toolName, map[string]interface{}{"path": "."})
|
||||
s.recordResult(h, "error")
|
||||
level, _ := s.detect(toolName, h)
|
||||
// Each tool is only called ~7-8 times, should at most warn
|
||||
// Each tool is only called 4 times, should at most warn
|
||||
if level == "critical" {
|
||||
t.Fatalf("iteration %d: unexpected critical for alternating tools", i)
|
||||
}
|
||||
|
||||
@@ -137,6 +137,11 @@ func (c *Channel) sendMediaMessage(ctx context.Context, chatID int64, msg bus.Ou
|
||||
msg.Content = "" // only use for first media
|
||||
}
|
||||
|
||||
// Convert caption from markdown to Telegram HTML (same as regular messages)
|
||||
if caption != "" {
|
||||
caption = markdownToTelegramHTML(caption)
|
||||
}
|
||||
|
||||
// Split caption if too long (Telegram limit: 1024 chars)
|
||||
var followUpText string
|
||||
if len(caption) > telegramCaptionMaxLen {
|
||||
|
||||
@@ -176,7 +176,7 @@ function SpanTreeNode({ node, depth }: { node: SpanNode; depth: number }) {
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className="mt-1.5 rounded-md border text-sm"
|
||||
className="mt-1.5 min-w-0 rounded-md border text-sm"
|
||||
style={{ marginLeft: depth * 24 }}
|
||||
>
|
||||
<div className="flex w-full items-center gap-1 px-2 py-2">
|
||||
@@ -233,7 +233,7 @@ function SpanTreeNode({ node, depth }: { node: SpanNode; depth: number }) {
|
||||
|
||||
{/* Expanded detail panel */}
|
||||
{detailOpen && (
|
||||
<div className="space-y-2 border-t px-3 py-2">
|
||||
<div className="space-y-2 overflow-hidden border-t px-3 py-2">
|
||||
{span.model && (
|
||||
<div className="text-xs">
|
||||
<span className="text-muted-foreground">Model:</span> {span.provider}/{span.model}
|
||||
|
||||
Reference in new issue
Block a user