-
10
Stablereleased this
2026-09-22 00:13:02 +00:00 | 14 commits to main since this releaseЧто в релизе
Refactor (protocol)
Три протокольных изменения по итогам ревью Android-клиента:
- toolName denormalization в ToolResult (3 слоя):
:outbox-api/Event.ToolResult,:journal-api/MessageRecord.ToolResult,:proto/Message.ToolResultтеперь несутtoolName: String? = null. КодекиResultPayloadв:storage-ksqlite+:journal-ksqliteобновлены,:standalone/ToolDispatcherпробрасываетtoolName = call.name. UI больше не обязан вести локальныйtoolCallId → toolNamemap — денормализация дешёвая, поле присутствует в payload. - Удалены typealias'ы в
:proto(Event.kt,AgentEvent.kt,CommonEvent.kt). Через aliasis proto.Event.Endпадает сUnresolved reference 'End'— alias теряет nested-class access. Все потребители (:proto,:server,:client,:standalone,:agentik-tui,:agentik-cli) перевёл на прямой импортpw.binom.agentik.outbox.{Event, AgentEvent, CommonEvent}. 21 файл rewired, 3 файла удалено. Event.ToolResult.id→toolCallId(semantic rename): в:outbox-apiEvent.ToolResult.id == Event.ToolCall.id(одно значение, одно имя) → переименовано вtoolCallId. Persistent journal (MessageRecord.ToolResult) оставлен как есть: тамid— собственный PK,toolCallId— FK на call (разные семантики). Заодно пофикшен баг вToolDispatcher: эмитилid = resultId, а KDoc утверждалid == ToolCall.id→ теперь эмититtoolCallId = callId.Conversation.events()удалён из:proto.OutboxStore— единственный источник live-событий.Conversationтеперь pure per-conversation abstraction (send/getMessages/rename/close). HTTP-роутGET /conversations/{id}/eventsсохранён для wire-compat, но внутри роутится черезagent.outbox.conversationEvents(after, id).map { it.event }. Клиент делаетagent.outbox.conversationEvents(Instant.DISTANT_PAST, convId).map { it.event }.
Docs (client)
- KDoc на
AgentikAgentтеперь содержит таблицу «Что клиент хранит локально (persistence)» —clientId(произвольная строка клиента для server-side log multiplexing, генерируется один раз, никогда не меняется),baseUrl(включает path-prefix фасада),token(Bearer,null= анонимный).client/README.mdполучил зеркальную секцию с минимальным JSON-примером.AgentSettingsRepositoryнамеренно НЕ добавлен — UI-фреймворки хранят настройки по-разному (JSON-файл, Keychain, Android DataStore, NSUserDefaults), либа формат не навязывает.
Feature (client)
-
ReconnectingOutboxв:client/commonMain(240 LOC + 4 теста): обёртка над любымOutboxStoreс auto-reconnect при обрыве SSE. Два независимых параллельных потока:events(after): Flow<CommonEvent>— cursorlastSeenсохраняется между попытками, клиент не теряет события при reconnectconnectionStatus(): Flow<ConnectionStatus>—Connecting(attempt)/Connected(since)/Disconnected(reason, willRetryIn)/Failed(cause)для UI-индикации, НЕ мешается с потоком событийBackoffPolicy.Default(1s → 2s → 4s → 8s → 16s → 30s, ±20% jitter, бесконечные попытки) +BackoffPolicy.Fixed(delay, attempts)для тестовAutoCloseable.close()отменяет background-loop
client/README.md— секция «Auto-reconnect для живого outbox» с примером (дваscope.launchна разные потоки).
Verified
- jvmTest: 95 задач зелёных, 0 падений
- 4 новых теста
ReconnectingOutboxTest: успех / disconnect+reconnect+cursor preserved / exhausted attempts → Failed / close cancels loop
Downloads
- toolName denormalization в ToolResult (3 слоя):