Files
crank/docs/architecture.md
T
2026-05-03 19:48:04 +00:00

356 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура
## 1. Назначение проекта
Crank - платформа для публикации внешних API в виде MCP tools без написания отдельного backend-кода под каждую интеграцию. Пользователь конфигурирует интеграции через UI, а система:
- хранит и версионирует операции;
- группирует их по workspace;
- публикует их в составе конкретных agents;
- выдает LLM не глобальный каталог tools, а curated toolset на один agent;
- собирает продуктовые логи и usage по workspace, agent и operation.
## 2. Переход `As Is -> To Be`
### 2.1. As Is
Текущее ядро системы построено вокруг:
- глобальной сущности `Operation`;
- registry версий операций;
- runtime adapters `REST / GraphQL / unary gRPC`;
- `admin-api` для CRUD и тестовых вызовов;
- `mcp-server`, который публикует tools из published operations.
### 2.2. To Be
Целевая архитектура расширяет текущее ядро до модели:
- `Workspace` - tenant boundary;
- `Operation` - интеграционный контракт;
- `Agent` - curated MCP surface;
- `Agent key`, `Agent token` и `Membership` - доступ к самой платформе;
- `Invocation log` и `Usage rollup` - observability слой.
`Operation` остается фундаментом интеграции, но tools больше не публикуются глобально. MCP публикует tools в контексте конкретного `workspace` и конкретного `agent`.
## 3. Ключевые сущности и их роль
### `Workspace`
Изолирует:
- операции;
- secrets;
- auth profiles;
- agents;
- agent keys;
- short-lived agent tokens;
- logs и usage;
- пользователей и роли.
### `Operation`
Описывает один вызываемый элемент независимо от протокола:
- `name`
- `display_name`
- `protocol`
- `target`
- `input_schema`
- `input_mapping`
- `execution_config`
- `security_level`
- `output_mapping`
- `tool_description`
- `status`
Принцип:
- уровень защиты определяется самой операцией;
- агент не может ослабить обязательный режим доступа;
- для более чувствительных данных требуется более строгий вид машинного credential.
### `Agent`
Является пользовательской MCP-поверхностью для LLM.
`Agent`:
- принадлежит одному workspace;
- имеет `slug`, `display_name`, `description`, `status`;
- ссылается на ограниченный набор published operations;
- формирует отдельный MCP endpoint;
- решает проблему "одному агенту нельзя отдавать 100 tools сразу".
При этом `Agent` не определяет чувствительность операции, а только публикует ее в составе MCP-поверхности.
### `Platform access`
Отдельный слой, не связанный с upstream auth:
- `User`
- `UserSession`
- `Membership`
- `Invitation`
- `AgentKey`
- `IssuedAgentToken`
Принцип:
- пользовательская аутентификация и машинная аутентификация разделены;
- длинноживущий доступ для вызова MCP tools привязан к конкретному агенту, а не к рабочей области целиком;
- в открытой редакции базовый режим строится на статическом ключе агента;
- в более защищенных редакциях используются короткоживущие и одноразовые токены;
- промежуточная схема с workspace-scoped ключами рассматривается как переходная и подлежит замене.
### `Upstream secrets`
Отдельный слой для доступа к внешним системам:
- `Secret`
- `SecretVersion`
- `AuthProfile`
Принцип:
- секреты принадлежат workspace;
- plaintext не хранится в открытом виде;
- `AuthProfile` описывает способ применения секрета к upstream request;
- runtime резолвит `auth_profile_ref` в реальный header/query/basic auth только в момент вызова.
### `Observability`
Отдельный продуктовый слой:
- `InvocationLog`
- `InvocationEvent`
- `UsageRollup`
- `LatencyStats`
## 4. Главный принцип проектирования
Система строится в три слоя:
1. `Operation` как низкоуровневый интеграционный контракт.
2. `Agent` как curated набор published operations.
3. `Workspace` как граница данных, доступа и observability.
Это позволяет:
- переиспользовать одну operation в нескольких agents;
- ограничивать tool catalog для конкретного LLM-сценария;
- изолировать данные команд;
- строить logs и usage не глобально, а по tenant boundary.
## 5. Границы целевого продукта
### Входит
- `Workspace` как tenant boundary.
- Операции `REST`, `GraphQL`, `gRPC`, `WebSocket`, `SOAP`.
- Controlled streaming operations поверх `Streamable HTTP`, REST SSE, gRPC server-streaming и WebSocket upstream.
- `Agent` и привязка операций к агенту.
- Agent-scoped MCP endpoints.
- Agent-scoped machine credentials.
- Short-lived MCP access tokens.
- Workspace-scoped encrypted secrets для upstream access.
- Workspace-scoped auth profiles для upstream access.
- Product logs и usage aggregates.
- Импорт и экспорт operation-конфигураций в `YAML`.
- Hot reload опубликованных agents и operations.
### Отложено
- GraphQL `subscription`.
- gRPC client-streaming и bidirectional streaming.
- raw infinite stream passthrough.
- полный стек WS-* расширений.
- Оркестрация workflow.
- Биллинг.
- Full RBAC policy engine.
- Traffic splitting и deployment orchestration.
## 6. Пользовательские сценарии
### Оператор операций
1. Выбирает workspace.
2. Создает или редактирует operation.
3. При необходимости выбирает или создает upstream secret / auth profile.
4. Выполняет test run.
5. Публикует operation version.
6. Привязывает operation к одному или нескольким agents.
### Оператор агентов
1. Создает agent.
2. Выбирает набор published operations.
3. Публикует agent.
4. Получает MCP endpoint вида `/mcp/v1/{workspace}/{agent}`.
### Администратор workspace
1. Управляет ключами AI-агентов и доверенных клиентов платформы.
2. Управляет пользователями и ролями.
3. Смотрит logs и usage.
## 7. Стратегия по протоколам
### REST
- `GET`
- `POST`
- `PUT`
- `PATCH`
- `DELETE`
- path parameters
- query parameters
- headers
- JSON request body
- JSON response body
### GraphQL
- `query`
- `mutation`
- endpoint URL
- request headers
- operation template
- variables mapping
## 8. Open-core граница
Crank развивается как open-core продукт.
Это означает:
- `Community` должна полностью собираться из этого репозитория;
- коммерческие возможности не должны храниться здесь как рабочий private code;
- различия между редакциями должны отражаться в capability model, API, UI и delivery pipeline.
Ключевые продуктовые различия зафиксированы в `docs/product-editions.md`.
## 9. Коммерческий контур
Коммерческий контур не должен защищаться "скрытием" уже опубликованного исходного кода. Правильная архитектурная граница выглядит так:
- в `crank-community` остается Community runtime и extension seams;
- коммерческие реализации поставляются из private repositories или private artifacts;
- критичные правила лицензирования, metering и token issuance исполняются на серверной стороне.
Практические правила зафиксированы в `docs/commercial-boundaries.md`.
- извлечение результата из `data`
GraphQL в MCP публикуется как фиксированная операция с предсказуемой структурой ответа.
### gRPC
- unary RPC;
- bounded server-streaming через `window`, `session` и `async_job` execution modes;
- `.proto` и `descriptor set`;
- JSON-oriented schema model поверх protobuf;
- без client-streaming и bidi.
### WebSocket
- upstream-only adapter;
- bounded `window`, `session` и `async_job`;
- subscribe/unsubscribe messages;
- heartbeat и reconnect policy;
- не используется как downstream MCP transport.
### SOAP
- WSDL-driven request-response integration;
- service/port/operation selection;
- SOAP envelope и fault normalization;
- request-response first;
- long-running workflows через `async_job`, если upstream это поддерживает.
### Streaming
Платформа поддерживает controlled streaming model:
- downstream transport: `Streamable HTTP` с optional SSE;
- upstream streaming: REST SSE, gRPC server-streaming и WebSocket;
- execution modes: `unary`, `window`, `session`, `async_job`;
- никакого raw infinite stream passthrough в MCP client.
## 8. Работа с файлами и автогенерация черновика
Поддерживаемые источники:
- пример входного `JSON`;
- пример выходного `JSON`;
- `.proto`;
- `descriptor set`.
Ожидаемый сценарий:
1. оператор загружает артефакты;
2. система строит черновую схему и mapping;
3. оператор вручную корректирует результат;
4. готовую конфигурацию можно экспортировать в `YAML`.
## 9. Внутренняя модель данных
Базовые сущности:
- `Workspace`
- `Secret`
- `SecretVersion`
- `Operation`
- `OperationVersion`
- `Agent`
- `AgentVersion`
- `AgentOperationBinding`
- `StreamSession`
- `AsyncJobHandle`
- `AuthProfile`
- `AgentKey`
- `IssuedAgentToken`
- `UserSession`
- `InvocationLog`
- `UsageRollup`
## 10. MCP publishing model
Публикация tools строится так:
1. `Operation` проходит versioning и publish.
2. `Agent` собирает curated набор published operations.
3. `MCP server` читает published view конкретного agent.
4. `tools/list` и `tools/call` работают в контексте `workspace + agent`.
## 11. Observability
На каждый вызов tool сохраняются:
- `workspace_id`
- `agent_id`
- `operation_id`
- `request_id`
- `timestamp`
- `status`
- `duration_ms`
- `error_kind`
- `request_preview`
- `response_preview`
Сверху строятся:
- logs page;
- usage page;
- периодические rollups;
- latency and error aggregates.
## 12. Модель маппинга
Платформе нужен отдельный слой маппинга:
- сопоставление поле-в-поле по `JSONPath`;
- константы;
- значения по умолчанию;
- извлечение вложенных полей из ответа.