Fork tasks from snapshots; snapshot only when text follows tool calls

This commit is contained in:
Ian Gulliver
2026-10-15 11:36:51 -07:00
parent 3fe0374ac5
commit 0000db1f86
25 changed files with 893 additions and 421 deletions
+28 -2
View File
@@ -503,6 +503,27 @@ paths:
items: { $ref: "#/components/schemas/Snapshot" }
"404": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/snapshots/{n}/fork:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
- { name: n, in: path, required: true, schema: { type: integer } }
post:
operationId: forkSnapshot
description: >
Creates a new task whose branch and worktree start from the snapshot's commit, with an idle agent session that
continues the snapshot's agent conversation as it stood at the snapshot (the vendor's own session fork). The
new session's first turn is the first message sent to it. Refused while the task is closed, and for a snapshot
with no recorded agent message at or before it.
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/tasks/{taskId}/sessions:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
@@ -820,6 +841,8 @@ components:
closed_at: { type: string, format: date-time, description: When the task was merged or discarded. }
merge_commit: { type: string, description: "merged: the squash commit on the default branch; empty when there was nothing to merge." }
todo_item: { type: string, description: "The title of the TODO.md item the task was started from; absent for other tasks." }
forked_from: { type: string, description: "The task this one was forked from; absent for other tasks." }
forked_at: { type: integer, description: "With forked_from: the n of the snapshot it was forked at." }
Todo:
type: object
@@ -945,8 +968,9 @@ components:
event_seq: { type: integer, format: int64, description: "The task's latest event when the snapshot was started: the tree holds at least the work up to it." }
trigger:
type: string
enum: [tool_call, turn_end, ask_human, timer]
x-enum-varnames: [SnapshotTriggerToolCall, SnapshotTriggerTurnEnd, SnapshotTriggerAskHuman, SnapshotTriggerTimer]
enum: [message, turn_end, tool_call, ask_human, timer]
x-enum-varnames: [SnapshotTriggerMessage, SnapshotTriggerTurnEnd, SnapshotTriggerToolCall, SnapshotTriggerAskHuman, SnapshotTriggerTimer]
description: "message: the agent wrote text after one or more tool calls; turn_end: after byre's end-of-turn commit. tool_call, ask_human and timer appear only on snapshots taken by earlier builds."
created_at: { type: string, format: date-time }
AgentSession:
@@ -967,6 +991,8 @@ components:
role: { type: string, enum: [implementer, lead] }
created_by: { type: string }
created_at: { type: string, format: date-time }
forked_from: { type: string, description: "A fork's first start resumes this vendor session, cut at forked_at, under a new vendor_session_id; absent for other sessions." }
forked_at: { type: string, description: "With forked_from: the vendor's id of the last message the fork keeps." }
SessionCreate:
type: object