Skip to content

Conversation

nathanfallet
Copy link
Contributor

@nathanfallet nathanfallet commented Jul 31, 2025

I added iOS native targets

Fixes #177


Type of the change

  • New feature
  • Bug fix
  • Documentation fix
  • Tests improvement
  • New KMP platforms

Checklist for all pull requests

  • The pull request has a description of the proposed change
  • I read the Contributing Guidelines before opening the pull request
  • The pull request uses develop as the base branch
  • Tests for the changes have been added
  • All new and existing tests passed
Additional steps for pull requests adding a new feature
  • An issue describing the proposed change exists
  • The pull request includes a link to the issue
  • The change was discussed and approved in the issue
  • Docs have been added / updated

@nathanfallet nathanfallet changed the title adding more multiplatform Add support for more multiplatform targets (Apple, Linux, Windows) Jul 31, 2025
@nathanfallet
Copy link
Contributor Author

It's ready for review now.

@kagg886
Copy link

kagg886 commented Jul 31, 2025

wow,that's good.

if we have multi engine in context(like okhttp),does we have some api to choose it?

@nathanfallet
Copy link
Contributor Author

There is the engineFactory function for Ollama, but for other things I think it chooses in what's available (it works with Js engine already so it should work the same with other platforms)

@nathanfallet
Copy link
Contributor Author

I also made a PR in kotlin-logging, so if I can have additional watchos targets directly I take them.
In my KMP libraries (like kourier or kdriver) I'm using the KtorSimpleLogger because it does the work for me without any additional librairies 👀

Copy link
Contributor

@devcrocod devcrocod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add only the following ios targets: iosArm64, iosX64, iosSimulatorArm64.

Also, have you tested it locally with ios?
Do we need to change the workflow for ios?

@nathanfallet
Copy link
Contributor Author

nathanfallet commented Jul 31, 2025

The more target we support, the more users can use the library everywhere. I always try to support as much targets as possible to be the more KMP possible.
I remember when I started to work with KMP, I was sometimes limited because some libraries were not supporting all iOS or watchOS targets, so I could not use it in my app. I don't want anyone to experience this again.

Also, there is not much work since Ktor does all the work of multiplatform abstraction, so we maintain only common code.

@nathanfallet
Copy link
Contributor Author

nathanfallet commented Jul 31, 2025

Imagine I want to build a Desktop Native Windows app. Why shouldn't I be allowed to use Koog?

So it perfectly makes sense as a library to be available on as many platforms as possible.

@nathanfallet
Copy link
Contributor Author

The latest version of Kotlin Logging was published with the Kotlin 2.2.0 compiler so it does not work. Do I rollback and skip some watchOS targets? Or do I upgrade the project to use Kotlin 2.2.0 too?

@devcrocod
Copy link
Contributor

@nathanfallet
I understand and support the idea of adding more targets. However, Koog is a framework, and with every new target comes a certain level of responsibility and maintenance overhead

Also, there is not much work since Ktor does all the work of multiplatform abstraction, so we maintain only common code.

That’s not entirely accurate, we rely on other dependencies as well. In addition, supporting more targets complicates the @Tool, which currently has a JVM-only implementation

Linux is particularly useful to use the library with Ktor Native on any Linux or Docker environment. Because Ktor Native is way smaller in binary size and memory consumption than Ktor JVM.

Imagine I want to build a Desktop Native Windows app. Why shouldn't I be allowed to use Koog?

In practice, all of these use cases are already covered by the JVM target. Also, Compose doesn’t support these native targets

Another important point is that Kotlin officially treats Linux as Tier 2 and Windows as Tier 3 platforms. This means Kotlin does not test mingwX64 on CI, and we might encounter compiler issues when building Koog for Windows. To manage this risk, we would need to introduce a tiered support model within Koog as well. So that users have a clear understanding of what’s officially supported and what may be unstable. Otherwise, we’d tie our release stability to the state of Kotlin’s native targets, which could negatively impact our main JVM releases

Therefore, I suggest that in this PR we proceed only with iOS support. For the other native targets, we can open a separate issue to discuss support levels, the process for adding and releasing them, and associated maintenance implications

@nathanfallet
Copy link
Contributor Author

nathanfallet commented Aug 1, 2025

Okay, I'll comment out the other targets, so we can uncomment them later when we want to (but they will be ready)

EDIT: I made the change. I kept the targets inside comments so we can easily get them again later when we want, as well as the xxxMain folders (appleMain is used for iOS, but other are unused for now but will be later so we don't have to rewrite it)

@nathanfallet nathanfallet changed the title Add support for more multiplatform targets (Apple, Linux, Windows) Add support for iOS targets Aug 1, 2025
@nathanfallet
Copy link
Contributor Author

I will take a look about adding tests for iOS (configuring GH Actions to run on macOS)

@nathanfallet
Copy link
Contributor Author

@devcrocod What do you think now? Also, I launched ios tests on macOS, but I might need to move some tests from jvmTest to commonTest, because otherwise they won't run on iOS (but strange thing since js & wasmjs are already added but they don't have any tests 🤷‍♂️). At least I can confirm iOS is compiling correctly from them succeeding.

Copy link
Contributor

@devcrocod devcrocod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it’s better to clean up the code from other targets to avoid confusion for other users and contributors

The main question is about testing, I hope @aozherelyeva can help with that part

@@ -98,6 +98,10 @@ jobs:
if: matrix.os != 'ubuntu-latest'
run: ./gradlew jvmTest --continue

- name: iosX64Test with Gradle Wrapper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the iosSimulatorArm64 tests should also be added, right?

@aozherelyeva How will this affect our current testing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only failing test is OpenAIEmbedderTest, but I'm not sure whether it's a critical issue, as JVM target is running for it without a problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure we should run them for the iOS target. @nathanfallet WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only failing test is OpenAIEmbedderTest

In my opinion, this is an issue because the provider code has no platform-specific dependencies and should run on any target

I also checked that macos-latest refers to macOS 14 on arm64, so iosX64Test won’t run on it. gradle will just skip it, since for arm devices it should be iosSimulatorArm64

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yes, I also see that iosX64Test is being skipped... good point!
@nathanfallet could you take a look at the tests?

Comment on lines 44 to 54
linuxMain {
dependencies {
api(libs.ktor.client.curl)
}
}

mingwMain {
dependencies {
api(libs.ktor.client.winhttp)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to remove all such places

It’s strange that this doesn’t lead to an exception

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If use native/, it will cover all cases with Kotlin/Native

Or do you think we’ll need to split it into specific targets in the future?

Comment on lines 19 to 40
// Tiers are in accordance with <https://kotlinlang.org/docs/native-target-support.html>
// Tier 1
//macosX64()
//macosArm64()
iosSimulatorArm64()
iosX64()

// Tier 2
//linuxX64()
//linuxArm64()
//watchosSimulatorArm64()
//watchosX64()
//watchosArm32()
//watchosArm64()
//tvosSimulatorArm64()
//tvosX64()
//tvosArm64()
iosArm64()

// Tier 3
//mingwX64()
//watchosDeviceArm64()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think leaving commented-out code is a good practice
At the very least, adding the targets to the build script in the future won’t be a difficult task

Comment on lines 40 to 50
linuxMain {
dependencies {
api(libs.ktor.client.curl)
}
}

mingwMain {
dependencies {
api(libs.ktor.client.winhttp)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please drop it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to get rid of the explicit/actual here, since ktor can choose the required engine automatically
However, if you decide to keep it, you’ll also need to remove it for linux and mingw, or place it under native/

@nathanfallet
Copy link
Contributor Author

nathanfallet commented Aug 12, 2025

@aozherelyeva @devcrocod I think we're good! I only kept changes related to iOS (linux and mingw changes were totally removed) and I also updated CI to run iOS tests for arm instead of previous ones.

@nathanfallet
Copy link
Contributor Author

Wait, iosSimulatorArm64Test fails. But I noticed there is no such tests for js and wasm. So this might be a bigger issue related to all non jvm platforms...

@devcrocod
Copy link
Contributor

I found the problem:
the OpenAIEmbedderTest tests are failing because in these tests the MockOpenAIEmbedderClient inherits from OpenAIClient(""). In Kotlin/Native this causes an error due to top-level initialization of the httpClient. If we change the inheritance to LLMEmbeddingProvider, like in the case of Ollama, it fixes the issue. However, in that case I’m not entirely sure about the correctness of the tests.

@aozherelyeva could you please advise?

@aozherelyeva
Copy link
Contributor

Thanks to @devcrocod, the problem is found and already solved. So now the iosSimulatorArm64Test target shall fully pass! 😃

@devcrocod devcrocod force-pushed the adding-more-multiplatform branch from b8b3546 to 600d415 Compare August 19, 2025 19:43
Copy link
Contributor

@aozherelyeva aozherelyeva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM test-wise!

@nathanfallet
Copy link
Contributor Author

I guess it's good now. So excited for the multiplatform area to start!

@devcrocod devcrocod force-pushed the adding-more-multiplatform branch from 600d415 to 9a604fe Compare August 24, 2025 19:21
@devcrocod devcrocod force-pushed the adding-more-multiplatform branch from 9a604fe to 735d298 Compare August 25, 2025 16:34
@devcrocod devcrocod self-requested a review August 25, 2025 18:32
Copy link
Contributor

@devcrocod devcrocod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finally 🎉

@devcrocod devcrocod merged commit 8779986 into JetBrains:develop Aug 25, 2025
6 of 7 checks passed
@aozherelyeva
Copy link
Contributor

Congrats! 🚀 🔥

@kagg886
Copy link

kagg886 commented Aug 26, 2025

Congratulations!🎆🎆🎆

@nicolasf
Copy link

Hi!

I can't build Koog on my Mac with these changes. I'm building from 8b313b0.
I didn't have time to debug this yet, but commenting out the ios targets fixes the issue for me.

Here's the build error:

> Task :integration-tests:generateMetadataFileForIosArm64Publication FAILED

[Incubating] Problems report is available at: file:///Users/nicolas/Projects/koog/build/reports/problems/problems-report.html

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':integration-tests:generateMetadataFileForIosArm64Publication'.
> java.io.FileNotFoundException: /Users/nicolas/Projects/koog/integration-tests/build/libs/integration-tests-iosArm64Main-0.3.0.1.klib (No such file or directory)

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/8.14.1/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD FAILED in 4s
125 actionable tasks: 8 executed, 4 from cache, 113 up-to-date

Might be some issue on my side, but I thought it was worth sharing.

@nathanfallet
Copy link
Contributor Author

@nicolasf Your error mentions 0.3.0.1 which is not publicly available (you can find it on https://packages.jetbrains.team/maven/p/grazi/grazie-platform-public/ai/koog/koog-agents/ but you need to add the repository to your gradle settings). But I don't get how it is related to the iOS target.

@nicolasf
Copy link

@nathanfallet
The error happens when building koog itself locally from the develop branch.
I forgot to add the command I'm using, which explains why it shows as 0.3.0.1:

BRANCH_KOOG_IS_RELEASING_FROM=develop TC_BUILD_COUNTER=1 ./gradlew publishToMavenLocal

The error will also happen without the env vars, but for 0.3.0 instead.

If no one else has issues building it, it might be something on my environment.

Thanks.

@ychescale9
Copy link

have the iOS targets been published to maven central?

@nathanfallet nathanfallet deleted the adding-more-multiplatform branch September 2, 2025 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support iOS target
7 participants