Каркас сборки десктопа: KMP (jvm), Compose Multiplatform, зависимости из :agentik
- только jvm-таргет; composite includeBuild("../agentik")
- mavenLocal() первым в репозиториях: локальные публикации перекрывают Nexus
- Compose 1.7.3 + Kotlin 2.4.20, compose.desktop.currentOs
- вендоренный markdown (ru.otpbank.ai:markdown), mic-api/asr-vosk/vad
- gradle wrapper, gradle.properties, .gitignore (локальный тулинг)
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
// `binaries {}` — экспериментальный API KGP, `compose.uiTest` — экспериментальная
|
||||
// библиотека Compose (компилятор требует явного opt-in в скрипте).
|
||||
@file:OptIn(
|
||||
org.jetbrains.compose.ExperimentalComposeLibrary::class,
|
||||
org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class,
|
||||
)
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
// UI — Compose Multiplatform. `kotlin-compose` — компиляторный плагин
|
||||
// (@Composable), `compose` — рантайм/DSL (`compose.material3`, ...).
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.compose)
|
||||
// `application` plugin (он тянет `java`) **несовместим** с
|
||||
// `kotlin("multiplatform")` — проверка `checkKotlinGradlePluginConfigurationErrors`
|
||||
// падает на старте. В KMP executable настраивается через
|
||||
// `kotlin { jvm { binaries { executable { ... } } } }` ниже — он создаёт
|
||||
// `run` / `installDist` / jar с mainClass автоматически.
|
||||
}
|
||||
|
||||
group = "pw.binom.agentik.desktop"
|
||||
version = "0.1.0-SNAPSHOT"
|
||||
|
||||
kotlin {
|
||||
// KMP-проект с **одной** целью — JVM. Структура каталогов
|
||||
// `src/jvmMain/kotlin/...` (а не `src/main/kotlin/...`), чтобы при
|
||||
// расширении целями (iOS / Native) не пришлось переименовывать.
|
||||
// Toolchain 21 = как у agentik (`:client` / `:journal-ksqlite` тоже
|
||||
// jvmToolchain(21)) — иначе Gradle тащит второй JDK через foojay.
|
||||
jvmToolchain(21)
|
||||
jvm {
|
||||
binaries {
|
||||
executable {
|
||||
mainClass.set("pw.binom.agentik.desktop.MainKt")
|
||||
// `jvmJar` создаётся автоматически; `run` запускает main.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
jvmMain.dependencies {
|
||||
// --- Agentik (композитная сборка, см. settings.gradle.kts) ---
|
||||
// `AgentikAgent` / `wrapWithLocalConversationCache` /
|
||||
// `ReconnectingOutbox` — всё что нужно для клиента уже здесь.
|
||||
implementation(libs.agentik.client)
|
||||
// Контракты `MessageRecord` / `ConversationRecord` /
|
||||
// `MutableJournalStore` / `MutableConversationStore`.
|
||||
implementation(libs.agentik.journal.api)
|
||||
// SQLite-реализации обоих store'ов из `:journal-ksqlite`.
|
||||
implementation(libs.agentik.journal.ksqlite)
|
||||
// `Event` / `AgentEvent` / `CommonEvent` / `OutboxStore` (live-поток).
|
||||
implementation(libs.agentik.outbox.api)
|
||||
// `Agent` / `Conversation` / `AgentInfo` / `Content` — proto-контракты.
|
||||
implementation(libs.agentik.proto)
|
||||
|
||||
// --- Ktor client engine (передаётся в AgentikAgent как engineFactory) ---
|
||||
implementation(libs.ktor.client.cio)
|
||||
|
||||
// --- Низкоуровневая БД (`SQLiteConnection` / prepared statements) ---
|
||||
implementation(libs.ksqlite)
|
||||
|
||||
// --- Kotlinx ---
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
|
||||
// --- UI: Compose Multiplatform (markdown-рендер + экраны) ---
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.ui)
|
||||
implementation(compose.material3)
|
||||
implementation(compose.materialIconsExtended)
|
||||
// Оконный рантайм Compose Desktop (Window/application) + skiko
|
||||
// для текущей ОС. Без него `compose.ui.window.application` не резолвится.
|
||||
implementation(compose.desktop.currentOs)
|
||||
|
||||
// --- Markdown: парсер (ru.otpbank.ai:markdown, обёртка над
|
||||
// org.intellij.markdown) + вендоренный рендер сегментов. ---
|
||||
implementation(libs.markdown)
|
||||
|
||||
// --- Голос: микрофон → VAD → распознавание (см. MIC-ASR-SEARCH.md).
|
||||
// JVM-реализация микрофона — `javax.sound.sampled`. ---
|
||||
implementation(libs.mic.api)
|
||||
implementation(libs.asr.api)
|
||||
implementation(libs.asr.vosk)
|
||||
implementation(libs.vad)
|
||||
|
||||
// --- Логирование ---
|
||||
implementation(libs.kotlin.logging)
|
||||
implementation(libs.logback.classic)
|
||||
}
|
||||
|
||||
jvmTest.dependencies {
|
||||
implementation(libs.kotlin.test)
|
||||
implementation(libs.kotlinx.coroutines.test)
|
||||
implementation(libs.junit.jupiter)
|
||||
// Оффскрин-рендер Compose: прогоняем реальную тему/компоненты
|
||||
// в ImageComposeScene и проверяем палитру по пикселям.
|
||||
implementation(compose.uiTest)
|
||||
// E2E: поднимаем настоящий `:server` (HTTP/SSE) поверх
|
||||
// in-memory-агента и гоняем десктопный стек по живому протоколу.
|
||||
implementation(libs.agentik.server)
|
||||
implementation(libs.agentik.journal.inmemory)
|
||||
implementation(libs.agentik.outbox.inmemory)
|
||||
implementation(libs.ktor.server.cio)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// `application` плагин в KMP конфликтует с `kotlin("multiplatform")`,
|
||||
// executable объявлен выше в `kotlin { jvm { binaries { executable { ... } } } }`
|
||||
// — он автоматически создаёт `run` / `installDist` и jvmJar.
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
// Один JVM на тест-класс. Причина не в изоляции данных, а в нативных
|
||||
// библиотеках: skiko (Compose) и C++-стек распознавания (Vosk/Kaldi, ONNX)
|
||||
// конфликтуют по порядку загрузки — тот, кто грузится ПОСЛЕ skiko, падает
|
||||
// с SIGSEGV. Классы, которым нужен нативный ASR, обязаны прогревать его
|
||||
// первым делом (VoiceNative / RealSpeechIT), а skiko-классы — не мешать им.
|
||||
// forkEvery = 1 гарантирует, что порядок классов не важен.
|
||||
forkEvery = 1
|
||||
// Изолируем данные приложения от реального $HOME разработчика:
|
||||
// AppPaths читает AGENTIK_DESKTOP_HOME, тесты пишут в build/.
|
||||
environment(
|
||||
"AGENTIK_DESKTOP_HOME",
|
||||
layout.buildDirectory.dir("test-agentik-home").get().asFile.absolutePath,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user