Files
subochev 960cd60120 Каркас сборки десктопа: 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 (локальный тулинг)
2026-09-28 10:07:52 +03:00

129 lines
6.8 KiB
Kotlin
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// `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,
)
}