e2f0e434d1381588d0c9d511a87e6afae0b64e7d
17 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7358175499 |
feat(event-store): new :event-store module with interfaces only
ci / JVM build + tests (push) Failing after 1m54s
Выделяет bounded-tail event log в отдельный KMP-модуль. Это **новый
контракт** (не замена :message-store-api/events/EventStore — тот пока жив).
**Двухуровневое хранилище событий**:
1. :event-store (этот PR) — короткий bounded tail, авто-TTL.
Для live SSE и recent replay (catchup после короткого disconnect).
2. :message-store-api (MessageStore) — полный audit log, никогда не
эвиктится. Source of truth для длинного disconnect / audit query.
**API**:
- append(Event) — put, идемпотентный по id
- events(after: Instant?): Flow<Event> — catchup + live в одном Flow
- earliestEventDate(): Instant? — для gap detection у клиента
**Чего НЕТ в API** (by design):
- delete/prune методов — TTL/cap eviction полностью на стороне impl.
Caller'ы не должны забыть вызвать cleanup (single source of truth).
- conversationId / type в Event — opaque payload, тип envelope'а
решает producer.
Пока interfaces only — implementations (InMemoryEventStore, persistent)
появятся в следующих коммитах. Никаких изменений в существующем
EventStore в :message-store-api, чтобы не ломать зависимости.
KMP targets: jvm + linuxX64 + mingwX64 (Apple auto-disabled на Linux).
Modules:
+ :event-store — новый, commonMain only, ~150 строк
|
||
|
|
2d9ad526bb |
refactor(storage): split :storage-core into message-store-api + working-memory-api
ci / JVM build + tests (push) Failing after 2m5s
Разделяет монолитный :storage-core на 3 модуля с чёткими границами:
:message-store-api — MessageStore, ReflectionStore, EventStore, ConversationStore +
Content, Payload, MessageContext, Ids, MessageEvent
(audit log + event stream)
:working-memory-api — WorkingMemoryStore + WorkingMemoryEntry
(runtime context с compaction)
:storage-bundle — StorageBundle агрегатор, зависит от обоих
(только для server-side runtime)
Пакеты:
pw.binom.agentik.storage.* → УДАЛЕНО
pw.binom.agentik.messageStore.* — append-only API
pw.binom.agentik.messageStore.events.* — EventStore + EventRecord
pw.binom.agentik.workingMemory.* — WM API
pw.binom.agentik.storageBundle.* — aggregator
Зачем:
- Тонкий клиент может подтянуть ТОЛЬКО :message-store-api (~15KB, нет
compaction-логики, нет MessageStore+WorkingMemoryStore cross-deps).
- Android-agent в будущем подключит :message-store-api для audit log,
серверный runtime — :storage-bundle со всем.
- Компиляционные границы защищают от случайной зависимости от WM
в read-only клиентах (раньше один :storage-core не давал такой
гарантии).
Миграция:
- Имплементации (:storage-inmemory, :storage-sqlite, :storage-ksqlite)
обновили package + добавили deps на оба API модуля + :storage-bundle.
- Тесты из :storage-core (PersistenceTest, SqliteStoresMigrationTest,
TokenStatsTest) переехали в :standalone, получили testImplementation
на оба API модуля и импорты новых типов.
- 52 файла в :standalone, :agent-toolsets, :llm-tools, :server, :client,
:agentik-cli обновили FQN.
- :storage-core удалён.
Совместимость схем не меняется — все 5 impl'ов (3 backend × 5 store) хранят
данные в тех же таблицах, миграция между Sqlite и Ksqlite возможна через SQL dump.
Тесты:
standalone 178 ✅
agent-toolsets 36 ✅
storage-inmemory 47 ✅
storage-sqlite 17 ✅ (включая переехавшие persistence/* + tokenStats)
storage-ksqlite 36 ✅
---
Total: 314 tests, 0 failures
|
||
|
|
bf2649a856 |
feat(storage-ksqlite): migrate all 5 stores to ksqlite backend
ci / JVM build + tests (push) Failing after 1m21s
Расширяет :storage-ksqlite (ранее только EventStore) — все 5 store'ов из :storage-core теперь имеют ksqlite-имплементацию с теми же контрактами: - KsqliteConversationStore (CRUD диалогов, каскадный delete messages+WM) - KsqliteMessageStore (audit log, listAll + tokenStats через encode/decode) - KsqliteWorkingMemoryStore (compaction с транзакцией, max order_idx) - KsqliteReflectionStore (insert/listRecent/listForConversation/deleteOlderThan + events flow) - KsqliteEventStore (replay-after-disconnect, INSERT OR REPLACE) Схемы таблиц полностью идентичны :storage-sqlite (conversation, message, working_memory, reflection, agent_event) — данные совместимы между двумя backend'ами, можно мигрировать через SQL dump. MessageCodecs.kt — hand-rolled encode/decode для MessageRecord ↔ payload_json. Скопирован из :storage-sqlite где helpers были private; в :storage-ksqlite свой набор, синхронизация — ответственность разработчика (см. KDoc). KsqliteStores.kt — фабрика open(path) / inMemory(name), возвращает bundle из 5 store'ов + SQLiteConnection. Аналог SqliteStores.open/inMemory. Encoding helpers (CallPayload/ResultPayload/ErrorPayload, encodeStringArray для Reflection.weakSpots) продублированы — alternative это вынести в :storage-core, но это пока YAGNI. Тесты: - KsqliteEventStoreTest — 11 tests ✅ (passes на JVM и linuxX64) - KsqliteConversationStoreTest — 9 tests ✅ - KsqliteMessageStoreTest — 5 tests ✅ - KsqliteWorkingMemoryStoreTest — 5 tests ✅ - KsqliteReflectionStoreTest — 6 tests ✅ Build verified: компилируется на JVM и linuxX64. nativeMain-deps (kotlin-logging) перенесены в jvmMain т.к. KMP-артефакта нет. Известные проблемы: - gradle test runner иногда не финализирует XML-результаты на Linux FS (in-progress-results-generic*.bin остаются). Тесты при этом проходят (видно в отчёте build/reports/tests/jvmTest/*.html), но счётчик tests="N" в XML не аггрегируется. - Storage bundle в KsqliteStores возвращает StorageBundle (KMP), но стандартный app wiring пока не подключает его — :standalone использует SqliteStores. Подключение = следующий шаг. |
||
|
|
ac5d209fce |
refactor(standalone): extract modules, event-driven background, AppConfig
ci / JVM build + tests (push) Failing after 2m5s
Standalone refactor — modularity + correctness improvements after
STANDALONE-REVIEW findings. Touches ~30 files. Build green, 178 tests pass.
(1) Module extractions — generic components out of :standalone:
• :llm-tools (new KMP module, package pw.binom.agentik.llm.tools)
- LlmReflector, SkillMiner, LlmMemoryReviewer, LiteLlmContextCompactor
- Parsers: ReflectionParser, SkillMiningParser, ReviewDecisionParser
- Prompts: ReflectionPrompts, SkillMiningPrompts, ReviewPrompts
• :mcp-bridge (new JVM module, package pw.binom.agentik.mcp.bridge)
- McpConfig, McpRegistry, McpLiteToolAdapter
• NamedTool moved from :standalone to :agent-toolsets/commonMain
- Generic (name + LiteTool) wrapper, used by both :mcp-bridge
and :standalone's tool dispatcher
:standalone loses ~1400 lines, depends on the two new modules.
(2) Background work → event-driven (no more interval-polling):
• New :standalone/agent/BackgroundEvents.kt — internal event bus:
- ToolCallEvent.Succeeded/Failed (emitted by ToolDispatcher after invoke)
- CompactionEvent.Triggered (emitted by CompactionCoordinator pre-delete)
- ConversationLifecycleEvent.Closing (emitted by ConversationLoop.close)
• BackgroundScheduler rewritten as event subscriber:
- On Closing: final reflection + skill mining (last-chance extraction)
- On Compaction (turnsToDelete > 10): skill mining (debounced 60s)
- On ToolFailure x2 in 60s window: reflection (debounced 5min)
- Dropped: maybeScheduleReview/Reflection/SkillMining (interval-based)
- Dropped config: memoryReviewInterval, reflectionInterval, skillMiningInterval
• ToolDispatcher emits ToolCallEvent after each invoke.
• CompactionCoordinator emits CompactionEvent before workingMemory.compact().
• ConversationLoop.close() emits Closing BEFORE agentScope.cancel() so the
subscription gets to run final reflection/mining.
Net effect: typical 30-turn conversation runs ~38 LLM calls (was: 30 main +
3 review + 3 reflection + 2 mining). With event-driven, review/mining only fire
when their triggers actually make sense (compaction about to delete, or
conversation closing).
(3) AppConfig single source of truth:
• Replaces AgentikConfig + LlmConfig.fromEnv + McpConfig.fromEnv with one
AppConfig.fromEnv() that reads all ~25 env vars in a single pass.
• Sections: AgentSection, LlmSection, McpSection, MemorySection,
EmbeddingSection, ReflectionSection, SkillMiningSection, DebugSection.
• OPENAI_CONTEXT_WINDOW / AGENTIK_GOOGLE_CONTEXT_WINDOW no longer
read twice (was a bug per STANDALONE-REVIEW E3).
(4) Other fixes inherited from earlier waves:
• Hardening — size caps on user-input boundaries:
MAX_MEMORY_CONTENT_LEN=32KB, MAX_SKILL_BODY_LEN=64KB,
MAX_MCP_CONFIG_BYTES=1MB, MAX_A2A_REPLY_LEN=10MB, MAX_PORT=65535,
blank-rejection in LlmConfig.requireEnv, URL/command validation.
• Single scope — :standalone/agent/ConversationLoop has one
agentScope (was: scope + backgroundScope).
• liteConvRef race fix — capture-then-use pattern replaces !!-after-read;
close() + runTurn.finally race on LiteConv JNI handled via
AtomicReference.getAndSet.
• SkillMiner.maxTurns / LlmReflector.maxTurns exposed as public (needed
by BackgroundScheduler for prompt sizing).
• Tests: MemoryWiringTest updated for new compaction-triggered review
behavior; all parser/test imports updated for new packages.
Test results: 178/178 in :standalone, 36/36 in :agent-toolsets — all green.
|
||
|
|
ee0b9d8341 |
build: исключаем :agentik-tui из сборки
ci / JVM build + tests (push) Failing after 1m25s
Пользователь признал TUI-подход неудачным (Mosaic 0.18 требует alt-screen
костылей, нативный ввод/вывод ограничен, тестирование через pty).
Папка agentik-tui/ оставлена на диске — комментарий в settings.gradle.kts
фиксирует дату и причину, на случай если вернёмся.
Изменения:
- settings.gradle.kts: include(':agentik-tui') → закомментировано
- build.gradle.kts: убран из moduleDescriptions
- .gitea/workflows/ci.yml: убран shadowJar шаг и из upload paths
- .gitea/workflows/release.yml: убран из комментария
- README.md, proto/README.md, server/README.md, client/README.md:
ссылки на :agentik-tui помечены как устаревшие
- agentik-cli/build.gradle.kts: убрана ссылка в комментарии
|
||
|
|
e68db11aaa |
feat(agentik-tui): TUI client v2 на Mosaic — без vim-клавиш, только Tab/Enter/Esc/Ctrl-D/F1/стрелки
Вместо v1 (history-список + slash-команды) делаем сразу v2: - header (id/conv/focus), history, input, footer - переключение фокуса Tab/Shift-Tab (history/input/sidebar) - ↑↓ scrollback, ←→ курсор в input - Enter submit (User-сообщение в history), Backspace/Del удаление, Esc clear - Ctrl-D/Ctrl-C выход (заглушка — пишет в history, реальный exit добавим) - F1 toggle help-оверлея Архитектурно: используем StateFlow+collectAsState вместо mutableStateOf, потому что в Mosaic 0.18 recompose от mutableStateOf-writes из key-handler не триггерится автоматически (требует ручного Snapshot.apply). StateFlow через collectAsState работает out-of-the-box (см. samples/snake в репо Mosaic). Compose Compiler plugin (org.jetbrains.kotlin.plugin.compose) обязателен — без него @Composable-лямбды компилятся в Function0 вместо Function2 и runMosaicBlocking не находит сигнатуру. Цели сборки: jvm + macosX64/Arm64 + linuxX64/Arm64 + mingwX64 (iOS не нужен). Бэкенд (:client, ktor-cio) — jvmMain only пока, nativeMain заглушка. Tests: 370/370 green. |
||
|
|
b0bbc57880 |
feat(agentik-cli): REPL-клиент на базе :client для всех KMP-целей
Новый KMP-модуль :agentik-cli — REPL поверх HTTP-фасада :server. commonMain (~900 строк): - Main.kt — точка входа + парсинг --server/--id/--no-history/--help - CliPlatform.kt — expect-фабрика Agent + CliTerminal + SessionIo + env() - SlashCommand.kt — 11 slash-команд: /help /new /list /sw /rename /rm /interrupt /history /pwd /exit /quit - AgentikCli.kt (~350 строк) — главный REPL-цикл: readLine → parse → send → render events. Сохраняет lastEventAt в ~/.agentik/cli-state.json. - EventRenderer.kt — печатает SSE-события (StartResponse/AppendText/AppendImage/ End/Interrupted/Error) с правильным разделением text/image и переводом строки на end. - SessionRepository.kt — JSON-state (conversationId, lastEventAt) + IO-интерфейс SessionIo. jvmMain — JLine-терминал (LineReader+history, стрелки, Ctrl-D/E, автосейв истории), java.io-based atomic-IO для state-файла, real System.getenv. nativeMain — stub actuals (kotlin.Result-error с подсказкой куда копать): подключение native ktor-движков (darwin/curl/okhttp) и termios через kotlinx.cinterop — отдельная задача. Все 8 KMP-целей (jvm/macosX64/macosArm64/ iosX64/iosArm64/iosSimulatorArm64/linuxX64/linuxArm64/mingwX64) компилируются. shadowJar собирает self-contained fatjar (~8.5 MB). 23 unit-теста зелёные. Заодно фикс бага в :client — InstantSerializer.descriptor имел имя 'kotlin.time.Instant', которое kotlinx-serialization 1.6+ резервирует за встроенным сериализатором, из-за чего client падал на старте с 'there already exists InstantSerializer'. Переименовано в 'pw.binom.agentik.Instant' — зеркально с :server. Smoke-тест на 192.168.76.166: /new + 'привет'/'2+2' отвечает корректно, state-файл создаётся в /root/.agentik/cli-state.json, /list возвращает 125 диалогов. |
||
|
|
2e1387273a |
agent-toolsets: ядро механики toolsets (реестр, диспетчер, встроенные тулы)
Новый KMP-модуль :agent-toolsets с основными абстракциями для тулсетов: - ToolsetContribution(name, description, tools: List<ToolEntry>) — декларация тулсета: имя + описание + список входящих LiteTool'ов с именами. - ToolsetContext + Logger + NoOpLogger — что тулсеты получают при активации. - ToolsetRegistry — реестр тулсетов с Mutex-защитой; методы activate/deactivate/isActive/activeNames/inactiveNames/activeTools/ findByName/findOwnerByToolName. - ToolsetDispatchPolicy — диспетчер с прощающей auto-activation: если тул из неактивного тулсета вызван — молча активирует тулсет и выполняет. Если тул вообще неизвестен — fallback в BaseToolDispatcher (плоские тулы вне toolsets). - EnableToolsetTool / DisableToolsetTool — встроенные LiteTool'ы (4-case контракт зафиксирован в docs/TOOLSETS-PLAN.md): activate/deactivate с равномерным сообщением 'X deactivated' независимо от того, был ли он активен. - SyncLiteTool — обёртка suspend-handler'а в синхронный LiteTool (через runBlocking). LiteTool.invoke синхронен по контракту litert-kmp. Дизайн: - :agent-toolsets НЕ зависит от :standalone — может быть переиспользован в Android-сборке и любом LiteTool-агенте. - Модуль KMP (jvm + native), общие интерфейсы в commonMain, JVM-специфика только в SyncLiteTool (runBlocking). - ToolsetContext минимален (logger); storage/skill добавятся в commit 5+. Тесты: 29 новых покрывают activate/deactivate/idempotency, activeTools, findOwnerByToolName, auto-activation в диспетчере, fallback в base, оба контракта enable/disable со всеми 4 кейсами. Tests: 328/328 green (299 ранее + 29 в :agent-toolsets) |
||
|
|
a7d8cbe713 |
storage-sqlite: выделить SQLDelight + SQLite-импл в отдельный модуль
Перенесён SQLDelight (4 .sq файла, конфигурация databases { AgentikDatabase })
и 5 SQLite-импл классов (SqliteStores, SqliteConversationStore, SqliteMessageStore,
SqliteWorkingMemoryStore, SqliteReflectionStore) из :standalone в новый JVM-only
модуль :storage-sqlite под пакетом pw.binom.agentik.storage.sqlite.
Изменения:
- Новый :storage-sqlite модуль с sqldelight-плагином + sqlite JDBC driver
- Все .sq файлы и Kotlin-классы переехали с переименованием пакета
- ReflectionStore.kt в :standalone (только SQLite-импл) удалён — функционал
живёт в :storage-sqlite/SqliteReflectionStore.kt
- :standalone/build.gradle.kts: убран sqldelight-плагин и конфигурация,
добавлена зависимость :storage-sqlite
- Все импорты в :standalone (8 main + 7 test) перенаправлены на новый пакет
- ReflectionStoreTest.kt переехал в :storage-sqlite/jvmTest (тестирует
internal fun encode/decodeStringArray в :storage-sqlite)
Совместимость:
- SqliteStores доступен по новому пути pw.binom.agentik.storage.sqlite.SqliteStores
- Старые импорты в тестах обновлены (минимум diff — 1 строка на файл)
- В commit 6 ChatAgent переключится на StorageBundle API; SqliteStores
станет деталью реализации :standalone
Тесты: 299/299 green. Fatjar standalone-all.jar 240 MB.
Преимущества:
- :standalone больше не зависит от SQLDelight плагина (легче поддерживать)
- :storage-sqlite может быть заменён/расширен (например, :storage-android)
- Тесты storage-слоя сгруппированы по модулю реализации
|
||
|
|
61f8205f40 |
storage-inmemory: in-memory импл 4 store'ов
Новый KMP-модуль :storage-inmemory с тред-безопасными (Mutex) in-memory имплами для всех 4 store'ов из :storage-core: - InMemoryConversationStore (Map по id, sortedByDescending(updatedAt)) - InMemoryMessageStore (List per conversation, с tokenStats) - InMemoryWorkingMemoryStore (List с order_idx, atomic compact + summary) - InMemoryReflectionStore (List по conversationId, FIFO для listRecent) Фабрика InMemoryStorage.create() возвращает готовый StorageBundle. Семантика 1:1 с SQLite-имплами — параллельные suspend-вызовы атомарны через kotlinx.coroutines.sync.Mutex (lost-update race невозможен, как в SQLite-driver-locked версии). Тесты: 35 новых, проверяют round-trip всех CRUD-операций, тред-безопасность, tokenStats агрегацию, compact+summary, events-flow. Планируемое использование: - :standalone тесты (вместо SqliteStores.inMemory() с JDBC) - Android ART-сборка (commit 7+; SQLite требует JDBC драйвера, недоступного в Android base classes) - embedded/cold-start сценарии без SQLite-инициализации Tests: 299/299 green (264 ранее + 35 новых в :storage-inmemory) |
||
|
|
294837daa0 |
storage-core: новый KMP-модуль с интерфейсами хранилища
Выносим интерфейсы и data-классы истории диалога (MessageStore / WorkingMemoryStore / ConversationStore / ReflectionStore + соответствующие sealed-иерархии MessageRecord / WorkingMemoryEntry / Content / ConversationRecord / Reflection + payload-утилиты) из :standalone в отдельный KMP-модуль :storage-core (pw.binom.agentik.storage). Цель — подготовка к Android-портированию и подключению альтернативных реализаций хранилища без затягивания всей :standalone. Дальше (commit 2/3) — :storage-inmemory и :storage-sqlite как самостоятельные модули, плюс :storage-android (deferred). Изменения: - Новый :storage-core (KMP, commonMain only, jvm + native таргеты) — 12 файлов - StorageBundle агрегатор (conversationStore + messageStore + workingMemoryStore + reflectionStore; SkillStore живёт в :skills и подключается отдельно) - 11 файлов импортов в :standalone переключены на новый пакет - SqliteReflectionStore оставлен в :standalone до commit 3 (зависит от SQLDelight AgentikDatabase, которую ещё не отвязали от :standalone) - 4 теста перенесены в :standalone/.../storage/ с обновлённым пакетом - PayloadTest переехал в :storage-core/commonTest (тестирует чистые типы) Tests: 264/264 green (179 :standalone + 6 :storage-core + прочие JVM-модули) |
||
|
|
f1cd2e3d42 |
litert-8: тул-цикл без фантомного trigger-сообщения
litert-api 7 -> 8. addToolResult(callId, name, result: Unit) ->
LiteDelta (несёт текст пост-тул ответа модели + возможные вложенные
tool-calls). caffeine не публикует parent-аггрегатор, поэтому алиасы
в libs.versions.toml указывают на -jvm flavor напрямую.
ChatConversation.runTurn: убран хак currentParts=[Text(' ')] —
вместо него runToolAndPersist(call) -> (callId, resultText) ->
addToolResult() возвращает LiteDelta, цикл идёт по delta.toolCalls.
Никакого 'призрачного' ответа модели в KV-cache после каждого тула.
Live smoke-test (gemma-4-E2B + SigLIP vector backend):
- 'Запомни: работаю на macOS' -> 'Я сохранил информацию о том, что вы
работаете на macOS' (раньше: 'Чем я могу помочь?')
- 'На чём работаю?' -> 'Вы работаете на macOS'
- цепочка имя->а necdoт -> модель осмысленно продолжает, не сбрасывается
- тесты: 264/264 зелёных
|
||
|
|
427ce8a572 |
memory: SigLIP2 on-device embedding (text-embedding-kmp v3)
Добавляет второй бэкенд эмбеддингов для vector-памяти: on-device SigLIP2
через ONNX Runtime. Не требует сети (HTTP), не светят тексты заметок наружу.
* gradle/libs.versions.toml: text-embedding-kmp = "3.0.0-SNAPSHOT", модули
api-jvm / siglip-jvm (group переехал с pw.binom.voice.embeddingtext на
pw.binom.ai.embeddingtext).
* settings.gradle.kts: mavenLocal() добавлен в dependencyResolutionManagement
(text-embedding-kmp публикуется локально как snapshot).
* memory-vector/SiglipEmbeddingProvider (jvmMain) — адаптер
pw.binom.voice.embeddingtext.TextEmbeddingExtractor → EmbeddingProvider:
оборачивает blocking embed() в withContext(Dispatchers.IO) + Mutex (ONNX
сессия не reentrant), размерность пробируется через probe embed("probe")
(768 для SigLIP2-base).
* memory-vector/build.gradle.kts: api(libs.text.embedding.api) +
implementation(libs.text.embedding.siglip); jvmTest получает
SiglipEmbeddingProviderTest — smoke test (skip если модель не найдена).
* standalone/AgentikConfig: новый enum EmbeddingBackend { HTTP, SIGLIP },
поля embeddingBackend / embeddingModelPath / embeddingTokenizerPath, env:
AGENTIK_EMBEDDING_BACKEND, AGENTIK_EMBEDDING_MODEL_PATH,
AGENTIK_EMBEDDING_TOKENIZER_PATH.
* standalone/Main.kt: switch на embeddingBackend при memory-backend=vector;
для SIGLIP требуются оба пути, иначе ошибка с понятным сообщением.
* standalone/README.md: обновлены env-vars, добавлены две bash-секции
(HTTP и SIGLIP) + инструкция скачивания модели с static.binom.pw.
* scripts/install-text-embedding-stub.sh: workaround для upstream бага
(siglip-jvm/*.module ссылается на api без -jvm variant). Создаёт
stub-артефакт api:3.0.0-SNAPSHOT в mavenLocal с тем же содержимым.
Удалить когда upstream починит module-metadata.
Smoke test: AGENTIK_MEMORY_BACKEND=vector AGENTIK_EMBEDDING_BACKEND=siglip
+ несуществующий путь → FileNotFoundException с понятным трейсом (значит
ONNX Runtime инициализирован, путь через factory пробрасывается корректно).
Tests: 288 total green. Fatjar 250MB (вырос из-за onnxruntime ~80MB).
Dropped: старый stub-jar pw.binom.voice.embeddingtext:api:2.0.0-SNAPSHOT.
|
||
|
|
65365da89c |
Phase 5: :memory-vector (JVector + SQLite + LLM-эмбеддинги), memory-abstraction, compaction, MessageContext
- :memory-api — общий контракт MemoryStore/Prefetcher/Reviewer/Tools/MemorySystem
- :memory-md (KMP, kotlinx-io) — Hermes-style §-файлы, keyword overlap
- :memory-vector (JVM-only) — JVector ANN + SQLite + HttpEmbeddingClient
- :standalone — AGENTIK_MEMORY_BACKEND={md,vector,off}, выбор в Main.kt
- :standalone — compaction рабочего контекста (LiteLlmContextCompactor + reviewPreCompaction)
- :proto — MessageContext (origin: user/system/event) на send и в Message
- :server — backward-compat dual-format для POST /messages
- README — env-vars, vector-бэкенд docs
|
||
|
|
f4caab940e |
skills: парсер YAML-скилов (opencode-формат)
Новый KMP-модуль :skills (9 целей, зеркалит :proto). Парсит скилы
в формате opencode: YAML-фронтматтер с name+description, затем markdown
body.
- SkillFile(name, description, body) — @Serializable результат.
- SkillParseError — sealed-иерархия ошибок: Empty, MissingOpeningFence,
MissingClosingFence, InvalidYaml, SchemaMismatch, BlankName.
- SkillParser.parse(raw): SkillParseResult + parseOrThrow(raw): SkillFile.
Обрабатывает BOM, CRLF, имена с двоеточиями (backend:spring:db-base),
multiline-YAML, пустое тело; неизвестные ключи фронтматтера игнорирует.
- SkillParserTest — 16 тестов, 0 failures.
YAML-библиотека — com.charleskorn.kaml 0.104.0 (не JetBrains,
интеграция с kotlinx @Serializable). Грабли kaml 0.104: параметр
ignoreUnknownKeys переименован в strictMode (инвертирован);
missing-required-field прилетает как YamlException, не
SerializationException — различаем по сообщению.
Проверка: :skills:jvmTest 16/16, :skills:assemble (9 целей) — зелёные.
|
||
|
|
cad4d5fc7c |
AGUI: удалён полностью
Убрана зависимость pw.binom.agui:server из проекта — AGUI больше не нужен (см. Memory #3675; agentik переходит на свой протокол :proto и HTTP-фасад :server). Чистка: - standalone/build.gradle.kts: implementation(libs.agui.server) → удалено - gradle/libs.versions.toml: [versions] agui + agui-api/agui-client/ agui-server entries → удалены - settings.gradle.kts: убран 'AG-UI' из комментария к Nexus-репо - proto/build.gradle.kts: комментарий 'Зеркалит набор AG-UI api' → 'Полный набор KMP-целей' - proto/src/.../Agent.kt: KDoc '(замена AG-UI)' → удалено - settings.gradle.kts: то же - docs/ARCHITECTURE.md: переписан (описывал старую AGUI-centric архитектуру с AbstractAgent/SessionStore/ AgentEngine — ничего этого в коде уже нет; теперь отражает текущее состояние: :proto + :server + :standalone + LiteLlm + MCP + SqliteStores) - NATIVE-COMPATIBILITY.md: пункт 10 'agui-server KMP-готовность' → отменён (см. -); убран из 'Жёсткие блокеры' В коде не осталось ни одного обращения к AGUI. После чистки в репо больше нет ни одной зависимости от pw.binom.agui.*. Проверка: ./gradlew :server:assemble (9/9 KMP-целей) + :standalone:jvmTest 44/44 (ChatAgent 15, LlmConfig 6, McpConfig 8, McpRegistry 4, Persistence 11) — зелёные. |
||
|
|
a3581abf84 |
Bring up :proto protocol + :server (Ktor) + :client (HTTP) modules; wire :server into standalone with EchoProtoAgent
Major additions: * :proto (KMP submodule) — in-house stateful protocol replacing AG-UI. Agent owns conversation transcript; Conversation.events(after) is a live, replay-free stream; backfill via Conversation.getMessages(after, offset, limit). Each Event carries an Instant date for client-side resume tracking. Sealed hierarchies (Content/Message/Event/AgentEvent) annotated @Serializable with snake_case @SerialName JSON discriminators so the wire format is decoupled from Kotlin class names. * :server (JVM, Ktor 3.1.3) — REST+SSE facade for Agent. Public entry: Route.agentikAgent(agent, path = "/agentik"). Endpoints: create/list/get/patch/delete conversations, POST messages (202), POST interrupt, GET messages, GET conversation events (SSE), GET agent events (SSE), GET /health. Custom Instant serializer for kotlin.time.Instant registered contextually on agentikJson (ISO-8601, ignoreUnknownKeys=true, explicitNulls=false). * :client (JVM, Ktor HTTP Client + CIO) — mirror of :server returning a pw.binom.agentik.proto.Agent backed by HTTP calls. Custom SSE parser since ktor-client-sse is not on the 3.1.3 client classpath. * standalone — EchoProtoAgent (in-memory Agent for :proto), EchoAgent (existing AG-UI echo), both mounted on the same Netty embedded server on port 8080 (/agui and /agentik); A2A stays on its own CIO engine on 8081. EchoProtoAgent smoke-tested end-to-end against :server: all 11 endpoints, including live SSE delivery of StartResponse/AppendText/End event triplets and Agent-level Created/Deleted events. Design notes pinned in: * agentik/IRC-QUESTIONS.md — closed 13-item checklist for the upcoming :irc-server transport (channel = conversation, CTCP for structural events, draft/chathistory for backfill, ImageStore side-channel, etc). * docs/ARCHITECTURE.md — overall layout snapshot. |