Files
byre/api/openapi.yaml
T

944 lines
35 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/me/notifications:
put:
operationId: updateNotificationPrefs
description: Sets which inbox items the calling user is sent push notifications for.
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/NotificationPrefs" }
responses:
"200":
description: The updated user.
content:
application/json:
schema: { $ref: "#/components/schemas/User" }
"400": { $ref: "#/components/responses/Error" }
/api/me/push-subscriptions:
post:
operationId: addPushSubscription
description: Registers a browser's push subscription for the calling user. Registering an endpoint again replaces it.
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/PushSubscription" }
responses:
"204":
description: Registered.
"400": { $ref: "#/components/responses/Error" }
delete:
operationId: removePushSubscription
parameters:
- { name: endpoint, in: query, required: true, schema: { type: string } }
responses:
"204":
description: Removed, or was not registered.
/api/push/key:
get:
operationId: getPushKey
responses:
"200":
description: The server's VAPID public key, the applicationServerKey for PushManager.subscribe.
content:
application/json:
schema: { $ref: "#/components/schemas/PushKey" }
/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}/unmerged:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: getUnmerged
description: What the task's worktree holds that its project's default branch doesn't.
responses:
"200":
description: The unmerged changes.
content:
application/json:
schema: { $ref: "#/components/schemas/Unmerged" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/merge:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
post:
operationId: mergeTask
description: >
Starts the same agent turn as merge-in. When that turn ends normally, byre squashes the task's worktree
into one commit titled with the task's merge_title on the project's default branch, fast-forwards the project's
checkout to it, then removes the worktree and branch and marks the task merged. Nothing is pushed. Refused while
a turn is running or queued.
responses:
"202":
description: The merge turn was started or queued.
content:
application/json:
schema: { $ref: "#/components/schemas/AgentSession" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/merge-in:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
post:
operationId: mergeIn
description: >
Asks the task's agent to merge the project's default branch into the task branch, resolving any conflicts
and regenerating generated files. Sent to the task's idle session, or starts a session when it has none.
Refused while a turn is running or queued.
responses:
"202":
description: The merge turn was started or queued.
content:
application/json:
schema: { $ref: "#/components/schemas/AgentSession" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/discard:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
post:
operationId: discardTask
description: Removes the task's worktree and branch without merging. The task's record and events remain.
responses:
"200":
description: The discarded 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}/changes:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: getTaskChanges
description: >
Everything in the task's worktree (committed, staged, unstaged and untracked, respecting .gitignore) as a tree,
compared with the merge-base of the task branch and the project's default branch, or with since when given.
The worktree's own index is not touched.
parameters:
- { name: since, in: query, required: false, schema: { type: string }, description: "A commit to compare with instead of the merge-base, such as a user.message event's head." }
responses:
"200":
description: Per-file stats.
content:
application/json:
schema: { $ref: "#/components/schemas/TaskChanges" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/diff:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: getTaskDiff
description: The unified diff of one file between a base and tree from getTaskChanges.
parameters:
- { name: base, in: query, required: true, schema: { type: string } }
- { name: tree, in: query, required: true, schema: { type: string } }
- { name: path, in: query, required: true, schema: { type: string } }
- { name: old_path, in: query, required: false, schema: { type: string } }
responses:
"200":
description: The patch.
content:
application/json:
schema: { $ref: "#/components/schemas/FileDiff" }
"400": { $ref: "#/components/responses/Error" }
"404": { $ref: "#/components/responses/Error" }
"409": { $ref: "#/components/responses/Error" }
/api/tasks/{taskId}/snapshots:
parameters:
- { name: taskId, in: path, required: true, schema: { type: string } }
get:
operationId: listSnapshots
description: >
The task's snapshots, oldest first. Each is a commit of the worktree as if everything were staged, kept at
refs/byre/tasks/{taskId}/snap/{n} until the task is merged or discarded; the rows remain after that.
responses:
"200":
description: The snapshots.
content:
application/json:
schema:
type: array
items: { $ref: "#/components/schemas/Snapshot" }
"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}/compact:
parameters:
- { name: sessionId, in: path, required: true, schema: { type: string } }
post:
operationId: compactSession
description: >
Asks the idle session's agent for a handoff (goal, decisions, state, dead ends, open questions, files). When that turn ends,
the session is completed and a new session on the same task and model starts with the handoff as its first message.
responses:
"202":
description: The handoff turn was started or queued.
content:
application/json:
schema: { $ref: "#/components/schemas/AgentSession" }
"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/blobs:
post:
operationId: uploadBlob
description: >
Stores an image for use in a message. The body is the raw image; its type is detected from the bytes
and must be PNG, JPEG, GIF or WebP. At most 5 MiB.
requestBody:
required: true
content:
image/png: { schema: { type: string, format: binary } }
image/jpeg: { schema: { type: string, format: binary } }
image/gif: { schema: { type: string, format: binary } }
image/webp: { schema: { type: string, format: binary } }
responses:
"201":
description: The stored blob.
content:
application/json:
schema: { $ref: "#/components/schemas/Blob" }
"400": { $ref: "#/components/responses/Error" }
"413": { $ref: "#/components/responses/Error" }
/api/blobs/{blobId}:
parameters:
- { name: blobId, in: path, required: true, schema: { type: string } }
get:
operationId: getBlob
responses:
"200":
description: The blob's bytes, with its content type.
content:
image/png: { schema: { type: string, format: binary } }
image/jpeg: { schema: { type: string, format: binary } }
image/gif: { schema: { type: string, format: binary } }
image/webp: { schema: { type: string, format: binary } }
"404": { $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" } }
responses:
"200":
description: Matching items with their responses. Defaults to open 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, notification_prefs]
properties:
login: { type: string }
display_name: { type: string }
git_name: { type: string }
git_email: { type: string }
notification_prefs: { $ref: "#/components/schemas/NotificationPrefs" }
NotificationPrefs:
type: object
description: Which new inbox items send this user a push notification.
required: [blocking_questions, questions, reports, errors, rate_limits]
properties:
blocking_questions: { type: boolean, description: "Questions asked with blocking: true. On by default." }
questions: { type: boolean, description: Non-blocking questions. }
reports: { type: boolean, description: Turn summaries. }
errors: { type: boolean, description: session_error items. }
rate_limits: { type: boolean, description: rate_limited items. }
PushSubscription:
type: object
required: [endpoint, p256dh, auth]
properties:
endpoint: { type: string }
p256dh: { type: string, description: The subscription's p256dh key, base64url. }
auth: { type: string, description: The subscription's auth secret, base64url. }
PushKey:
type: object
required: [public_key]
properties:
public_key: { type: string, description: Base64url, uncompressed P-256 point. }
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, merge_title, branch, worktree_path, base_ref, status, created_by, created_at]
properties:
id: { type: string }
project_id: { type: string }
title: { type: string }
merge_title: { type: string, description: "The title of the squash commit Merge makes: the task title until the agent sets another with set_merge_title." }
branch: { type: string }
worktree_path: { type: string }
base_ref: { type: string }
status:
type: string
enum: [active, merged, discarded]
x-enum-varnames: [TaskStatusActive, TaskStatusMerged, TaskStatusDiscarded]
created_by: { type: string }
created_at: { type: string, format: date-time }
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." }
Unmerged:
type: object
required: [commits, files, insertions, deletions, uncommitted]
properties:
commits: { type: integer, description: Commits on the task branch that aren't on the default branch. }
files: { type: integer, description: Files that differ from the merge base, uncommitted changes included. }
insertions: { type: integer }
deletions: { type: integer }
uncommitted: { type: integer, description: Paths with uncommitted changes in the worktree. }
TaskCreate:
type: object
required: [title]
properties:
title: { type: string }
TaskChanges:
type: object
required: [base, tree, files]
properties:
base: { type: string, description: Merge-base commit of the task branch and the default branch. }
tree: { type: string, description: Tree of the worktree as if everything were staged. }
files:
type: array
items: { $ref: "#/components/schemas/FileChange" }
FileChange:
type: object
required: [path, status, additions, deletions, binary]
properties:
path: { type: string }
old_path: { type: string, description: "renamed: the path before the rename." }
status: { type: string, enum: [added, modified, deleted, renamed, type_changed] }
additions: { type: integer }
deletions: { type: integer }
binary: { type: boolean }
FileDiff:
type: object
required: [path, patch]
properties:
path: { type: string }
patch: { type: string }
Snapshot:
type: object
required: [id, task_id, agent_session_id, n, commit_sha, tree_sha, event_seq, trigger, created_at]
properties:
id: { type: string }
task_id: { type: string }
agent_session_id: { type: string }
n: { type: integer, description: "Position in the task's snapshots, from 1; the ref is refs/byre/tasks/{task_id}/snap/{n}." }
commit_sha: { type: string, description: A commit of tree_sha whose parent is the worktree's HEAD when it was taken. }
tree_sha: { type: string }
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]
created_at: { type: string, format: date-time }
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]
x-enum-varnames: [AgentSessionStateIdle, AgentSessionStateQueued, AgentSessionStateRunning, AgentSessionStateCompleted]
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 }
images:
type: array
items: { type: string }
description: Blob ids from uploadBlob, sent to the agent as images alongside the prompt.
MessageCreate:
type: object
required: [text]
properties:
text: { type: string, description: May be empty when images are given. }
images:
type: array
items: { type: string }
description: Blob ids from uploadBlob, sent to the agent as images alongside the text.
model:
type: string
description: Model for this turn and later ones. When it differs from the session's model, the session switches before the message is sent.
Blob:
type: object
required: [id, content_type, created_by, created_at]
properties:
id: { type: string }
content_type: { type: string }
created_by: { type: string }
created_at: { type: string, format: date-time }
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 (Markdown with the choices inline as `- ( ) text` / `- (*) text` pick-one or `- [ ] text` / `- [x] text` pick-any list items),
question, why_blocked, options (each choice's text, in order), multiple (true for pick-any), recommended (the marked choices' text), attachments.
report: text (the final message of a turn that ended normally).
session_error: error.
rate_limited: vendor, rate_limit (the vendor's rate-limit status), error.
state: { $ref: "#/components/schemas/InboxState" }
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, 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" }
options:
type: array
items: { type: string }
text: { type: string }
attachments:
type: array
items: { $ref: "#/components/schemas/Attachment" }
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" }
options:
type: array
items: { type: string }
description: "option: the chosen options; exactly one for a pick-one question, one or more for a pick-any question."
text: { type: string, description: "other: the text sent to the agent." }
attachments:
type: array
items: { $ref: "#/components/schemas/Attachment" }
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, caps, rate_limits, agent_processes, zombies, stuck_after_seconds, protocol_errors]
properties:
live_agents: { type: integer, description: Agent processes currently running. }
agent_processes:
type: array
description: Every agent process byre is tracking, idle sessions included.
items: { $ref: "#/components/schemas/AgentProcess" }
zombies:
type: array
description: Sessions marked running with no live process, and agent processes byre has no session for.
items: { $ref: "#/components/schemas/Zombie" }
stuck_after_seconds: { type: integer, description: How long a running turn may go without a stream event before it counts as stuck. }
protocol_errors: { $ref: "#/components/schemas/ProtocolErrors" }
running_turns:
type: array
description: Turns running now, oldest session first.
items: { $ref: "#/components/schemas/TurnRef" }
queued_turns:
type: array
description: Turns waiting for room under the caps, in the order they will start.
items: { $ref: "#/components/schemas/TurnRef" }
caps: { $ref: "#/components/schemas/Caps" }
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 }
Caps:
type: object
required: [global, per_vendor]
properties:
global: { type: integer, description: Most turns running at once across all vendors. }
per_vendor:
type: object
description: Most turns running at once per vendor, keyed by vendor.
additionalProperties: { type: integer }
TurnRef:
type: object
required: [session_id, task_id, vendor]
properties:
session_id: { type: string }
task_id: { type: string }
vendor: { type: string }
AgentProcess:
type: object
required: [session_id, task_id, vendor, pid, state, last_event_at, health]
properties:
session_id: { type: string }
task_id: { type: string }
vendor: { type: string }
pid: { type: integer }
state: { type: string, description: The session's state, as on AgentSession. }
last_event_at: { type: string, format: date-time, description: When the process last wrote a line to its stream, or when it started. }
health:
type: string
enum: [ok, stuck, exited]
x-enum-varnames: [HealthOk, HealthStuck, HealthExited]
description: stuck means a turn is running and no stream event has arrived for stuck_after_seconds; exited means the process is gone.
Zombie:
type: object
required: [kind, detail]
properties:
kind:
type: string
enum: [running_without_process, process_without_session]
detail: { type: string }
session_id: { type: string }
task_id: { type: string }
pid: { type: integer }
ProtocolErrors:
type: object
required: [counts, recent]
properties:
counts:
type: object
description: Stream lines the adapter couldn't parse or didn't recognise since byre started, keyed by vendor.
additionalProperties: { type: integer }
recent:
type: array
description: The most recent ones, newest first.
items: { $ref: "#/components/schemas/ProtocolError" }
ProtocolError:
type: object
required: [vendor, session_id, at, reason, raw, size]
properties:
vendor: { type: string }
session_id: { type: string }
at: { type: string, format: date-time }
reason: { type: string }
raw: { type: string, description: The line as received, cut to its first 4 KiB. }
size: { type: integer, description: The line's full length in bytes. }