Merge pull request #7 from dj-oyu/fix/think-tag-leak-and-search-log
fix: strip think tags from heartbeat and log web search provider
This commit is contained in:
commit
5c57a98427
4 changed files with 43 additions and 7 deletions
|
|
@ -80,6 +80,11 @@ func gatewayCmd(debug bool, orchestration bool, enableStats bool) error {
|
|||
toolsInfo := startupInfo["tools"].(map[string]any)
|
||||
skillsInfo := startupInfo["skills"].(map[string]any)
|
||||
fmt.Printf(" • Tools: %d loaded\n", toolsInfo["count"])
|
||||
if wsProvider, ok := toolsInfo["web_search_provider"].(string); ok {
|
||||
fmt.Printf(" • Web search: %s\n", wsProvider)
|
||||
} else {
|
||||
fmt.Println(" • Web search: disabled")
|
||||
}
|
||||
fmt.Printf(" • Skills: %d/%d available\n",
|
||||
skillsInfo["available"],
|
||||
skillsInfo["total"])
|
||||
|
|
|
|||
|
|
@ -240,6 +240,14 @@ func registerSharedTools(
|
|||
Proxy: cfg.Tools.Web.Proxy,
|
||||
}); searchTool != nil {
|
||||
agent.Tools.Register(searchTool)
|
||||
logger.InfoCF("agent", "Web search provider registered", map[string]any{
|
||||
"agent_id": agentID,
|
||||
"provider": searchTool.ProviderName(),
|
||||
})
|
||||
} else {
|
||||
logger.WarnCF("agent", "No web search provider configured", map[string]any{
|
||||
"agent_id": agentID,
|
||||
})
|
||||
}
|
||||
agent.Tools.Register(tools.NewWebFetchToolWithProxy(50000, cfg.Tools.Web.Proxy))
|
||||
|
||||
|
|
@ -2775,7 +2783,7 @@ func (al *AgentLoop) runLLMIteration(
|
|||
"prompt_cache_key": agent.ID,
|
||||
})
|
||||
if forceErr == nil && forceResp.Content != "" {
|
||||
finalContent = forceResp.Content
|
||||
finalContent = utils.StripThinkBlocks(forceResp.Content)
|
||||
if forceResp.Usage != nil && al.stats != nil {
|
||||
al.stats.RecordUsage(
|
||||
forceResp.Usage.PromptTokens,
|
||||
|
|
@ -2896,10 +2904,17 @@ func (al *AgentLoop) GetStartupInfo() map[string]any {
|
|||
|
||||
// Tools info
|
||||
toolsList := agent.Tools.List()
|
||||
info["tools"] = map[string]any{
|
||||
toolsMap := map[string]any{
|
||||
"count": len(toolsList),
|
||||
"names": toolsList,
|
||||
}
|
||||
// Report web search provider if registered
|
||||
if t, ok := agent.Tools.Get("web_search"); ok {
|
||||
if wst, ok := t.(*tools.WebSearchTool); ok {
|
||||
toolsMap["web_search_provider"] = wst.ProviderName()
|
||||
}
|
||||
}
|
||||
info["tools"] = toolsMap
|
||||
|
||||
// Skills info
|
||||
info["skills"] = agent.ContextBuilder.GetSkillsInfo()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/sipeed/picoclaw/pkg/logger"
|
||||
"github.com/sipeed/picoclaw/pkg/state"
|
||||
"github.com/sipeed/picoclaw/pkg/tools"
|
||||
"github.com/sipeed/picoclaw/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -308,8 +309,11 @@ Add your heartbeat tasks below this line:
|
|||
}
|
||||
}
|
||||
|
||||
// sendResponse sends the heartbeat response to the last channel
|
||||
// sendResponse sends the heartbeat response to the last channel.
|
||||
// Think blocks are stripped as a safety net to prevent LLM reasoning
|
||||
// artifacts from leaking into user-facing messages.
|
||||
func (hs *HeartbeatService) sendResponse(response string) {
|
||||
response = utils.StripThinkBlocks(response)
|
||||
hs.mu.RLock()
|
||||
msgBus := hs.bus
|
||||
hs.mu.RUnlock()
|
||||
|
|
|
|||
|
|
@ -387,8 +387,14 @@ func (p *PerplexitySearchProvider) Search(ctx context.Context, query string, cou
|
|||
}
|
||||
|
||||
type WebSearchTool struct {
|
||||
provider SearchProvider
|
||||
maxResults int
|
||||
provider SearchProvider
|
||||
providerName string
|
||||
maxResults int
|
||||
}
|
||||
|
||||
// ProviderName returns the name of the active search provider (e.g. "brave", "perplexity").
|
||||
func (t *WebSearchTool) ProviderName() string {
|
||||
return t.providerName
|
||||
}
|
||||
|
||||
type WebSearchToolOptions struct {
|
||||
|
|
@ -409,16 +415,19 @@ type WebSearchToolOptions struct {
|
|||
|
||||
func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool {
|
||||
var provider SearchProvider
|
||||
var providerName string
|
||||
maxResults := 5
|
||||
|
||||
// Priority: Perplexity > Brave > Tavily > DuckDuckGo
|
||||
if opts.PerplexityEnabled && opts.PerplexityAPIKey != "" {
|
||||
provider = &PerplexitySearchProvider{apiKey: opts.PerplexityAPIKey, proxy: opts.Proxy}
|
||||
providerName = "perplexity"
|
||||
if opts.PerplexityMaxResults > 0 {
|
||||
maxResults = opts.PerplexityMaxResults
|
||||
}
|
||||
} else if opts.BraveEnabled && opts.BraveAPIKey != "" {
|
||||
provider = &BraveSearchProvider{apiKey: opts.BraveAPIKey, proxy: opts.Proxy}
|
||||
providerName = "brave"
|
||||
if opts.BraveMaxResults > 0 {
|
||||
maxResults = opts.BraveMaxResults
|
||||
}
|
||||
|
|
@ -428,11 +437,13 @@ func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool {
|
|||
baseURL: opts.TavilyBaseURL,
|
||||
proxy: opts.Proxy,
|
||||
}
|
||||
providerName = "tavily"
|
||||
if opts.TavilyMaxResults > 0 {
|
||||
maxResults = opts.TavilyMaxResults
|
||||
}
|
||||
} else if opts.DuckDuckGoEnabled {
|
||||
provider = &DuckDuckGoSearchProvider{proxy: opts.Proxy}
|
||||
providerName = "duckduckgo"
|
||||
if opts.DuckDuckGoMaxResults > 0 {
|
||||
maxResults = opts.DuckDuckGoMaxResults
|
||||
}
|
||||
|
|
@ -441,8 +452,9 @@ func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool {
|
|||
}
|
||||
|
||||
return &WebSearchTool{
|
||||
provider: provider,
|
||||
maxResults: maxResults,
|
||||
provider: provider,
|
||||
providerName: providerName,
|
||||
maxResults: maxResults,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue