Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agents/agents-tools/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ plugins {
}

kotlin {
jvm()
sourceSets {
commonMain {
dependencies {
Expand Down
7 changes: 1 addition & 6 deletions agents/agents-utils/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,14 @@ plugins {
}

kotlin {
jvm()
sourceSets {
commonMain {
dependencies {
implementation(libs.kotlinx.serialization.json)
}
}

commonTest {
dependencies {
implementation(project(":test-utils"))
}
}

jvmTest {
dependencies {
implementation(kotlin("test-junit5"))
Expand Down
47 changes: 23 additions & 24 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ subprojects {
}

subprojects {
tasks.matching { it.name.endsWith("Annotations") && it.name.startsWith("extract") }
.configureEach { enabled = false }

afterEvaluate {
val releaseTypedef = layout.buildDirectory
.file("intermediates/annotations_typedef_file/release/extractReleaseAnnotations/typedefs.txt")
.get()
.asFile
if (!releaseTypedef.exists()) {
releaseTypedef.parentFile.mkdirs()
releaseTypedef.writeText("")
}
val debugTypedef = layout.buildDirectory
.file("intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt")
.get()
.asFile
if (!debugTypedef.exists()) {
debugTypedef.parentFile.mkdirs()
debugTypedef.writeText("")
}
}

extensions.configure<KtlintExtension> {
outputToConsole = true
coloredOutput = true
Expand Down Expand Up @@ -220,37 +242,14 @@ dependencies {
dokka(project(":agents:agents-test"))
dokka(project(":agents:agents-tools"))
dokka(project(":agents:agents-utils"))
dokka(project(":embeddings:embeddings-base"))
dokka(project(":embeddings:embeddings-llm"))
dokka(project(":koog-ktor"))
dokka(project(":koog-spring-boot-starter"))
dokka(project(":prompt:prompt-cache:prompt-cache-files"))
dokka(project(":prompt:prompt-cache:prompt-cache-model"))
dokka(project(":prompt:prompt-cache:prompt-cache-redis"))
dokka(project(":prompt:prompt-executor:prompt-executor-cached"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-anthropic-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-bedrock-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-deepseek-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-google-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-mistralai-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-ollama-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-openai-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-openai-client-base"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-openrouter-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-dashscope-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-llms"))
dokka(project(":prompt:prompt-executor:prompt-executor-llms-all"))
dokka(project(":prompt:prompt-executor:prompt-executor-clients:prompt-executor-litertlm-client"))
dokka(project(":prompt:prompt-executor:prompt-executor-model"))
dokka(project(":prompt:prompt-llm"))
dokka(project(":prompt:prompt-markdown"))
dokka(project(":prompt:prompt-model"))
dokka(project(":prompt:prompt-processor"))
dokka(project(":prompt:prompt-structure"))
dokka(project(":prompt:prompt-tokenizer"))
dokka(project(":prompt:prompt-xml"))
dokka(project(":rag:rag-base"))
dokka(project(":rag:vector-storage"))
dokka(project(":utils"))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@file:OptIn(ExperimentalWasmDsl::class)

import ai.koog.gradle.publish.maven.configureJvmJarManifest
import ai.koog.gradle.tests.configureTests
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import jetbrains.sign.GpgSignSignatoryProvider
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl

Expand All @@ -15,38 +15,8 @@ plugins {
}

kotlin {
// Tiers are in accordance with <https://kotlinlang.org/docs/native-target-support.html>
// Tier 1
iosSimulatorArm64()
iosX64()

// Tier 2
iosArm64()

// Tier 3

// Android
androidTarget()

// jvm & js
jvm {
configureTests()
}

js(IR) {
browser {
binaries.library()
}

configureTests()
}

wasmJs {
browser()
nodejs()
binaries.library()
}

sourceSets {
androidUnitTest {
dependencies {
Expand All @@ -70,7 +40,27 @@ android {
}
}

configureJvmJarManifest("jvmJar")
extensions.configure<LibraryAndroidComponentsExtension>("androidComponents") {
beforeVariants(selector().all()) { variantBuilder ->
val booleanType = Boolean::class.javaPrimitiveType
if (booleanType != null) {
runCatching {
variantBuilder.javaClass.getMethod("setEnableUnitTest", booleanType).invoke(variantBuilder, false)
}
runCatching {
variantBuilder.javaClass.getMethod("setUnitTestEnabled", booleanType).invoke(variantBuilder, false)
}
runCatching {
variantBuilder.javaClass.getMethod("setEnableAndroidTest", booleanType).invoke(variantBuilder, false)
}
runCatching {
variantBuilder.javaClass.getMethod("setAndroidTestEnabled", booleanType).invoke(variantBuilder, false)
}
}
}
}

tasks.findByName("jvmJar")?.let { configureJvmJarManifest("jvmJar") }

val javadocJar by tasks.registering(Jar::class) {
archiveClassifier.set("javadoc")
Expand Down
9 changes: 7 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[versions]
acp = "0.3.0"
agp = "8.12.3"
agp = "8.13.2"
annotations = "26.0.2-1"
assertj = "3.27.6"
awaitility = "4.3.0"
aws-sdk-kotlin = "1.5.16"
litertlm = "0.8.0"
dokka = "2.1.0"
exposed = "0.61.0"
h2 = "2.4.240"
Expand All @@ -14,7 +15,7 @@ jetsign = "45.47"
junit = "5.8.2"
knit = "0.5.0"
kotest = "6.0.7"
kotlin = "2.2.21"
kotlin = "2.3.0"
kotlinx-coroutines = "1.10.2"
kotlinx-datetime = "0.6.2"
kotlinx-io = "0.7.0"
Expand Down Expand Up @@ -46,6 +47,8 @@ mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.
assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" }
awaitility = { module = "org.awaitility:awaitility-kotlin", version.ref = "awaitility" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" }
kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
kotest-assertions-json = { module = "io.kotest:kotest-assertions-json", version.ref = "kotest" }
Expand Down Expand Up @@ -114,6 +117,8 @@ aws-sdk-kotlin-bedrock = { module = "aws.sdk.kotlin:bedrock", version.ref = "aws
aws-sdk-kotlin-bedrockruntime = { module = "aws.sdk.kotlin:bedrockruntime", version.ref = "aws-sdk-kotlin" }
aws-sdk-kotlin-sts = { module = "aws.sdk.kotlin:sts", version.ref = "aws-sdk-kotlin" }
android-tools-gradle = { module = "com.android.tools.build:gradle", version.ref = "agp" }
litertlm-jvm = { module = "com.google.ai.edge.litertlm:litertlm-jvm", version.ref = "litertlm" }
litertlm-android = { module = "com.google.ai.edge.litertlm:litertlm-android", version.ref = "litertlm" }

# Spring
spring-boot-bom = { module = "org.springframework.boot:spring-boot-dependencies", version.ref = "spring-boot" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins {
}

kotlin {
jvm()
sourceSets {
commonMain {
dependencies {
Expand All @@ -29,7 +30,6 @@ kotlin {
}
commonTest {
dependencies {
implementation(project(":test-utils"))
}
}
jvmTest {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# LiteRT-LM native binaries
# These should be obtained separately (see natives/README.md)

# Native library staging directory
natives/**
!natives/**/.gitkeep

# Copied native libraries in source sets
src/androidMain/jniLibs/**
!src/androidMain/jniLibs/**/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import ai.koog.gradle.publish.maven.Publishing.publishToMaven

plugins {
id("ai.kotlin.multiplatform")
// id("litertlm-natives-convention") // Disabled - natives come from Maven dependency
alias(libs.plugins.kotlin.serialization)
}

group = rootProject.group
version = rootProject.version

// Check if Kotlin version is >= 2.3 for experimental features
val kotlinVersionString = libs.versions.kotlin.get()
val kotlinMajorMinor = kotlinVersionString.split(".").take(2).joinToString(".")
val isKotlin23OrHigher = try {
val (major, minor) = kotlinMajorMinor.split(".").map { it.toInt() }
major > 2 || (major == 2 && minor >= 3)
} catch (e: Exception) {
false
}

kotlin {
// LiteRT-LM has full implementation on JVM/Android, stubs on other platforms
// The convention plugin handles all target declarations
jvm()

// Enable Kotlin 2.3+ experimental features when available
if (isKotlin23OrHigher) {
compilerOptions {
// @MustUseReturnValues checker - warns when return values are ignored
freeCompilerArgs.add("-Xreturn-value-checker=check")
// Explicit backing fields - allows field keyword in property accessors
freeCompilerArgs.add("-Xexplicit-backing-fields")
}
}

sourceSets {
commonMain {
dependencies {
api(project(":agents:agents-tools"))
api(project(":prompt:prompt-llm"))
api(project(":prompt:prompt-model"))
api(project(":prompt:prompt-executor:prompt-executor-model"))
api(project(":prompt:prompt-executor:prompt-executor-clients"))

api(libs.kotlinx.datetime)
api(libs.kotlinx.coroutines.core)
implementation(libs.oshai.kotlin.logging)
}
}

jvmMain {
dependencies {
// LiteRT-LM JVM dependency
// This is marked as compileOnly - users must add this dependency to their project
// at runtime when they want to use the LiteRT-LM provider.
// See: https://github.com/google-ai-edge/LiteRT-LM
compileOnly(libs.litertlm.jvm)
}
}

androidMain {
dependencies {
// LiteRT-LM Android dependency
// This is marked as compileOnly - users must add this dependency to their project
// at runtime when they want to use the LiteRT-LM provider.
// Native libraries are bundled separately via the litertlm-natives-convention plugin.
compileOnly(libs.litertlm.android)
}
}

commonTest {
dependencies {
implementation(project(":test-utils"))
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.test)
}
}

jvmTest {
dependencies {
// Add LiteRT-LM for testing (when available)
implementation(libs.litertlm.jvm)
implementation(libs.mockk)
implementation(libs.kotest.assertions.core)
implementation(libs.junit.jupiter.api)
runtimeOnly(libs.junit.jupiter.engine)
}
}
}

explicitApi()
}

// Configure Android native library source directory
android {
sourceSets {
getByName("main") {
jniLibs.srcDirs("src/androidMain/jniLibs")
}
}
}

publishToMaven()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# LiteRT-LM model files (too large for git, download separately)
*.litertlm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ai.koog.prompt.executor.litertlm.client

import ai.koog.prompt.executor.clients.LLMClient

/**
* Creates a LiteRT-LM client for Android platform.
*
* Note: Android support requires the litertlm-android dependency and native libraries.
* This is a placeholder - full Android implementation coming soon.
*/
public actual fun createLiteRTLMClient(config: LiteRTLMClientConfig): LLMClient {
throw UnsupportedOperationException(
"LiteRT-LM Android support requires litertlm-android dependency. " +
"Add 'com.google.ai.edge.litertlm:litertlm-android' to your dependencies."
)
}

/**
* LiteRT-LM is supported on Android (requires additional setup).
*/
public actual fun isLiteRTLMSupported(): Boolean = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ai.koog.prompt.executor.litertlm.client

import ai.koog.prompt.executor.clients.LLMClient

/**
* LiteRT-LM is not available on Apple platforms (iOS/macOS).
*/
public actual fun createLiteRTLMClient(config: LiteRTLMClientConfig): LLMClient {
throw UnsupportedOperationException(
"LiteRT-LM is not supported on Apple platforms. " +
"LiteRT-LM only supports JVM and Android."
)
}

/**
* LiteRT-LM is not supported on Apple platforms.
*/
public actual fun isLiteRTLMSupported(): Boolean = false
Loading