docs: add OpenAPI 3.0 specification for all API endpoints
This commit is contained in:
@@ -0,0 +1,565 @@
|
||||
openapi: "3.0.3"
|
||||
info:
|
||||
title: Pipeline Runner API
|
||||
version: "0.1.0"
|
||||
description: >-
|
||||
REST API for managing and executing AI pipelines. Each pipeline consists
|
||||
of ordered prompts that are executed sequentially via opencode.
|
||||
servers:
|
||||
- url: http://localhost:8080
|
||||
description: Local development server
|
||||
tags:
|
||||
- name: Pipelines
|
||||
description: Pipeline CRUD operations
|
||||
- name: Runs
|
||||
description: Pipeline execution and monitoring
|
||||
paths:
|
||||
/api/pipelines:
|
||||
get:
|
||||
tags:
|
||||
- Pipelines
|
||||
summary: List all pipelines
|
||||
description: Returns all stored pipelines as a JSON array.
|
||||
operationId: listPipelines
|
||||
responses:
|
||||
"200":
|
||||
description: A JSON array of all pipelines
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Pipeline'
|
||||
example:
|
||||
- id: "my-pipeline"
|
||||
name: "My Pipeline"
|
||||
working_dir: "/workspace"
|
||||
created_at: "2025-01-15T10:30:00Z"
|
||||
updated_at: "2025-01-15T10:30:00Z"
|
||||
prompts:
|
||||
- id: "p1"
|
||||
text: "Summarize the document"
|
||||
title: "Summarization"
|
||||
order: 0
|
||||
- id: "p2"
|
||||
text: "Translate to French"
|
||||
title: "Translation"
|
||||
order: 1
|
||||
"500":
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Internal server error"
|
||||
post:
|
||||
tags:
|
||||
- Pipelines
|
||||
summary: Create a new pipeline
|
||||
description: >-
|
||||
Creates a new pipeline and persists it as a JSON file. Returns the
|
||||
created pipeline with generated timestamps.
|
||||
operationId: createPipeline
|
||||
requestBody:
|
||||
required: true
|
||||
description: Pipeline data to create
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreatePipelineRequest'
|
||||
example:
|
||||
id: "my-pipeline"
|
||||
name: "My Pipeline"
|
||||
working_dir: "/workspace"
|
||||
prompts:
|
||||
- id: "p1"
|
||||
text: "Summarize the document"
|
||||
title: "Summarization"
|
||||
order: 0
|
||||
- id: "p2"
|
||||
text: "Translate to French"
|
||||
title: "Translation"
|
||||
order: 1
|
||||
responses:
|
||||
"200":
|
||||
description: Pipeline created successfully
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pipeline'
|
||||
example:
|
||||
id: "my-pipeline"
|
||||
name: "My Pipeline"
|
||||
working_dir: "/workspace"
|
||||
created_at: "2025-01-15T10:30:00Z"
|
||||
updated_at: "2025-01-15T10:30:00Z"
|
||||
prompts:
|
||||
- id: "p1"
|
||||
text: "Summarize the document"
|
||||
title: "Summarization"
|
||||
order: 0
|
||||
"400":
|
||||
description: Invalid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
examples:
|
||||
invalidJson:
|
||||
summary: Malformed JSON body
|
||||
value:
|
||||
error: "Invalid JSON"
|
||||
missingFields:
|
||||
summary: Missing required fields
|
||||
value:
|
||||
error: "id and name are required"
|
||||
"409":
|
||||
description: Pipeline with this ID already exists
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Pipeline already exists"
|
||||
"500":
|
||||
description: Failed to save pipeline
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Failed to save pipeline"
|
||||
|
||||
/api/pipelines/{id}:
|
||||
get:
|
||||
tags:
|
||||
- Pipelines
|
||||
summary: Get a single pipeline by ID
|
||||
description: Returns a specific pipeline by its ID.
|
||||
operationId: getPipeline
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The pipeline ID
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Pipeline found
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pipeline'
|
||||
"404":
|
||||
description: Pipeline not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Pipeline not found"
|
||||
delete:
|
||||
tags:
|
||||
- Pipelines
|
||||
summary: Delete a pipeline
|
||||
description: Deletes a pipeline by its ID. Removes the corresponding JSON file.
|
||||
operationId: deletePipeline
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The pipeline ID
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Pipeline deleted successfully
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DeletePipelineResponse'
|
||||
example:
|
||||
deleted: "my-pipeline"
|
||||
"404":
|
||||
description: Pipeline not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Pipeline not found"
|
||||
"500":
|
||||
description: Failed to delete pipeline
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Failed to delete pipeline"
|
||||
|
||||
/api/runs:
|
||||
post:
|
||||
tags:
|
||||
- Runs
|
||||
summary: Start a pipeline execution
|
||||
description: >-
|
||||
Starts asynchronous execution of a pipeline. Each step runs
|
||||
`opencode run <text> --title <title>` with a 300-second timeout.
|
||||
Execution stops on the first step error.
|
||||
operationId: startRun
|
||||
requestBody:
|
||||
required: true
|
||||
description: Pipeline ID to execute
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StartRunRequest'
|
||||
example:
|
||||
pipeline_id: "my-pipeline"
|
||||
responses:
|
||||
"200":
|
||||
description: Run started successfully
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StartRunResponse'
|
||||
example:
|
||||
run_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
pipeline_id: "my-pipeline"
|
||||
status: "running"
|
||||
"400":
|
||||
description: Invalid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
examples:
|
||||
invalidJson:
|
||||
summary: Malformed JSON body
|
||||
value:
|
||||
error: "Invalid JSON"
|
||||
missingPipelineId:
|
||||
summary: Missing pipeline_id
|
||||
value:
|
||||
error: "pipeline_id is required"
|
||||
"404":
|
||||
description: Pipeline not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Pipeline not found"
|
||||
"500":
|
||||
description: Failed to start run
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Failed to start run"
|
||||
|
||||
/api/runs/{run_id}/status:
|
||||
get:
|
||||
tags:
|
||||
- Runs
|
||||
summary: Get run status and step results
|
||||
description: >-
|
||||
Returns the current execution state of a run, including the status
|
||||
of each step. Poll this endpoint to track progress.
|
||||
operationId: getRunStatus
|
||||
parameters:
|
||||
- name: run_id
|
||||
in: path
|
||||
required: true
|
||||
description: The run ID returned by POST /api/runs
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Run state
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RunState'
|
||||
example:
|
||||
run_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
pipeline_id: "my-pipeline"
|
||||
status: "running"
|
||||
current_step: 1
|
||||
steps:
|
||||
- step_index: 0
|
||||
title: "Summarization"
|
||||
status: "completed"
|
||||
returncode: 0
|
||||
output: "Document summary generated."
|
||||
error: ""
|
||||
"404":
|
||||
description: Run not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "Run not found"
|
||||
|
||||
/api/runs/{run_id}/log:
|
||||
get:
|
||||
tags:
|
||||
- Runs
|
||||
summary: Get run log file contents
|
||||
description: Returns the raw log file for a given run as plain text.
|
||||
operationId: getRunLog
|
||||
parameters:
|
||||
- name: run_id
|
||||
in: path
|
||||
required: true
|
||||
description: The run ID returned by POST /api/runs
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Log file contents
|
||||
headers:
|
||||
Access-Control-Allow-Origin:
|
||||
schema:
|
||||
type: string
|
||||
description: CORS wildcard origin
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Raw log contents
|
||||
example: |
|
||||
[2025-01-15T10:30:01Z] Starting pipeline: my-pipeline
|
||||
[2025-01-15T10:30:01Z] Step 0: Summarization - running
|
||||
[2025-01-15T10:30:05Z] Step 0: Summarization - completed (rc=0)
|
||||
[2025-01-15T10:30:05Z] Step 1: Translation - running
|
||||
components:
|
||||
schemas:
|
||||
Pipeline:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- prompts
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique pipeline identifier
|
||||
example: "my-pipeline"
|
||||
name:
|
||||
type: string
|
||||
description: Human-readable pipeline name
|
||||
example: "My Pipeline"
|
||||
working_dir:
|
||||
type: string
|
||||
description: Working directory for pipeline execution
|
||||
example: "/workspace"
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: ISO 8601 timestamp of pipeline creation
|
||||
example: "2025-01-15T10:30:00Z"
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: ISO 8601 timestamp of last update
|
||||
example: "2025-01-15T10:30:00Z"
|
||||
prompts:
|
||||
type: array
|
||||
description: Ordered list of prompts to execute
|
||||
items:
|
||||
$ref: '#/components/schemas/Prompt'
|
||||
|
||||
Prompt:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- text
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique prompt identifier within the pipeline
|
||||
example: "p1"
|
||||
text:
|
||||
type: string
|
||||
description: Prompt text passed to `opencode run`
|
||||
example: "Summarize the document"
|
||||
title:
|
||||
type: string
|
||||
description: Display title for the step
|
||||
example: "Summarization"
|
||||
order:
|
||||
type: integer
|
||||
description: Execution order (lower values run first)
|
||||
default: 0
|
||||
example: 0
|
||||
|
||||
CreatePipelineRequest:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique pipeline identifier
|
||||
example: "my-pipeline"
|
||||
name:
|
||||
type: string
|
||||
description: Human-readable pipeline name
|
||||
example: "My Pipeline"
|
||||
working_dir:
|
||||
type: string
|
||||
description: Working directory for pipeline execution
|
||||
example: "/workspace"
|
||||
prompts:
|
||||
type: array
|
||||
description: Ordered list of prompts to execute
|
||||
items:
|
||||
$ref: '#/components/schemas/Prompt'
|
||||
|
||||
DeletePipelineResponse:
|
||||
type: object
|
||||
properties:
|
||||
deleted:
|
||||
type: string
|
||||
description: ID of the deleted pipeline
|
||||
example: "my-pipeline"
|
||||
|
||||
StartRunRequest:
|
||||
type: object
|
||||
required:
|
||||
- pipeline_id
|
||||
properties:
|
||||
pipeline_id:
|
||||
type: string
|
||||
description: ID of the pipeline to execute
|
||||
example: "my-pipeline"
|
||||
|
||||
StartRunResponse:
|
||||
type: object
|
||||
properties:
|
||||
run_id:
|
||||
type: string
|
||||
description: Unique identifier for this execution run
|
||||
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
pipeline_id:
|
||||
type: string
|
||||
description: ID of the executed pipeline
|
||||
example: "my-pipeline"
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- running
|
||||
description: Initial status is always "running"
|
||||
example: "running"
|
||||
|
||||
RunState:
|
||||
type: object
|
||||
properties:
|
||||
run_id:
|
||||
type: string
|
||||
description: Unique identifier for this execution run
|
||||
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||||
pipeline_id:
|
||||
type: string
|
||||
description: ID of the executed pipeline
|
||||
example: "my-pipeline"
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- pending
|
||||
- running
|
||||
- completed
|
||||
- error
|
||||
description: >-
|
||||
Current status of the run. "pending" before execution begins,
|
||||
"running" during execution, "completed" on success, "error" if
|
||||
any step failed.
|
||||
example: "running"
|
||||
current_step:
|
||||
type: integer
|
||||
description: >-
|
||||
Index of the step currently being executed, or -1 if not yet
|
||||
started.
|
||||
example: 1
|
||||
steps:
|
||||
type: array
|
||||
description: Results of each executed step in order
|
||||
items:
|
||||
$ref: '#/components/schemas/StepResult'
|
||||
|
||||
StepResult:
|
||||
type: object
|
||||
properties:
|
||||
step_index:
|
||||
type: integer
|
||||
description: Zero-based index of the step in the pipeline
|
||||
example: 0
|
||||
title:
|
||||
type: string
|
||||
description: Display title of the step
|
||||
example: "Summarization"
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- pending
|
||||
- running
|
||||
- completed
|
||||
- error
|
||||
description: Status of this individual step
|
||||
example: "completed"
|
||||
returncode:
|
||||
type: integer
|
||||
description: Process exit code (0 for success)
|
||||
example: 0
|
||||
output:
|
||||
type: string
|
||||
description: Standard output from the step execution
|
||||
example: "Document summary generated."
|
||||
error:
|
||||
type: string
|
||||
description: Standard error or error message from the step
|
||||
example: ""
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: Human-readable error message
|
||||
example: "Pipeline not found"
|
||||
Reference in New Issue
Block a user