566 lines
17 KiB
YAML
566 lines
17 KiB
YAML
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"
|