feat(subagent): attribute subagent responses with agent name

When a named subagent (e.g. agent_id="karen") completes a task, its
response is now prefixed with the agent's name in bold so the user
can tell which agent produced the result. Self-spawns (no agent_id)
are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Eric Jacksch 2026-03-19 23:10:29 -04:00
parent eef15f97d0
commit 7f8efb9e62

View file

@ -3,12 +3,22 @@ package tools
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"sync" "sync"
"time" "time"
"github.com/sipeed/picoclaw/pkg/providers" "github.com/sipeed/picoclaw/pkg/providers"
) )
// attributedContent prepends "AgentName: " to content when agentID is non-empty.
func attributedContent(agentID, content string) string {
if strings.TrimSpace(agentID) == "" {
return content
}
name := strings.ToUpper(agentID[:1]) + agentID[1:]
return "**" + name + ":** " + content
}
type SubagentTask struct { type SubagentTask struct {
ID string ID string
Task string Task string
@ -255,7 +265,7 @@ After completing the task, provide a clear summary of what was done.`
loopResult.Iterations, loopResult.Iterations,
loopResult.Content, loopResult.Content,
), ),
ForUser: loopResult.Content, ForUser: attributedContent(task.AgentID, loopResult.Content),
Silent: false, Silent: false,
IsError: false, IsError: false,
Async: false, Async: false,
@ -326,6 +336,7 @@ func (t *SubagentTool) Execute(ctx context.Context, args map[string]any) *ToolRe
} }
label, _ := args["label"].(string) label, _ := args["label"].(string)
agentID, _ := args["agent_id"].(string)
if t.manager == nil { if t.manager == nil {
return ErrorResult("Subagent manager not configured").WithError(fmt.Errorf("manager is nil")) return ErrorResult("Subagent manager not configured").WithError(fmt.Errorf("manager is nil"))
@ -383,7 +394,7 @@ func (t *SubagentTool) Execute(ctx context.Context, args map[string]any) *ToolRe
return &ToolResult{ return &ToolResult{
ForLLM: llmContent, ForLLM: llmContent,
ForUser: userContent, ForUser: attributedContent(agentID, userContent),
Silent: false, Silent: false,
IsError: false, IsError: false,
Async: false, Async: false,