server: convert :server from kotlin-jvm to KMP with all 9 targets

Punkt 6 of NATIVE-COMPATIBILITY.md. Mirrors :proto's target set:
jvm + macosX64 + macosArm64 + iosX64 + iosArm64 + iosSimulatorArm64
+ linuxX64 + linuxArm64 + mingwX64.

All 9 targets compile via './gradlew :server:assemble'.

No blockers: the only deps (ktor-server-core, ktor-server-content-
negotiation, ktor-serialization-kotlinx-json, kotlinx-coroutines-core,
kotlinx-serialization-json) ship native variants for every target.
kotlin.time.Instant was already in use (not the deprecated
kotlinx.datetime.Instant), so no proto-side work needed.

Only API change vs the JVM version: respondTextWriter (JVM-only) ->
respondBytesWriter + writeStringUtf8 (KMP, ByteWriteChannel API).
SSE behaviour is identical ('data: <json>\n\n' chunks flushed as
they arrive).

Verification: :standalone:jvmTest 44/44 green after the migration
(ChatAgent 15, LlmConfig 6, McpConfig 8, McpRegistry 4, Persistence 11).
No call-site changes needed; :standalone picks up the new :server
jvm artifact automatically.
This commit is contained in:
2026-09-13 18:28:12 +03:00
parent adab112b5b
commit 5b4c8ceae8
6 changed files with 52 additions and 31 deletions
@@ -6,13 +6,14 @@ import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.call
import io.ktor.server.request.receive
import io.ktor.server.response.respond
import io.ktor.server.response.respondBytesWriter
import io.ktor.server.response.respondText
import io.ktor.server.response.respondTextWriter
import io.ktor.server.routing.Route
import io.ktor.server.routing.delete
import io.ktor.server.routing.get
import io.ktor.server.routing.patch
import io.ktor.server.routing.post
import io.ktor.utils.io.writeStringUtf8
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.serialization.KSerializer
@@ -147,13 +148,13 @@ private suspend fun <T> ApplicationCall.streamJsonSse(
serializer: KSerializer<T>,
json: Json = agentikJson,
) {
respondTextWriter(contentType = ContentType.Text.EventStream) {
respondBytesWriter(contentType = ContentType.Text.EventStream) {
flow.catch { /* клиент отвалился — глушим */ }
.collect { value ->
val s = json.encodeToString(serializer, value)
write("data: ")
write(s)
write("\n\n")
writeStringUtf8("data: ")
writeStringUtf8(s)
writeStringUtf8("\n\n")
flush()
}
}