diff --git a/TODO.md b/TODO.md index 0aa71db..d8132ce 100644 --- a/TODO.md +++ b/TODO.md @@ -17,8 +17,6 @@ # M7 — Inbox triage -- Answer a question again - From an answered question in the Questions tab, give a different answer, which forks the task: a new task starts from the snapshot taken just before the original answer was delivered (the answer's `snapshot_n`), its agent continuing the conversation as it stood there (as Fork does from a snapshot), and gets the new answer. The original task carries on untouched. - Take both paths when unattended An agent working unattended (no human to ask) that hits a question with two plausible answers forks at it: the task carries on with one answer and a fork, started the same way as answering again, carries on with the other, so the human later compares both results instead of the agent guessing. diff --git a/api/openapi.yaml b/api/openapi.yaml index a79d11a..f296530 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1031,6 +1031,29 @@ paths: "404": { $ref: "#/components/responses/Error" } "409": { $ref: "#/components/responses/Error" } + /api/inbox/answer-again: + post: + operationId: answerAgain + description: > + Gives an answered question a different answer by forking its task, as forkSnapshot does, at the snapshot taken + just before the original answer was handed to the agent. The new task gets a copy of the question, already + answered with this response, and its agent gets the answer as its first message. The original task is untouched. + Refused for a question that isn't answered, an answer delivered without a snapshot, and anything forkSnapshot refuses. + requestBody: + required: true + content: + application/json: + schema: { $ref: "#/components/schemas/InboxResponseCreate" } + responses: + "201": + description: The new task. + content: + application/json: + schema: { $ref: "#/components/schemas/Task" } + "400": { $ref: "#/components/responses/Error" } + "404": { $ref: "#/components/responses/Error" } + "409": { $ref: "#/components/responses/Error" } + /api/events: get: operationId: streamEvents diff --git a/docs/operations.md b/docs/operations.md index c33268b..435a9f8 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -442,6 +442,8 @@ A fork of a workflow stage task gets a copy of the source's frozen workflow, bri The fork's session guidance gets one more line (`forkGuidance` in `internal/agents/guidance.go`) naming the source task, the snapshot, the fork's branch and worktree and the source's worktree, telling the agent that everything before the fork happened in the other worktree and to work only in its own. Claude Code can reuse the system prompt recorded for the source conversation on a fork, the source's cwd included, so the `UserPromptSubmit` hook's copy is what reliably tells it. The fork's transcript starts with a note from its `task.created` event, "forked this task from at snapshot #n", linking the source while it is active; the lead's signal for it reads " was forked by from at snapshot n", and `list_tasks` notes the source. The fork's transcript shows only its own events, not the source's history. +An answered question can be answered again. Expanding an answered question's bubble in the transcript shows an **Answer again** button when the question is `answered` (the transcript's copy of the question comes from its `inbox.*` events, which carry no `snapshot_n`, so the server is what checks for one); it reopens the card's choices, Other box and "Let the agent decide", with Cancel in place of Ignore, and sending posts the new answer, an `InboxResponseCreate`, to `POST /api/inbox/answer-again` (`AnswerAgain` in `internal/agents/fork.go`) instead of `respondInbox`. byre checks the answer against the question as if it were open, forks the question's task at the answer's `snapshot_n` exactly as the **fork** button does, and files in the fork a copy of the question (same payload, its own id and thread) already `answered` with the new response, in one transaction (`Store.CreateAnsweredItem`), whose `inbox.created` event carries the answered item and the human as actor. `Deliver` then hands that answer to the fork's idle session as its first turn, the usual delivery message, so the forked conversation, cut just before the original answer reached the agent, continues with the new one. The app opens the fork; the original task and its question are untouched. An `inbox.created` for an item that isn't open raises no notification, and the lead's signal for it reads as an answer, not a question. Refused (409) when the question isn't `answered` or its answer has no `snapshot_n`, and for anything the fork refuses; 400 for an answer that doesn't fit the question. + ## Reviews Every new snapshot of a task gets a review: a separate agent session on the vendor the task's agent doesn't use reads the change and reports on it (`internal/agents/review.go`, `internal/store/review.go`). A turn that changes no files makes no snapshot and so no review, an interrupted turn makes no snapshot (see "Snapshots"), and a snapshot whose change (the diff below) has no files runs no reviewer: it gets a `reviews` row in state `skipped`, with no session, vendor or model. The snapshot at the end of a Merge turn that finishes into the squash (the turn ended cleanly with `merging_by` still set, read by `turnEnded` before it asks for the snapshot) gets no review and no `reviews` row at all, since the task closes a moment later; a Merge turn that errors or calls `stop_merge` is reviewed as usual. Besides `take_snapshot` (see "Snapshots"), nothing else starts a review, and nothing waits for one: reviews ride along for the human to look at when they want. diff --git a/internal/agents/fork.go b/internal/agents/fork.go index c14f68d..b69a4f1 100644 --- a/internal/agents/fork.go +++ b/internal/agents/fork.go @@ -3,6 +3,7 @@ package agents import ( "context" "fmt" + "log/slog" "time" "g.fc.run/ai/byre/internal/api" @@ -10,38 +11,104 @@ import ( ) func (m *Manager) Fork(ctx context.Context, src api.Task, project api.Project, n int, creator api.User) (api.Task, error) { + t, _, err := m.fork(ctx, src, project, n, creator) + return t, err +} + +func (m *Manager) AnswerAgain(ctx context.Context, creator api.User, create api.InboxResponseCreate) (api.Task, error) { + item, err := m.store.GetInboxItem(ctx, create.ItemId) + if err != nil { + return api.Task{}, err + } + if item.State != api.Answered { + return api.Task{}, fmt.Errorf("%w: question %s is %s, not answered", ErrConflict, item.Id, item.State) + } + n := 0 + for _, r := range item.Responses { + if r.SnapshotN != nil { + n = *r.SnapshotN + } + } + if n == 0 { + return api.Task{}, fmt.Errorf("%w: question %s's answer reached the agent without a snapshot to fork from", ErrConflict, item.Id) + } + open := item + open.State = api.Open + _, err = CheckResponse(open, create) + if err != nil { + return api.Task{}, err + } + + src, err := m.store.GetTask(ctx, item.TaskId) + if err != nil { + return api.Task{}, err + } + project, err := m.store.GetProject(ctx, src.ProjectId) + if err != nil { + return api.Task{}, err + } + t, sessionID, err := m.fork(ctx, src, project, n, creator) + if err != nil { + return api.Task{}, err + } + + id := store.NewID() + err = m.store.CreateAnsweredItem(ctx, api.InboxItem{ + Id: id, + ProjectId: t.ProjectId, + TaskId: t.Id, + AgentSessionId: sessionID, + ThreadId: id, + Payload: item.Payload, + CreatedAt: time.Now().UTC(), + }, newResponse(id, creator.Login, create)) + if err != nil { + return api.Task{}, fmt.Errorf("task %s forked, but its answer was not recorded: %w", t.Id, err) + } + slog.Info("question answered again", "item", item.Id, "fork", t.Id, "snapshot", n, "user", creator.Login) + + go func() { + err := m.Deliver(context.Background(), sessionID) + if err != nil { + slog.Error("deliver inbox responses", "session", sessionID, "err", err) + } + }() + return t, nil +} + +func (m *Manager) fork(ctx context.Context, src api.Task, project api.Project, n int, creator api.User) (api.Task, string, error) { if creator.GitName == "" || creator.GitEmail == "" { - return api.Task{}, ErrNoGitIdentity + return api.Task{}, "", ErrNoGitIdentity } if src.Status != api.TaskStatusActive { - return api.Task{}, fmt.Errorf("%w: task %s is %s", ErrConflict, src.Id, src.Status) + return api.Task{}, "", fmt.Errorf("%w: task %s is %s", ErrConflict, src.Id, src.Status) } snap, err := m.store.GetSnapshot(ctx, src.Id, n) if err != nil { - return api.Task{}, err + return api.Task{}, "", err } srcSess, err := m.store.GetSession(ctx, snap.AgentSessionId) if err != nil { - return api.Task{}, err + return api.Task{}, "", err } if srcSess.Vendor == api.Antigravity { - return api.Task{}, fmt.Errorf("%w: snapshot %d of task %s is from an Antigravity session, and agy can't fork a conversation", ErrConflict, n, src.Id) + return api.Task{}, "", fmt.Errorf("%w: snapshot %d of task %s is from an Antigravity session, and agy can't fork a conversation", ErrConflict, n, src.Id) } events, err := m.store.TaskEvents(ctx, src.Id, 0, -1) if err != nil { - return api.Task{}, err + return api.Task{}, "", err } at := forkPoint(events, snap.AgentSessionId, snap.EventSeq) if at == "" { - return api.Task{}, fmt.Errorf("%w: snapshot %d of task %s has no recorded agent message at or before it to fork the conversation from", ErrConflict, n, src.Id) + return api.Task{}, "", fmt.Errorf("%w: snapshot %d of task %s has no recorded agent message at or before it to fork the conversation from", ErrConflict, n, src.Id) } var frozen *store.FrozenWorkflow if src.Workflow != nil { f, err := m.store.TaskWorkflow(ctx, src.Id) if err != nil { - return api.Task{}, err + return api.Task{}, "", err } frozen = &f } @@ -58,7 +125,7 @@ func (m *Manager) Fork(ctx context.Context, src api.Task, project api.Project, n ParentTaskId: src.ParentTaskId, }, frozen, snap.CommitSha, creator.Login) if err != nil { - return api.Task{}, err + return api.Task{}, "", err } id := newUUID() @@ -76,9 +143,9 @@ func (m *Manager) Fork(ctx context.Context, src api.Task, project api.Project, n ForkedAt: &at, }, t.ProjectId) if err != nil { - return api.Task{}, fmt.Errorf("task %s created, but its agent session was not: %w", t.Id, err) + return api.Task{}, "", fmt.Errorf("task %s created, but its agent session was not: %w", t.Id, err) } - return t, nil + return t, id, nil } func forkPoint(events []api.Event, sessionID string, seq int64) string { diff --git a/internal/agents/lead.go b/internal/agents/lead.go index 3e7c468..f79f189 100644 --- a/internal/agents/lead.go +++ b/internal/agents/lead.go @@ -489,7 +489,7 @@ func (m *Manager) signalText(ctx context.Context, ev api.Event) (string, error) if err != nil { return "", err } - if ev.Kind == "inbox.updated" { + if ev.Kind == "inbox.updated" || item.State != api.Open { return m.answeredText(ctx, item), nil } return m.itemText(ctx, item), nil diff --git a/internal/agents/respond.go b/internal/agents/respond.go index 1284091..19cc51e 100644 --- a/internal/agents/respond.go +++ b/internal/agents/respond.go @@ -38,28 +38,9 @@ func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxR return nil, err } - attachments := []api.Attachment{} - if create.Attachments != nil { - attachments = *create.Attachments - } - images := []string{} - if create.Images != nil { - images = *create.Images - } - resolutions = append(resolutions, store.Resolution{ - State: state, - Response: api.InboxResponse{ - Id: store.NewID(), - ItemId: item.Id, - User: user, - Type: create.Type, - Options: create.Options, - Text: create.Text, - Images: images, - Attachments: attachments, - CreatedAt: time.Now().UTC(), - }, + State: state, + Response: newResponse(item.Id, user, create), }) if !slices.Contains(sessions, item.AgentSessionId) { sessions = append(sessions, item.AgentSessionId) @@ -98,6 +79,28 @@ func (m *Manager) Respond(ctx context.Context, user string, creates []api.InboxR return items, nil } +func newResponse(itemID, user string, create api.InboxResponseCreate) api.InboxResponse { + attachments := []api.Attachment{} + if create.Attachments != nil { + attachments = *create.Attachments + } + images := []string{} + if create.Images != nil { + images = *create.Images + } + return api.InboxResponse{ + Id: store.NewID(), + ItemId: itemID, + User: user, + Type: create.Type, + Options: create.Options, + Text: create.Text, + Images: images, + Attachments: attachments, + CreatedAt: time.Now().UTC(), + } +} + func (m *Manager) Dismiss(ctx context.Context, user, itemID string) (api.InboxItem, error) { item, err := m.store.GetInboxItem(ctx, itemID) if err != nil { diff --git a/internal/api/api.gen.go b/internal/api/api.gen.go index eb825a9..725e41f 100644 --- a/internal/api/api.gen.go +++ b/internal/api/api.gen.go @@ -1642,6 +1642,9 @@ type GetTaskTerminalParams struct { // UpdateUsageCommandsJSONRequestBody defines body for UpdateUsageCommands for application/json ContentType. type UpdateUsageCommandsJSONRequestBody = UsageCommands +// AnswerAgainJSONRequestBody defines body for AnswerAgain for application/json ContentType. +type AnswerAgainJSONRequestBody = InboxResponseCreate + // RespondInboxJSONRequestBody defines body for RespondInbox for application/json ContentType. type RespondInboxJSONRequestBody = InboxRespond @@ -1732,6 +1735,9 @@ type ServerInterface interface { // (GET /api/inbox) ListInbox(w http.ResponseWriter, r *http.Request, params ListInboxParams) + // (POST /api/inbox/answer-again) + AnswerAgain(w http.ResponseWriter, r *http.Request) + // (POST /api/inbox/responses) RespondInbox(w http.ResponseWriter, r *http.Request) @@ -2217,6 +2223,20 @@ func (siw *ServerInterfaceWrapper) ListInbox(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } +// AnswerAgain operation middleware +func (siw *ServerInterfaceWrapper) AnswerAgain(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.AnswerAgain(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // RespondInbox operation middleware func (siw *ServerInterfaceWrapper) RespondInbox(w http.ResponseWriter, r *http.Request) { @@ -3963,6 +3983,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/clients/transfers/{transferId}", wrapper.GetClientTransfer) m.HandleFunc(http.MethodPut+" "+options.BaseURL+"/api/clients/transfers/{transferId}", wrapper.PutClientTransfer) m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/api/inbox/responses", wrapper.RespondInbox) + m.HandleFunc(http.MethodPost+" "+options.BaseURL+"/api/inbox/answer-again", wrapper.AnswerAgain) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/events", wrapper.StreamEvents) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/admin/status", wrapper.GetStatus) m.HandleFunc(http.MethodGet+" "+options.BaseURL+"/api/admin/usage-commands", wrapper.GetUsageCommands) @@ -3981,276 +4002,279 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "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", + "IET5dDmtt2jGzlLNg/v8XtV63r//PwMA", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/server/inbox.go b/internal/server/inbox.go index 42326e7..abfbeb9 100644 --- a/internal/server/inbox.go +++ b/internal/server/inbox.go @@ -45,6 +45,30 @@ func (s *Server) DismissInbox(w http.ResponseWriter, r *http.Request, itemID str writeJSON(w, http.StatusOK, item) } +func (s *Server) AnswerAgain(w http.ResponseWriter, r *http.Request) { + req := api.InboxResponseCreate{} + if !readJSON(w, r, &req) { + return + } + _, ok := s.images(w, r, req.Images) + if !ok { + return + } + + u, err := s.store.GetUser(r.Context(), actor(r)) + if err != nil { + writeStoreError(w, err) + return + } + + fork, err := s.agents.AnswerAgain(r.Context(), u, req) + if err != nil { + writeAgentError(w, err) + return + } + writeJSON(w, http.StatusCreated, fork) +} + func (s *Server) RespondInbox(w http.ResponseWriter, r *http.Request) { req := api.InboxRespond{} if !readJSON(w, r, &req) { diff --git a/internal/store/inbox.go b/internal/store/inbox.go index 8c3721b..c22399c 100644 --- a/internal/store/inbox.go +++ b/internal/store/inbox.go @@ -32,6 +32,31 @@ func (s *Store) CreateInboxItem(ctx context.Context, item api.InboxItem) error { }) } +func (s *Store) CreateAnsweredItem(ctx context.Context, item api.InboxItem, resp api.InboxResponse) error { + return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error { + payload, err := json.Marshal(item.Payload) + if err != nil { + return err + } + + _, err = tx.ExecContext(ctx, ` + INSERT INTO inbox_items (id, project_id, task_id, agent_session_id, thread_id, payload, state, created_at, resolved_by, resolved_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `, item.Id, item.ProjectId, item.TaskId, item.AgentSessionId, item.ThreadId, + string(payload), string(api.Answered), formatTime(item.CreatedAt), resp.User, now()) + if err != nil { + return err + } + + err = insertResponse(ctx, tx, resp) + if err != nil { + return err + } + + return emitItem(ctx, tx, emit, "inbox.created", item.Id, resp.User) + }) +} + const agentActor = "agent" func (s *Store) GetInboxItem(ctx context.Context, id string) (api.InboxItem, error) { @@ -120,30 +145,7 @@ func (s *Store) Respond(ctx context.Context, actor string, resolutions []Resolut return fmt.Errorf("%w: %s", ErrNotOpen, resp.ItemId) } - attachments, err := json.Marshal(resp.Attachments) - if err != nil { - return err - } - - images, err := json.Marshal(resp.Images) - if err != nil { - return err - } - - var options *string - if resp.Options != nil { - b, err := json.Marshal(*resp.Options) - if err != nil { - return err - } - s := string(b) - options = &s - } - - _, err = tx.ExecContext(ctx, ` - INSERT INTO inbox_responses (id, item_id, user_login, type, options, text, images, attachments, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) - `, resp.Id, resp.ItemId, resp.User, string(resp.Type), options, resp.Text, string(images), string(attachments), formatTime(resp.CreatedAt)) + err = insertResponse(ctx, tx, resp) if err != nil { return err } @@ -157,6 +159,34 @@ func (s *Store) Respond(ctx context.Context, actor string, resolutions []Resolut }) } +func insertResponse(ctx context.Context, tx *sql.Tx, resp api.InboxResponse) error { + attachments, err := json.Marshal(resp.Attachments) + if err != nil { + return err + } + + images, err := json.Marshal(resp.Images) + if err != nil { + return err + } + + var options *string + if resp.Options != nil { + b, err := json.Marshal(*resp.Options) + if err != nil { + return err + } + s := string(b) + options = &s + } + + _, err = tx.ExecContext(ctx, ` + INSERT INTO inbox_responses (id, item_id, user_login, type, options, text, images, attachments, created_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + `, resp.Id, resp.ItemId, resp.User, string(resp.Type), options, resp.Text, string(images), string(attachments), formatTime(resp.CreatedAt)) + return err +} + var ErrNotOpen = errors.New("inbox item is not open") func (s *Store) WithdrawItem(ctx context.Context, id string) error { diff --git a/mac/Sources/Byre/Notifications.swift b/mac/Sources/Byre/Notifications.swift index 54e7ae9..d901df5 100644 --- a/mac/Sources/Byre/Notifications.swift +++ b/mac/Sources/Byre/Notifications.swift @@ -77,7 +77,7 @@ private func show(_ store: Store, _ taskId: String, _ tag: String, _ text: Strin @MainActor func notifyInbox(_ store: Store, _ item: InboxItem) { - guard let me = store.me, me.notificationPrefs.questions else { + guard let me = store.me, me.notificationPrefs.questions, item.state == .open else { return } show(store, item.taskId, item.id, str(item.payload.value, "question") ?? "") diff --git a/mac/Sources/Byre/Questions.swift b/mac/Sources/Byre/Questions.swift index 0a34f09..4e5f139 100644 --- a/mac/Sources/Byre/Questions.swift +++ b/mac/Sources/Byre/Questions.swift @@ -61,6 +61,7 @@ private final class CardModel { let context: [MDBlock] let firstChoice: [String: Int] var busy = false + var again = false @ObservationIgnored var shown: Set = [] init(_ item: InboxItem, _ store: Store, _ overlays: Overlays) { @@ -95,7 +96,11 @@ private final class CardModel { } var answered: Bool { - item.state != .open + item.state != .open && !again + } + + var canAnswerAgain: Bool { + item.state == .answered } var chosen: [String] { @@ -148,6 +153,15 @@ private final class CardModel { do { var r = response r.images = try await uploadImages(store.api, imgs) + if again { + let task = try await store.api.client.answerAgain(body: .json(r)).created.body.json + store.drafts?.clearAnswer(item.id) + store.paneFocus.setDraft(key, false) + again = false + busy = false + store.focusTask(task.id) + return + } _ = try await store.api.client.respondInbox(body: .json(.init(responses: [r]))).ok store.drafts?.clearAnswer(item.id) store.paneFocus.setDraft(key, false) @@ -251,6 +265,15 @@ struct QuestionDetails: View { if let model { CardBody(model: model, focus: $focus, question: false) Thread(item: item) + if model.again { + CardActions(model: model, focus: $focus) + } else if model.canAnswerAgain { + Button("Answer again") { + model.again = true + } + .buttonStyle(WebButtonStyle()) + .help("Fork this task from the snapshot taken just before this answer reached the agent, and give the fork a different answer; this task carries on untouched") + } } } .frame(maxWidth: .infinity, alignment: .leading) @@ -447,11 +470,18 @@ private struct CardActions: View { model.submit(InboxResponseCreate(itemId: model.item.id, _type: .other, text: delegateText)) } .buttonStyle(WebButtonStyle()) - Button("Ignore") { - model.dismiss() + if model.again { + Button("Cancel") { + model.again = false + } + .buttonStyle(WebButtonStyle()) + } else { + Button("Ignore") { + model.dismiss() + } + .buttonStyle(WebButtonStyle()) + .help("Dismiss this question without answering it; the agent is not told") } - .buttonStyle(WebButtonStyle()) - .help("Dismiss this question without answering it; the agent is not told") Spacer() Button("Submit") { model.submitQuestion()