Let the lead reorder tabs on what the pane already shows
This commit is contained in:
@@ -2,6 +2,7 @@ package agents_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -89,6 +90,22 @@ func TestLeadSignalsAndShow(t *testing.T) {
|
||||
t.Fatalf("focus moved while the pane was focused: %+v", f)
|
||||
}
|
||||
|
||||
_, err = m.MessageLead(e.ctx, e.user, "Call the show tool with task_id "+e.task.Id+", tabs [\"inbox\", \"changes\"] and tab \"inbox\". Then say done.", "", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("message lead: %v", err)
|
||||
}
|
||||
e.waitFor("show of what is already shown", func(ev api.Event) bool {
|
||||
return ev.Kind == "agent.tool_result" && ev.Owner != nil && strings.Contains(fmt.Sprint(ev.Payload), "Already shown")
|
||||
})
|
||||
e.waitFor("lead idle after already-shown show", leadIdle)
|
||||
f, err = e.store.GetFocus(e.ctx, login)
|
||||
if err != nil {
|
||||
t.Fatalf("get focus: %v", err)
|
||||
}
|
||||
if f.Tab != api.TabInbox || !slices.Equal(f.Tabs, []api.TaskTab{api.TabInbox, api.TabChanges}) {
|
||||
t.Fatalf("tabs not reordered on the shown tab: %+v", f)
|
||||
}
|
||||
|
||||
err = e.store.WithdrawItem(e.ctx, created[len(created)-1].Payload["id"].(string))
|
||||
if err != nil {
|
||||
t.Fatalf("withdraw report: %v", err)
|
||||
|
||||
@@ -295,7 +295,8 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
"Point the human's right pane at a task, or at a project with no task: tabs are the tabs to put first, in order (the rest follow), and tab is the one to select. "+
|
||||
"Tabs: transcript, changes, files, inbox (the task's open items), project (the project's dashboard: its active tasks and its TODO.md items); with only project_id, only project shows anything. "+
|
||||
"Omit both task_id and project_id to clear the pane. "+
|
||||
"Refused while the human is working in the right pane, unless what it shows is finished (a merged or discarded task, or an inbox tab with nothing left).",
|
||||
"If the pane already shows that task (or project) on that tab, only the tab order changes and you are told so, even while the human is working in the pane. "+
|
||||
"Otherwise refused while the human is working in the right pane, unless what it shows is finished (a merged or discarded task, or an inbox tab with nothing left).",
|
||||
`{"type": "object", "properties": {
|
||||
"task_id": {"type": "string"},
|
||||
"project_id": {"type": "string", "description": "Ignored when task_id is given."},
|
||||
@@ -308,14 +309,24 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
current, err := m.store.GetFocus(ctx, user.Login)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if sameView(current, f) {
|
||||
if slices.Equal(current.Tabs, f.Tabs) {
|
||||
return "Already shown: the right pane shows that now, so nothing changed.", nil
|
||||
}
|
||||
err = m.SetFocus(ctx, user.Login, f, leadActor(user.Login))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "Already shown on that tab; the tab order was updated.", nil
|
||||
}
|
||||
m.mu.Lock()
|
||||
focused := m.paneFocused[user.Login]
|
||||
m.mu.Unlock()
|
||||
if focused {
|
||||
current, err := m.store.GetFocus(ctx, user.Login)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
finished, err := m.paneFinished(ctx, current)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -370,6 +381,17 @@ func (m *Manager) SetFocus(ctx context.Context, login string, f api.Focus, actor
|
||||
return m.store.SetFocus(ctx, login, f, actor)
|
||||
}
|
||||
|
||||
func sameView(a, b api.Focus) bool {
|
||||
if a.Tab != b.Tab {
|
||||
return false
|
||||
}
|
||||
at, bt := deref(a.TaskId), deref(b.TaskId)
|
||||
if at != "" || bt != "" {
|
||||
return at == bt
|
||||
}
|
||||
return deref(a.ProjectId) == deref(b.ProjectId)
|
||||
}
|
||||
|
||||
const inboxEmptied = "has nothing left in its inbox"
|
||||
|
||||
func (m *Manager) paneFinished(ctx context.Context, f api.Focus) (string, error) {
|
||||
|
||||
Reference in New Issue
Block a user