@file:OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.gradle.api.artifacts.ConfigurationContainer plugins { alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.shadow) } // CI-флаг: при -PskipVectorMemory=true :memory-vector не подключается как // зависимость — нужно для CI runner'а (text-embedding-kmp ещё не опубликован // в caffeine). Подробнее см. memory-vector/build.gradle.kts. val skipVectorMemory: Boolean = (project.findProperty("skipVectorMemory") == "true") || System.getenv("SKIP_VECTOR_MEMORY") == "1" kotlin { jvmToolchain(21) // Отключаем auto-propagation Apple-таргетов от KMP-зависимостей (`:proto`, // `:server`, `:agent-toolsets` имеют Apple-варианты). `:standalone` JVM-only, // Apple таргеты не нужны и ломают резолюцию `:message-store-api` в appleMain // (он KMP jvm+linuxX64+mingwX64 без Apple). // @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) // applyDefaultHierarchyTemplate { } jvm { binaries { executable { mainClass.set("pw.binom.agentik.standalone.MainKt") } } } sourceSets { commonMain.dependencies { implementation(project(":proto")) implementation(project(":server")) implementation(project(":message-store-api")) implementation(project(":message-log-api")) implementation(project(":working-memory-api")) // Commons implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) // litert-kmp: контракт (commonMain) api(libs.litert.api) // litert-openai: JVM-реализация implementation(libs.litert.openai) } jvmMain.dependencies { // Парсер и загрузчик скилов (YAML frontmatter + markdown body). implementation(project(":skills")) // Долговременная память (Hermes-style MD-бэкенд) + хранилище истории. implementation(project(":memory-api")) implementation(project(":memory-md")) if (!skipVectorMemory) { implementation(project(":memory-vector")) } implementation(project(":message-store-api")) implementation(project(":working-memory-api")) implementation(project(":storage-ksqlite")) // Новый единый канал событий агента — заменил старые // `agentEvents: MutableSharedFlow` и per-conv `ConversationEvents._flow`. // Bounded tail + auto-TTL, generic CommonEvent envelope. implementation(project(":event-store")) implementation(project(":event-store-in-memory")) implementation(project(":agent-toolsets")) // Generic LLM-side tools (LlmReflector, SkillMiner, LlmMemoryReviewer, // ContextCompactor, парсеры/промпты). Вынесены из :standalone. implementation(project(":llm-tools")) // Generic MCP-bridge (McpConfig, McpRegistry, McpLiteToolAdapter). // Вынесен из :standalone — generic мост между MCP-SDK и LiteTool. implementation(project(":mcp-bridge")) // litert-google: встроенный LiteRT-LM движок, нужен только на runtime runtimeOnly(libs.litert.google) // Ktor server (для :server facade + a2aServer) // Используем CIO вместо Netty — он KMP (jvm + linuxX64/ios/...), нам нужен // для будущей native-сборки; на JVM работает идентично для нашего сценария. implementation(libs.ktor.server.core) implementation(libs.ktor.server.sse) implementation(libs.ktor.server.cio) implementation(libs.ktor.server.content.negotiation) implementation(libs.ktor.serialization.kotlinx.json) // Транспортные фасады (A2A остаётся заготовкой; на v1 не подключается в Main.kt — // см. docs/ARCHITECTURE.md §3). implementation(libs.a2a.server) // MCP (Model Context Protocol) клиент — подключение внешних/внутренних MCP-серверов implementation(libs.mcp.sdk.client) implementation(libs.ktor.client.core) implementation(libs.ktor.client.cio) implementation(libs.ktor.client.content.negotiation) implementation(libs.ktor.serialization.kotlinx.json) // Логирование: kotlin-logging (тонкая обёртка slf4j-api) + logback-classic // (binding для JVM; без него slf4j-api NOP-логирует и не падает). implementation(libs.kotlin.logging) implementation(libs.logback.classic) } commonTest.dependencies { implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlin.test) } jvmTest.dependencies { implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) implementation(libs.kotlin.test) // Ktor test engine для smoke-тестов HTTP implementation(libs.ktor.server.test.host) } } } // --- Fatjar (uberjar) --- // // :standalone — KMP jvm-only бэкенд. Стандартный KMP `jvmJar` содержит только // наши классы и требует подтянуть все зависимости на runtime через classpath. // Для дистрибутива нужен self-contained `*-all.jar`, который содержит и наш // код, и runtime classpath. Делается это Shadow-плагином: // // 1. shadowJar расширяет `jvmJar` (через from(tasks.named("jvmJar"))) // 2. Добавляет все артефакты из jvmRuntimeClasspath как `zipTree` // 3. Корректно сливает META-INF/services (через ServiceFileTransformer) // 4. Прописывает Main-Class в манифесте // // Результат: `build/libs/standalone-*-all.jar` запускается как // java -jar standalone-0.1.0-all.jar // // KMP-сборка под ios/lin/macos не затрагивается — задача живёт только в jvm. // Shadow 8.x не авторегистрирует shadowJar в KMP-проектах (нет стандартного `jar`), // поэтому регистрируем явно через tasks.register. // // В Gradle 9 KGP подменяет `configurations` на сгенерированный dependency-accessor // (он возвращает List), поэтому используем прямой доступ к Project API. val shadowJarTask = tasks.register("shadowJar") { archiveBaseName.set("standalone") archiveClassifier.set("all") description = "Self-contained fatjar with all runtime dependencies bundled." group = "build" from(tasks.named("jvmJar")) // javaClass-каст через Any? чтобы вытащить реальный ConfigurationContainer // из любого типа, который сейчас прикидывается `configurations`. val cc = try { @Suppress("UNCHECKED_CAST") configurations as org.gradle.api.artifacts.ConfigurationContainer } catch (_: ClassCastException) { // KGP-generated dependency accessor; обходим через raw project. @Suppress("UNCHECKED_CAST") (project as org.gradle.api.Project).configurations as org.gradle.api.artifacts.ConfigurationContainer } from(cc.getByName("jvmRuntimeClasspath")) mergeServiceFiles() duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { attributes["Main-Class"] = "pw.binom.agentik.standalone.MainKt" attributes["Implementation-Title"] = "agentik-standalone" attributes["Implementation-Version"] = project.version.toString() } includeEmptyDirs = false }