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:
+56
-53
@@ -1,77 +1,80 @@
|
||||
# :memory-api — `pw.binom.agentik.memory`
|
||||
# `:memory-api` — контракт долговременной памяти (KMP, jvm + native)
|
||||
|
||||
**Интерфейсы долговременной памяти агента: `MemoryStore`, `MemoryNote`,
|
||||
`MemoryCategory`, `MemoryPrefetcher`, `MemoryReviewer`, `MemoryTools`.**
|
||||
Без зависимостей от конкретного хранилища.
|
||||
## Что это
|
||||
|
||||
## Какую проблему решает
|
||||
Интерфейсы долговременной памяти агента:
|
||||
|
||||
LLM не помнит между сессиями. Чтобы агент становился **умнее с каждым
|
||||
диалогом**, нужна долговременная память: факты о пользователе, мире,
|
||||
предпочтениях, плюс механизм извлечения (reviewer) и подмешивания (prefetcher)
|
||||
в контекст. Бэкенды памяти бывают разные (md-файлы, векторный ANN, sqlite,
|
||||
KV-store), и `:standalone` не должен быть привязан ни к одному из них.
|
||||
- `MemoryStore` — append-only журнал `MemoryNote(id, content, createdAt)`.
|
||||
- `MemoryCategory` — discriminator (`USER`, `WORLD`, `PREFERENCE`,
|
||||
кастомные).
|
||||
- `MemoryNote` — структурная единица памяти; immutable.
|
||||
- Прелоадер / ревьювер по контракту, не по реализации.
|
||||
|
||||
`:memory-api` определяет **контракт**: что умеет любая реализация памяти.
|
||||
Конкретные бэкенды — `:memory-md` (Hermes-style §-файлы) и `:memory-vector`
|
||||
(SQLite + JVector + эмбеддинги).
|
||||
Решает: как единая абстракция позволяет иметь одновременно файловую
|
||||
память (`:memory-md`), SQLite + ANN (`:memory-vector`) и тестовую
|
||||
in-memory (в `:standalone/tests`). Агент работает с `MemoryStore`,
|
||||
не с конкретным бэкендом.
|
||||
|
||||
## Что в контракте
|
||||
## Где используется
|
||||
|
||||
- `:memory-md` — Hermes-style `§`-файлы (user.md / world.md /
|
||||
preference.md).
|
||||
- `:memory-vector` — SQLite + JVector + LLM-эмбеддинги.
|
||||
- `:standalone` подключает обе реализации и переключает через
|
||||
`AGENTIK_MEMORY_BACKEND=md|vector|off`.
|
||||
|
||||
## Как подключить
|
||||
|
||||
```kotlin
|
||||
interface MemoryStore : AutoCloseable {
|
||||
suspend fun upsert(note: MemoryNote)
|
||||
suspend fun get(id: String): MemoryNote?
|
||||
suspend fun list(category: MemoryCategory?, conversationId: String?, limit, offset): List<MemoryNote>
|
||||
suspend fun search(query: MemorySearchQuery): List<MemorySearchResult>
|
||||
suspend fun delete(id: String): Boolean
|
||||
suspend fun markUsed(ids: List<String>) // бампит lastUsedAt + useCount
|
||||
fun events(): Flow<MemoryStoreEvent> // опционально
|
||||
kotlin {
|
||||
sourceSets.commonMain.dependencies {
|
||||
api("pw.binom.agentik:memory-api:0.1.0")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Артефакт публикуется в `caffeine`.
|
||||
|
||||
## Версии
|
||||
|
||||
`gradle/libs.versions.toml` → `[versions] agentik-memory-api`.
|
||||
|
||||
## Что в API
|
||||
|
||||
```kotlin
|
||||
interface MemoryStore {
|
||||
suspend fun save(category: MemoryCategory, content: String): MemoryNote
|
||||
suspend fun query(category: MemoryCategory?, q: String, limit: Int = 10): List<MemoryNote>
|
||||
suspend fun all(category: MemoryCategory? = null): List<MemoryNote>
|
||||
}
|
||||
|
||||
enum class MemoryCategory { USER, WORLD, PREFERENCE }
|
||||
enum class MemoryCategory(val path: String) {
|
||||
USER("user"),
|
||||
WORLD("world"),
|
||||
PREFERENCE("preference");
|
||||
}
|
||||
|
||||
data class MemoryNote(
|
||||
val id: String,
|
||||
val conversationId: String?,
|
||||
val category: MemoryCategory,
|
||||
val title: String,
|
||||
val body: String,
|
||||
val source: MemorySource, // AUTO_REVIEW / USER / MANUAL
|
||||
val content: String,
|
||||
val createdAt: Instant,
|
||||
val lastUsedAt: Instant?,
|
||||
val useCount: Int,
|
||||
)
|
||||
```
|
||||
|
||||
`MemoryPrefetcher` — компонент, который **перед** каждым user-ходом выбирает
|
||||
релевантные заметки (через `search()`) и форматирует `[Memory context…]` блок
|
||||
в начало user-сообщения. `MemoryReviewer` — компонент, который **после**
|
||||
assistant-хода извлекает новые факты (через LiteLlm) и вызывает `upsert`.
|
||||
`MemoryTools` — `memory_save` / `memory_recall` / `memory_list` / `memory_delete`,
|
||||
которыми модель может пользоваться явно.
|
||||
## Тесты
|
||||
|
||||
## Подключение
|
||||
|
||||
```kotlin
|
||||
commonMain {
|
||||
implementation("pw.binom.agentik:memory-api:$version")
|
||||
// + выберите реализацию:
|
||||
implementation("pw.binom.agentik:memory-md:$version") // md-файлы
|
||||
// или
|
||||
implementation("pw.binom.agentik:memory-vector:$version") // JVector+SQLite
|
||||
}
|
||||
```
|
||||
./gradlew :memory-api:allTests
|
||||
```
|
||||
|
||||
## Где смотреть версии
|
||||
Контрактные тесты на Kotlin Multiplatform (без jvmTest-специфики).
|
||||
|
||||
- `version` из `gradle.properties` (`version=0.1.0`)
|
||||
- релизы: `https://git.binom.pw/subochev/agentik/releases`
|
||||
## Чего здесь НЕТ
|
||||
|
||||
## Сборка
|
||||
- Никаких конкретных storage — это API. Backend-ы в `:memory-md` и
|
||||
`:memory-vector`.
|
||||
|
||||
```bash
|
||||
./gradlew :memory-api:build
|
||||
```
|
||||
## Текущий статус
|
||||
|
||||
KMP-таргеты — полный набор. Зависимостей нет (только `kotlinx-coroutines-core` для `Flow`).
|
||||
Используется продакшеном. Контракт стабильный.
|
||||
|
||||
Reference in New Issue
Block a user