docs: per-module READMEs (run vs library) + root navigation hub
ci / JVM build + tests (pull_request) Failing after 54s
ci / JVM build + tests (pull_request) Failing after 54s
Every subproject now has README.md:
- 3 runnable modules (:standalone, :agentik-cli, :agentik-tui):
quickstart, env table, parameters, known limits
- 11 library modules: what it is, which problem solves, how to
wire it in, where versions live
Root README.md is the navigation hub (Quickstart, Modules table,
publish + CI/CD notes).
Also: ci.yml prunes the :memory-vector -x excludes now that
text-embedding-kmp artifacts are published to caffeine.
518 tests green.
Verified publish pipeline: :proto:publish to caffeine produces
pom.module + per-target klibs + sources for all 9 KMP targets.
🤖 Generated with [opencode]
This commit is contained in:
+57
-57
@@ -1,77 +1,77 @@
|
||||
# :storage-core — `pw.binom.agentik.storage`
|
||||
# `:storage-core` — контракт хранилища (KMP, jvm + native)
|
||||
|
||||
**Интерфейсы хранилища разговорной истории агента: `ConversationStore`,
|
||||
`MessageStore`, `WorkingMemoryStore`, `ReflectionStore`.**
|
||||
Без зависимостей от конкретной БД.
|
||||
## Что это
|
||||
|
||||
## Какую проблему решает
|
||||
Интерфейсы persistence-уровня для `:standalone`:
|
||||
|
||||
`:standalone` нужно сохранять диалоги между перезапусками, держать working
|
||||
memory (сжатую историю, которую видит LLM), reflection-записи. Но привязываться
|
||||
к конкретной БД (SQLite) в контракте нельзя — для Android подходит другая
|
||||
история, для тестов — in-memory, для экспериментов с Postgres — третья.
|
||||
- `MessageStore` — append-only история сообщений по диалогу.
|
||||
- `WorkingMemoryStore` — rolling buffer текущего хода (`AssistantMessage`,
|
||||
`ToolExchange`, `UserMessage`, system-prompt) для fast-recovery
|
||||
при reconnect/relance.
|
||||
- `ConversationStore` — метаданные диалогов (id, title, model,
|
||||
timestamps).
|
||||
- `ReflectionStore` — LLM-reflections (свободная форма заметок
|
||||
хранителя).
|
||||
|
||||
`:storage-core` отделяет **что хранить** (контракт) от **где хранить**
|
||||
(бэкенды — `:storage-sqlite`, `:storage-inmemory`, и в будущем `:storage-android`).
|
||||
Агрегатор `StorageBundle` собирает все 4 стора разом.
|
||||
Решает: позволяет запустить агента на Android-in-memory, на
|
||||
desktop-SQLite, или на production-SQLite, не переписывая логику.
|
||||
Контракт минимален и async-friendly.
|
||||
|
||||
## Что в контракте
|
||||
## Где используется
|
||||
|
||||
- `:storage-inmemory` — для тестов и Android.
|
||||
- `:storage-sqlite` — прод (Desktop / server / однодесктопный
|
||||
Android-development).
|
||||
|
||||
## Как подключить
|
||||
|
||||
```kotlin
|
||||
interface ConversationStore : AutoCloseable {
|
||||
suspend fun upsert(c: Conversation)
|
||||
suspend fun get(id: String): Conversation?
|
||||
suspend fun list(offset, limit, orderBy): List<Conversation>
|
||||
suspend fun delete(id: String): Boolean
|
||||
fun events(after: Instant): Flow<ConversationStoreEvent>
|
||||
}
|
||||
|
||||
interface MessageStore : AutoCloseable {
|
||||
suspend fun append(message: Message, conversationId: String, workingMemoryIndex: Int?)
|
||||
suspend fun listByConversation(conversationId: String, after: Instant?, offset, limit): List<Message>
|
||||
suspend fun update(message: Message, conversationId: String) // правка + бамп updatedAt
|
||||
suspend fun deleteByConversation(conversationId: String)
|
||||
}
|
||||
|
||||
interface WorkingMemoryStore : AutoCloseable {
|
||||
suspend fun append(conversationId: String, entry: WorkingMemoryEntry, index: Int)
|
||||
suspend fun listByConversation(conversationId: String, after: Instant?): List<WorkingMemoryEntry>
|
||||
suspend fun compact(conversationId: String, fromIndex: Int, summary: SummaryEntry)
|
||||
suspend fun reset(conversationId: String)
|
||||
}
|
||||
|
||||
interface ReflectionStore : AutoCloseable {
|
||||
suspend fun append(conversationId: String, reflection: ReflectionEntry)
|
||||
suspend fun recent(conversationId: String?, topK: Int): List<ReflectionEntry>
|
||||
kotlin {
|
||||
sourceSets.commonMain.dependencies {
|
||||
api("pw.binom.agentik:storage-core:0.1.0")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`WorkingMemoryEntry` — `sealed interface`: `User`, `Assistant`, `ToolExchange`,
|
||||
`Summary`. Каждый entry имеет `instant` (когда попал в working memory) и
|
||||
`index` (порядковый номер для восстановления при компакции).
|
||||
## Версии
|
||||
|
||||
## Подключение
|
||||
`gradle/libs.versions.toml` → `[versions] agentik-storage-core`.
|
||||
|
||||
## Что в API
|
||||
|
||||
```kotlin
|
||||
commonMain {
|
||||
implementation("pw.binom.agentik:storage-core:$version")
|
||||
// + бэкенд:
|
||||
implementation("pw.binom.agentik:storage-inmemory:$version") // тесты
|
||||
// или
|
||||
implementation("pw.binom.agentik:storage-sqlite:$version") // прод
|
||||
interface MessageStore {
|
||||
suspend fun append(conversationId: String, message: Message): Unit
|
||||
suspend fun after(conversationId: String, instant: Instant, limit: Int = 100): List<Message>
|
||||
}
|
||||
|
||||
interface WorkingMemoryStore {
|
||||
suspend fun save(conv: String, entry: WorkingMemoryEntry): Unit
|
||||
fun load(conv: String): Flow<WorkingMemoryEntry> // cold flow
|
||||
suspend fun clear(conv: String): Unit
|
||||
}
|
||||
|
||||
sealed interface WorkingMemoryEntry {
|
||||
val id: String
|
||||
val date: Instant
|
||||
class UserMessage(...) : WorkingMemoryEntry
|
||||
class AssistantMessage(...) : WorkingMemoryEntry
|
||||
class ToolExchange(val toolName: String, val toolArgsJson: String, val resultText: String, val wasCancelled: Boolean) : WorkingMemoryEntry
|
||||
class SystemPrompt(...) : WorkingMemoryEntry
|
||||
}
|
||||
```
|
||||
|
||||
## Где смотреть версии
|
||||
## Тесты
|
||||
|
||||
- `version` из `gradle.properties` (`version=0.1.0`)
|
||||
- релизы: `https://git.binom.pw/subochev/agentik/releases`
|
||||
Контрактные тесты (общие для всех имплементаций) — в `:storage-sqlite`
|
||||
и `:storage-inmemory`.
|
||||
|
||||
## Сборка
|
||||
## Чего здесь НЕТ
|
||||
|
||||
```bash
|
||||
./gradlew :storage-core:build
|
||||
```
|
||||
- Никакого HTTP / SSE.
|
||||
- Никакой конкретной БД. Backend'ы в `:storage-*`.
|
||||
|
||||
KMP-таргеты — полный набор. Зависимости — только `kotlinx-coroutines` +
|
||||
`kotlinx-serialization`.
|
||||
## Текущий статус
|
||||
|
||||
Используется продакшеном. Контракт зафиксирован после
|
||||
interrupt-имплементации (см. [INTERRUPT-DESIGN.md](../../docs/INTERRUPT-DESIGN.md)).
|
||||
|
||||
Reference in New Issue
Block a user