532 lines
18 KiB
YAML
532 lines
18 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: byre
|
|
version: 0.0.0
|
|
paths:
|
|
/api/me:
|
|
get:
|
|
operationId: getMe
|
|
responses:
|
|
"200":
|
|
description: The calling user.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/User" }
|
|
put:
|
|
operationId: updateMe
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/UserUpdate" }
|
|
responses:
|
|
"200":
|
|
description: The updated user.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/User" }
|
|
"400": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/projects:
|
|
get:
|
|
operationId: listProjects
|
|
responses:
|
|
"200":
|
|
description: All projects.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/Project" }
|
|
post:
|
|
operationId: createProject
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/ProjectCreate" }
|
|
responses:
|
|
"201":
|
|
description: The new project.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Project" }
|
|
"400": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/projects/{projectId}:
|
|
parameters:
|
|
- { name: projectId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: getProject
|
|
responses:
|
|
"200":
|
|
description: The project.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Project" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/projects/{projectId}/tasks:
|
|
parameters:
|
|
- { name: projectId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: listTasks
|
|
responses:
|
|
"200":
|
|
description: The project's tasks, newest first.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/Task" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
post:
|
|
operationId: createTask
|
|
description: Creates the task's branch and worktree from the project's default branch.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/TaskCreate" }
|
|
responses:
|
|
"201":
|
|
description: The new task.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Task" }
|
|
"400": { $ref: "#/components/responses/Error" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/tasks/{taskId}:
|
|
parameters:
|
|
- { name: taskId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: getTask
|
|
responses:
|
|
"200":
|
|
description: The task.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Task" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/tasks/{taskId}/complete:
|
|
parameters:
|
|
- { name: taskId, in: path, required: true, schema: { type: string } }
|
|
post:
|
|
operationId: completeTask
|
|
description: Removes the task's worktree and branch. The task's record and events remain.
|
|
responses:
|
|
"200":
|
|
description: The completed task.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Task" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
"409": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/tasks/{taskId}/events:
|
|
parameters:
|
|
- { name: taskId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: listTaskEvents
|
|
description: The task's events after a seq, oldest first. Page by passing the last seq back as after.
|
|
parameters:
|
|
- { name: after, in: query, required: false, schema: { type: integer, format: int64 } }
|
|
- { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 1000 } }
|
|
responses:
|
|
"200":
|
|
description: Up to limit events (default 500).
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/Event" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/tasks/{taskId}/sessions:
|
|
parameters:
|
|
- { name: taskId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: listSessions
|
|
responses:
|
|
"200":
|
|
description: The task's agent sessions, oldest first.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/AgentSession" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
post:
|
|
operationId: createSession
|
|
description: Starts an agent session in the task's worktree and sends it the prompt as its first turn.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/SessionCreate" }
|
|
responses:
|
|
"201":
|
|
description: The new session.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/AgentSession" }
|
|
"400": { $ref: "#/components/responses/Error" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
"409": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/sessions/{sessionId}:
|
|
parameters:
|
|
- { name: sessionId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: getSession
|
|
responses:
|
|
"200":
|
|
description: The session.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/AgentSession" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/sessions/{sessionId}/messages:
|
|
parameters:
|
|
- { name: sessionId, in: path, required: true, schema: { type: string } }
|
|
post:
|
|
operationId: sendMessage
|
|
description: Starts a new turn with this message. The session must be idle.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/MessageCreate" }
|
|
responses:
|
|
"202":
|
|
description: The turn has started.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/AgentSession" }
|
|
"400": { $ref: "#/components/responses/Error" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
"409": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/sessions/{sessionId}/interrupt:
|
|
parameters:
|
|
- { name: sessionId, in: path, required: true, schema: { type: string } }
|
|
post:
|
|
operationId: interruptSession
|
|
description: Ends the current turn.
|
|
responses:
|
|
"202":
|
|
description: The interrupt was delivered.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/AgentSession" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
"409": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/inbox:
|
|
get:
|
|
operationId: listInbox
|
|
description: >
|
|
Inbox items, highest priority first (blocked, gate, review, fyi), then oldest first.
|
|
Filters narrow the one query to a project's or a task's view.
|
|
parameters:
|
|
- { name: project_id, in: query, required: false, schema: { type: string } }
|
|
- { name: task_id, in: query, required: false, schema: { type: string } }
|
|
- { name: state, in: query, required: false, schema: { $ref: "#/components/schemas/InboxState" } }
|
|
- { name: include_snoozed, in: query, required: false, schema: { type: boolean } }
|
|
responses:
|
|
"200":
|
|
description: Matching items with their responses. Defaults to open, unsnoozed items.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/InboxItem" }
|
|
|
|
/api/inbox/{itemId}:
|
|
parameters:
|
|
- { name: itemId, in: path, required: true, schema: { type: string } }
|
|
get:
|
|
operationId: getInboxItem
|
|
responses:
|
|
"200":
|
|
description: The item with its responses.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/InboxItem" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/inbox/responses:
|
|
post:
|
|
operationId: respondInbox
|
|
description: >
|
|
Answers one or more items in one submission. Answers reach the agent as one message once
|
|
it is idle and none of its blocking questions are unanswered.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/InboxRespond" }
|
|
responses:
|
|
"200":
|
|
description: The updated items.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/InboxItem" }
|
|
"400": { $ref: "#/components/responses/Error" }
|
|
"404": { $ref: "#/components/responses/Error" }
|
|
"409": { $ref: "#/components/responses/Error" }
|
|
|
|
/api/events:
|
|
get:
|
|
operationId: streamEvents
|
|
description: >
|
|
Server-sent events. Each event's id is its seq; data is the Event as JSON.
|
|
Events after Last-Event-ID (or the after query parameter) are replayed before live events.
|
|
parameters:
|
|
- { name: Last-Event-ID, in: header, required: false, schema: { type: integer, format: int64 } }
|
|
- { name: after, in: query, required: false, schema: { type: integer, format: int64 } }
|
|
responses:
|
|
"200":
|
|
description: Event stream.
|
|
content:
|
|
text/event-stream:
|
|
schema: { type: string }
|
|
|
|
/api/admin/status:
|
|
get:
|
|
operationId: getStatus
|
|
responses:
|
|
"200":
|
|
description: Server health and usage.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Status" }
|
|
|
|
components:
|
|
responses:
|
|
Error:
|
|
description: Error.
|
|
content:
|
|
application/json:
|
|
schema: { $ref: "#/components/schemas/Error" }
|
|
|
|
schemas:
|
|
Error:
|
|
type: object
|
|
required: [message]
|
|
properties:
|
|
message: { type: string }
|
|
|
|
User:
|
|
type: object
|
|
required: [login, display_name, git_name, git_email]
|
|
properties:
|
|
login: { type: string }
|
|
display_name: { type: string }
|
|
git_name: { type: string }
|
|
git_email: { type: string }
|
|
|
|
UserUpdate:
|
|
type: object
|
|
required: [git_name, git_email]
|
|
properties:
|
|
git_name: { type: string }
|
|
git_email: { type: string }
|
|
|
|
Project:
|
|
type: object
|
|
required: [id, name, repo_path, default_branch, remote, created_by, created_at]
|
|
properties:
|
|
id: { type: string }
|
|
name: { type: string }
|
|
repo_path: { type: string }
|
|
default_branch: { type: string }
|
|
remote: { type: string }
|
|
created_by: { type: string }
|
|
created_at: { type: string, format: date-time }
|
|
|
|
ProjectCreate:
|
|
type: object
|
|
required: [name, repo_path]
|
|
properties:
|
|
name: { type: string }
|
|
repo_path: { type: string }
|
|
|
|
Task:
|
|
type: object
|
|
required: [id, project_id, title, branch, worktree_path, base_ref, status, created_by, created_at]
|
|
properties:
|
|
id: { type: string }
|
|
project_id: { type: string }
|
|
title: { type: string }
|
|
branch: { type: string }
|
|
worktree_path: { type: string }
|
|
base_ref: { type: string }
|
|
status: { type: string, enum: [active, completed] }
|
|
created_by: { type: string }
|
|
created_at: { type: string, format: date-time }
|
|
completed_at: { type: string, format: date-time }
|
|
|
|
TaskCreate:
|
|
type: object
|
|
required: [title]
|
|
properties:
|
|
title: { type: string }
|
|
|
|
AgentSession:
|
|
type: object
|
|
required: [id, task_id, vendor, model, vendor_session_id, state, role, created_by, created_at]
|
|
properties:
|
|
id: { type: string }
|
|
task_id: { type: string }
|
|
vendor: { type: string, enum: [claude] }
|
|
model: { type: string, description: Requested model; empty means the vendor's default. }
|
|
vendor_session_id: { type: string }
|
|
state:
|
|
type: string
|
|
enum: [idle, queued, running, completed]
|
|
description: queued means a turn is waiting for a free slot under the concurrency caps.
|
|
role: { type: string, enum: [implementer] }
|
|
created_by: { type: string }
|
|
created_at: { type: string, format: date-time }
|
|
|
|
SessionCreate:
|
|
type: object
|
|
required: [prompt]
|
|
properties:
|
|
prompt: { type: string }
|
|
model: { type: string }
|
|
|
|
MessageCreate:
|
|
type: object
|
|
required: [text]
|
|
properties:
|
|
text: { type: string }
|
|
|
|
Attachment:
|
|
type: object
|
|
required: [kind]
|
|
properties:
|
|
kind: { type: string, enum: [file, diff, image, diagram, task, snapshot, url] }
|
|
path: { type: string, description: "file: repo-relative path." }
|
|
start_line: { type: integer }
|
|
end_line: { type: integer }
|
|
ref: { type: string, description: "diff: git revision range." }
|
|
url: { type: string }
|
|
mermaid: { type: string, description: "diagram: Mermaid source." }
|
|
image: { type: string, description: "image: data URL." }
|
|
task_id: { type: string }
|
|
snapshot_id: { type: string }
|
|
caption: { type: string }
|
|
|
|
InboxState:
|
|
type: string
|
|
enum: [open, answered, dismissed, superseded]
|
|
|
|
InboxItem:
|
|
type: object
|
|
required: [id, project_id, task_id, agent_session_id, thread_id, kind, priority, blocking, payload, state, created_at, responses]
|
|
properties:
|
|
id: { type: string }
|
|
project_id: { type: string }
|
|
task_id: { type: string }
|
|
agent_session_id: { type: string }
|
|
thread_id: { type: string }
|
|
kind: { type: string, enum: [question, report, session_error, rate_limited] }
|
|
priority: { type: string, enum: [blocked, gate, review, fyi] }
|
|
blocking: { type: boolean }
|
|
payload:
|
|
type: object
|
|
description: >
|
|
question: context, question, why_blocked, options, recommended_option, attachments.
|
|
report: done, next_steps, risks, deviations.
|
|
session_error: error.
|
|
rate_limited: vendor, rate_limit (the vendor's rate-limit status), error.
|
|
state: { $ref: "#/components/schemas/InboxState" }
|
|
snoozed_until: { type: string, format: date-time }
|
|
created_at: { type: string, format: date-time }
|
|
resolved_by: { type: string }
|
|
resolved_at: { type: string, format: date-time }
|
|
responses:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/InboxResponse" }
|
|
|
|
InboxResponseType:
|
|
type: string
|
|
enum: [option, other, snooze, dismiss]
|
|
|
|
InboxResponse:
|
|
type: object
|
|
required: [id, item_id, user, type, attachments, created_at]
|
|
properties:
|
|
id: { type: string }
|
|
item_id: { type: string }
|
|
user: { type: string }
|
|
type: { $ref: "#/components/schemas/InboxResponseType" }
|
|
option: { type: string }
|
|
text: { type: string }
|
|
attachments:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/Attachment" }
|
|
snooze_until: { type: string, format: date-time }
|
|
created_at: { type: string, format: date-time }
|
|
delivered_at: { type: string, format: date-time }
|
|
|
|
InboxResponseCreate:
|
|
type: object
|
|
required: [item_id, type]
|
|
properties:
|
|
item_id: { type: string }
|
|
type: { $ref: "#/components/schemas/InboxResponseType" }
|
|
option: { type: string, description: "option: one of the question's options." }
|
|
text: { type: string, description: "other: the text sent to the agent." }
|
|
attachments:
|
|
type: array
|
|
items: { $ref: "#/components/schemas/Attachment" }
|
|
snooze_until: { type: string, format: date-time, description: "snooze: when the item reappears." }
|
|
|
|
InboxRespond:
|
|
type: object
|
|
required: [responses]
|
|
properties:
|
|
responses:
|
|
type: array
|
|
minItems: 1
|
|
items: { $ref: "#/components/schemas/InboxResponseCreate" }
|
|
|
|
Event:
|
|
type: object
|
|
required: [seq, kind, actor, payload, created_at]
|
|
properties:
|
|
seq: { type: integer, format: int64 }
|
|
kind: { type: string }
|
|
project_id: { type: string }
|
|
task_id: { type: string }
|
|
agent_session_id: { type: string }
|
|
actor: { type: string }
|
|
payload: { type: object }
|
|
created_at: { type: string, format: date-time }
|
|
|
|
Status:
|
|
type: object
|
|
required: [started_at, db_bytes, last_event_seq, projects, active_tasks, sse_clients, live_agents, running_turns, queued_turns, rate_limits]
|
|
properties:
|
|
live_agents: { type: integer, description: Agent processes currently running. }
|
|
running_turns: { type: integer }
|
|
queued_turns: { type: integer }
|
|
rate_limits:
|
|
type: object
|
|
description: The latest rate-limit status each vendor reported, keyed by vendor.
|
|
additionalProperties: { type: object }
|
|
started_at: { type: string, format: date-time }
|
|
db_bytes: { type: integer, format: int64 }
|
|
last_event_seq: { type: integer, format: int64 }
|
|
projects: { type: integer }
|
|
active_tasks: { type: integer }
|
|
sse_clients: { type: integer }
|