Files
prod-end-2026/docs/ml_core_backend_openapi.yaml
2026-03-17 18:32:44 +03:00

945 lines
31 KiB
YAML

openapi: 3.0.3
info:
title: AI Copilot ML Core Backend API
version: 1.0.0
description: |
Сдаваемая спецификация ML core части реального backend.
Источник истины: текущие роуты FastAPI `/api/v1/pipelines*` и `/api/v1/executions*`.
Документ не включает auth/actions/capabilities endpoint'ы, кроме использования JWT bearer security.
servers:
- url: http://localhost:8000
tags:
- name: Pipelines
description: Генерация и управление pipeline-диалогом, запуск выполнения.
- name: Executions
description: История и детали запусков pipeline.
security:
- bearerAuth: []
paths:
/api/v1/pipelines/generate:
post:
tags: [Pipelines]
operationId: generatePipeline
summary: Сгенерировать pipeline по сообщению пользователя
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PipelineGenerateRequest"
examples:
travel_offer_case:
summary: Travel-offer бизнес-задача
value:
dialog_id: "11111111-1111-1111-1111-111111111111"
message: "Сформируй и запусти рассылку тревел-офферов для активных пользователей за последние 7 дней, подбери топ-5 отелей в Берлине, сегментируй пользователей и отправь персональные email по шаблону offer_template_2026."
capability_ids: null
responses:
"200":
description: Pipeline обработан (готов / требует ввод / не может быть собран)
content:
application/json:
schema:
$ref: "#/components/schemas/PipelineGenerateResponse"
examples:
ready:
summary: Линейный pipeline 1 -> 2 -> 3 -> 4 -> 5
value:
status: "ready"
message_ru: "Пайплайн собран. Можно запускать."
chat_reply_ru: "Пайплайн собран: получаем пользователей и отели, сегментируем, назначаем офферы, затем отправляем email."
pipeline_id: "7b17ac70-3f39-4e70-8f8a-4a2f1fd4ff7e"
nodes:
- step: 1
name: "get_recent_users"
description: "Получить активных пользователей за последние 7 дней."
input_connected_from: []
output_connected_to: [3]
input_data_type_from_previous: []
external_inputs: ["days_back"]
endpoints:
- name: "get_recent_users"
capability_id: "c4be1e66-2e04-4c6f-8d8f-6f39f1f46087"
action_id: "e4b0bcb6-6a8c-4b0a-8e18-3f44b5f7d1c2"
output_type: "users[]"
- step: 2
name: "get_top_hotels"
description: "Получить топ-5 отелей в Берлине."
input_connected_from: []
output_connected_to: [3]
input_data_type_from_previous: []
external_inputs: ["city", "hotels_limit"]
endpoints:
- name: "get_top_hotels"
capability_id: "470ae37e-029e-4c67-a293-acb848675d0b"
action_id: "96f0bc8f-e294-46a9-9a0e-48e1b8f2a941"
output_type: "hotels[]"
- step: 3
name: "segment_users_by_hotel_preferences"
description: "Сегментация пользователей по предпочтениям."
input_connected_from: [1, 2]
output_connected_to: [4]
input_data_type_from_previous:
- from_step: 1
type: "users[]"
- from_step: 2
type: "hotels[]"
external_inputs: []
endpoints:
- name: "segment_users_by_hotel_preferences"
capability_id: "518ea04f-f891-4529-8c74-06e8cd9d2f43"
action_id: "92dfce86-34dd-4c1d-9ee7-4214a16cbd99"
output_type: "segments[]"
- step: 4
name: "assign_users_to_hotels"
description: "Назначить пользователю релевантный отель."
input_connected_from: [3]
output_connected_to: [5]
input_data_type_from_previous:
- from_step: 3
type: "segments[]"
external_inputs: []
endpoints:
- name: "assign_users_to_hotels"
capability_id: "70c67642-c8d2-4eb2-a57b-d5e42dc04342"
action_id: "c57f4c88-7307-4e2c-9d36-6756be8e6ab0"
output_type: "assignments[]"
- step: 5
name: "send_hotel_offers_by_email"
description: "Отправить персональные email-офферы."
input_connected_from: [4]
output_connected_to: []
input_data_type_from_previous:
- from_step: 4
type: "assignments[]"
external_inputs: ["template_id"]
endpoints:
- name: "send_hotel_offers_by_email"
capability_id: "3b90595e-3f6f-4b4a-a89a-63daecf8ed03"
action_id: "3c97cc71-5cf6-45fd-8f75-2cf1ccfc7c45"
output_type: "delivery_report"
edges:
- from_step: 1
to_step: 3
type: "data_dependency"
- from_step: 2
to_step: 3
type: "data_dependency"
- from_step: 3
to_step: 4
type: "data_dependency"
- from_step: 4
to_step: 5
type: "data_dependency"
missing_requirements: []
context_summary: "Используются 5 capability для travel-рассылки."
needs_input:
summary: Требуется один уточняющий параметр
value:
status: "needs_input"
message_ru: "Уточните template_id для email-рассылки."
chat_reply_ru: "Нужен template_id для шага отправки email. Например: offer_template_2026."
pipeline_id: null
nodes: []
edges: []
missing_requirements: ["template_id"]
context_summary: null
cannot_build:
summary: Модель недоступна
value:
status: "cannot_build"
message_ru: "Не удалось обратиться к локальной модели Ollama. Проверьте OLLAMA_HOST/OLLAMA_MODEL и повторите запрос."
chat_reply_ru: "Не удалось обратиться к локальной модели Ollama. Проверьте OLLAMA_HOST/OLLAMA_MODEL и повторите запрос."
pipeline_id: null
nodes: []
edges: []
missing_requirements: ["ollama_unavailable"]
context_summary: null
"401":
$ref: "#/components/responses/UnauthorizedError"
"403":
$ref: "#/components/responses/ForbiddenError"
"404":
$ref: "#/components/responses/NotFoundError"
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/pipelines/dialogs:
get:
tags: [Pipelines]
operationId: listPipelineDialogs
summary: Получить список диалогов pipeline
parameters:
- in: query
name: limit
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 20
- in: query
name: offset
required: false
schema:
type: integer
minimum: 0
default: 0
responses:
"200":
description: Список диалогов пользователя
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/PipelineDialogListItemResponse"
"401":
$ref: "#/components/responses/UnauthorizedError"
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/pipelines/dialogs/{dialog_id}/history:
get:
tags: [Pipelines]
operationId: getPipelineDialogHistory
summary: Получить историю сообщений диалога
parameters:
- in: path
name: dialog_id
required: true
schema:
type: string
format: uuid
- in: query
name: limit
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 30
- in: query
name: offset
required: false
schema:
type: integer
minimum: 0
default: 0
responses:
"200":
description: История диалога
content:
application/json:
schema:
$ref: "#/components/schemas/PipelineDialogHistoryResponse"
"401":
$ref: "#/components/responses/UnauthorizedError"
"403":
$ref: "#/components/responses/ForbiddenError"
"404":
$ref: "#/components/responses/NotFoundError"
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/pipelines/dialog/reset:
post:
tags: [Pipelines]
operationId: resetPipelineDialog
summary: Сбросить контекст диалога pipeline
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/DialogResetRequest"
responses:
"200":
description: Диалог успешно сброшен
content:
application/json:
schema:
$ref: "#/components/schemas/DialogResetResponse"
"401":
$ref: "#/components/responses/UnauthorizedError"
"403":
$ref: "#/components/responses/ForbiddenError"
"404":
$ref: "#/components/responses/NotFoundError"
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/pipelines/{pipeline_id}/run:
post:
tags: [Pipelines]
operationId: runPipeline
summary: Запустить pipeline на выполнение
parameters:
- in: path
name: pipeline_id
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RunPipelineRequest"
examples:
travel_inputs:
value:
inputs:
days_back: 7
city: "Berlin"
hotels_limit: 5
template_id: "offer_template_2026"
responses:
"202":
description: Запуск поставлен в очередь/начат
content:
application/json:
schema:
$ref: "#/components/schemas/RunPipelineResponse"
examples:
queued:
value:
run_id: "2fb1f647-b769-4f56-8a44-6a63a364b478"
pipeline_id: "7b17ac70-3f39-4e70-8f8a-4a2f1fd4ff7e"
status: "QUEUED"
"400":
$ref: "#/components/responses/BadRequestError"
"401":
$ref: "#/components/responses/UnauthorizedError"
"404":
$ref: "#/components/responses/NotFoundError"
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/executions:
get:
tags: [Executions]
operationId: listExecutions
summary: Получить список запусков execution
parameters:
- in: query
name: limit
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 50
- in: query
name: offset
required: false
schema:
type: integer
minimum: 0
default: 0
responses:
"200":
description: Список запусков
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ExecutionRunListItemResponse"
"401":
$ref: "#/components/responses/UnauthorizedError"
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/executions/{run_id}:
get:
tags: [Executions]
operationId: getExecution
summary: Получить детальный отчёт execution run
parameters:
- in: path
name: run_id
required: true
schema:
type: string
format: uuid
responses:
"200":
description: Детали запуска с шагами
content:
application/json:
schema:
$ref: "#/components/schemas/ExecutionRunDetailResponse"
examples:
partial_failed:
summary: Пример со статусами SUCCEEDED/FAILED/SKIPPED
value:
id: "2fb1f647-b769-4f56-8a44-6a63a364b478"
pipeline_id: "7b17ac70-3f39-4e70-8f8a-4a2f1fd4ff7e"
status: "PARTIAL_FAILED"
inputs:
days_back: 7
city: "Berlin"
hotels_limit: 5
template_id: "offer_template_2026"
summary:
total_steps: 5
succeeded: 3
failed: 1
skipped: 1
error: "Step 4 failed: upstream service timeout"
started_at: "2026-03-16T12:10:15Z"
finished_at: "2026-03-16T12:10:31Z"
created_at: "2026-03-16T12:10:15Z"
updated_at: "2026-03-16T12:10:31Z"
steps:
- step: 1
name: "get_recent_users"
capability_id: "c4be1e66-2e04-4c6f-8d8f-6f39f1f46087"
action_id: "e4b0bcb6-6a8c-4b0a-8e18-3f44b5f7d1c2"
method: "GET"
status_code: 200
status: "SUCCEEDED"
resolved_inputs:
days_back: 7
accepted_payload: null
output_payload:
users: []
request_snapshot:
method: "GET"
path: "/users/recent"
response_snapshot:
status_code: 200
body:
users: []
error: null
started_at: "2026-03-16T12:10:15Z"
finished_at: "2026-03-16T12:10:17Z"
duration_ms: 2100
created_at: "2026-03-16T12:10:15Z"
updated_at: "2026-03-16T12:10:17Z"
- step: 4
name: "assign_users_to_hotels"
capability_id: "70c67642-c8d2-4eb2-a57b-d5e42dc04342"
action_id: "c57f4c88-7307-4e2c-9d36-6756be8e6ab0"
method: "POST"
status_code: 504
status: "FAILED"
resolved_inputs:
segments: []
accepted_payload:
segments: []
output_payload:
detail: "Gateway Timeout"
request_snapshot:
method: "POST"
path: "/assignments/hotels"
json_body:
segments: []
response_snapshot:
status_code: 504
body:
detail: "Gateway Timeout"
error: "Upstream timeout"
started_at: "2026-03-16T12:10:23Z"
finished_at: "2026-03-16T12:10:29Z"
duration_ms: 6010
created_at: "2026-03-16T12:10:23Z"
updated_at: "2026-03-16T12:10:29Z"
- step: 5
name: "send_hotel_offers_by_email"
capability_id: "3b90595e-3f6f-4b4a-a89a-63daecf8ed03"
action_id: "3c97cc71-5cf6-45fd-8f75-2cf1ccfc7c45"
method: null
status_code: null
status: "SKIPPED"
resolved_inputs: null
accepted_payload: null
output_payload: null
request_snapshot: null
response_snapshot: null
error: "Skipped: run stopped after failure at step 4"
started_at: null
finished_at: null
duration_ms: null
created_at: "2026-03-16T12:10:29Z"
updated_at: "2026-03-16T12:10:29Z"
"401":
$ref: "#/components/responses/UnauthorizedError"
"404":
$ref: "#/components/responses/NotFoundError"
"422":
$ref: "#/components/responses/ValidationError"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
BadRequestError:
description: Некорректный запрос
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
not_ready:
value:
detail: "Pipeline is not ready for execution"
UnauthorizedError:
description: Не передан или некорректен JWT токен
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
invalid_credentials:
value:
detail: "Could not validate credentials"
ForbiddenError:
description: Нет доступа к ресурсу диалога
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
dialog_denied:
value:
detail: "Access denied for dialog"
NotFoundError:
description: Сущность не найдена
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
not_found:
value:
detail: "Pipeline not found"
ValidationError:
description: Ошибка валидации входных данных
content:
application/json:
schema:
$ref: "#/components/schemas/HTTPValidationError"
schemas:
ErrorResponse:
type: object
properties:
detail:
oneOf:
- type: string
- type: object
additionalProperties: true
- type: array
items:
type: object
additionalProperties: true
ValidationError:
type: object
required: [loc, msg, type]
properties:
loc:
type: array
items:
oneOf:
- type: string
- type: integer
msg:
type: string
type:
type: string
HTTPValidationError:
type: object
properties:
detail:
type: array
items:
$ref: "#/components/schemas/ValidationError"
PipelineInputTypeFromPrevious:
type: object
required: [from_step, type]
properties:
from_step:
type: integer
type:
type: string
PipelineStepEndpoint:
type: object
required: [name, capability_id]
properties:
name:
type: string
capability_id:
type: string
format: uuid
action_id:
type: string
format: uuid
nullable: true
type:
type: string
nullable: true
input_type:
oneOf:
- type: string
- type: object
additionalProperties: true
nullable: true
output_type:
oneOf:
- type: string
- type: object
additionalProperties: true
nullable: true
PipelineGraphNode:
type: object
required: [step, name]
properties:
step:
type: integer
name:
type: string
description:
type: string
nullable: true
input_connected_from:
type: array
items:
type: integer
default: []
output_connected_to:
type: array
items:
type: integer
default: []
input_data_type_from_previous:
type: array
items:
$ref: "#/components/schemas/PipelineInputTypeFromPrevious"
default: []
external_inputs:
type: array
items:
type: string
default: []
endpoints:
type: array
items:
$ref: "#/components/schemas/PipelineStepEndpoint"
default: []
PipelineGraphEdge:
type: object
required: [from_step, to_step, type]
properties:
from_step:
type: integer
to_step:
type: integer
type:
type: string
PipelineGenerateRequest:
type: object
required: [dialog_id, message]
properties:
dialog_id:
type: string
format: uuid
message:
type: string
minLength: 1
capability_ids:
type: array
items:
type: string
format: uuid
nullable: true
PipelineGenerateResponse:
type: object
required: [status, message_ru, chat_reply_ru, nodes, edges, missing_requirements]
properties:
status:
type: string
enum: [ready, needs_input, cannot_build]
message_ru:
type: string
chat_reply_ru:
type: string
pipeline_id:
type: string
format: uuid
nullable: true
nodes:
type: array
items:
$ref: "#/components/schemas/PipelineGraphNode"
default: []
edges:
type: array
items:
$ref: "#/components/schemas/PipelineGraphEdge"
default: []
missing_requirements:
type: array
items:
type: string
default: []
context_summary:
type: string
nullable: true
DialogResetRequest:
type: object
required: [dialog_id]
properties:
dialog_id:
type: string
format: uuid
DialogResetResponse:
type: object
required: [status, message_ru]
properties:
status:
type: string
enum: [ok]
message_ru:
type: string
PipelineDialogListItemResponse:
type: object
required: [dialog_id, created_at, updated_at]
properties:
dialog_id:
type: string
format: uuid
title:
type: string
nullable: true
last_status:
type: string
nullable: true
last_pipeline_id:
type: string
format: uuid
nullable: true
last_message_preview:
type: string
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
PipelineDialogMessageResponse:
type: object
required: [id, role, content, created_at]
properties:
id:
type: string
format: uuid
role:
type: string
enum: [user, assistant]
content:
type: string
assistant_payload:
type: object
additionalProperties: true
nullable: true
created_at:
type: string
format: date-time
PipelineDialogHistoryResponse:
type: object
required: [dialog_id, messages]
properties:
dialog_id:
type: string
format: uuid
title:
type: string
nullable: true
messages:
type: array
items:
$ref: "#/components/schemas/PipelineDialogMessageResponse"
default: []
RunPipelineRequest:
type: object
properties:
inputs:
type: object
additionalProperties: true
default: {}
RunPipelineResponse:
type: object
required: [run_id, pipeline_id, status]
properties:
run_id:
type: string
format: uuid
pipeline_id:
type: string
format: uuid
status:
type: string
enum: [QUEUED, RUNNING]
ExecutionRunListItemResponse:
type: object
required: [id, pipeline_id, status, created_at, updated_at]
properties:
id:
type: string
format: uuid
pipeline_id:
type: string
format: uuid
status:
type: string
enum: [QUEUED, RUNNING, SUCCEEDED, FAILED, PARTIAL_FAILED]
error:
type: string
nullable: true
started_at:
type: string
format: date-time
nullable: true
finished_at:
type: string
format: date-time
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ExecutionStepRunResponse:
type: object
required: [step, status, accepted_payload, output_payload, created_at, updated_at]
properties:
step:
type: integer
name:
type: string
nullable: true
capability_id:
type: string
format: uuid
nullable: true
action_id:
type: string
format: uuid
nullable: true
method:
type: string
enum: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS]
nullable: true
status_code:
type: integer
nullable: true
status:
type: string
enum: [PENDING, RUNNING, SUCCEEDED, FAILED, SKIPPED]
resolved_inputs:
type: object
additionalProperties: true
nullable: true
accepted_payload:
nullable: true
output_payload:
nullable: true
request_snapshot:
type: object
additionalProperties: true
nullable: true
response_snapshot:
type: object
additionalProperties: true
nullable: true
error:
type: string
nullable: true
started_at:
type: string
format: date-time
nullable: true
finished_at:
type: string
format: date-time
nullable: true
duration_ms:
type: integer
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ExecutionRunDetailResponse:
type: object
required: [id, pipeline_id, status, inputs, created_at, updated_at, steps]
properties:
id:
type: string
format: uuid
pipeline_id:
type: string
format: uuid
status:
type: string
enum: [QUEUED, RUNNING, SUCCEEDED, FAILED, PARTIAL_FAILED]
inputs:
type: object
additionalProperties: true
default: {}
summary:
type: object
additionalProperties: true
nullable: true
error:
type: string
nullable: true
started_at:
type: string
format: date-time
nullable: true
finished_at:
type: string
format: date-time
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
steps:
type: array
items:
$ref: "#/components/schemas/ExecutionStepRunResponse"
default: []