Make task agents' lead messaging capability clear

This commit is contained in:
Ian Gulliver
2026-10-23 20:52:30 -07:00
parent 6434eee45c
commit b9fcca999e
2 changed files with 48 additions and 2 deletions
+2 -2
View File
@@ -899,13 +899,13 @@ func (m *Manager) startLive(ctx context.Context, sess api.AgentSession, task api
tools := append([]mcp.Tool{m.askTool(l), m.cancelQuestionTool(l), m.setTitlesTool(l), m.stopMergeTool(l), m.mergeToMainTool(l), m.setTaskSummaryTool(l), m.searchClosedTool(l), m.exposePortTool(l), m.takeSnapshotTool(l), m.terminalReadTool(l), m.terminalTypeTool(l), m.bashTool(l), m.readKnowledgeTool(), m.renderDiagramTool(), m.exportDiagramTool(l), m.randomChoiceTool()}, append(append(m.fileTools(l), m.subtaskTools(l)...), m.clientTools(l)...)...)
lead := true
if sess.Role == api.Implementer {
g += longTitleGuidance(task)
g += longTitleGuidance(task) + messageLeadGuidance
notes, err := m.notesText(ctx, task.CreatedBy, task.ProjectId)
if err != nil {
return nil, err
}
l.notes = "\n\n" + taskNotesGuidance + "\n\n" + notes
tools = append(tools, m.suggestNoteTool(l), m.readyForMergeTool(l), m.suggestDiscardTool(l), m.cancelReadyTool(l), m.respondToFindingTool(l))
tools = append(tools, m.messageLeadTool(l), m.suggestNoteTool(l), m.readyForMergeTool(l), m.suggestDiscardTool(l), m.cancelReadyTool(l), m.respondToFindingTool(l))
if sess.Vendor == api.Claude {
tools = append(tools, m.forkTool(l))
}
+46
View File
@@ -0,0 +1,46 @@
package agents
import (
"context"
"encoding/json"
"fmt"
"strings"
"g.fc.run/ai/byre/internal/mcp"
"g.fc.run/ai/byre/internal/store"
)
const messageLeadGuidance = "\n- To contact the human's lead agent, use message_lead with a self-contained message (for example, a task brief the human asked you to pass along). You don't need to find a session or ask the human to paste it. Your final messages also reach the lead automatically."
func (m *Manager) messageLeadTool(l *live) mcp.Tool {
return mcp.Tool{
Name: "message_lead",
Description: "Send a message to this task creator's lead agent. Use it to pass along a task brief, request coordination, or share information the lead needs before your turn ends. Include all the context the lead needs; it cannot see your conversation. Your final messages already reach the lead automatically.",
InputSchema: json.RawMessage(`{"type":"object","properties":{"text":{"type":"string","description":"A self-contained message for the lead."}},"required":["text"]}`),
Handler: mcp.Typed(func(ctx context.Context, args struct {
Text string `json:"text"`
}) (string, error) {
text := strings.TrimSpace(args.Text)
if text == "" {
return "", fmt.Errorf("%w: text must not be empty", ErrInvalid)
}
task, err := m.store.GetTask(ctx, l.taskID)
if err != nil {
return "", err
}
_, found, err := m.activeLead(ctx, task.CreatedBy)
if err != nil {
return "", err
}
if !found {
return "", fmt.Errorf("%w: %s has no lead agent to receive the message", ErrConflict, task.CreatedBy)
}
signal := fmt.Sprintf("Message from the agent working on %s (project %s):\n\n%s", m.taskLabel(ctx, task.Id), task.ProjectId, text)
err = m.addLeadInput(ctx, store.LeadInput{Owner: task.CreatedBy, Kind: store.LeadSignal, Actor: "byre", Text: signal})
if err != nil {
return "", err
}
return "Message sent to the lead.", nil
}),
}
}