From b040463cd382985c0a8769abea9000a9cec89605 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 17:48:50 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20hasAttachments?= =?UTF-8?q?=20in=20routing=20by=20bypassing=20strings.ToLower=20for=20most?= =?UTF-8?q?=20inputs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hobbyistlabs-coder <267281733+hobbyistlabs-coder@users.noreply.github.com> --- .jules/bolt.md | 4 ++++ pkg/agent/loop_test.go | 18 ++++++++--------- pkg/config/channels.go | 24 +++++++++++------------ pkg/health/resource_tracker.go | 12 ++++++------ pkg/logger/logger.go | 6 +++--- pkg/migrate/sources/openclaw/common.go | 20 +++++++++---------- pkg/routing/features.go | 27 +++++++++++++++++++------- pkg/tools/alpaca/alpaca.go | 4 ++-- pkg/tools/mcp2cli.go | 2 +- pkg/tools/mcp2cli_test.go | 2 +- pkg/tools/web/fetch.go | 2 +- pkg/tools/web/search.go | 2 +- 12 files changed, 70 insertions(+), 53 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 80e90d5aa..7416f0a69 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -4,3 +4,7 @@ ## 2024-05-25 - Efficient String Building in Loops **Learning:** In Go, string concatenation (`+=`) in a loop leads to $O(N^2)$ complexity due to immutability. Using `strings.Builder` provides $O(N)$ efficiency. Additionally, `fmt.Fprintf` has overhead due to format string parsing; direct `sb.WriteString` calls are significantly faster. **Action:** Use `strings.Builder` for building strings in loops and prefer direct `WriteString` calls over `fmt.Fprintf` for maximum performance in hot paths. + +## 2024-05-26 - Avoid Unnecessary `strings.ToLower` +**Learning:** Calling `strings.ToLower` on the entire message content allocates a new string and iterates over all runes. This causes measurable GC pressure and latency on hot paths like feature extraction during routing. +**Action:** Use fast paths to bypass `strings.ToLower`. For instance, check if a requisite character (like a dot `.`) exists, or check common casings directly (`DATA:IMAGE` vs `data:image`) before falling back to full case-normalization. diff --git a/pkg/agent/loop_test.go b/pkg/agent/loop_test.go index d3b5f304f..d41728103 100644 --- a/pkg/agent/loop_test.go +++ b/pkg/agent/loop_test.go @@ -844,15 +844,15 @@ func TestTargetReasoningChannelID_AllChannels(t *testing.T) { t.Fatalf("Failed to create channel manager: %v", err) } for name, id := range map[string]string{ - "whatsapp": "rid-whatsapp", - "telegram": "rid-telegram", - "discord": "rid-discord", - "maixcam": "rid-maixcam", - "qq": "rid-qq", - "dingtalk": "rid-dingtalk", - "slack": "rid-slack", - "line": "rid-line", - "onebot": "rid-onebot", + "whatsapp": "rid-whatsapp", + "telegram": "rid-telegram", + "discord": "rid-discord", + "maixcam": "rid-maixcam", + "qq": "rid-qq", + "dingtalk": "rid-dingtalk", + "slack": "rid-slack", + "line": "rid-line", + "onebot": "rid-onebot", } { chManager.RegisterChannel(name, &fakeChannel{id: id}) } diff --git a/pkg/config/channels.go b/pkg/config/channels.go index b3c46a93f..cbc7d7db1 100644 --- a/pkg/config/channels.go +++ b/pkg/config/channels.go @@ -1,18 +1,18 @@ package config type ChannelsConfig struct { - WhatsApp WhatsAppConfig `json:"whatsapp"` - Telegram TelegramConfig `json:"telegram"` - Discord DiscordConfig `json:"discord"` - MaixCam MaixCamConfig `json:"maixcam"` - QQ QQConfig `json:"qq"` - DingTalk DingTalkConfig `json:"dingtalk"` - Slack SlackConfig `json:"slack"` - Matrix MatrixConfig `json:"matrix"` - LINE LINEConfig `json:"line"` - OneBot OneBotConfig `json:"onebot"` - Pico PicoConfig `json:"pico"` - IRC IRCConfig `json:"irc"` + WhatsApp WhatsAppConfig `json:"whatsapp"` + Telegram TelegramConfig `json:"telegram"` + Discord DiscordConfig `json:"discord"` + MaixCam MaixCamConfig `json:"maixcam"` + QQ QQConfig `json:"qq"` + DingTalk DingTalkConfig `json:"dingtalk"` + Slack SlackConfig `json:"slack"` + Matrix MatrixConfig `json:"matrix"` + LINE LINEConfig `json:"line"` + OneBot OneBotConfig `json:"onebot"` + Pico PicoConfig `json:"pico"` + IRC IRCConfig `json:"irc"` } // GroupTriggerConfig controls when the bot responds in group chats. diff --git a/pkg/health/resource_tracker.go b/pkg/health/resource_tracker.go index 2ce4291a5..8ac247814 100644 --- a/pkg/health/resource_tracker.go +++ b/pkg/health/resource_tracker.go @@ -66,12 +66,12 @@ func (rt *ResourceTracker) logResources() { sysMB := float64(m.Sys) / 1024 / 1024 logger.InfoCF("SystemHealth", "Resource tracking telemetry", map[string]any{ - "goroutines": goroutines, - "memory_alloc_mb": allocMB, - "memory_total_mb": totalAllocMB, - "memory_sys_mb": sysMB, - "num_gc": m.NumGC, - "gc_pause_ns": m.PauseNs[(m.NumGC+255)%256], // Latest GC pause time + "goroutines": goroutines, + "memory_alloc_mb": allocMB, + "memory_total_mb": totalAllocMB, + "memory_sys_mb": sysMB, + "num_gc": m.NumGC, + "gc_pause_ns": m.PauseNs[(m.NumGC+255)%256], // Latest GC pause time "gc_pause_total_ns": m.PauseTotalNs, }) } diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 1f2e82baf..df83ad263 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -34,9 +34,9 @@ var ( currentTimeFormat = "15:04:05" logger zerolog.Logger fileLogger zerolog.Logger - logFile *os.File - once sync.Once - mu sync.RWMutex + logFile *os.File + once sync.Once + mu sync.RWMutex ) func init() { diff --git a/pkg/migrate/sources/openclaw/common.go b/pkg/migrate/sources/openclaw/common.go index eb6cc0391..227dc159e 100644 --- a/pkg/migrate/sources/openclaw/common.go +++ b/pkg/migrate/sources/openclaw/common.go @@ -13,14 +13,14 @@ var migrateableDirs = []string{ } var supportedChannels = map[string]bool{ - "whatsapp": true, - "telegram": true, - "discord": true, - "maixcam": true, - "qq": true, - "dingtalk": true, - "slack": true, - "matrix": true, - "line": true, - "onebot": true, + "whatsapp": true, + "telegram": true, + "discord": true, + "maixcam": true, + "qq": true, + "dingtalk": true, + "slack": true, + "matrix": true, + "line": true, + "onebot": true, } diff --git a/pkg/routing/features.go b/pkg/routing/features.go index 5393617d6..04d012d46 100644 --- a/pkg/routing/features.go +++ b/pkg/routing/features.go @@ -105,21 +105,34 @@ func countRecentToolCalls(history []providers.Message) int { // false negatives (missing an attachment) just mean the routing falls back to // the primary model anyway. func hasAttachments(msg string) bool { - lower := strings.ToLower(msg) - - // Base64 data URIs embedded directly in the message - if strings.Contains(lower, "data:image/") || - strings.Contains(lower, "data:audio/") || - strings.Contains(lower, "data:video/") { + // Bolt: Fast path to avoid strings.ToLower memory allocation and full string pass + // for the vast majority of messages that contain no media. + hasDataURI := strings.Contains(msg, "data:image/") || strings.Contains(msg, "DATA:IMAGE/") || + strings.Contains(msg, "data:audio/") || strings.Contains(msg, "DATA:AUDIO/") || + strings.Contains(msg, "data:video/") || strings.Contains(msg, "DATA:VIDEO/") + if hasDataURI { return true } - // Common image/audio extensions in URLs or file references + // Extensions must have a dot + if !strings.Contains(msg, ".") { + return false + } + + // Check common extensions without ToLower first to capture standard lowercase domains mediaExts := []string{ ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".mp3", ".wav", ".ogg", ".m4a", ".flac", ".mp4", ".avi", ".mov", ".webm", } + for _, ext := range mediaExts { + if strings.Contains(msg, ext) { + return true + } + } + + // Fallback to ToLower for weirdly cased extensions + lower := strings.ToLower(msg) for _, ext := range mediaExts { if strings.Contains(lower, ext) { return true diff --git a/pkg/tools/alpaca/alpaca.go b/pkg/tools/alpaca/alpaca.go index e7ddb1cdf..36cc30332 100644 --- a/pkg/tools/alpaca/alpaca.go +++ b/pkg/tools/alpaca/alpaca.go @@ -107,8 +107,8 @@ func (t *AlpacaTool) getPrice(symbol string) *tools.ToolResult { func (t *AlpacaTool) getSMA(symbol string) *tools.ToolResult { req := marketdata.GetBarsRequest{ - TimeFrame: marketdata.OneDay, - TotalLimit: 10, // 10-day simple moving average + TimeFrame: marketdata.OneDay, + TotalLimit: 10, // 10-day simple moving average } bars, err := t.marketData.GetBars(symbol, req) if err != nil { diff --git a/pkg/tools/mcp2cli.go b/pkg/tools/mcp2cli.go index a057630fb..58ac1f429 100644 --- a/pkg/tools/mcp2cli.go +++ b/pkg/tools/mcp2cli.go @@ -259,7 +259,7 @@ func splitQuoted(s string) []string { var quoteChar rune for _, r := range s { - if (r == '"' || r == '\'') { + if r == '"' || r == '\'' { if inQuotes && quoteChar == r { inQuotes = false } else if !inQuotes { diff --git a/pkg/tools/mcp2cli_test.go b/pkg/tools/mcp2cli_test.go index 7fc9fa438..177e42491 100644 --- a/pkg/tools/mcp2cli_test.go +++ b/pkg/tools/mcp2cli_test.go @@ -2,8 +2,8 @@ package tools import ( "context" - "testing" "github.com/stretchr/testify/assert" + "testing" ) func TestSplitQuoted(t *testing.T) { diff --git a/pkg/tools/web/fetch.go b/pkg/tools/web/fetch.go index 44d836f18..3bdb8966a 100644 --- a/pkg/tools/web/fetch.go +++ b/pkg/tools/web/fetch.go @@ -1,12 +1,12 @@ package web import ( - "jane/pkg/tools" "context" "encoding/json" "errors" "fmt" "io" + "jane/pkg/tools" "net" "net/http" "net/url" diff --git a/pkg/tools/web/search.go b/pkg/tools/web/search.go index d23b7d619..c40d29525 100644 --- a/pkg/tools/web/search.go +++ b/pkg/tools/web/search.go @@ -1,9 +1,9 @@ package web import ( - "jane/pkg/tools" "context" "fmt" + "jane/pkg/tools" ) type WebSearchTool struct {