Questions tab, question bubbles, answer snapshots; errors to transcript
This commit is contained in:
@@ -36,7 +36,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
|
||||
return append([]mcp.Tool{
|
||||
tool("list_tasks",
|
||||
"List every project and its active tasks (id, title, worktree path, the agent's state and model, and open inbox items), "+
|
||||
"List every project and its active tasks (id, title, worktree path, the agent's state and model, and open questions), "+
|
||||
"and the titles of its TODO.md items on the default branch that no active task was started from.",
|
||||
`{"type": "object", "properties": {}}`,
|
||||
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
|
||||
@@ -44,7 +44,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
}),
|
||||
|
||||
tool("read_transcript",
|
||||
"Read a task's transcript: messages, tool calls (briefly), tool results (cut short), turn ends and inbox filings, each with its event seq. "+
|
||||
"Read a task's transcript: messages, tool calls (briefly), tool results (cut short), turn ends, questions asked, errors and rate limits, each with its event seq. "+
|
||||
"Without after_seq it returns the last limit events; with it, the events after that seq.",
|
||||
`{"type": "object", "properties": {
|
||||
"task_id": {"type": "string"},
|
||||
@@ -77,7 +77,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
}),
|
||||
|
||||
tool("read_inbox",
|
||||
"Read open inbox items as JSON, with each question's full context, choices and responses. Give task_id for one task's items.",
|
||||
"Read open questions as JSON, with each one's full context, choices and responses. Give task_id for one task's questions.",
|
||||
`{"type": "object", "properties": {"task_id": {"type": "string"}}}`,
|
||||
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
|
||||
args := struct {
|
||||
@@ -110,12 +110,12 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
}),
|
||||
|
||||
tool("answer_question",
|
||||
"Respond to an open inbox item on the human's behalf. Only when the answer is clear or the human told you it. "+
|
||||
"Answer an open question on the human's behalf. Only when the answer is clear or the human told you it. "+
|
||||
"type option: options holds the chosen choices' exact text (one for pick-one; pick-any may add text). "+
|
||||
"type other: free text to a question or an error. type dismiss: clears an error.",
|
||||
"type other: free text.",
|
||||
`{"type": "object", "properties": {
|
||||
"item_id": {"type": "string"},
|
||||
"type": {"type": "string", "enum": ["option", "other", "dismiss"]},
|
||||
"type": {"type": "string", "enum": ["option", "other"]},
|
||||
"options": {"type": "array", "items": {"type": "string"}},
|
||||
"text": {"type": "string"}
|
||||
}, "required": ["item_id", "type"]}`,
|
||||
@@ -388,7 +388,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
"Merge a task as the human: its agent merges the default branch in, then byre squashes it into one commit, pushes it to origin and closes the task. "+
|
||||
"While another task in the project is merging, byre holds the merge and starts it when that one is done. "+
|
||||
"For a subtask, target parent instead asks its parent task's agent to merge it into the parent's branch, and the subtask closes once the parent has. "+
|
||||
"Refused for a task with active subtasks. Only when the human asks. You get a signal when it is merged; failures are filed in the task's inbox.",
|
||||
"Refused for a task with active subtasks. Only when the human asks. You get a signal when it is merged; failures show as errors in the task's transcript, and you get a signal for each.",
|
||||
`{"type": "object", "properties": {
|
||||
"task_id": {"type": "string"},
|
||||
"target": {"type": "string", "enum": ["main", "parent"], "description": "Default main."}
|
||||
@@ -458,18 +458,18 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
tool("show",
|
||||
"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. "+
|
||||
"Whenever the human asks you to show something (\"show me that when you can\") or you want to show something, call show right away; never hold back because you expect a refusal, since only a refused show arranges byre's signal to try again. "+
|
||||
"Tabs: transcript, board (a team task's board: its agents' posts, the human's and yours), changes, files, terminal (a shell in the task's worktree), inbox (the task's open items), reviews (the task's reviews by reviewer agents), workflow (a workflow stage task's run: its graph and each stage's state, attempts and outputs), project (the project's dashboard: its active tasks and its TODO.md items); with only project_id, only project shows anything. "+
|
||||
"Tabs: transcript, board (a team task's board: its agents' posts, the human's and yours), changes, files, terminal (a shell in the task's worktree), questions (the task's oldest open question), reviews (the task's reviews by reviewer agents), workflow (a workflow stage task's run: its graph and each stage's state, attempts and outputs), 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. "+
|
||||
"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 for 10 seconds after the human last moved the pane themselves (switching task or tab), whatever else holds; if a show was refused for it, byre signals you \"The move hold is over\" when those 10 seconds pass without another move, and sends no signal otherwise. "+
|
||||
"Otherwise refused while the human is working in the right pane (focused in it, or with unsent text in it), unless it is on the project tab, or what it shows is finished (a merged or discarded task, or an inbox tab with nothing left), "+
|
||||
"Otherwise refused while the human is working in the right pane (focused in it, or with unsent text in it), unless it is on the project tab, or what it shows is finished (a merged or discarded task, or a questions tab with nothing left open),"+
|
||||
"or it is on the transcript tab of a task whose agent is mid-turn, the human has no unsent text there, and either the human sent the message that started that turn since the pane last moved or the pane moved there 10 seconds ago or more; byre signals you \"Your right pane is free\" when either happens. "+
|
||||
"Also refused while the pane is on the project tab and the human started a TODO item there in the last 10 seconds, unless they switched task or tab or messaged you since; if a show was refused for it, byre signals you \"The start hold is over\" when those 10 seconds pass with the pane still on the project tab, and sends no signal otherwise.",
|
||||
`{"type": "object", "properties": {
|
||||
"task_id": {"type": "string"},
|
||||
"project_id": {"type": "string", "description": "Ignored when task_id is given."},
|
||||
"tabs": {"type": "array", "items": {"type": "string", "enum": ["transcript", "board", "changes", "files", "terminal", "inbox", "reviews", "workflow", "project"]}},
|
||||
"tab": {"type": "string", "enum": ["transcript", "board", "changes", "files", "terminal", "inbox", "reviews", "workflow", "project"]}
|
||||
"tabs": {"type": "array", "items": {"type": "string", "enum": ["transcript", "board", "changes", "files", "terminal", "questions", "reviews", "workflow", "project"]}},
|
||||
"tab": {"type": "string", "enum": ["transcript", "board", "changes", "files", "terminal", "questions", "reviews", "workflow", "project"]}
|
||||
}, "required": ["tabs", "tab"]}`,
|
||||
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
|
||||
f := api.Focus{}
|
||||
@@ -640,7 +640,7 @@ func sameView(a, b api.Focus) bool {
|
||||
return deref(a.ProjectId) == deref(b.ProjectId)
|
||||
}
|
||||
|
||||
const inboxEmptied = "has nothing left in its inbox"
|
||||
const inboxEmptied = "has no open questions left"
|
||||
|
||||
func (m *Manager) paneFinished(ctx context.Context, f api.Focus) (string, error) {
|
||||
if f.TaskId == nil {
|
||||
@@ -656,7 +656,7 @@ func (m *Manager) paneFinished(ctx context.Context, f api.Focus) (string, error)
|
||||
if task.Merging {
|
||||
return "is merging", nil
|
||||
}
|
||||
if f.Tab != api.TabInbox {
|
||||
if f.Tab != api.TabQuestions {
|
||||
return "", nil
|
||||
}
|
||||
items, err := m.store.ListInbox(ctx, store.InboxFilter{State: api.Open, TaskID: task.Id})
|
||||
@@ -883,7 +883,7 @@ func (m *Manager) listTasksText(ctx context.Context) (string, error) {
|
||||
open++
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(b, "- %s %q: %s; inbox %d open; worktree %s", t.Id, t.Title, agent, open, t.WorktreePath)
|
||||
fmt.Fprintf(b, "- %s %q: %s; %d open questions; worktree %s", t.Id, t.Title, agent, open, t.WorktreePath)
|
||||
if t.TodoItem != nil {
|
||||
fmt.Fprintf(b, "; from TODO item %q", *t.TodoItem)
|
||||
}
|
||||
@@ -1023,7 +1023,11 @@ func transcriptLine(ev api.Event, root string) string {
|
||||
}
|
||||
return "turn ended"
|
||||
case "inbox.created":
|
||||
return fmt.Sprintf("filed %s %s", text("kind"), text("id"))
|
||||
return fmt.Sprintf("asked question %s", text("id"))
|
||||
case "session.error":
|
||||
return "error: " + clip(text("error"), 300)
|
||||
case "session.rate_limited":
|
||||
return "rate limited: " + clip(text("error"), 300)
|
||||
case "session.created":
|
||||
return fmt.Sprintf("session started by %s", ev.Actor)
|
||||
case "session.state":
|
||||
|
||||
Reference in New Issue
Block a user