cad4d5fc7c
Убрана зависимость 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) — зелёные.
11 KiB
11 KiB
Совместимость с native (linuxX64) — чеклист
Цель: :standalone собирается и запускается как linuxX64 executable (и потенциально
остальные нативные таргеты KMP). Текущее состояние — JVM-only executable на
runJvm-таске.
Формат: - N. [ ] — задача; - N. [x] — выполнена; - N. [-] — отменена/не нужна.
Решения (что выбрали и почему) — курсивом внизу пункта.
Блок 1. Подготовка (уже сделана или тривиальная)
-
- Замена
java.util.UUIDна KMP-stdlib (kotlin.uuid.Uuid). HelperIds.new(prefix)вstandalone/src/commonMain/.../persistence/Ids.kt, три call-site (ChatAgent,ChatConversation,SqliteWorkingMemoryStore). Коммитe816d8d.
- Замена
-
- HTTP-движок:
ktor-server-netty→ktor-server-cio. Netty — JVM-only; CIO — KMP (jvm + linuxX64 + ios/...). Каталог-эntry Netty оставлен вlibs.versions.tomlна случай отката. Коммитe816d8d.
- HTTP-движок:
Блок 2. Библиотеки litert-kmp (наши)
-
litert-api: добавитьlinuxX64()вkotlin{}. Сейчас толькоandroidTarget() + jvm(). commonMain уже KMP-ready (толькоkotlinx-coroutines-core). Объём: одна строка вlitert-api/build.gradle.kts, одинlitert-api-linuxx64-артефакт публикуется в Nexus.
-
litert-openai: добавитьlinuxX64()вkotlin{}. Та же история. commonMain deps (ktor-client-core,ktor-client-cio,kotlinx-serialization-json) — все KMP с готовыми linuxX64-артефактами. Объём: одна строка + проверить, что Android-only фичи (если есть) изолированы вandroidMain(сейчас модуль не имеетandroidMain-специфичного кода). Каталог-записьlitert-openai-jvm→ переименовать вlitert-openai(чтобы Linux-таргет подтягивал-linuxx64-вариант автоматически, не нужно ручногоwhen target).
-
- [-]
litert-google: linuxX64 — невозможно. Upstream-блокер: Google публикуетlitertlm-android(AAR с.so) иlitertlm-jvm(fat-jar с.soдля linux/mac/win JVM), но НЕ нативногоlitertlm-linuxx64. Без правки upstream LiteRT-LM KMP-враппер для linuxX64 не напишется. Варианты: (a) выкинутьlitert-googleна linuxX64 (backend=google→ отказ); (b) альтернативный движок (llama.cpp через JNI/Kotlin/Native); (c) upstream PR вlitertlm. Решение: (a) для v1 linuxX64 — упасть с понятной ошибкойLlmBackend.GOOGLE is not supported on this platformвместо reflection-fallback на JVM .so, который на linuxX64 не сработает бы.
- [-]
Блок 3. Наш :server модуль
-
- Переписать
:serverсkotlin("jvm")наkotlin("multiplatform"). Все 9 целей сборки (jvm + macosX64 + macosArm64 + iosX64 + iosArm64 + iosSimulatorArm64 + linuxX64 + linuxArm64 + mingwX64) собираются./gradlew :server:assembleбез ошибок. Блокеров нет: Ktorktor-server-{core,sse,cio,content-negotiation}иktor-io(дляByteWriteChannel.writeStringUtf8) есть в KMP-вариантах под все цели;kotlin.time.Instantуже использовался. Единственное изменение по сравнению с JVM-версией:respondTextWriter(JVM-only) →respondBytesWriter+writeStringUtf8(KMP, тот жеByteWriteChannelAPI). Источники переехалиsrc/main/kotlin/...→src/commonMain/kotlin/....:standalone:jvmTest44/44 зелёные после миграции.
- Переписать
Блок 4. Наш :proto модуль
-
:proto: убратьkotlinx-datetimeapi-dep, оставитьkotlin.time.Instant. Источник уже был наkotlin.time.Instant(мигрирован ранее), ноkotlinx-datetimeоставался в gradle как мёртваяapi-зависимость. Удалено:
api(libs.kotlinx.datetime)изproto/build.gradle.ktsimplementation(libs.kotlinx.datetime)изstandalone/build.gradle.kts[versions] kotlinx-datetimeи[libraries] kotlinx-datetimeизgradle/libs.versions.tomlkotlin.time.Instantдоступен во всех KMP-целях без opt-in../gradlew :server:assemble+:standalone:jvmTest44/44 — зелёные.
Блок 5. SQLDelight — нативный драйвер
-
sqlite-driver(JVM/JDBC) →native-driverдля linuxX64. В jvmMain: оставитьsqlite-driver(JDBC overjava.sql.DriverManager). В linuxX64Main: добавитьnative-driver— KMP driver поверх cinterop сlibsqlite3(нужен-lsqlite3linker-флаг илиSQLiteBundleизco.touchlab:sqliterдля бандлинга). СоздатьSqliteStores- нейтральный интерфейс хранилищ (он уже есть вcommonMain), разделитьjvmMain/SqliteStores.ktиlinuxX64Main/SqliteStoresNative.kt— оба реализуют одинcommonMain-интерфейс. Объём: ~150 строк (новыйSqliteStoresNative.kt+ gradle wiring). Решение по бандлу: использоватьSQLiteBundleизco.touchlab:sqliter(KMP-обёртка, тянет свой libsqlite) — без зависимости от системного libsqlite3, бинарь работает на любом linux.
-
- Тесты SQLite переписать на commonTest +
expect/actualобёртку.inMemory()-открытие вnative-driverиспользует другой API (нет JDBC:memory:). Объём: одинexpect fun openInMemory()в commonMain + дваactual(JDBCjdbc:sqlite::memory:/ native-driver нативный API).
- Тесты SQLite переписать на commonTest +
Блок 6. Внешние либы (a2a-server) — наши
-
- AGUI убран из проекта. catalog-entries
agui-api/agui-client/agui-server,[versions] aguiиimplementation(libs.agui.server)в:standaloneудалены — AGUI больше не нужен (см. Memory #3675 и переписанныйdocs/ARCHITECTURE.md). AGUI-фасад был stateless request/response, а agentik переходит на свой stateful протокол:proto/:server.
- AGUI убран из проекта. catalog-entries
-
a2a-server: JVM-only → KMP. Per Memory #3561 — JVM-only (client/server; shared уже KMP). Без native-таргета весь стек A2A недоступен на linuxX64. Объём: переписать наmultiplatform, выделить engine-нейтральную маршрутизацию. Альтернатива: на linuxX64 не подключать a2a-server вообще (только:server-фасад). Решение отложено — зависит от того, нужен ли нативный MCP-юзер-кейс вообще подключаться к A2A.
Блок 7. :standalone — добавить native target
-
standalone/build.gradle.kts: добавитьlinuxX64()иlinuxX64Main/linuxX64Testsource-sets. ВlinuxX64Main::server(после п.6),litert-openai(после п.4),litert-api(после п.3),ktor-server-cio(engine),ktor-client-cio,kotlin-sdk-client(MCP — KMP, готов),kotlinx-io(KMP, готов). Исключитьlitert-google(п.5) иa2a-server(п.11) из linuxX64Main.
-
Main.kt: разделить наcommonMain(бизнес-логика: создание ChatAgent, MCP, LlmConfig) +jvmMain/linuxX64Main(выбор engine, embeddedServer). embeddedServer(CIO, …) — один и тот же код на обеих платформах, KMP-нейтрален. Главное отличие —SqliteStores.open()и обработка GOOGLE-бэкенда на linuxX64 (fail-fast).
Блок 8. Тесты и CI
-
linuxX64Testsource-set. Покрыть те же 44 теста на native: должен зелёный прогон через./gradlew :standalone:linuxX64Test. SQLDelight-тесты на native требуютlibsqlite3/SQLiteBundleна машине (CI-linux предоставляет).
-
- Smoke e2e на linuxX64. Запустить
./gradlew :standalone:runLinuxX64локально, проверитьPOST /agentik/conversations→ 201, цикл с реальным LLM через OpenAI backend; убедиться что LiteRT-LM GOOGLE не подключается (отказ с понятной ошибкой).
- Smoke e2e на linuxX64. Запустить
Блок 9. Дистрибуция native-бинаря
-
runLinuxX64-таска через KMP binaries DSL. После добавленияlinuxX64()KMP генерирует её автоматически — нужно только убедиться чтоbinaries { executable { mainClass.set("pw.binom.agentik.standalone.MainKt") } }работает для linuxX64 (по аналогии с уже настроеннымrunJvm).
-
- Дистрибутив
.tar/.zip/AppImage/Docker. KMPassembleDistдля linuxX64 делает tar.gz/zip. Для прод-дистрибуции — Docker-образ (FROM gcr.io/distroless/cc) или AppImage. Объём: ~50 строк Dockerfile + GitHub Action.
- Дистрибутив
Что НЕ блокирует linuxX64 (закрыто или тривиально)
kotlinx-coroutines-core— KMP linuxX64 ✓kotlinx-serialization-json— KMP linuxX64 ✓kotlinx-io— KMP linuxX64 (используется в MCP stdio-transport) ✓kotlin-sdk-client(MCP) — KMP full targets ✓ktor-server-core,ktor-server-sse,ktor-server-cio— KMP linuxX64 ✓ktor-client-core,ktor-client-cio— KMP linuxX64 ✓pw.binom.uuid— отсутствует в проекте (используемkotlin.uuid) ✓
Жёсткие блокеры (не обойти без upstream-работы)
litertlm-jvm→ нуженlitertlm-nativeот Google (см. п.5)a2a-serverJVM-only (см. п.11) — нужно переписать или явно не подключать