20. Протокол: TUI ↔ app-server
Связь между TUI/CLI и app-server идёт через JSON-RPC-подобный протокол (без обязательного поля "jsonrpc": "2.0"), определённый в крейте app-server-protocol/. Версионирование — две неймспейс-версии (v1 / v2), сосуществующие в одном протоколе.
1. Структура сообщений
Используется в app-server-protocol/src/jsonrpc_lite.rs:
// Client → Server
JSONRPCRequest {
id: RequestId, // строка или число
method: String, // "thread/start", "turn/start", ...
params: Option<Value>,
trace: Option<W3cTraceContext>, // OpenTelemetry pass-through
}
// Server → Client (notification, без id)
JSONRPCNotification {
method: String,
params: Option<Value>,
}
// Server → Client (response на request с тем же id)
JSONRPCResponse {
id: RequestId,
result: Value,
}
// Error response
JSONRPCError {
id: RequestId,
error: { code: i64, message: String, data: Option<Value> },
}
// Server → Client (server request, требует ответа)
// Использует те же поля что и JSONRPCRequest, но идёт от сервера.
"jsonrpc": "2.0" опущено — для уменьшения размера сообщений в hot-path.
2. Транспорты
| Транспорт | Где |
|---|---|
| In-process (mpsc) | TUI запускает app-server в той же tokio-runtime; общение через tokio::sync::mpsc::channel(CHANNEL_CAPACITY). Без сериализации в JSON. |
| WebSocket | Удалённый app-server; обычно через TLS. |
| Unix Domain Socket | Для локальных удалённых подключений (например, astracode app-server запущен в фоне). |
Серверная in-process обвязка реализована в app-server/src/in_process.rs, а
InProcessAppServerClient — в app-server-client/src/lib.rs. Удалённые
транспорты используют тот же protocol contract.
Backpressure: try_send возвращает WouldBlock при переполнении канала.
Оба транспорта идут через AstraCodeMessageProcessor::process_request() — единая логика, разные транспорты.
3. Версионирование (v1 / v2)
Файлы:
- app-server-protocol/src/protocol/v1.rs — legacy.
- app-server-protocol/src/protocol/v2.rs — основной API (~10 000 строк типов).
Сосуществуют под одним протоколом — нет «переключения» с v1 на v2. Вместо этого:
- Старые методы остаются доступны под именами v1 (getAuthStatus).
- Новые/расширенные методы используют v2-имена и типы.
- Экспериментальные поля помечены #[experimental(...)] и сериализуются только если клиент в Initialize сообщил experimental_api: true.
4. Handshake
Client → Server: Initialize { request_id, params: InitializeParams }
params.client_info: { name, version }
params.capabilities: {
experimental_api: bool,
opt_out_notification_methods: Option<Vec<String>>
}
Server → Client: Response { result: InitializeResponse }
user_agent, astracode_home, platform_family, platform_os
Client → Server: Notification: "initialized"
opt_out_notification_methods — список нотификаций, которые клиент не хочет получать (например, нет смысла шлёть thread/started тестовому клиенту).
5. Поддерживаемые публичные client requests
Группировка по доменам для проверенной ревизии. Канонический источник полного
wire registry — client_request_definitions! в
app-server-protocol/src/protocol/common.rs; experimental и legacy surface
может меняться независимо от этого обзорного документа.
Thread API
| Метод | Параметры | Ответ |
|---|---|---|
thread/start |
ThreadStartParams |
ThreadStartResponse |
thread/resume |
ThreadResumeParams |
ThreadResumeResponse |
thread/fork |
ThreadForkParams |
ThreadForkResponse |
thread/archive |
ThreadArchiveParams |
ThreadArchiveResponse |
thread/unarchive |
ThreadUnarchiveParams |
ThreadUnarchiveResponse |
thread/unsubscribe |
ThreadUnsubscribeParams |
ThreadUnsubscribeResponse |
thread/list |
ThreadListParams |
ThreadListResponse |
thread/loaded/list |
ThreadLoadedListParams |
ThreadLoadedListResponse |
thread/read |
ThreadReadParams |
ThreadReadResponse |
thread/turns/list |
ThreadTurnsListParams |
ThreadTurnsListResponse |
thread/inject_items |
ThreadInjectItemsParams |
ThreadInjectItemsResponse |
thread/rollback |
ThreadRollbackParams |
ThreadRollbackResponse |
thread/name/set |
ThreadSetNameParams |
ThreadSetNameResponse |
thread/goal/set |
ThreadGoalSetParams |
ThreadGoalSetResponse |
thread/goal/get |
ThreadGoalGetParams |
ThreadGoalGetResponse |
thread/goal/clear |
ThreadGoalClearParams |
ThreadGoalClearResponse |
thread/metadata/update |
ThreadMetadataUpdateParams |
ThreadMetadataUpdateResponse |
thread/settings/update [EXP] |
ThreadSettingsUpdateParams |
ThreadSettingsUpdateResponse |
thread/memoryMode/set [EXP] |
ThreadMemoryModeSetParams |
ThreadMemoryModeSetResponse |
thread/compact/start |
ThreadCompactStartParams |
ThreadCompactStartResponse |
thread/shellCommand |
ThreadShellCommandParams |
ThreadShellCommandResponse |
thread/approveGuardianDeniedAction |
ThreadApproveGuardianDeniedActionParams |
… |
thread/backgroundTerminals/clean [EXP] |
ThreadBackgroundTerminalsCleanParams |
… |
thread/increment_elicitation [EXP] |
ThreadIncrementElicitationParams |
… |
thread/decrement_elicitation [EXP] |
… | … |
Turn API
| Метод | Параметры | Ответ |
|---|---|---|
turn/start |
TurnStartParams |
TurnStartResponse |
turn/steer |
TurnSteerParams |
TurnSteerResponse |
turn/interrupt |
TurnInterruptParams |
TurnInterruptResponse |
Realtime (голосовой режим, EXP)
| Метод | Параметры | Ответ |
|---|---|---|
thread/realtime/start |
ThreadRealtimeStartParams |
… |
thread/realtime/appendAudio |
…AppendAudioParams | … |
thread/realtime/appendText |
…AppendTextParams | … |
thread/realtime/stop |
…StopParams | … |
thread/realtime/listVoices |
…ListVoicesParams | … |
Review
| Метод | Параметры | Ответ |
|---|---|---|
review/start |
ReviewStartParams |
ReviewStartResponse |
Skills
| Метод | Параметры | Ответ |
|---|---|---|
skills/list |
SkillsListParams |
SkillsListResponse |
skills/config/write |
SkillsConfigWriteParams |
… |
Plugin
| Метод | Параметры | Ответ |
|---|---|---|
plugin/list |
PluginListParams |
… |
plugin/read |
PluginReadParams |
… |
plugin/install |
PluginInstallParams |
… |
plugin/uninstall |
PluginUninstallParams |
… |
Slash-команды
| Метод | Параметры | Ответ |
|---|---|---|
slashCommand/registry |
Option<()> |
SlashCommandRegistryResponse — список команд с метаданными |
slashCommand/dispatch |
SlashCommandDispatchParams |
SlashCommandDispatchResponse — серверное исполнение и разбор аргументов |
MCP
| Метод | Параметры | Ответ |
|---|---|---|
mcpServer/oauth/login |
McpServerOauthLoginParams |
… |
mcpServerStatus/list |
ListMcpServerStatusParams |
ListMcpServerStatusResponse |
mcpServer/resource/read |
McpResourceReadParams |
McpResourceReadResponse |
mcpServer/tool/call |
McpServerToolCallParams |
McpServerToolCallResponse |
config/mcpServer/reload |
Option<()> |
McpServerRefreshResponse |
File system
| Метод | Параметры | Ответ |
|---|---|---|
fs/readFile |
…Params | … |
fs/writeFile |
… | … |
fs/createDirectory |
… | … |
fs/getMetadata |
… | … |
fs/readDirectory |
… | … |
fs/remove |
… | … |
fs/copy |
… | … |
fs/watch |
FsWatchParams |
FsWatchResponse |
fs/unwatch |
FsUnwatchParams |
… |
fs/listChanges |
Option<()> |
… |
fs/undo |
FsUndoParams |
… |
Command exec (для запуска команд из UI, не из модели)
| Метод | Параметры | Ответ |
|---|---|---|
command/exec |
CommandExecParams |
CommandExecResponse |
command/exec/write |
…WriteParams | … |
command/exec/terminate |
…TerminateParams | … |
command/exec/resize |
…ResizeParams | … |
Config
| Метод | Параметры | Ответ |
|---|---|---|
config/read |
ConfigReadParams |
ConfigReadResponse |
config/value/write |
ConfigValueWriteParams |
ConfigWriteResponse |
config/batchWrite |
ConfigBatchWriteParams |
ConfigWriteResponse |
configRequirements/read |
Option<()> |
ConfigRequirementsReadResponse |
externalAgentConfig/detect |
… | … |
externalAgentConfig/import |
… | … |
Model
| Метод | Параметры | Ответ |
|---|---|---|
model/list |
ModelListParams |
ModelListResponse |
modelProvider/capabilities/read |
… | … |
Auth / Account / Device
| Метод | Параметры | Ответ |
|---|---|---|
account/read |
GetAccountParams |
GetAccountResponse |
getAuthStatus (v1) |
GetAuthStatusParams |
GetAuthStatusResponse |
device/key/create |
DeviceKeyCreateParams |
… |
device/key/public |
DeviceKeyPublicParams |
… |
Feature flags / permissions
| Метод | Параметры | Ответ |
|---|---|---|
experimentalFeature/list |
… | … |
experimentalFeature/enablement/set |
… | … |
permissionProfile/list |
… | … |
collaborationMode/list [EXP] |
… | … |
Memory
| Метод | Параметры | Ответ |
|---|---|---|
memory/reset [EXP] |
Option<()> |
MemoryResetResponse |
Прочее
| Метод | Параметры | Ответ |
|---|---|---|
windowsSandbox/setupStart |
WindowsSandboxSetupStartParams |
… |
fuzzyFileSearch (legacy) |
FuzzyFileSearchParams |
… |
fuzzyFileSearch/sessionStart [EXP] |
… | … |
fuzzyFileSearch/sessionUpdate [EXP] |
… | … |
fuzzyFileSearch/sessionStop [EXP] |
… | … |
mock/experimentalMethod [EXP] |
… | … (для тестов) |
feedback/submit |
FeedbackSubmitParams |
FeedbackSubmitResponse — отправка фидбэка/категории |
index/build/start |
IndexBuildStartParams |
Запуск построения индекса проекта |
[EXP] — методы за experimental_api capability.
6. Поддерживаемые публичные server notifications
Notifications (без id) идут server → client стримом. Группировка:
В wire enum также существует внутреннее уведомление
rawResponseItem/completed. Генератор публичной JSON schema намеренно исключает
его через EXCLUDED_SERVER_NOTIFICATION_METHODS_FOR_JSON, поэтому оно не
входит в поддерживаемый клиентский API и ниже не перечисляется.
Thread lifecycle
thread/started, thread/status/changed, thread/archived, thread/unarchived, thread/closed, thread/name/updated, thread/goal/updated, thread/goal/cleared, thread/settings/updated [EXP], thread/tokenUsage/updated, thread/compacted
Turn и item streaming
turn/started, turn/completed, turn/diff/updated, turn/plan/updated, item/started, item/completed, item/agentMessage/delta, # streaming текста ассистента item/plan/delta [EXP], # streaming плана item/reasoning/summaryTextDelta, # reasoning (o1/o3, claude extended thinking) item/reasoning/summaryPartAdded, item/reasoning/textDelta
Command/file execution streaming
command/exec/outputDelta, item/commandExecution/outputDelta, item/commandExecution/terminalInteraction, item/fileChange/outputDelta, item/fileChange/patchUpdated
Hooks
hook/started, hook/completed
Обе notifications содержат threadId, опциональный turnId и run типа
HookRunSummary. В summary передаются event/source, display order,
running|completed|failed|blocked|stopped, status message, timestamps,
duration и output entries (warning, stop, feedback, context, error).
Это transport-события для UI и внешних клиентов, а не API запуска hooks:
конфигурация, stdin/stdout и решения lifecycle описаны в
08-hooks.md.
Approval / guardian
item/autoApprovalReview/started, item/autoApprovalReview/completed, guardianWarning
MCP / tools
mcpServer/oauthLogin/completed, mcpServer/startupStatus/updated, item/mcpToolCall/progress
System / прочее
error, warning, deprecationNotice, configWarning, account/updated, account/login/completed, model/rerouted, # fallback к другой модели model/verification, skills/changed, fs/changed, # от fs/watch fuzzyFileSearch/sessionUpdated, fuzzyFileSearch/sessionCompleted, windows/worldWritableWarning, windowsSandbox/setupCompleted, externalAgentConfig/import/completed, serverRequest/resolved # завершение pending server request
Realtime [EXP]
thread/realtime/started, thread/realtime/itemAdded, thread/realtime/transcript/delta, thread/realtime/transcript/done, thread/realtime/outputAudio/delta, thread/realtime/sdp, thread/realtime/error, thread/realtime/closed
7. Server requests (требуют ответа от UI)
Это сообщения server → client с id, на которые клиент обязан ответить. Используется для approval-диалогов и подобных интерактивных решений.
| Метод | Параметры | Ответ (Decision) |
|---|---|---|
item/commandExecution/requestApproval |
CommandExecutionRequestApprovalParams |
accept, acceptForSession, acceptWithExecpolicyAmendment, applyNetworkPolicyAmendment, decline, cancel |
item/fileChange/requestApproval |
FileChangeRequestApprovalParams |
accept, acceptForSession, decline, cancel |
item/permissions/requestApproval |
PermissionsRequestApprovalParams |
(запрос дополнительных привилегий) |
mcpServer/elicitation/request |
McpServerElicitationRequestParams (union: credential / OAuth / …) |
McpServerElicitationRequestResponse |
item/tool/requestUserInput [EXP] |
ToolRequestUserInputParams |
ToolRequestUserInputResponse |
item/tool/call |
DynamicToolCallParams |
DynamicToolCallResponse |
Deprecated (v1)
item/fileChange/requestApproval (v1) → ApplyPatchApprovalParams / Response item/commandExecution/requestApproval (v1) → ExecCommandApprovalParams / Response
UI обязан отвечать в разумное время — иначе core зависнет. Можно ответить deny, можно показать модальный диалог.
8. Error handling
Стандартные коды JSON-RPC + расширения AstraCode (в app-server/src/error_code.rs):
| Код | Имя | Описание |
|---|---|---|
-32600 |
INVALID_REQUEST_ERROR_CODE | Plain malformed request |
-32601 |
(стандарт) | Method not found |
-32603 |
INTERNAL_ERROR_CODE | Internal server error |
-32001 |
OVERLOADED_ERROR_CODE | 429/rate-limit/перегруз |
-32602 |
INVALID_PARAMS_ERROR_CODE | Не прошёл валидацию параметров |
Превышение лимита пользовательского ввода возвращается как обычный JSON-RPC
error с code = -32602. Строка "input_too_large" находится в
error.data.input_error_code; рядом передаются max_chars и actual_chars.
Retry-стратегия — на клиенте. AstraCode-клиент использует exponential backoff на OVERLOADED_ERROR_CODE и сетевые ошибки.
9. Trace context
Каждый JSONRPCRequest может содержать trace: Option<W3cTraceContext> — W3C trace context (traceparent, tracestate). Используется для распределённого трейсинга через otel крейт. Сервер пробрасывает trace ID в свои downstream-вызовы (LLM, MCP, tools).
10. Соответствие in-process / remote
| Аспект | In-process | Remote (WS/UDS) |
|---|---|---|
| Сериализация | Нет (структуры передаются как есть) | JSON |
| Backpressure | mpsc::try_send WouldBlock |
Сетевая буферизация |
| Trace propagation | Через канал | Через JSON-поле |
MessageProcessor логика |
Та же | Та же |
| Латентность | ~μs | ~ms |
С точки зрения логики идентичны. Удалённый режим даёт возможность переподключаться (например, после crash'а TUI app-server остался жив).
11. Где определены типы
- Сами типы методов и параметров:
app-server-protocol/src/protocol/v2.rs(~10000 строк). - Макросы генерации:
app-server-protocol/src/lib.rs—client_request_definitions!,server_notification_definitions!,server_request_definitions!. - v1 legacy:
app-server-protocol/src/protocol/v1.rs. - Клиент:
app-server-client/src/. - Сервер:
app-server/src/astracode_message_processor.rs.
12. Как добавить новый метод
См. 22-cookbook.md.