refactor: outbox становится live-only стримом, cursor вынесен в :cursor-api
Семантика outbox'а — теперь чистый live-канал:
* OutboxStore.conversationEvents(id) — больше не принимает after-cursor.
Catchup (replay) делает клиент: journal.listFlow(afterSeq) + подписка
на live. Outbox ответственен только за уведомления «что-то произошло».
* OutboxStore.oldestCursor()/currentCursor()/OutboxGapException — удалены.
Эпоха и offset живут ТОЛЬКО в CursorHolder/CursorStore, переживают
рестарт и инкремент для каждого commit.
* DurableEvent: commit принимает блок { cursor -> MessageRecord }
(cursor выдаёт CursorStore; клиент не вычисляет offset сам).
* MessageRecord больше не несёт cursor — это не его ответственность.
Новые модули:
* :cursor-api — Cursor(epoch, offset) + CursorHolder / MutableCursorHolder
* :cursor-ksqlite — KsqliteCursorHolder (персистентный)
* :cursor-inmemory — для тестов
* :client-sync — LocalSyncAgent (мини-агент поверх :client для десктопа)
Удалены:
* :sync-core — старая референсная реализация, заменена
cursor-разделением и :client.
* outbox-ksqlite — CursorStore/Schema уехали в :cursor-ksqlite.
* OffsetSequencer / PersistentOffsetSequencer / InMemoryOffsetSequencer.
standalone:
* ChatAgent/ConversationLoop/DurableLog/ToolDispatcher/ReflectionScheduler/
ConversationEvents — подписка через push-паттерн (collect событий).
* A2aBridge — currentCursor() и conversationEvents(after=) убраны.
* SqliteStores — cursor_offset удалён из schema v4; seedNextFromJournal
читает MAX(created_at).
* Main.kt — outboxSequencer → outboxCursorHolder; user→agent (:server)
transport удалён; debug-routes удалены; A2A остался.
* Тесты ChatAgentTest/PersistenceTest переписаны на push-паттерн
(subscribe-before-act, snapshot∪live = итоговое состояние). 25/25 + 19/19 ✅
server / client:
* Routes эпоху читают из CursorHolder; снимки несут Cursor? для catchup.
* AgentikAgent и HttpEventStore — те же подписки, без after-параметра.
* ReconnectingOutbox / ReconnectingOutboxTest — без изменений API.
* JournalStore API расширен count(after=Instant?) для unread-badge.
This commit is contained in:
+21
-10
@@ -44,6 +44,12 @@ include(":skills")
|
||||
include(":server")
|
||||
// Ktor-клиент, превращающий HTTP-фасад в `Agent`/`Conversation`.
|
||||
include(":client")
|
||||
// Транспорт-агностичный слой клиентской синхронизации: оборачивает `Agent`
|
||||
// локальным стором бесед + durable-курсором (MutableCursorHolder) и ведёт
|
||||
// протокол «снапшот + дельты». Зависит только от :proto/:journal-api/:cursor-api,
|
||||
// поэтому переиспользуется любым клиентом (desktop, CLI, embedded), не только
|
||||
// HTTP-овым :client.
|
||||
include(":client-sync")
|
||||
// CLI-клиент поверх :client — REPL со slash-командами и стримингом ответов.
|
||||
// KMP со всеми целями (jvm + весь натив), jvm-таргет собирается как shadowJar.
|
||||
// include(":agentik-cli") — отключено 2026-09-21: пользователь временно вывел
|
||||
@@ -114,10 +120,14 @@ include(":context-ksqlite")
|
||||
// ConversationStore / conversation table). Минимальный модуль:
|
||||
// таблицы `message` + `conversation` + индексы.
|
||||
include(":journal-ksqlite")
|
||||
// ksqlite-реализация :outbox-api (CursorStore / outbox_cursor table).
|
||||
// ksqlite-реализация :cursor-api (CursorHolder / outbox_cursor table).
|
||||
// Персистентная позиция счётчика событий агента — переживает рестарт, чтобы
|
||||
// клиент продолжал инкрементально (см. PersistentOffsetSequencer).
|
||||
include(":outbox-ksqlite")
|
||||
// клиент продолжал инкрементально (см. CursorHolder).
|
||||
include(":cursor-ksqlite")
|
||||
|
||||
// In-memory-реализация :cursor-api (CursorHolder) — для тестов, dev-режима
|
||||
// и ephemeral runtime; эпоха не переживает пересоздание holder'а.
|
||||
include(":cursor-inmemory")
|
||||
// ksqlite-реализация :reflection-api (ReflectionStore / reflection table).
|
||||
// Минимальный модуль: только таблица `reflection` + 2 индекса.
|
||||
include(":reflection-ksqlite")
|
||||
@@ -150,10 +160,11 @@ include(":agent-api")
|
||||
// SkillMiningComponent, слушающий outbox (Event.ConversationClosing /
|
||||
// Event.CompactionTriggered) и добывающий новые скилы через SkillMiner.
|
||||
include(":skill-mining")
|
||||
// Референсная реализация спеки `SYNC-SYSTEM.md` — журнал событий с
|
||||
// монотонным курсором + материализация + replace-resync, единый протокол
|
||||
// для клиента и сервера. KMP с jvm/linuxX64/mingwX64 целями (ksqlite-
|
||||
// ограничение). Тесты спеки в commonTest, интеграция с ksqlite — в jvmTest.
|
||||
// Существующий код (outbox/journal/client/server) не трогаем; это чистый
|
||||
// референс для последующей миграции.
|
||||
include(":sync-core")
|
||||
include(":cursor-api")
|
||||
include(":sync")
|
||||
include(":ksqlite-message-storage")
|
||||
// Мосты между :proto-агентом и внешними мессенджерами. Каждый модуль —
|
||||
// `pw.binom.agentik.integrations.<messenger>` с `TelegramBridgeComponent`
|
||||
// (реализация `pw.binom.agentik.agent.Component`). Подключаются в
|
||||
// `:standalone` при наличии соответствующего токена в env (см. AppConfig).
|
||||
include(":integrations-telegram")
|
||||
|
||||
Reference in New Issue
Block a user