docs: add detailed streaming specifications

This commit is contained in:
a.tolmachev
2026-04-06 02:35:00 +03:00
parent 7f15b2db9e
commit dbc57a0419
8 changed files with 1775 additions and 4 deletions
+607
View File
@@ -0,0 +1,607 @@
# 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.