Add review workflows, tree-shaped workflows and a workflow editor
This commit is contained in:
+74
-61
@@ -78,23 +78,6 @@ paths:
|
||||
schema: { $ref: "#/components/schemas/User" }
|
||||
"400": { $ref: "#/components/responses/Error" }
|
||||
|
||||
/api/me/review-models:
|
||||
put:
|
||||
operationId: updateReviewModels
|
||||
description: Sets the models that review the calling user's tasks.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ReviewModels" }
|
||||
responses:
|
||||
"200":
|
||||
description: The updated user.
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/User" }
|
||||
"400": { $ref: "#/components/responses/Error" }
|
||||
|
||||
/api/me/lead/sessions:
|
||||
get:
|
||||
operationId: listLeadSessions
|
||||
@@ -256,6 +239,26 @@ paths:
|
||||
schema: { $ref: "#/components/schemas/Project" }
|
||||
"404": { $ref: "#/components/responses/Error" }
|
||||
|
||||
/api/projects/{projectId}/review-workflow:
|
||||
parameters:
|
||||
- { name: projectId, in: path, required: true, schema: { type: string } }
|
||||
put:
|
||||
operationId: setReviewWorkflow
|
||||
description: Sets the review workflow that reviews the project's snapshots from the next one on; empty turns reviews off. Records project.updated.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/ReviewWorkflow" }
|
||||
responses:
|
||||
"200":
|
||||
description: The updated project.
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/Project" }
|
||||
"400": { $ref: "#/components/responses/Error" }
|
||||
"404": { $ref: "#/components/responses/Error" }
|
||||
|
||||
/api/projects/{projectId}/tasks:
|
||||
parameters:
|
||||
- { name: projectId, in: path, required: true, schema: { type: string } }
|
||||
@@ -1210,21 +1213,27 @@ paths:
|
||||
operationId: getWorkflow
|
||||
responses:
|
||||
"200":
|
||||
description: "The workflow's file: its WorkflowDefinition as YAML, as an attachment named after it."
|
||||
description: >
|
||||
The workflow's WorkflowDefinition: as JSON when the request accepts only application/json, else its file as
|
||||
YAML, as an attachment named after it.
|
||||
content:
|
||||
application/yaml:
|
||||
schema: { type: string }
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/WorkflowDefinition" }
|
||||
"404": { $ref: "#/components/responses/Error" }
|
||||
put:
|
||||
operationId: putWorkflow
|
||||
description: >
|
||||
Creates or replaces the workflow from its file, a WorkflowDefinition as YAML (or JSON). The name is one line
|
||||
of 1 to 100 characters. Tasks that already froze the workflow keep their copy.
|
||||
Creates or replaces the workflow from its file, a WorkflowDefinition as YAML or JSON. The name is one line of
|
||||
1 to 100 characters. Tasks that already froze the workflow keep their copy.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/yaml:
|
||||
schema: { type: string }
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/WorkflowDefinition" }
|
||||
responses:
|
||||
"200":
|
||||
description: The stored workflow.
|
||||
@@ -1256,7 +1265,7 @@ components:
|
||||
|
||||
User:
|
||||
type: object
|
||||
required: [login, display_name, git_name, git_email, notification_prefs, default_model, review_model, second_review_model, away]
|
||||
required: [login, display_name, git_name, git_email, notification_prefs, default_model, away]
|
||||
properties:
|
||||
login: { type: string }
|
||||
display_name: { type: string }
|
||||
@@ -1264,8 +1273,6 @@ components:
|
||||
git_email: { type: string }
|
||||
notification_prefs: { $ref: "#/components/schemas/NotificationPrefs" }
|
||||
default_model: { type: string, description: The model the app starts new tasks on. }
|
||||
review_model: { type: string, description: The model that reviews this user's tasks, unless it wrote the work under review. }
|
||||
second_review_model: { type: string, description: The model that reviews this user's tasks when review_model wrote the work under review. }
|
||||
away: { type: boolean, description: "While true, byre answers the questions agents ask in this user's tasks at once." }
|
||||
|
||||
Away:
|
||||
@@ -1280,13 +1287,6 @@ components:
|
||||
properties:
|
||||
model: { type: string }
|
||||
|
||||
ReviewModels:
|
||||
type: object
|
||||
required: [review_model, second_review_model]
|
||||
properties:
|
||||
review_model: { type: string }
|
||||
second_review_model: { type: string }
|
||||
|
||||
NotificationPrefs:
|
||||
type: object
|
||||
description: Which task events notify this user in the macOS app.
|
||||
@@ -1310,7 +1310,7 @@ components:
|
||||
|
||||
Project:
|
||||
type: object
|
||||
required: [id, name, repo_path, default_branch, remote, created_by, created_at]
|
||||
required: [id, name, repo_path, default_branch, remote, created_by, created_at, review_workflow]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
@@ -1319,6 +1319,13 @@ components:
|
||||
remote: { type: string }
|
||||
created_by: { type: string }
|
||||
created_at: { type: string, format: date-time }
|
||||
review_workflow: { type: string, description: "The review workflow whose stages review every snapshot of the project's tasks; empty for no reviews." }
|
||||
|
||||
ReviewWorkflow:
|
||||
type: object
|
||||
required: [workflow]
|
||||
properties:
|
||||
workflow: { type: string, description: "A saved workflow of kind review, or empty for no reviews." }
|
||||
|
||||
ProjectCreate:
|
||||
type: object
|
||||
@@ -1430,51 +1437,56 @@ components:
|
||||
workflow:
|
||||
type: string
|
||||
description: >
|
||||
The name of a saved workflow to run instead of creating one task with no agent: each stage with no after
|
||||
stages becomes its own task, titled "<title>: <stage>", with the title as the run's brief. The response is
|
||||
the first of those tasks.
|
||||
The name of a saved workflow to run instead of creating one task with no agent: each stage that starts it
|
||||
becomes its own task, titled "<title>: <stage>", with the title as the run's brief. The response is the
|
||||
first of those tasks.
|
||||
|
||||
WorkflowSummary:
|
||||
type: object
|
||||
required: [name, description]
|
||||
required: [name, description, kind]
|
||||
properties:
|
||||
name: { type: string }
|
||||
description: { type: string }
|
||||
kind: { type: string, enum: [task, review] }
|
||||
|
||||
WorkflowDefinition:
|
||||
type: object
|
||||
description: >
|
||||
A workflow's file, which holds everything but its name: its stages, each run as its own task once the stages
|
||||
it comes after have finished. Sent and returned as YAML.
|
||||
required: [stages]
|
||||
A workflow's file, which holds everything but its name: its steps, run in order. Each stage runs as its own
|
||||
task once the steps before it have finished. Sent and returned as YAML.
|
||||
required: [steps]
|
||||
properties:
|
||||
description: { type: string, x-go-type-skip-optional-pointer: true }
|
||||
stages:
|
||||
kind:
|
||||
type: string
|
||||
enum: [task, review]
|
||||
x-enum-varnames: [WorkflowKindTask, WorkflowKindReview]
|
||||
x-go-type-skip-optional-pointer: true
|
||||
description: >
|
||||
task (the default): each stage runs as its own task. review: each stage is a reviewer of a snapshot, run
|
||||
when a project names the workflow as its review workflow; a stage gets the earlier stages' reviews.
|
||||
steps:
|
||||
type: array
|
||||
minItems: 1
|
||||
items: { $ref: "#/components/schemas/Stage" }
|
||||
items: { $ref: "#/components/schemas/WorkflowStep" }
|
||||
|
||||
Stage:
|
||||
WorkflowStep:
|
||||
type: object
|
||||
required: [name, prompt]
|
||||
description: >
|
||||
Exactly one of stage (with its model or agents, and prompt), order or parallel. A stage gets the outputs of
|
||||
the stages that end the step before it: the last stage of an order, every branch's last stage of a parallel.
|
||||
properties:
|
||||
name: { type: string, description: "One line of 1 to 100 characters, unique within the workflow." }
|
||||
after:
|
||||
type: array
|
||||
items: { type: string }
|
||||
description: >
|
||||
The stages whose outputs this stage gets, by name; it starts once all of them have finished. Absent means
|
||||
the previous stage in the list (for the first stage, none); empty means it starts from the brief.
|
||||
base:
|
||||
type: string
|
||||
enum: [parent, main]
|
||||
x-enum-varnames: [StageBaseParent, StageBaseMain]
|
||||
description: >
|
||||
Where the stage's task branches from. parent (the default): the commit its one after stage finished at, or
|
||||
for a stage with none, where the workflow was started from. main: the project's default branch. Refused on
|
||||
a stage with more than one after stage, which always branches from the default branch.
|
||||
stage: { type: string, x-go-type-skip-optional-pointer: true, description: "The stage's name, one line of 1 to 100 characters, unique within the workflow." }
|
||||
model: { type: string, x-go-type-skip-optional-pointer: true, description: "The stage agent's model, which also picks its vendor: gpt-* models run on Codex, gemini-* models on Antigravity, every other model on Claude Code. Required without agents, refused with them." }
|
||||
prompt: { type: string, description: "The stage agent's instructions; with agents, the instructions every agent of the team gets before its own." }
|
||||
prompt: { type: string, x-go-type-skip-optional-pointer: true, description: "The stage agent's instructions; with agents, the instructions every agent of the team gets before its own." }
|
||||
order:
|
||||
type: array
|
||||
items: { $ref: "#/components/schemas/WorkflowStep" }
|
||||
description: Steps run one after another, each getting the outputs of the one before.
|
||||
parallel:
|
||||
type: array
|
||||
items: { $ref: "#/components/schemas/WorkflowStep" }
|
||||
description: Branches run at the same time, each getting the outputs of the step before the parallel.
|
||||
agents:
|
||||
type: array
|
||||
items: { $ref: "#/components/schemas/TeamMember" }
|
||||
@@ -1520,7 +1532,7 @@ components:
|
||||
name: { type: string }
|
||||
after:
|
||||
type: array
|
||||
description: The stages it comes after, with the definition's defaults applied.
|
||||
description: The stages whose outputs it gets, from the steps' shape.
|
||||
items: { type: string }
|
||||
state:
|
||||
type: string
|
||||
@@ -1669,12 +1681,13 @@ components:
|
||||
|
||||
Review:
|
||||
type: object
|
||||
description: An agent session on the vendor the task's agent doesn't use, reviewing one snapshot's change.
|
||||
required: [id, task_id, snapshot_n, agent_session_id, vendor, model, state, error, created_at, finding_states, finding_responses]
|
||||
description: One stage of the project's review workflow, an agent session reviewing one snapshot's change.
|
||||
required: [id, task_id, snapshot_n, stage, agent_session_id, vendor, model, state, error, created_at, finding_states, finding_responses]
|
||||
properties:
|
||||
id: { type: string }
|
||||
task_id: { type: string }
|
||||
snapshot_n: { type: integer }
|
||||
stage: { type: string, description: "The review workflow's stage this reviewer ran; empty when skipped." }
|
||||
agent_session_id: { type: string, description: "The reviewer's session; empty when skipped." }
|
||||
vendor: { type: string, description: "Empty when skipped." }
|
||||
model: { type: string, description: "Empty when skipped." }
|
||||
|
||||
Reference in New Issue
Block a user