# WebSocket

## 1. Роль протокола в проекте

WebSocket поддерживается как полноценный upstream protocol для realtime, push-oriented и stateful integrations. Он не заменяет downstream MCP transport, а работает за Crank proxy.

Иными словами:

- downstream: MCP `Streamable HTTP`;
- upstream: WebSocket;
- Crank нормализует WebSocket lifecycle в bounded MCP tool semantics.

## 2. Что поддерживается в целевом продукте

- клиентское WebSocket подключение к внешнему upstream;
- custom headers и auth profiles;
- handshake config;
- optional subprotocol selection;
- subscription payload или start message;
- bounded `window` mode;
- `session` mode с `start/poll/stop`;
- `async_job` mode для control-plane и progress channels;
- JSON message parsing;
- text-frame based event collection;
- mapping `MCP input -> subscribe payload`;
- mapping `WebSocket message -> normalized JSON`;
- heartbeat/keepalive config;
- reconnect policy для controlled session modes.

## 3. Что не входит в текущий продуктовый scope

- raw binary frame passthrough в LLM;
- arbitrary bidirectional conversation tunnel;
- full message bus semantics;
- generic browser-like socket inspector;
- guaranteed resumability across arbitrary upstream websocket providers.

## 4. Ключевое архитектурное ограничение

WebSocket не публикуется как "живой канал в чат". Он должен быть выражен в одной из execution models:

- `window`
- `session`
- `async_job`

Недопустимо:

- бесконечно проксировать frames напрямую в MCP client;
- скрывать жизненный цикл сокета за одним неопределенным tool call;
- смешивать downstream SSE transport и upstream WebSocket semantics в одну абстракцию.

## 5. Типовые use cases

### 5.1. Monitoring and telemetry

- realtime метрики;
- device telemetry;
- market data;
- anomaly events.

### 5.2. Event subscriptions

- alert streams;
- queue events;
- workflow transitions;
- security events.

### 5.3. Stateful control channels

- rollout progress;
- remote task status;
- infrastructure control plane updates;
- long-running remote sessions.

## 6. Внутренняя модель WebSocket operation

WebSocket operation должна включать:

- `url`
- `headers`
- `subprotocols`
- `subscribe_message_template`
- `unsubscribe_message_template`
- `input_mapping`
- `output_mapping`
- `execution_config`
- `tool_description`

Protocol-specific runtime tuning хранится отдельно в `ProtocolOptions.websocket`:

- `heartbeat_interval_ms`
- `reconnect_max_attempts`
- `reconnect_backoff_ms`

## 7. Как оператор настраивает WebSocket operation

1. Указывает URL WebSocket upstream.
2. При необходимости выбирает auth profile и headers.
3. Указывает subprotocol или оставляет пустым.
4. Выбирает execution mode: `window`, `session` или `async_job`.
5. Настраивает subscribe payload.
6. Указывает правила извлечения items, status и cursor.
7. Настраивает aggregation limits.
8. Выполняет test run.
9. Публикует operation как MCP tool или tool family.

## 7.1. Текущий UI foundation

Текущий wizard support для WebSocket уже включает:

- выбор `WebSocket` как protocol family на шаге 1;
- step 2 reuse общего upstream/auth selector;
- отдельный step 3 для:
  - socket path override;
  - subprotocol list;
  - subscribe message template;
  - unsubscribe message template;
  - `heartbeat_interval_ms`;
  - `reconnect_max_attempts`;
  - `reconnect_backoff_ms`.

На текущем этапе wizard сериализует:

- `Target::Websocket`
- `ExecutionConfig.protocol_options.websocket`

Это дает оператору usable foundation для `window`, `session` и `async_job` flows even before deeper inspection/test-run polish.

## 8. Поведение runtime

При выполнении WebSocket operation runtime должен:

1. Валидировать MCP input.
2. Построить subscribe payload.
3. Открыть WebSocket connection.
4. Пройти handshake и auth.
5. Отправить subscribe message.
6. Собрать bounded window или session step.
7. Нормализовать messages в JSON.
8. Применить output mapping.
9. Закрыть соединение или сохранить session state.

## 9. Критические нюансы

- upstream WebSocket может быть stateful и требовать explicit unsubscribe;
- heartbeat и reconnect должны быть управляемыми через config, а не захардкоженными;
- session state должен хранить cursor, last_event и subscription metadata;
- disconnect downstream MCP client не означает cancel upstream session;
- runtime обязан уметь cleanly завершать orphaned connections.

## 10. Почему WebSocket должен быть отдельным adapter

WebSocket нельзя свести к "почти SSE" или "почти HTTP", потому что:

- transport двунаправленный;
- lifecycle connection stateful;
- есть handshake, heartbeat и reconnect;
- подписка часто задается сообщением, а не URL;
- semantics событий и прогресса отличаются от request-response вызова.
