Files
crank/docs/streaming-admin-api.md
T
2026-04-06 02:35:00 +03:00

608 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Streaming Admin API
## 1. Назначение документа
Этот документ фиксирует точные HTTP-контракты для потоковой модели Crank.
Он дополняет:
- [admin-api.md](/home/a.tolmachev/code/rust/mcpaas/docs/admin-api.md)
- [streaming-mcp-plan.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-mcp-plan.md)
- [streaming-ui-contract.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-ui-contract.md)
- [streaming-runtime-design.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-runtime-design.md)
Цель документа:
- зафиксировать DTO;
- зафиксировать route groups;
- зафиксировать валидацию;
- зафиксировать expected error model;
- зафиксировать page-to-endpoint contract для streaming configuration и test-runs.
## 2. Общие принципы
- все ресурсы являются `workspace-scoped`;
- streaming configuration является частью `operation version`;
- `session` и `async_job` state не редактируются напрямую из UI;
- test-runs могут создавать временные sessions и jobs, но не публикуют их как runtime resources;
- transport errors и validation errors разделяются;
- лимиты и safety-параметры валидируются на сервере, а не только в UI.
Базовый префикс:
```text
/api/admin/workspaces/{workspace_id}
```
## 3. Основные ресурсы
- `streaming-presets`
- `streaming-validation`
- `stream-test-runs`
- `stream-sessions`
- `async-jobs`
- `protocol-capabilities`
## 4. Общие DTO
### 4.1. `ExecutionMode`
```json
{
"mode": "unary"
}
```
Допустимые значения:
- `unary`
- `window`
- `session`
- `async_job`
### 4.2. `StreamingConfig`
```json
{
"mode": "window",
"transport_behavior": "server_stream",
"window_duration_ms": 5000,
"poll_interval_ms": 2000,
"upstream_timeout_ms": 10000,
"idle_timeout_ms": 30000,
"max_session_lifetime_ms": 300000,
"max_items": 200,
"max_bytes": 131072,
"aggregation_mode": "summary_plus_samples",
"summary_path": "$.summary",
"items_path": "$.items",
"cursor_path": "$.cursor",
"status_path": "$.status",
"done_path": "$.done",
"redacted_paths": [
"$.items[*].token",
"$.summary.secret"
],
"truncate_item_fields": true,
"max_field_length": 512,
"drop_duplicates": true,
"sampling_rate": 1.0,
"tool_family": {
"start_tool_name": "cluster_events_start",
"poll_tool_name": "cluster_events_poll",
"stop_tool_name": "cluster_events_stop",
"status_tool_name": "deploy_status",
"result_tool_name": "deploy_result",
"cancel_tool_name": "deploy_cancel"
}
}
```
### 4.3. `StreamingValidationError`
```json
{
"code": "streaming_validation_error",
"message": "Streaming configuration is invalid",
"details": [
{
"field": "window_duration_ms",
"reason": "must_be_positive"
},
{
"field": "max_items",
"reason": "must_not_exceed_workspace_limit"
}
]
}
```
### 4.4. `ProtocolCapability`
```json
{
"protocol": "grpc",
"supports_execution_modes": [
"unary",
"window",
"session",
"async_job"
],
"supports_transport_behaviors": [
"request_response",
"server_stream"
],
"supports_auth_kinds": [
"none",
"bearer",
"basic",
"api_key_header",
"api_key_query"
],
"supports_upload_artifacts": [
"proto",
"descriptor_set"
],
"supports_cursor_path": true,
"supports_done_path": true,
"supports_aggregation_mode": [
"raw_items",
"summary_only",
"summary_plus_samples",
"stats",
"latest_state"
]
}
```
## 5. Capabilities endpoints
### `GET /api/admin/workspaces/{workspace_id}/protocol-capabilities`
Назначение:
- отдать UI полную capability matrix;
- убрать protocol-specific hardcode из frontend.
Ответ:
```json
{
"items": [
{
"protocol": "rest",
"supports_execution_modes": ["unary", "window", "session", "async_job"],
"supports_transport_behaviors": ["request_response", "server_stream"],
"supports_auth_kinds": ["none", "bearer", "basic", "api_key_header", "api_key_query"],
"supports_upload_artifacts": [],
"supports_cursor_path": true,
"supports_done_path": true,
"supports_aggregation_mode": ["raw_items", "summary_only", "summary_plus_samples", "stats", "latest_state"]
}
]
}
```
## 6. Streaming validation endpoints
### `POST /api/admin/workspaces/{workspace_id}/streaming/validate`
Назначение:
- проверить streaming config до сохранения operation;
- вернуть protocol-aware ошибки.
Тело:
```json
{
"protocol": "websocket",
"target": {},
"execution_config": {
"streaming": {}
}
}
```
Успех:
```json
{
"valid": true,
"warnings": [
{
"field": "max_bytes",
"code": "may_truncate_large_event_payloads",
"message": "Large event payloads may be truncated"
}
]
}
```
Ошибка:
```json
{
"valid": false,
"errors": [
{
"field": "transport_behavior",
"code": "unsupported_transport_behavior"
}
]
}
```
## 7. Streaming presets endpoints
### `GET /api/admin/workspaces/{workspace_id}/streaming-presets`
Назначение:
- отдать рекомендованные UI presets.
Ответ:
```json
{
"items": [
{
"preset_id": "logs_window_5s",
"display_name": "Logs Window 5s",
"protocols": ["rest", "grpc", "websocket"],
"streaming": {
"mode": "window",
"window_duration_ms": 5000,
"max_items": 100,
"max_bytes": 65536,
"aggregation_mode": "summary_plus_samples"
}
}
]
}
```
## 8. Streaming operation test-runs
### `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/stream-test-runs`
Назначение:
- выполнить `window`, `session` или `async_job` test-run для draft version;
- показать оператору runtime behavior до publish.
Тело:
```json
{
"version": 4,
"input": {
"service": "billing",
"level": "error"
},
"test_mode": "window",
"overrides": {
"streaming": {
"window_duration_ms": 3000,
"max_items": 50
}
}
}
```
Успех для `window`:
```json
{
"run_id": "strun_01j0test",
"mode": "window",
"status": "completed",
"window_complete": true,
"truncated": false,
"has_more": false,
"summary": {},
"items": [],
"cursor": null,
"duration_ms": 2871
}
```
Успех для `session`:
```json
{
"run_id": "strun_01j0test",
"mode": "session",
"status": "running",
"session": {
"session_id": "sess_01j0stream",
"expires_at": "2026-04-06T12:05:00Z",
"poll_after_ms": 2000
},
"preview": {
"summary": {},
"items": []
}
}
```
Успех для `async_job`:
```json
{
"run_id": "strun_01j0test",
"mode": "async_job",
"status": "running",
"job": {
"job_id": "job_01j0deploy",
"status": "running",
"progress": {
"pct": 12
}
}
}
```
### `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/stream-test-runs/{run_id}/poll`
Назначение:
- продолжить session-oriented test-run.
Тело:
```json
{
"session_id": "sess_01j0stream"
}
```
Ответ:
```json
{
"run_id": "strun_01j0test",
"mode": "session",
"status": "running",
"window_complete": false,
"truncated": false,
"has_more": true,
"summary": {},
"items": [],
"cursor": "next_cursor"
}
```
### `POST /api/admin/workspaces/{workspace_id}/operations/{operation_id}/stream-test-runs/{run_id}/stop`
Назначение:
- остановить test session.
### `GET /api/admin/workspaces/{workspace_id}/operations/{operation_id}/stream-test-runs/{run_id}/result`
Назначение:
- получить финальный результат async-job test-run.
## 9. Runtime session resources
### `GET /api/admin/workspaces/{workspace_id}/stream-sessions`
Назначение:
- список активных и недавних session resources для observability/debug UI.
Query params:
- `operation_id`
- `agent_id`
- `status`
- `page`
- `page_size`
Ответ:
```json
{
"items": [
{
"id": "sess_01j0stream",
"operation_id": "op_01j0",
"agent_id": "agent_01j0",
"mode": "session",
"status": "running",
"expires_at": "2026-04-06T12:05:00Z",
"last_poll_at": "2026-04-06T12:00:10Z",
"created_at": "2026-04-06T12:00:00Z"
}
],
"page": 1,
"page_size": 20,
"total": 1
}
```
### `GET /api/admin/workspaces/{workspace_id}/stream-sessions/{session_id}`
Назначение:
- detail session metadata;
- без возврата полного raw state.
### `POST /api/admin/workspaces/{workspace_id}/stream-sessions/{session_id}/stop`
Назначение:
- административно остановить runtime session.
### `DELETE /api/admin/workspaces/{workspace_id}/stream-sessions/{session_id}`
Назначение:
- hard cleanup завершенной session;
- доступен только для `stopped`, `failed`, `expired`.
## 10. Async job resources
### `GET /api/admin/workspaces/{workspace_id}/async-jobs`
Назначение:
- список активных и недавних job resources.
### `GET /api/admin/workspaces/{workspace_id}/async-jobs/{job_id}`
Назначение:
- status/progress/result metadata.
### `POST /api/admin/workspaces/{workspace_id}/async-jobs/{job_id}/cancel`
Назначение:
- административная отмена long-running job.
### `GET /api/admin/workspaces/{workspace_id}/async-jobs/{job_id}/result`
Назначение:
- получить финальный нормализованный результат.
## 11. Integration into operation contracts
`streaming` не является отдельным top-level resource для опубликованной операции. Он живет внутри:
- `OperationVersionDocument.execution_config.streaming`
и входит в:
- `POST /operations`
- `PATCH /operations/{operation_id}`
- `POST /operations/{operation_id}/versions`
- `GET /operations/{operation_id}/versions/{version}`
### 11.1. `OperationVersionDocument.execution_config.streaming`
```json
{
"execution_config": {
"timeout_ms": 10000,
"retries": 0,
"auth_profile_ref": "auth_profile_01j0",
"streaming": {
"mode": "window",
"transport_behavior": "server_stream",
"window_duration_ms": 5000,
"upstream_timeout_ms": 10000,
"max_items": 100,
"max_bytes": 65536,
"aggregation_mode": "summary_plus_samples",
"summary_path": "$.summary",
"items_path": "$.items",
"cursor_path": "$.cursor",
"status_path": "$.status",
"done_path": "$.done",
"redacted_paths": [],
"truncate_item_fields": true,
"max_field_length": 512,
"drop_duplicates": true,
"sampling_rate": 1.0,
"tool_family": {}
}
}
}
```
## 12. Validation rules
### 12.1. Общие
- `mode=unary` запрещает `tool_family`;
- `max_items` > 0;
- `max_bytes` > 0;
- `window_duration_ms` > 0 для `window`;
- `idle_timeout_ms` обязателен для `session`;
- `max_session_lifetime_ms` обязателен для `session`;
- `tool_family.start_tool_name/poll_tool_name/stop_tool_name` обязательны для `session`;
- `tool_family.start_tool_name/status_tool_name/result_tool_name/cancel_tool_name` обязательны для `async_job`.
### 12.2. Protocol-aware
REST:
- `transport_behavior=server_stream` допустим только при streaming-capable target.
GraphQL:
- `window`, `session`, `async_job` пока запрещены;
- `subscription` невалиден как target type.
gRPC:
- `transport_behavior=server_stream` допустим только для server-streaming method.
WebSocket:
- `mode=unary` запрещен;
- требуется `subscribe_message_template` для `session` и `window`.
SOAP:
- `mode=session` запрещен в первой волне;
- `mode=window` допустим только при наличии polling-style status operation family;
- `mode=async_job` требует status/result contract.
## 13. Error model
Коды:
- `streaming_validation_error`
- `unsupported_execution_mode`
- `unsupported_transport_behavior`
- `stream_window_timeout`
- `stream_window_truncated`
- `stream_session_expired`
- `stream_session_not_found`
- `async_job_not_found`
- `async_job_not_ready`
- `async_job_cancelled`
- `protocol_capability_mismatch`
### 13.1. Ошибка несовместимого protocol mode
```json
{
"code": "protocol_capability_mismatch",
"message": "websocket target does not support unary execution mode",
"details": [
{
"field": "execution_config.streaming.mode",
"reason": "unsupported_for_protocol"
}
]
}
```
## 14. Route-to-service mapping
Ожидаемые service handlers в `apps/admin-api`:
- `list_protocol_capabilities`
- `list_streaming_presets`
- `validate_streaming_config`
- `start_stream_test_run`
- `poll_stream_test_run`
- `stop_stream_test_run`
- `get_stream_test_result`
- `list_stream_sessions`
- `get_stream_session`
- `stop_stream_session`
- `delete_stream_session`
- `list_async_jobs`
- `get_async_job`
- `cancel_async_job`
- `get_async_job_result`
Это не route names, а service-level функции orchestration.