Let task agents create and manage subtasks
This commit is contained in:
@@ -302,13 +302,35 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
tool("merge_task",
|
||||
"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. "+
|
||||
"Only when the human asks. You get a signal when it is merged; failures are filed in the task's inbox.",
|
||||
taskOnly,
|
||||
"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.",
|
||||
`{"type": "object", "properties": {
|
||||
"task_id": {"type": "string"},
|
||||
"target": {"type": "string", "enum": ["main", "parent"], "description": "Default main."}
|
||||
}, "required": ["task_id"]}`,
|
||||
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
|
||||
args := struct {
|
||||
Target string `json:"target"`
|
||||
}{}
|
||||
err := json.Unmarshal(raw, &args)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
task, project, err := m.taskArg(ctx, raw)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch args.Target {
|
||||
case "", "main":
|
||||
case "parent":
|
||||
_, err = m.MergeIntoParent(ctx, task, user)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("Merge of %s into its parent %s requested.", task.Id, *task.ParentTaskId), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: target must be main or parent, not %q", ErrInvalid, args.Target)
|
||||
}
|
||||
task, err = m.Merge(ctx, task, project, user, task.MergeTitle)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -320,7 +342,7 @@ func (m *Manager) leadTools(l *live) []mcp.Tool {
|
||||
}),
|
||||
|
||||
tool("discard_task",
|
||||
"Discard a task: its agent gets one turn to write the task summary, then byre stops it and deletes its worktree and branch without merging. This destroys its unmerged work. Only when the human asks. "+
|
||||
"Discard a task: its agent gets one turn to write the task summary, then byre stops it and deletes its worktree and branch without merging. This destroys its unmerged work. Refused for a task with active subtasks. Only when the human asks. "+
|
||||
"If the agent is mid-turn, the summary turn starts when that turn ends; no other turn runs in between.",
|
||||
taskOnly,
|
||||
func(ctx context.Context, user api.User, raw json.RawMessage) (string, error) {
|
||||
@@ -712,6 +734,12 @@ func (m *Manager) listTasksText(ctx context.Context) (string, error) {
|
||||
if t.ForkedFrom != nil {
|
||||
fmt.Fprintf(b, "; forked from %s at snapshot %d", *t.ForkedFrom, *t.ForkedAt)
|
||||
}
|
||||
if t.ParentTaskId != nil {
|
||||
fmt.Fprintf(b, "; subtask of %s", *t.ParentTaskId)
|
||||
if t.MergingIntoParent {
|
||||
b.WriteString(", merging into it")
|
||||
}
|
||||
}
|
||||
if t.Workflow != nil {
|
||||
stage, err := m.workflowStatus(ctx, t)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user