Files
crank/docs/streaming-admin-api.md
T
2026-04-07 18:30:08 +03:00

14 KiB
Raw Blame History

Streaming Admin API

1. Назначение документа

Этот документ фиксирует точные HTTP-контракты для потоковой модели Crank.

Он дополняет:

Цель документа:

  • зафиксировать 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.

Базовый префикс:

/api/admin/workspaces/{workspace_id}

3. Основные ресурсы

  • streaming-presets
  • streaming-validation
  • stream-test-runs
  • stream-sessions
  • async-jobs
  • protocol-capabilities

4. Общие DTO

4.1. ExecutionMode

{
  "mode": "unary"
}

Допустимые значения:

  • unary
  • window
  • session
  • async_job

4.2. StreamingConfig

{
  "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

{
  "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

{
  "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.

Ответ:

{
  "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 ошибки.

Тело:

{
  "protocol": "websocket",
  "target": {},
  "execution_config": {
    "streaming": {}
  }
}

Успех:

{
  "valid": true,
  "warnings": [
    {
      "field": "max_bytes",
      "code": "may_truncate_large_event_payloads",
      "message": "Large event payloads may be truncated"
    }
  ]
}

Ошибка:

{
  "valid": false,
  "errors": [
    {
      "field": "transport_behavior",
      "code": "unsupported_transport_behavior"
    }
  ]
}

7. Streaming presets endpoints

GET /api/admin/workspaces/{workspace_id}/streaming-presets

Назначение:

  • отдать рекомендованные UI presets.

Ответ:

{
  "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}/test-runs

Назначение:

  • выполнить unary, window, session или async_job test-run для draft version;
  • показать оператору runtime behavior до publish.

Тело:

{
  "version": 4,
  "input": {
    "service": "billing",
    "level": "error"
  },
  "version": 4,
  "input": {
    "service": "billing",
    "level": "error"
  }
}

Успех для unary:

{
  "ok": true,
  "mode": "unary",
  "request_preview": {
    "service": "billing",
    "level": "error"
  },
  "response_preview": {
    "summary": "completed"
  },
  "errors": [],
  "window": null,
  "stream_session": null,
  "async_job": null
}

Успех для window:

{
  "ok": true,
  "mode": "window",
  "request_preview": {
    "service": "billing",
    "level": "error"
  },
  "response_preview": {
    "summary": {},
    "items": []
  },
  "errors": [],
  "window": {
    "window_complete": true,
    "truncated": false,
    "has_more": false,
    "cursor": null
  },
  "stream_session": null,
  "async_job": null
}

Успех для session:

{
  "ok": true,
  "mode": "session",
  "request_preview": {
    "service": "billing",
    "level": "error"
  },
  "response_preview": {
    "summary": {},
    "items": []
  },
  "errors": [],
  "window": null,
  "stream_session": {
    "session_id": "sess_01j0stream",
    "status": "running",
    "expires_at": "2026-04-06T12:05:00Z",
    "poll_after_ms": 2000,
    "preview": {
      "summary": {},
      "items": []
    }
  },
  "async_job": null
}

Успех для async_job:

{
  "ok": true,
  "mode": "async_job",
  "request_preview": {
    "service": "billing",
    "level": "error"
  },
  "response_preview": {
    "job": "started"
  },
  "errors": [],
  "window": null,
  "stream_session": null,
  "async_job": {
    "job_id": "job_01j0deploy",
    "status": "running",
    "progress": {
      "pct": 12
    }
  }
}

Ошибка:

{
  "ok": false,
  "mode": "window",
  "request_preview": {
    "service": "billing",
    "level": "error"
  },
  "response_preview": null,
  "errors": [
    {
      "code": "runtime_test_failure",
      "message": "upstream timeout"
    }
  ],
  "window": null,
  "stream_session": null,
  "async_job": null
}

Примечания:

  • endpoint не использует отдельные stream-test-runs/* subresources;
  • session и async-job test-runs создают обычные runtime resources в stream_sessions и async_jobs;
  • дальнейшее наблюдение идет через GET /stream-sessions, GET /stream-sessions/{session_id}, POST /stream-sessions/{session_id}/stop, GET /async-jobs, GET /async-jobs/{job_id}, GET /async-jobs/{job_id}/result, POST /async-jobs/{job_id}/cancel.

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

Ответ:

{
  "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

{
  "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

{
  "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.