585 lines
17 KiB
Markdown
585 lines
17 KiB
Markdown
# Streaming Implementation Specification
|
||
|
||
## 1. Назначение документа
|
||
|
||
Этот документ переводит streaming architecture в execution-oriented plan, пригодный для агентной разработки.
|
||
|
||
Он отвечает на вопросы:
|
||
|
||
- в каком порядке реализовывать фичи;
|
||
- какие файлы менять в каждом срезе;
|
||
- какие новые модули создавать;
|
||
- какие тесты обязательны;
|
||
- какие риски и зависимости есть между срезами;
|
||
- какой Definition of Done нужен для каждого шага.
|
||
|
||
Документ дополняет:
|
||
|
||
- [streaming-mcp-plan.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-mcp-plan.md)
|
||
- [streaming-admin-api.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-admin-api.md)
|
||
- [streaming-runtime-design.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-runtime-design.md)
|
||
- [streaming-ui-contract.md](/home/a.tolmachev/code/rust/mcpaas/docs/streaming-ui-contract.md)
|
||
- [protocol-capability-matrix.md](/home/a.tolmachev/code/rust/mcpaas/docs/protocol-capability-matrix.md)
|
||
|
||
## 2. Принципы агентной реализации
|
||
|
||
- один vertical slice на ветку;
|
||
- docs first, code second;
|
||
- не смешивать transport alignment, core model, registry, runtime и UI в одном срезе;
|
||
- каждый срез должен быть протестирован отдельно;
|
||
- stateful streaming нельзя вводить через скрытые side effects;
|
||
- session/job lifecycle должен появляться в коде и API явно.
|
||
|
||
## 3. Dependency graph
|
||
|
||
Порядок реализации:
|
||
|
||
1. `feat/mcp-streamable-http-alignment`
|
||
2. `feat/streaming-core-model`
|
||
3. `feat/stream-session-store`
|
||
4. `feat/runtime-window-mode`
|
||
5. `feat/rest-sse-adapter`
|
||
6. `feat/grpc-server-streaming-adapter`
|
||
7. `feat/session-and-job-tools`
|
||
8. `feat/streaming-ui-config`
|
||
9. `feat/streaming-e2e`
|
||
10. `feat/websocket-upstream-adapter`
|
||
11. `feat/soap-architecture-and-core-model`
|
||
12. `feat/soap-adapter-foundation`
|
||
|
||
Почему именно так:
|
||
|
||
- сначала transport correctness;
|
||
- потом core types;
|
||
- потом persistence;
|
||
- потом bounded runtime;
|
||
- потом protocol adapters;
|
||
- потом MCP tool publishing;
|
||
- потом UI;
|
||
- потом e2e;
|
||
- потом расширение protocol platform.
|
||
|
||
## 4. Slice 1: `feat/mcp-streamable-http-alignment`
|
||
|
||
### 4.1. Цель
|
||
|
||
Довести `apps/mcp-server` до полного и явного соответствия MCP `Streamable HTTP`.
|
||
|
||
### 4.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [apps/mcp-server/src/app.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/app.rs)
|
||
- [apps/mcp-server/src/jsonrpc.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/jsonrpc.rs)
|
||
- [apps/mcp-server/src/session.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/session.rs)
|
||
- [apps/mcp-server/src/main.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/main.rs)
|
||
|
||
Добавить при необходимости:
|
||
|
||
- `apps/mcp-server/src/transport.rs`
|
||
- `apps/mcp-server/src/sse.rs`
|
||
|
||
### 4.3. Что должно быть сделано
|
||
|
||
- parse `Accept` корректно для `application/json` и `text/event-stream`;
|
||
- `GET` endpoint перестает быть `405` и становится SSE-capable transport stream;
|
||
- `POST` может отвечать JSON или SSE в зависимости от negotiated transport;
|
||
- `Mcp-Session-Id` создается, читается и валидируется явно;
|
||
- `MCP-Protocol-Version` валидируется и возвращается явно;
|
||
- `DELETE` корректно завершает transport session;
|
||
- disconnect не трактуется как cancel operation.
|
||
|
||
### 4.4. Тесты
|
||
|
||
Обязательно добавить:
|
||
|
||
- initialize через JSON response;
|
||
- initialize через SSE response;
|
||
- `GET` SSE handshake;
|
||
- повторное использование `Mcp-Session-Id`;
|
||
- invalid protocol version;
|
||
- invalid accept header;
|
||
- session close through `DELETE`.
|
||
|
||
### 4.5. DoD
|
||
|
||
- `mcp-server` ведет себя согласно spec;
|
||
- transport tests зелёные;
|
||
- docs и code names совпадают.
|
||
|
||
## 5. Slice 2: `feat/streaming-core-model`
|
||
|
||
### 5.1. Цель
|
||
|
||
Ввести доменные типы streaming execution.
|
||
|
||
### 5.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-core/src/lib.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/lib.rs)
|
||
- [crates/crank-core/src/operation.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/operation.rs)
|
||
- [crates/crank-core/src/ids.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/ids.rs)
|
||
- [crates/crank-core/src/protocol.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/protocol.rs)
|
||
|
||
Добавить:
|
||
|
||
- `crates/crank-core/src/streaming.rs`
|
||
- `crates/crank-core/src/stream_session.rs`
|
||
|
||
### 5.3. Что должно быть сделано
|
||
|
||
- добавить `ExecutionMode`;
|
||
- добавить `TransportBehavior`;
|
||
- добавить `AggregationMode`;
|
||
- добавить `StreamingConfig`;
|
||
- добавить `StreamSessionId`, `AsyncJobId`;
|
||
- добавить `StreamSession`, `AsyncJobHandle`, `StreamStatus`, `JobStatus`;
|
||
- вшить `streaming: Option<StreamingConfig>` в `ExecutionConfig`.
|
||
|
||
### 5.4. Тесты
|
||
|
||
- serde roundtrip для `StreamingConfig`;
|
||
- validation rules для `ExecutionMode`;
|
||
- protocol-aware validation helpers.
|
||
|
||
### 5.5. DoD
|
||
|
||
- core types стабильны;
|
||
- экспортированы через `lib.rs`;
|
||
- naming не спорит с docs.
|
||
|
||
## 6. Slice 3: `feat/stream-session-store`
|
||
|
||
### 6.1. Цель
|
||
|
||
Добавить persistent store для `stream_sessions` и `async_jobs`.
|
||
|
||
### 6.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-registry/src/lib.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/lib.rs)
|
||
- [crates/crank-registry/src/model.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/model.rs)
|
||
- [crates/crank-registry/src/migrations.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/migrations.rs)
|
||
- [crates/crank-registry/src/postgres.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/postgres.rs)
|
||
|
||
### 6.3. Что должно быть сделано
|
||
|
||
- таблицы `stream_sessions`, `async_jobs`;
|
||
- record types;
|
||
- create/get/update/close/list/delete-expired methods;
|
||
- filters and paging;
|
||
- optimistic transitions для state updates.
|
||
|
||
### 6.4. Тесты
|
||
|
||
- migration test;
|
||
- create/get/update/close session;
|
||
- create/get/update/cancel async job;
|
||
- cleanup expired rows;
|
||
- invalid transition rejection.
|
||
|
||
### 6.5. DoD
|
||
|
||
- storage API соответствует runtime design;
|
||
- transitions не допускают silent corruption.
|
||
|
||
## 7. Slice 4: `feat/runtime-window-mode`
|
||
|
||
### 7.1. Цель
|
||
|
||
Ввести bounded `window` mode до session/job complexity.
|
||
|
||
### 7.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-runtime/src/lib.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/lib.rs)
|
||
- [crates/crank-runtime/src/model.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/model.rs)
|
||
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
|
||
- [crates/crank-runtime/src/error.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/error.rs)
|
||
|
||
Добавить:
|
||
|
||
- `crates/crank-runtime/src/streaming.rs`
|
||
- `crates/crank-runtime/src/aggregation.rs`
|
||
- `crates/crank-runtime/src/redaction.rs`
|
||
|
||
### 7.3. Что должно быть сделано
|
||
|
||
- `execute_window_operation`;
|
||
- bounded item/byte limiting;
|
||
- `truncated`, `window_complete`, `has_more`;
|
||
- summary building;
|
||
- redaction and truncation;
|
||
- observability write.
|
||
|
||
### 7.4. Тесты
|
||
|
||
- raw items mode;
|
||
- summary only mode;
|
||
- summary plus samples;
|
||
- max item truncation;
|
||
- max byte truncation;
|
||
- redaction;
|
||
- timeout handling.
|
||
|
||
### 7.5. DoD
|
||
|
||
- unary execution не ломается;
|
||
- window mode работает для synthetic adapter-level fixtures.
|
||
|
||
## 8. Slice 5: `feat/rest-sse-adapter`
|
||
|
||
### 8.1. Цель
|
||
|
||
Добавить bounded REST SSE support.
|
||
|
||
### 8.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- текущий crate [crates/crank-adapter-rest](/home/a.tolmachev/code/rust/mcpaas/crates/crank-adapter-rest)
|
||
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
|
||
|
||
Ожидаемые файлы:
|
||
|
||
- `src/lib.rs`
|
||
- `src/error.rs`
|
||
- `src/client.rs`
|
||
- `src/sse.rs`
|
||
|
||
### 8.3. Что должно быть сделано
|
||
|
||
- SSE connect;
|
||
- event parsing;
|
||
- bounded collect window;
|
||
- session start/poll/stop hooks, если adapter slice сразу включает stateful mode;
|
||
- proper close.
|
||
|
||
### 8.4. Тесты
|
||
|
||
- local SSE upstream fixture;
|
||
- collect N events;
|
||
- timeout without events;
|
||
- malformed event handling;
|
||
- reconnect not enabled by default.
|
||
|
||
## 9. Slice 6: `feat/grpc-server-streaming-adapter`
|
||
|
||
### 9.1. Цель
|
||
|
||
Добавить bounded gRPC server-streaming.
|
||
|
||
### 9.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-adapter-grpc](/home/a.tolmachev/code/rust/mcpaas/crates/crank-adapter-grpc)
|
||
- [crates/crank-proto](/home/a.tolmachev/code/rust/mcpaas/crates/crank-proto)
|
||
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
|
||
|
||
### 9.3. Что должно быть сделано
|
||
|
||
- identify unary vs server-streaming method from descriptors;
|
||
- invoke server stream;
|
||
- collect bounded window;
|
||
- decode stream items to normalized JSON;
|
||
- integrate with window mode.
|
||
|
||
### 9.4. Тесты
|
||
|
||
- local grpc fixture with server-streaming;
|
||
- descriptor-backed invocation;
|
||
- bounded collection;
|
||
- timeout;
|
||
- malformed item handling.
|
||
|
||
## 10. Slice 7: `feat/session-and-job-tools`
|
||
|
||
### 10.1. Цель
|
||
|
||
Ввести `session` и `async_job` как first-class runtime and MCP constructs.
|
||
|
||
### 10.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
|
||
- [apps/mcp-server/src/app.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/app.rs)
|
||
- [apps/mcp-server/src/catalog.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/catalog.rs)
|
||
- [apps/mcp-server/src/session.rs](/home/a.tolmachev/code/rust/mcpaas/apps/mcp-server/src/session.rs)
|
||
- [crates/crank-registry/src/postgres.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-registry/src/postgres.rs)
|
||
|
||
### 10.3. Что должно быть сделано
|
||
|
||
- runtime methods for start/poll/stop and start/status/result/cancel;
|
||
- MCP tool-family generation;
|
||
- binding-level tool-name derivation;
|
||
- JSON-RPC call routing for tool families;
|
||
- session/job observability.
|
||
|
||
### 10.4. Тесты
|
||
|
||
- tool listing shows generated family;
|
||
- `session start -> poll -> stop`;
|
||
- `async_job start -> status -> result -> cancel`;
|
||
- invalid session id;
|
||
- expired session;
|
||
- result before ready.
|
||
|
||
## 11. Slice 8: `feat/streaming-ui-config`
|
||
|
||
### 11.1. Цель
|
||
|
||
Добавить UI для streaming configuration.
|
||
|
||
### 11.2. Файлы
|
||
|
||
Изменить:
|
||
|
||
- `apps/ui/html/wizard/*.html`
|
||
- `apps/ui/js/wizard.js`
|
||
- `apps/ui/js/api.js`
|
||
- `apps/ui/js/i18n.js`
|
||
- CSS файлы wizard/settings/pages по необходимости
|
||
|
||
Добавить:
|
||
|
||
- `apps/ui/js/streaming-form.js`
|
||
- `apps/ui/js/stream-test-run.js`
|
||
- `apps/ui/html/stream-sessions.html`
|
||
- `apps/ui/html/async-jobs.html`
|
||
|
||
### 11.3. Что должно быть сделано
|
||
|
||
- protocol capabilities fetch;
|
||
- execution mode selector;
|
||
- protocol-specific field visibility;
|
||
- validation wiring;
|
||
- test-run UX for window/session/async job;
|
||
- sessions/jobs views;
|
||
- localization.
|
||
|
||
### 11.4. Тесты
|
||
|
||
- Playwright:
|
||
- configure REST window;
|
||
- configure gRPC streaming;
|
||
- validation error render;
|
||
- session test flow;
|
||
- async job test flow.
|
||
|
||
## 12. Slice 9: `feat/streaming-e2e`
|
||
|
||
### 12.1. Цель
|
||
|
||
Зафиксировать end-to-end behavior на живом тестовом стеке.
|
||
|
||
### 12.2. Что должно быть сделано
|
||
|
||
- добавить local fixtures:
|
||
- REST SSE server
|
||
- gRPC server-streaming server
|
||
- WebSocket event server
|
||
- SOAP fixture, если adapter уже готов
|
||
- добавить smoke scenarios;
|
||
- включить их в CI.
|
||
|
||
### 12.3. Тесты
|
||
|
||
- tool call end-to-end through mcp-server;
|
||
- usage/logging on streaming calls;
|
||
- session cleanup;
|
||
- async job cleanup.
|
||
|
||
## 13. Slice 10: `feat/websocket-upstream-adapter`
|
||
|
||
### 13.1. Файлы
|
||
|
||
Добавить:
|
||
|
||
- `crates/crank-adapter-websocket/Cargo.toml`
|
||
- `crates/crank-adapter-websocket/src/lib.rs`
|
||
- `crates/crank-adapter-websocket/src/error.rs`
|
||
- `crates/crank-adapter-websocket/src/client.rs`
|
||
- `crates/crank-adapter-websocket/src/session.rs`
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-core/src/protocol.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/protocol.rs)
|
||
- [crates/crank-core/src/operation.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/operation.rs)
|
||
- [crates/crank-runtime/src/executor.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-runtime/src/executor.rs)
|
||
|
||
### 13.2. DoD
|
||
|
||
- bounded WebSocket window;
|
||
- session support;
|
||
- reconnect and heartbeat policy;
|
||
- capability matrix exposed in admin-api and UI.
|
||
|
||
## 14. Slice 11: `feat/soap-architecture-and-core-model`
|
||
|
||
### 14.1. Файлы
|
||
|
||
Изменить:
|
||
|
||
- [crates/crank-core/src/protocol.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/protocol.rs)
|
||
- [crates/crank-core/src/operation.rs](/home/a.tolmachev/code/rust/mcpaas/crates/crank-core/src/operation.rs)
|
||
- [crates/crank-schema](/home/a.tolmachev/code/rust/mcpaas/crates/crank-schema)
|
||
|
||
Добавить:
|
||
|
||
- `crates/crank-core/src/soap.rs`
|
||
|
||
### 14.2. DoD
|
||
|
||
- SOAP target model;
|
||
- WSDL/XSD-derived metadata model;
|
||
- XML normalization strategy documented in code-level types.
|
||
|
||
## 15. Slice 12: `feat/soap-adapter-foundation`
|
||
|
||
### 15.1. Файлы
|
||
|
||
Добавить:
|
||
|
||
- `crates/crank-adapter-soap/Cargo.toml`
|
||
- `crates/crank-adapter-soap/src/lib.rs`
|
||
- `crates/crank-adapter-soap/src/error.rs`
|
||
- `crates/crank-adapter-soap/src/wsdl.rs`
|
||
- `crates/crank-adapter-soap/src/xml.rs`
|
||
- `crates/crank-adapter-soap/src/client.rs`
|
||
|
||
Изменить:
|
||
|
||
- `apps/admin-api`
|
||
- `apps/ui`
|
||
- `crates/crank-runtime`
|
||
|
||
### 15.2. DoD
|
||
|
||
- WSDL import;
|
||
- service/port/operation selection;
|
||
- SOAP request-response execution;
|
||
- fault normalization;
|
||
- UI test-run support.
|
||
|
||
## 16. State transition tables
|
||
|
||
## 16.1. `StreamSession`
|
||
|
||
Allowed:
|
||
|
||
- `created -> running`
|
||
- `running -> running`
|
||
- `running -> stopped`
|
||
- `running -> expired`
|
||
- `running -> failed`
|
||
- `stopped -> deleted`
|
||
- `expired -> deleted`
|
||
- `failed -> deleted`
|
||
|
||
Forbidden:
|
||
|
||
- `stopped -> running`
|
||
- `expired -> running`
|
||
- `deleted -> *`
|
||
|
||
## 16.2. `AsyncJob`
|
||
|
||
Allowed:
|
||
|
||
- `created -> running`
|
||
- `running -> running`
|
||
- `running -> completed`
|
||
- `running -> failed`
|
||
- `running -> cancelled`
|
||
- `completed -> expired`
|
||
- `failed -> expired`
|
||
- `cancelled -> expired`
|
||
|
||
Forbidden:
|
||
|
||
- `completed -> running`
|
||
- `cancelled -> running`
|
||
|
||
## 17. Sequence outlines
|
||
|
||
## 17.1. Window
|
||
|
||
1. MCP client calls tool.
|
||
2. `mcp-server` resolves tool binding.
|
||
3. `runtime.execute_window_operation`.
|
||
4. adapter collects bounded upstream data.
|
||
5. runtime aggregates and truncates.
|
||
6. `mcp-server` returns final JSON-RPC result.
|
||
|
||
## 17.2. Session
|
||
|
||
1. MCP client calls `{tool}_start`.
|
||
2. runtime starts upstream session and persists `StreamSession`.
|
||
3. client calls `{tool}_poll`.
|
||
4. runtime loads session and collects next bounded chunk.
|
||
5. client calls `{tool}_stop`.
|
||
6. runtime closes upstream and marks session stopped.
|
||
|
||
## 17.3. Async Job
|
||
|
||
1. MCP client calls `{tool}_start`.
|
||
2. runtime starts long-running job and persists `AsyncJob`.
|
||
3. client calls `{tool}_status`.
|
||
4. runtime returns current progress.
|
||
5. client calls `{tool}_result`.
|
||
6. runtime returns final normalized result if ready.
|
||
|
||
## 18. Acceptance checklist per slice
|
||
|
||
Перед merge каждого slice агент обязан проверить:
|
||
|
||
- docs updated if contract changed;
|
||
- `just fmt-check`
|
||
- `just check`
|
||
- `just clippy`
|
||
- `just test`
|
||
- relevant Playwright/e2e if UI touched;
|
||
- no hidden feature flags without docs;
|
||
- no unsupported combinations exposed in UI.
|
||
|
||
## 19. Branch and commit policy
|
||
|
||
Ожидаемые branch names:
|
||
|
||
- `feat/mcp-streamable-http-alignment`
|
||
- `feat/streaming-core-model`
|
||
- `feat/stream-session-store`
|
||
- `feat/runtime-window-mode`
|
||
- `feat/rest-sse-adapter`
|
||
- `feat/grpc-server-streaming-adapter`
|
||
- `feat/session-and-job-tools`
|
||
- `feat/streaming-ui-config`
|
||
- `feat/streaming-e2e`
|
||
- `feat/websocket-upstream-adapter`
|
||
- `feat/soap-architecture-and-core-model`
|
||
- `feat/soap-adapter-foundation`
|
||
|
||
Ожидаемые commit classes:
|
||
|
||
- `docs: ...`
|
||
- `feat: ...`
|
||
- `test: ...`
|
||
- `refactor: ...`
|
||
- `fix: ...`
|
||
|
||
## 20. Practical rule for agents
|
||
|
||
Агент не должен брать следующий slice, пока не выполнены DoD и тесты предыдущего slice.
|
||
|
||
Если slice требует новый contract:
|
||
|
||
1. обновить docs;
|
||
2. обновить tests;
|
||
3. обновить code;
|
||
4. только потом переходить дальше.
|