docs: add detailed streaming specifications
This commit is contained in:
@@ -49,6 +49,10 @@ Crank - платформа для публикации внешних API в в
|
|||||||
- `docs/public-smoke-targets.md` - готовые публичные upstream-сервисы и payload-ы для smoke-проверки MCP.
|
- `docs/public-smoke-targets.md` - готовые публичные upstream-сервисы и payload-ы для smoke-проверки MCP.
|
||||||
- `docs/secrets-auth-plan.md` - целевая модель upstream secrets, auth profiles и пошаговый план реализации.
|
- `docs/secrets-auth-plan.md` - целевая модель upstream secrets, auth profiles и пошаговый план реализации.
|
||||||
- `docs/streaming-mcp-plan.md` - целевая модель MCP transport streaming, upstream streaming и поэтапный план реализации.
|
- `docs/streaming-mcp-plan.md` - целевая модель MCP transport streaming, upstream streaming и поэтапный план реализации.
|
||||||
|
- `docs/streaming-admin-api.md` - точные HTTP-контракты и DTO для streaming configuration, sessions и jobs.
|
||||||
|
- `docs/streaming-runtime-design.md` - функция-за-функцией разложенная streaming runtime architecture.
|
||||||
|
- `docs/streaming-ui-contract.md` - точный UI-контракт для streaming configuration и test flows.
|
||||||
|
- `docs/protocol-capability-matrix.md` - capability matrix по всем protocol families и execution modes.
|
||||||
- `docs/rust-design.md` - правила распределения поведения в Rust.
|
- `docs/rust-design.md` - правила распределения поведения в Rust.
|
||||||
- `docs/development-rules.md` - правила разработки и workflow.
|
- `docs/development-rules.md` - правила разработки и workflow.
|
||||||
- `docs/rust-code-rules.md` - Rust-specific coding rules.
|
- `docs/rust-code-rules.md` - Rust-specific coding rules.
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
## Current
|
## Current
|
||||||
|
|
||||||
### `feat/full-protocol-platform-architecture`
|
### `feat/streaming-detailed-specs`
|
||||||
|
|
||||||
Status: completed
|
Status: completed
|
||||||
|
|
||||||
DoD:
|
DoD:
|
||||||
- Product scope covers REST, GraphQL, gRPC, WebSocket and SOAP
|
- Streaming API, runtime, UI and capability docs exist as separate detailed specs
|
||||||
- Execution model is documented independently from protocol families
|
- Function-level responsibilities are documented
|
||||||
- Core docs and protocol docs are synchronized around full protocol platform scope
|
- Field-level UI contract and validation rules are documented
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
@@ -30,6 +30,9 @@ DoD:
|
|||||||
- `feat/soap-adapter-foundation`
|
- `feat/soap-adapter-foundation`
|
||||||
- `feat/streaming-ui-config`
|
- `feat/streaming-ui-config`
|
||||||
- `feat/streaming-e2e`
|
- `feat/streaming-e2e`
|
||||||
|
- `feat/websocket-upstream-adapter`
|
||||||
|
- `feat/soap-architecture-and-core-model`
|
||||||
|
- `feat/soap-adapter-foundation`
|
||||||
- `feat/auth-profile-secret-resolution`
|
- `feat/auth-profile-secret-resolution`
|
||||||
- `feat/runtime-upstream-auth`
|
- `feat/runtime-upstream-auth`
|
||||||
- `feat/secrets-ui`
|
- `feat/secrets-ui`
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
Этот документ фиксирует целевые HTTP-контракты административного API, через которое UI управляет workspace, operations, agents, platform access и observability.
|
Этот документ фиксирует целевые HTTP-контракты административного API, через которое UI управляет workspace, operations, agents, platform access и observability.
|
||||||
|
|
||||||
|
Для потоковой модели детальные HTTP DTO вынесены отдельно в:
|
||||||
|
|
||||||
|
- `docs/streaming-admin-api.md`
|
||||||
|
|
||||||
## 2. Общие правила API
|
## 2. Общие правила API
|
||||||
|
|
||||||
- все payload по умолчанию в `JSON`;
|
- все payload по умолчанию в `JSON`;
|
||||||
@@ -205,6 +209,10 @@
|
|||||||
- gRPC descriptor upload и discovery.
|
- gRPC descriptor upload и discovery.
|
||||||
- upstream auth selector;
|
- upstream auth selector;
|
||||||
- quick-create secret / auth profile modal.
|
- quick-create secret / auth profile modal.
|
||||||
|
- execution mode selector;
|
||||||
|
- streaming config blocks;
|
||||||
|
- stream test-runs;
|
||||||
|
- tool family preview.
|
||||||
|
|
||||||
Детальные DTO и response shapes для экранов `Operations` и `Wizard` зафиксированы отдельно в:
|
Детальные DTO и response shapes для экранов `Operations` и `Wizard` зафиксированы отдельно в:
|
||||||
|
|
||||||
|
|||||||
@@ -175,3 +175,15 @@ DoD:
|
|||||||
- runtime умеет строить SOAP envelopes и нормализовать SOAP Faults;
|
- runtime умеет строить SOAP envelopes и нормализовать SOAP Faults;
|
||||||
- operator может выбрать service, port и operation;
|
- operator может выбрать service, port и operation;
|
||||||
- test-run, publish и observability работают так же, как для остальных протоколов.
|
- test-run, publish и observability работают так же, как для остальных протоколов.
|
||||||
|
|
||||||
|
## 15. Этап 14. Detailed streaming specs
|
||||||
|
|
||||||
|
Цель:
|
||||||
|
|
||||||
|
- довести streaming-docs до function-level и field-level design спецификации.
|
||||||
|
|
||||||
|
DoD:
|
||||||
|
|
||||||
|
- есть отдельные docs для streaming admin-api, runtime, UI и capability matrix;
|
||||||
|
- protocol docs не противоречат общей execution model;
|
||||||
|
- roadmap и `TASKS.md` синхронизированы с full-detail architecture.
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
# Protocol Capability Matrix
|
||||||
|
|
||||||
|
## 1. Назначение документа
|
||||||
|
|
||||||
|
Этот документ фиксирует capability matrix по всем protocol families и execution modes.
|
||||||
|
|
||||||
|
Он нужен как source of truth для:
|
||||||
|
|
||||||
|
- UI availability rules;
|
||||||
|
- admin-api validation;
|
||||||
|
- runtime dispatch;
|
||||||
|
- roadmap planning.
|
||||||
|
|
||||||
|
## 2. Matrix by protocol and execution mode
|
||||||
|
|
||||||
|
| Protocol | Unary | Window | Session | Async Job | Notes |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| REST | Yes | Yes | Yes | Yes | window/session используют SSE или bounded polling |
|
||||||
|
| GraphQL | Yes | No | No | Limited | async job только как явная status/result workflow model |
|
||||||
|
| gRPC | Yes | Yes | Yes | Yes | только unary и server-streaming |
|
||||||
|
| WebSocket | No | Yes | Yes | Yes | upstream-only adapter |
|
||||||
|
| SOAP | Yes | Limited | No | Yes | request-response first, async через separate workflow contract |
|
||||||
|
|
||||||
|
## 3. Matrix by protocol and transport behavior
|
||||||
|
|
||||||
|
| Protocol | Request/Response | Server Stream | Stateful Session |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| REST | Yes | Yes | Limited |
|
||||||
|
| GraphQL | Yes | No | No |
|
||||||
|
| gRPC | Yes | Yes | Yes |
|
||||||
|
| WebSocket | No | Yes | Yes |
|
||||||
|
| SOAP | Yes | Limited | No |
|
||||||
|
|
||||||
|
## 4. Matrix by protocol and artifact requirements
|
||||||
|
|
||||||
|
| Protocol | Sample JSON | Descriptor | WSDL/XSD | Query Template | Subscribe Template |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| REST | Optional | No | No | No | Optional |
|
||||||
|
| GraphQL | Optional | No | No | Yes | No |
|
||||||
|
| gRPC | Optional | Yes | No | No | No |
|
||||||
|
| WebSocket | Optional | No | No | No | Yes |
|
||||||
|
| SOAP | Optional | No | Yes | No | No |
|
||||||
|
|
||||||
|
## 5. Matrix by protocol and auth support
|
||||||
|
|
||||||
|
| Protocol | None | Bearer | Basic | API Key Header | API Key Query | WS-Security |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| REST | Yes | Yes | Yes | Yes | Yes | No |
|
||||||
|
| GraphQL | Yes | Yes | Yes | Yes | Limited | No |
|
||||||
|
| gRPC | Yes | Yes | Yes | Limited | No | No |
|
||||||
|
| WebSocket | Yes | Yes | Yes | Yes | Limited | No |
|
||||||
|
| SOAP | Yes | Yes | Yes | Limited | Limited | Future |
|
||||||
|
|
||||||
|
## 6. Matrix by protocol and UI blocks
|
||||||
|
|
||||||
|
| UI Block | REST | GraphQL | gRPC | WebSocket | SOAP |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| Endpoint URL | Yes | Yes | No | Yes | Optional |
|
||||||
|
| Method selector | Yes | No | No | No | No |
|
||||||
|
| Query template | No | Yes | No | No | No |
|
||||||
|
| Descriptor upload | No | No | Yes | No | No |
|
||||||
|
| WSDL upload | No | No | No | No | Yes |
|
||||||
|
| Subscribe template | Optional | No | No | Yes | No |
|
||||||
|
| Subprotocol list | No | No | No | Yes | No |
|
||||||
|
| SOAP headers | No | No | No | No | Yes |
|
||||||
|
| Stream kind selector | Optional | No | Yes | Yes | Limited |
|
||||||
|
|
||||||
|
## 7. Validation rules matrix
|
||||||
|
|
||||||
|
## 7.1. Unsupported combinations
|
||||||
|
|
||||||
|
- `GraphQL + Window`
|
||||||
|
- `GraphQL + Session`
|
||||||
|
- `WebSocket + Unary`
|
||||||
|
- `SOAP + Session`
|
||||||
|
- `gRPC + Session` для non-server-streaming method
|
||||||
|
- `REST + Server Stream` без stream-capable target model
|
||||||
|
|
||||||
|
## 7.2. Conditionally supported combinations
|
||||||
|
|
||||||
|
- `GraphQL + Async Job`
|
||||||
|
Требует отдельного status/result workflow contract.
|
||||||
|
|
||||||
|
- `SOAP + Window`
|
||||||
|
Допускается только для polling-style workflow, а не для native stream.
|
||||||
|
|
||||||
|
- `SOAP + Async Job`
|
||||||
|
Требует отдельной operation family для status/result.
|
||||||
|
|
||||||
|
## 8. Product-wave grouping
|
||||||
|
|
||||||
|
### Wave 1
|
||||||
|
|
||||||
|
- REST
|
||||||
|
- GraphQL query/mutation
|
||||||
|
- gRPC unary
|
||||||
|
- Streamable HTTP downstream
|
||||||
|
- Window/session/job core model
|
||||||
|
|
||||||
|
### Wave 2
|
||||||
|
|
||||||
|
- REST SSE
|
||||||
|
- gRPC server-streaming
|
||||||
|
- session/job tool families
|
||||||
|
- streaming UI
|
||||||
|
|
||||||
|
### Wave 3
|
||||||
|
|
||||||
|
- WebSocket upstream adapter
|
||||||
|
- richer streaming observability
|
||||||
|
|
||||||
|
### Wave 4
|
||||||
|
|
||||||
|
- SOAP foundation
|
||||||
|
- WSDL/XSD tooling
|
||||||
|
- SOAP UI flow
|
||||||
|
|
||||||
|
### Wave 5
|
||||||
|
|
||||||
|
- GraphQL subscriptions
|
||||||
|
- gRPC client-streaming
|
||||||
|
- gRPC bidi
|
||||||
|
- advanced enterprise security stacks
|
||||||
@@ -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.
|
||||||
@@ -0,0 +1,580 @@
|
|||||||
|
# Streaming Runtime Design
|
||||||
|
|
||||||
|
## 1. Назначение документа
|
||||||
|
|
||||||
|
Этот документ фиксирует, как потоковая модель должна быть разложена по crates, traits, services и функциям.
|
||||||
|
|
||||||
|
Цель:
|
||||||
|
|
||||||
|
- избежать god-services;
|
||||||
|
- зафиксировать boundaries между `core`, `registry`, `runtime`, protocol adapters и `mcp-server`;
|
||||||
|
- расписать ожидаемые функции и их ответственность до уровня инженерной спецификации.
|
||||||
|
|
||||||
|
## 2. Общая схема слоев
|
||||||
|
|
||||||
|
### 2.1. `crank-core`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- типы `ExecutionMode`, `StreamingConfig`, `AggregationMode`;
|
||||||
|
- типы `StreamSession`, `AsyncJobHandle`, `StreamStatus`, `JobStatus`;
|
||||||
|
- validation helpers без инфраструктуры.
|
||||||
|
|
||||||
|
### 2.2. `crank-registry`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- persistence session/job state;
|
||||||
|
- optimistic transitions;
|
||||||
|
- cleanup expired state.
|
||||||
|
|
||||||
|
### 2.3. `crank-runtime`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- orchestration execution modes;
|
||||||
|
- dispatch в protocol adapter;
|
||||||
|
- bounded collection;
|
||||||
|
- aggregation;
|
||||||
|
- state transitions;
|
||||||
|
- invocation logging.
|
||||||
|
|
||||||
|
### 2.4. Protocol adapters
|
||||||
|
|
||||||
|
Отвечают за:
|
||||||
|
|
||||||
|
- protocol-specific upstream behavior;
|
||||||
|
- connect/request/collect/close;
|
||||||
|
- преобразование upstream payload в нормализованный JSON.
|
||||||
|
|
||||||
|
### 2.5. `apps/mcp-server`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- downstream MCP transport;
|
||||||
|
- tool-family generation;
|
||||||
|
- JSON-RPC lifecycle;
|
||||||
|
- transport/session routing.
|
||||||
|
|
||||||
|
### 2.6. `apps/admin-api`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- config CRUD;
|
||||||
|
- test-runs;
|
||||||
|
- validation;
|
||||||
|
- UI-oriented metadata and previews.
|
||||||
|
|
||||||
|
## 3. Core domain types
|
||||||
|
|
||||||
|
## 3.1. `ExecutionMode`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum ExecutionMode {
|
||||||
|
Unary,
|
||||||
|
Window,
|
||||||
|
Session,
|
||||||
|
AsyncJob,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Методы:
|
||||||
|
|
||||||
|
- `fn is_stateful(&self) -> bool`
|
||||||
|
- `fn requires_tool_family(&self) -> bool`
|
||||||
|
|
||||||
|
## 3.2. `AggregationMode`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum AggregationMode {
|
||||||
|
RawItems,
|
||||||
|
SummaryOnly,
|
||||||
|
SummaryPlusSamples,
|
||||||
|
Stats,
|
||||||
|
LatestState,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Методы:
|
||||||
|
|
||||||
|
- `fn needs_items(&self) -> bool`
|
||||||
|
- `fn needs_summary(&self) -> bool`
|
||||||
|
|
||||||
|
## 3.3. `StreamingConfig`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct StreamingConfig {
|
||||||
|
pub mode: ExecutionMode,
|
||||||
|
pub transport_behavior: TransportBehavior,
|
||||||
|
pub window_duration_ms: Option<u64>,
|
||||||
|
pub poll_interval_ms: Option<u64>,
|
||||||
|
pub upstream_timeout_ms: Option<u64>,
|
||||||
|
pub idle_timeout_ms: Option<u64>,
|
||||||
|
pub max_session_lifetime_ms: Option<u64>,
|
||||||
|
pub max_items: Option<u32>,
|
||||||
|
pub max_bytes: Option<u32>,
|
||||||
|
pub aggregation_mode: AggregationMode,
|
||||||
|
pub summary_path: Option<String>,
|
||||||
|
pub items_path: Option<String>,
|
||||||
|
pub cursor_path: Option<String>,
|
||||||
|
pub status_path: Option<String>,
|
||||||
|
pub done_path: Option<String>,
|
||||||
|
pub redacted_paths: Vec<String>,
|
||||||
|
pub truncate_item_fields: bool,
|
||||||
|
pub max_field_length: Option<u32>,
|
||||||
|
pub drop_duplicates: bool,
|
||||||
|
pub sampling_rate: Option<f64>,
|
||||||
|
pub tool_family: ToolFamilyConfig,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Методы:
|
||||||
|
|
||||||
|
- `fn validate_common(&self) -> Result<(), StreamingConfigError>`
|
||||||
|
- `fn validate_for_protocol(&self, protocol: Protocol) -> Result<(), StreamingConfigError>`
|
||||||
|
- `fn effective_max_items(&self, limits: &StreamingLimits) -> u32`
|
||||||
|
- `fn effective_max_bytes(&self, limits: &StreamingLimits) -> u32`
|
||||||
|
- `fn effective_timeout(&self, defaults: &StreamingDefaults) -> Duration`
|
||||||
|
|
||||||
|
## 3.4. `StreamSession`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct StreamSession {
|
||||||
|
pub id: StreamSessionId,
|
||||||
|
pub workspace_id: WorkspaceId,
|
||||||
|
pub agent_id: Option<AgentId>,
|
||||||
|
pub operation_id: OperationId,
|
||||||
|
pub protocol: Protocol,
|
||||||
|
pub mode: ExecutionMode,
|
||||||
|
pub status: StreamStatus,
|
||||||
|
pub cursor: Option<Value>,
|
||||||
|
pub state: Value,
|
||||||
|
pub expires_at: DateTime<Utc>,
|
||||||
|
pub last_poll_at: Option<DateTime<Utc>>,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
pub closed_at: Option<DateTime<Utc>>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Методы:
|
||||||
|
|
||||||
|
- `fn is_expired(&self, now: DateTime<Utc>) -> bool`
|
||||||
|
- `fn can_poll(&self, now: DateTime<Utc>) -> bool`
|
||||||
|
- `fn mark_polled(&mut self, now: DateTime<Utc>)`
|
||||||
|
- `fn mark_closed(&mut self, now: DateTime<Utc>)`
|
||||||
|
|
||||||
|
## 3.5. `AsyncJobHandle`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct AsyncJobHandle {
|
||||||
|
pub id: AsyncJobId,
|
||||||
|
pub workspace_id: WorkspaceId,
|
||||||
|
pub agent_id: Option<AgentId>,
|
||||||
|
pub operation_id: OperationId,
|
||||||
|
pub status: JobStatus,
|
||||||
|
pub progress: Value,
|
||||||
|
pub result: Option<Value>,
|
||||||
|
pub error: Option<Value>,
|
||||||
|
pub expires_at: Option<DateTime<Utc>>,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
pub updated_at: DateTime<Utc>,
|
||||||
|
pub finished_at: Option<DateTime<Utc>>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Методы:
|
||||||
|
|
||||||
|
- `fn is_finished(&self) -> bool`
|
||||||
|
- `fn can_cancel(&self) -> bool`
|
||||||
|
- `fn mark_finished(&mut self, now: DateTime<Utc>, result: Value)`
|
||||||
|
- `fn mark_failed(&mut self, now: DateTime<Utc>, error: Value)`
|
||||||
|
|
||||||
|
## 4. Registry contracts
|
||||||
|
|
||||||
|
## 4.1. `StreamSessionRepository`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[async_trait]
|
||||||
|
pub trait StreamSessionRepository {
|
||||||
|
async fn create_stream_session(&self, session: NewStreamSession) -> Result<StreamSession, RegistryError>;
|
||||||
|
async fn get_stream_session(&self, id: &StreamSessionId) -> Result<Option<StreamSession>, RegistryError>;
|
||||||
|
async fn update_stream_session_state(&self, update: StreamSessionStateUpdate) -> Result<StreamSession, RegistryError>;
|
||||||
|
async fn close_stream_session(&self, id: &StreamSessionId, now: DateTime<Utc>) -> Result<(), RegistryError>;
|
||||||
|
async fn list_stream_sessions(&self, filter: StreamSessionFilter) -> Result<Page<StreamSession>, RegistryError>;
|
||||||
|
async fn delete_expired_stream_sessions(&self, now: DateTime<Utc>) -> Result<u64, RegistryError>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4.2. `AsyncJobRepository`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[async_trait]
|
||||||
|
pub trait AsyncJobRepository {
|
||||||
|
async fn create_async_job(&self, job: NewAsyncJob) -> Result<AsyncJobHandle, RegistryError>;
|
||||||
|
async fn get_async_job(&self, id: &AsyncJobId) -> Result<Option<AsyncJobHandle>, RegistryError>;
|
||||||
|
async fn update_async_job_status(&self, update: AsyncJobStatusUpdate) -> Result<AsyncJobHandle, RegistryError>;
|
||||||
|
async fn cancel_async_job(&self, id: &AsyncJobId, now: DateTime<Utc>) -> Result<(), RegistryError>;
|
||||||
|
async fn list_async_jobs(&self, filter: AsyncJobFilter) -> Result<Page<AsyncJobHandle>, RegistryError>;
|
||||||
|
async fn delete_expired_async_jobs(&self, now: DateTime<Utc>) -> Result<u64, RegistryError>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4.3. Storage rules
|
||||||
|
|
||||||
|
- update methods должны использовать optimistic concurrency, если state transitions конфликтуют;
|
||||||
|
- `poll` не должен silently reopen closed session;
|
||||||
|
- cleanup job должен быть отдельным service;
|
||||||
|
- session/job state не должен хранить необрезанные raw payloads без лимитов.
|
||||||
|
|
||||||
|
## 5. Runtime contracts
|
||||||
|
|
||||||
|
## 5.1. `ProtocolAdapter`
|
||||||
|
|
||||||
|
Базовый trait не должен пытаться описать все streaming cases в одном методе.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[async_trait]
|
||||||
|
pub trait ProtocolAdapter {
|
||||||
|
async fn execute_unary(&self, ctx: UnaryExecutionContext) -> Result<NormalizedResponse, AdapterError>;
|
||||||
|
async fn execute_window(&self, ctx: WindowExecutionContext) -> Result<WindowExecutionResult, AdapterError>;
|
||||||
|
async fn start_session(&self, ctx: SessionStartContext) -> Result<SessionStartResult, AdapterError>;
|
||||||
|
async fn poll_session(&self, ctx: SessionPollContext) -> Result<SessionPollResult, AdapterError>;
|
||||||
|
async fn stop_session(&self, ctx: SessionStopContext) -> Result<(), AdapterError>;
|
||||||
|
async fn start_async_job(&self, ctx: AsyncJobStartContext) -> Result<AsyncJobStartResult, AdapterError>;
|
||||||
|
async fn get_async_job_status(&self, ctx: AsyncJobStatusContext) -> Result<AsyncJobStatusResult, AdapterError>;
|
||||||
|
async fn get_async_job_result(&self, ctx: AsyncJobResultContext) -> Result<NormalizedResponse, AdapterError>;
|
||||||
|
async fn cancel_async_job(&self, ctx: AsyncJobCancelContext) -> Result<(), AdapterError>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Не каждый adapter обязан поддерживать все методы. Capability mismatch должен проверяться выше.
|
||||||
|
|
||||||
|
## 5.2. `OperationExecutor`
|
||||||
|
|
||||||
|
Главная orchestration точка в `crank-runtime`.
|
||||||
|
|
||||||
|
Ожидаемые функции:
|
||||||
|
|
||||||
|
- `execute_unary_operation`
|
||||||
|
- `execute_window_operation`
|
||||||
|
- `start_stream_session`
|
||||||
|
- `poll_stream_session`
|
||||||
|
- `stop_stream_session`
|
||||||
|
- `start_async_job`
|
||||||
|
- `get_async_job_status`
|
||||||
|
- `get_async_job_result`
|
||||||
|
- `cancel_async_job`
|
||||||
|
|
||||||
|
### `execute_unary_operation`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- schema validation;
|
||||||
|
- auth resolution;
|
||||||
|
- adapter dispatch;
|
||||||
|
- output mapping;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `execute_window_operation`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- schema validation;
|
||||||
|
- auth resolution;
|
||||||
|
- adapter dispatch в `execute_window`;
|
||||||
|
- aggregation;
|
||||||
|
- truncation flags;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `start_stream_session`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- schema validation;
|
||||||
|
- auth resolution;
|
||||||
|
- adapter `start_session`;
|
||||||
|
- registry `create_stream_session`;
|
||||||
|
- initial preview result;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `poll_stream_session`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- load session from registry;
|
||||||
|
- expiration check;
|
||||||
|
- adapter `poll_session`;
|
||||||
|
- registry `update_stream_session_state`;
|
||||||
|
- output mapping;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `stop_stream_session`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- load session;
|
||||||
|
- adapter `stop_session`;
|
||||||
|
- registry close;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `start_async_job`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- schema validation;
|
||||||
|
- adapter `start_async_job`;
|
||||||
|
- registry `create_async_job`;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `get_async_job_status`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- registry load;
|
||||||
|
- adapter `get_async_job_status`, если upstream status is live;
|
||||||
|
- registry update;
|
||||||
|
- normalized status result.
|
||||||
|
|
||||||
|
### `get_async_job_result`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- job readiness check;
|
||||||
|
- adapter `get_async_job_result`, если result lazy-loaded;
|
||||||
|
- output mapping;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
### `cancel_async_job`
|
||||||
|
|
||||||
|
Отвечает за:
|
||||||
|
|
||||||
|
- adapter cancel;
|
||||||
|
- registry cancel transition;
|
||||||
|
- observability write.
|
||||||
|
|
||||||
|
## 5.3. Aggregation services
|
||||||
|
|
||||||
|
Нужно отделить aggregation от adapters.
|
||||||
|
|
||||||
|
Отдельные services:
|
||||||
|
|
||||||
|
- `WindowAggregator`
|
||||||
|
- `SummaryBuilder`
|
||||||
|
- `CursorTracker`
|
||||||
|
- `PayloadLimiter`
|
||||||
|
- `RedactionService`
|
||||||
|
|
||||||
|
### `WindowAggregator`
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `collect_items`
|
||||||
|
- `apply_item_limit`
|
||||||
|
- `apply_byte_limit`
|
||||||
|
- `mark_truncated`
|
||||||
|
|
||||||
|
### `SummaryBuilder`
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `build_summary`
|
||||||
|
- `build_stats_summary`
|
||||||
|
- `build_latest_state_summary`
|
||||||
|
- `build_summary_plus_samples`
|
||||||
|
|
||||||
|
### `PayloadLimiter`
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `truncate_item_fields`
|
||||||
|
- `truncate_bytes`
|
||||||
|
- `enforce_max_items`
|
||||||
|
|
||||||
|
### `RedactionService`
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `redact_paths`
|
||||||
|
- `redact_object`
|
||||||
|
- `redact_item`
|
||||||
|
|
||||||
|
## 6. Adapter responsibilities
|
||||||
|
|
||||||
|
## 6.1. REST adapter
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `execute_rest_unary`
|
||||||
|
- `execute_rest_window`
|
||||||
|
- `start_rest_session`
|
||||||
|
- `poll_rest_session`
|
||||||
|
- `stop_rest_session`
|
||||||
|
- `start_rest_async_job`
|
||||||
|
- `get_rest_async_job_status`
|
||||||
|
- `get_rest_async_job_result`
|
||||||
|
- `cancel_rest_async_job`
|
||||||
|
|
||||||
|
Дополнительные helpers:
|
||||||
|
|
||||||
|
- `open_sse_stream`
|
||||||
|
- `collect_sse_window`
|
||||||
|
- `parse_sse_event`
|
||||||
|
- `close_sse_stream`
|
||||||
|
|
||||||
|
## 6.2. GraphQL adapter
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `execute_graphql_unary`
|
||||||
|
|
||||||
|
Отдельно отложено:
|
||||||
|
|
||||||
|
- `execute_graphql_subscription_window`
|
||||||
|
- `start_graphql_subscription_session`
|
||||||
|
|
||||||
|
## 6.3. gRPC adapter
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `execute_grpc_unary`
|
||||||
|
- `execute_grpc_window`
|
||||||
|
- `start_grpc_session`
|
||||||
|
- `poll_grpc_session`
|
||||||
|
- `stop_grpc_session`
|
||||||
|
- `start_grpc_async_job`
|
||||||
|
- `get_grpc_async_job_status`
|
||||||
|
- `get_grpc_async_job_result`
|
||||||
|
- `cancel_grpc_async_job`
|
||||||
|
|
||||||
|
Helpers:
|
||||||
|
|
||||||
|
- `invoke_unary_method`
|
||||||
|
- `open_server_stream`
|
||||||
|
- `collect_server_stream_window`
|
||||||
|
- `decode_stream_item`
|
||||||
|
|
||||||
|
## 6.4. WebSocket adapter
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `execute_websocket_window`
|
||||||
|
- `start_websocket_session`
|
||||||
|
- `poll_websocket_session`
|
||||||
|
- `stop_websocket_session`
|
||||||
|
- `start_websocket_async_job`
|
||||||
|
- `get_websocket_async_job_status`
|
||||||
|
- `cancel_websocket_async_job`
|
||||||
|
|
||||||
|
Helpers:
|
||||||
|
|
||||||
|
- `connect_websocket`
|
||||||
|
- `send_subscribe_message`
|
||||||
|
- `send_unsubscribe_message`
|
||||||
|
- `read_next_frame`
|
||||||
|
- `decode_text_frame`
|
||||||
|
- `heartbeat_tick`
|
||||||
|
- `reconnect_if_needed`
|
||||||
|
|
||||||
|
## 6.5. SOAP adapter
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `execute_soap_unary`
|
||||||
|
- `start_soap_async_job`
|
||||||
|
- `get_soap_async_job_status`
|
||||||
|
- `get_soap_async_job_result`
|
||||||
|
- `cancel_soap_async_job`
|
||||||
|
|
||||||
|
Helpers:
|
||||||
|
|
||||||
|
- `render_soap_envelope`
|
||||||
|
- `render_soap_headers`
|
||||||
|
- `parse_soap_envelope`
|
||||||
|
- `parse_soap_fault`
|
||||||
|
- `normalize_xml_value`
|
||||||
|
|
||||||
|
## 7. MCP server design
|
||||||
|
|
||||||
|
## 7.1. Route handlers
|
||||||
|
|
||||||
|
Ожидаемые handlers:
|
||||||
|
|
||||||
|
- `handle_initialize`
|
||||||
|
- `handle_notifications_initialized`
|
||||||
|
- `handle_ping`
|
||||||
|
- `handle_tools_list`
|
||||||
|
- `handle_tools_call`
|
||||||
|
- `handle_get_sse_stream`
|
||||||
|
- `handle_delete_session`
|
||||||
|
|
||||||
|
## 7.2. Tool-family generation
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `build_unary_tool_definition`
|
||||||
|
- `build_window_tool_definition`
|
||||||
|
- `build_session_tool_family`
|
||||||
|
- `build_async_job_tool_family`
|
||||||
|
|
||||||
|
Для `session`:
|
||||||
|
|
||||||
|
- `build_session_start_tool`
|
||||||
|
- `build_session_poll_tool`
|
||||||
|
- `build_session_stop_tool`
|
||||||
|
|
||||||
|
Для `async_job`:
|
||||||
|
|
||||||
|
- `build_async_job_start_tool`
|
||||||
|
- `build_async_job_status_tool`
|
||||||
|
- `build_async_job_result_tool`
|
||||||
|
- `build_async_job_cancel_tool`
|
||||||
|
|
||||||
|
## 7.3. Transport session management
|
||||||
|
|
||||||
|
Функции:
|
||||||
|
|
||||||
|
- `ensure_protocol_version`
|
||||||
|
- `resolve_transport_mode`
|
||||||
|
- `ensure_mcp_session`
|
||||||
|
- `attach_session_headers`
|
||||||
|
- `stream_sse_event`
|
||||||
|
- `close_transport_session`
|
||||||
|
|
||||||
|
## 8. Admin API service design
|
||||||
|
|
||||||
|
Ожидаемые service функции:
|
||||||
|
|
||||||
|
- `validate_streaming_config`
|
||||||
|
- `list_protocol_capabilities`
|
||||||
|
- `list_streaming_presets`
|
||||||
|
- `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`
|
||||||
|
|
||||||
|
## 9. Cleanup jobs
|
||||||
|
|
||||||
|
Отдельные jobs:
|
||||||
|
|
||||||
|
- `expire_stream_sessions`
|
||||||
|
- `expire_async_jobs`
|
||||||
|
- `reap_orphaned_transport_sessions`
|
||||||
|
- `compact_stream_payloads`, если будет нужен storage optimization layer
|
||||||
|
|
||||||
|
## 10. Design rules
|
||||||
|
|
||||||
|
- adapters не агрегируют product-level summaries;
|
||||||
|
- runtime не знает деталей transport framing;
|
||||||
|
- `mcp-server` не знает про upstream protocols;
|
||||||
|
- `admin-api` не управляет live protocol connections напрямую;
|
||||||
|
- session/job lifecycle должен быть явным в names и contracts;
|
||||||
|
- cancellation не должна зависеть от TCP disconnect;
|
||||||
|
- bounded limits должны применяться раньше, чем payload попадет в final result.
|
||||||
@@ -0,0 +1,434 @@
|
|||||||
|
# Streaming UI Contract
|
||||||
|
|
||||||
|
## 1. Назначение документа
|
||||||
|
|
||||||
|
Этот документ фиксирует точный UI-контракт для настройки потоковых операций.
|
||||||
|
|
||||||
|
Цель:
|
||||||
|
|
||||||
|
- определить экраны и блоки wizard;
|
||||||
|
- перечислить все поля;
|
||||||
|
- перечислить валидации;
|
||||||
|
- определить protocol-specific visibility rules;
|
||||||
|
- зафиксировать UX states, warnings и system messages.
|
||||||
|
|
||||||
|
## 2. Основные экраны
|
||||||
|
|
||||||
|
Потоковая конфигурация живет в:
|
||||||
|
|
||||||
|
- `Operations Wizard`
|
||||||
|
- `Operation Detail`
|
||||||
|
- `Test Run`
|
||||||
|
- `Agent Tool Preview`
|
||||||
|
- `Logs` / `Usage` observability surfaces
|
||||||
|
|
||||||
|
Дополнительно админские страницы:
|
||||||
|
|
||||||
|
- `Stream Sessions`
|
||||||
|
- `Async Jobs`
|
||||||
|
|
||||||
|
## 3. Wizard information architecture
|
||||||
|
|
||||||
|
## 3.1. Shared wizard structure
|
||||||
|
|
||||||
|
Шаги:
|
||||||
|
|
||||||
|
1. `Protocol`
|
||||||
|
2. `Upstream`
|
||||||
|
3. `Request / Subscription`
|
||||||
|
4. `Execution Mode`
|
||||||
|
5. `Input Schema`
|
||||||
|
6. `Output / Aggregation`
|
||||||
|
7. `Safety and Limits`
|
||||||
|
8. `Tool Family`
|
||||||
|
9. `Test Run`
|
||||||
|
10. `Publish`
|
||||||
|
|
||||||
|
## 3.2. Step `Execution Mode`
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Mode`
|
||||||
|
- `Unary`
|
||||||
|
- `Window`
|
||||||
|
- `Session`
|
||||||
|
- `Async Job`
|
||||||
|
- `Transport behavior`
|
||||||
|
- `Request / response`
|
||||||
|
- `Server stream`
|
||||||
|
|
||||||
|
Подсказки:
|
||||||
|
|
||||||
|
- `Unary` для обычных request-response integrations.
|
||||||
|
- `Window` для bounded snapshots из stream или feed.
|
||||||
|
- `Session` для follow-style tools с `start/poll/stop`.
|
||||||
|
- `Async Job` для long-running operations с `status/result/cancel`.
|
||||||
|
|
||||||
|
Валидации:
|
||||||
|
|
||||||
|
- `Transport behavior=server_stream` не может использоваться с protocol, который его не поддерживает.
|
||||||
|
- `WebSocket` не может быть `Unary`.
|
||||||
|
- `SOAP` в первой волне не может быть `Session`.
|
||||||
|
|
||||||
|
## 3.3. Step `Input Schema`
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Input schema source`
|
||||||
|
- manual
|
||||||
|
- sample-derived
|
||||||
|
- descriptor/wsdl-derived
|
||||||
|
- `Input fields`
|
||||||
|
- `Required fields`
|
||||||
|
- `Defaults`
|
||||||
|
- `Mapping preview`
|
||||||
|
|
||||||
|
## 3.4. Step `Output / Aggregation`
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Aggregation mode`
|
||||||
|
- `Raw items`
|
||||||
|
- `Summary only`
|
||||||
|
- `Summary + samples`
|
||||||
|
- `Stats`
|
||||||
|
- `Latest state`
|
||||||
|
- `Items path`
|
||||||
|
- `Summary path`
|
||||||
|
- `Cursor path`
|
||||||
|
- `Status path`
|
||||||
|
- `Done path`
|
||||||
|
- `Output mapping`
|
||||||
|
|
||||||
|
Валидации:
|
||||||
|
|
||||||
|
- `Items path` обязателен для `Raw items` и `Summary + samples`.
|
||||||
|
- `Summary path` обязателен для `Summary only`, `Summary + samples`, `Stats`, `Latest state`.
|
||||||
|
- `Done path` обязателен для `Async Job`, если upstream status не выражается отдельным field set.
|
||||||
|
|
||||||
|
## 3.5. Step `Safety and Limits`
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Window duration`
|
||||||
|
- `Poll interval`
|
||||||
|
- `Upstream timeout`
|
||||||
|
- `Idle timeout`
|
||||||
|
- `Session lifetime`
|
||||||
|
- `Max items`
|
||||||
|
- `Max bytes`
|
||||||
|
- `Max field length`
|
||||||
|
- `Drop duplicates`
|
||||||
|
- `Sampling rate`
|
||||||
|
- `Redacted paths`
|
||||||
|
|
||||||
|
Валидации:
|
||||||
|
|
||||||
|
- `Window duration` обязателен для `Window`.
|
||||||
|
- `Poll interval` обязателен для `Session`.
|
||||||
|
- `Idle timeout` обязателен для `Session`.
|
||||||
|
- `Session lifetime` обязателен для `Session`.
|
||||||
|
- `Max items` > 0.
|
||||||
|
- `Max bytes` > 0.
|
||||||
|
- `Sampling rate` > 0 and <= 1.
|
||||||
|
|
||||||
|
## 3.6. Step `Tool Family`
|
||||||
|
|
||||||
|
Показывается только для:
|
||||||
|
|
||||||
|
- `Session`
|
||||||
|
- `Async Job`
|
||||||
|
|
||||||
|
Для `Session`:
|
||||||
|
|
||||||
|
- `Start tool name`
|
||||||
|
- `Poll tool name`
|
||||||
|
- `Stop tool name`
|
||||||
|
|
||||||
|
Для `Async Job`:
|
||||||
|
|
||||||
|
- `Start tool name`
|
||||||
|
- `Status tool name`
|
||||||
|
- `Result tool name`
|
||||||
|
- `Cancel tool name`
|
||||||
|
|
||||||
|
Валидации:
|
||||||
|
|
||||||
|
- имена обязательны;
|
||||||
|
- имена должны быть уникальны в пределах agent;
|
||||||
|
- имена не должны конфликтовать с already bound tools.
|
||||||
|
|
||||||
|
## 4. Protocol-specific UI
|
||||||
|
|
||||||
|
## 4.1. REST
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Base URL`
|
||||||
|
- `HTTP method`
|
||||||
|
- `Path template`
|
||||||
|
- `Headers`
|
||||||
|
- `Query mapping`
|
||||||
|
- `Body mapping`
|
||||||
|
- `SSE enabled`
|
||||||
|
- `SSE event filter`
|
||||||
|
|
||||||
|
Visibility:
|
||||||
|
|
||||||
|
- `SSE enabled` показывается только если method/endpoint допускают stream use case;
|
||||||
|
- `Window` и `Session` доступны, если оператор включает stream behavior.
|
||||||
|
|
||||||
|
## 4.2. GraphQL
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Endpoint`
|
||||||
|
- `Operation type`
|
||||||
|
- `Operation name`
|
||||||
|
- `Query template`
|
||||||
|
- `Variables schema`
|
||||||
|
- `Response path`
|
||||||
|
|
||||||
|
Visibility:
|
||||||
|
|
||||||
|
- `Window`, `Session`, `Async Job` скрыты в текущей продуктовой волне;
|
||||||
|
- `Subscription` UI не показывается.
|
||||||
|
|
||||||
|
## 4.3. gRPC
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `Server address`
|
||||||
|
- `Package`
|
||||||
|
- `Service`
|
||||||
|
- `Method`
|
||||||
|
- `Descriptor source`
|
||||||
|
- `Stream kind`
|
||||||
|
- `Unary`
|
||||||
|
- `Server streaming`
|
||||||
|
|
||||||
|
Visibility:
|
||||||
|
|
||||||
|
- `Window`, `Session`, `Async Job` доступны только для `Server streaming`;
|
||||||
|
- `Client streaming` и `Bidirectional` не показываются вообще.
|
||||||
|
|
||||||
|
## 4.4. WebSocket
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `WebSocket URL`
|
||||||
|
- `Subprotocols`
|
||||||
|
- `Connect timeout`
|
||||||
|
- `Heartbeat interval`
|
||||||
|
- `Subscribe message template`
|
||||||
|
- `Unsubscribe message template`
|
||||||
|
- `Message envelope path`
|
||||||
|
|
||||||
|
Visibility:
|
||||||
|
|
||||||
|
- `Unary` не показывается;
|
||||||
|
- `Window`, `Session`, `Async Job` доступны всегда;
|
||||||
|
- `Subscribe message template` обязательно для `Window` и `Session`.
|
||||||
|
|
||||||
|
## 4.5. SOAP
|
||||||
|
|
||||||
|
Поля:
|
||||||
|
|
||||||
|
- `WSDL source`
|
||||||
|
- `Service`
|
||||||
|
- `Port`
|
||||||
|
- `Operation`
|
||||||
|
- `SOAP version`
|
||||||
|
- `SOAPAction`
|
||||||
|
- `Endpoint override`
|
||||||
|
- `Header config`
|
||||||
|
|
||||||
|
Visibility:
|
||||||
|
|
||||||
|
- `Session` скрыт;
|
||||||
|
- `Window` скрыт по умолчанию и включается только для polling-style enterprise workflows;
|
||||||
|
- `Unary` и `Async Job` доступны.
|
||||||
|
|
||||||
|
## 5. Test Run UX
|
||||||
|
|
||||||
|
## 5.1. Window
|
||||||
|
|
||||||
|
UI должен показывать:
|
||||||
|
|
||||||
|
- `Status`
|
||||||
|
- `Duration`
|
||||||
|
- `Items count`
|
||||||
|
- `Bytes count`
|
||||||
|
- `Window complete`
|
||||||
|
- `Truncated`
|
||||||
|
- `Has more`
|
||||||
|
- `Summary`
|
||||||
|
- `Items preview`
|
||||||
|
- `Cursor`
|
||||||
|
|
||||||
|
Кнопки:
|
||||||
|
|
||||||
|
- `Run window test`
|
||||||
|
- `Repeat`
|
||||||
|
- `Save config`
|
||||||
|
|
||||||
|
## 5.2. Session
|
||||||
|
|
||||||
|
UI должен показывать:
|
||||||
|
|
||||||
|
- `Session id`
|
||||||
|
- `Status`
|
||||||
|
- `Expires at`
|
||||||
|
- `Poll after`
|
||||||
|
- `Summary preview`
|
||||||
|
- `Items preview`
|
||||||
|
|
||||||
|
Кнопки:
|
||||||
|
|
||||||
|
- `Start session`
|
||||||
|
- `Poll next chunk`
|
||||||
|
- `Stop session`
|
||||||
|
|
||||||
|
## 5.3. Async Job
|
||||||
|
|
||||||
|
UI должен показывать:
|
||||||
|
|
||||||
|
- `Job id`
|
||||||
|
- `Status`
|
||||||
|
- `Progress`
|
||||||
|
- `Started at`
|
||||||
|
- `Finished at`
|
||||||
|
- `Result preview`
|
||||||
|
|
||||||
|
Кнопки:
|
||||||
|
|
||||||
|
- `Start job`
|
||||||
|
- `Refresh status`
|
||||||
|
- `Get result`
|
||||||
|
- `Cancel job`
|
||||||
|
|
||||||
|
## 6. Page-level states
|
||||||
|
|
||||||
|
Каждый streaming-aware экран обязан поддерживать:
|
||||||
|
|
||||||
|
- `idle`
|
||||||
|
- `validating`
|
||||||
|
- `saving`
|
||||||
|
- `testing`
|
||||||
|
- `running`
|
||||||
|
- `completed`
|
||||||
|
- `failed`
|
||||||
|
- `stopped`
|
||||||
|
- `expired`
|
||||||
|
|
||||||
|
## 7. Warnings and messages
|
||||||
|
|
||||||
|
## 7.1. Validation warnings
|
||||||
|
|
||||||
|
- `This mode will truncate responses above the configured byte limit.`
|
||||||
|
- `Current protocol does not support the selected execution mode.`
|
||||||
|
- `Session lifetime is shorter than idle timeout.`
|
||||||
|
- `Aggregation mode summary_only hides raw items from the final tool output.`
|
||||||
|
- `WebSocket reconnect may duplicate events if upstream does not provide cursor semantics.`
|
||||||
|
- `SOAP async mode requires a separate status/result contract.`
|
||||||
|
|
||||||
|
## 7.2. Confirmations
|
||||||
|
|
||||||
|
- `Stop current session?`
|
||||||
|
- `Cancel running job?`
|
||||||
|
- `Switching execution mode will reset protocol-specific fields.`
|
||||||
|
|
||||||
|
## 7.3. Errors
|
||||||
|
|
||||||
|
- `Streaming configuration is invalid.`
|
||||||
|
- `Test session expired.`
|
||||||
|
- `Upstream did not return any messages within the configured window.`
|
||||||
|
- `The collected stream payload was truncated by size limits.`
|
||||||
|
- `This protocol does not support the selected execution mode.`
|
||||||
|
|
||||||
|
## 8. Stream Sessions page
|
||||||
|
|
||||||
|
Колонки:
|
||||||
|
|
||||||
|
- `Session ID`
|
||||||
|
- `Operation`
|
||||||
|
- `Agent`
|
||||||
|
- `Mode`
|
||||||
|
- `Status`
|
||||||
|
- `Created`
|
||||||
|
- `Last poll`
|
||||||
|
- `Expires`
|
||||||
|
|
||||||
|
Actions:
|
||||||
|
|
||||||
|
- `Open`
|
||||||
|
- `Stop`
|
||||||
|
- `Delete`
|
||||||
|
|
||||||
|
Detail view:
|
||||||
|
|
||||||
|
- `Session metadata`
|
||||||
|
- `Cursor preview`
|
||||||
|
- `State summary`
|
||||||
|
- `Recent events summary`
|
||||||
|
|
||||||
|
## 9. Async Jobs page
|
||||||
|
|
||||||
|
Колонки:
|
||||||
|
|
||||||
|
- `Job ID`
|
||||||
|
- `Operation`
|
||||||
|
- `Agent`
|
||||||
|
- `Status`
|
||||||
|
- `Progress`
|
||||||
|
- `Created`
|
||||||
|
- `Updated`
|
||||||
|
- `Finished`
|
||||||
|
|
||||||
|
Actions:
|
||||||
|
|
||||||
|
- `Open`
|
||||||
|
- `Cancel`
|
||||||
|
- `Get result`
|
||||||
|
|
||||||
|
Detail view:
|
||||||
|
|
||||||
|
- `Job metadata`
|
||||||
|
- `Progress payload`
|
||||||
|
- `Result preview`
|
||||||
|
- `Error preview`
|
||||||
|
|
||||||
|
## 10. Exact frontend adapters
|
||||||
|
|
||||||
|
Ожидаемые frontend modules:
|
||||||
|
|
||||||
|
- `streaming-form.js`
|
||||||
|
- `streaming-validation.js`
|
||||||
|
- `stream-test-run.js`
|
||||||
|
- `stream-sessions.js`
|
||||||
|
- `async-jobs.js`
|
||||||
|
|
||||||
|
Ожидаемые frontend functions:
|
||||||
|
|
||||||
|
- `loadProtocolCapabilities()`
|
||||||
|
- `applyStreamingPreset()`
|
||||||
|
- `validateStreamingConfig()`
|
||||||
|
- `serializeStreamingConfig()`
|
||||||
|
- `deserializeStreamingConfig()`
|
||||||
|
- `startWindowTest()`
|
||||||
|
- `startSessionTest()`
|
||||||
|
- `pollSessionTest()`
|
||||||
|
- `stopSessionTest()`
|
||||||
|
- `startAsyncJobTest()`
|
||||||
|
- `refreshAsyncJobStatus()`
|
||||||
|
- `loadAsyncJobResult()`
|
||||||
|
|
||||||
|
## 11. Shared UI rules
|
||||||
|
|
||||||
|
- UI никогда не должен предлагать unsupported mode;
|
||||||
|
- UI должен строить availability по `protocol-capabilities`, а не по hardcoded if-else;
|
||||||
|
- UI должен явно объяснять, почему поле скрыто или disabled;
|
||||||
|
- UI должен всегда показывать итоговую tool topology:
|
||||||
|
- `1 tool`
|
||||||
|
- `3 tools start/poll/stop`
|
||||||
|
- `4 tools start/status/result/cancel`
|
||||||
Reference in New Issue
Block a user