From fdfe6c7b5dd2a94681b065c44509eaff7e2b4c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Garci=CC=81a?= Date: Tue, 11 Feb 2025 15:21:00 +0100 Subject: [PATCH] Patch method `submitStreamingToolOutput` --- .../internal/api/RunsApi.kt | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/openai-client/src/commonMain/kotlin/com.aallam.openai.client/internal/api/RunsApi.kt b/openai-client/src/commonMain/kotlin/com.aallam.openai.client/internal/api/RunsApi.kt index 7dfa17ce..0f694af0 100644 --- a/openai-client/src/commonMain/kotlin/com.aallam.openai.client/internal/api/RunsApi.kt +++ b/openai-client/src/commonMain/kotlin/com.aallam.openai.client/internal/api/RunsApi.kt @@ -15,8 +15,7 @@ import io.ktor.client.call.* import io.ktor.client.request.* import io.ktor.http.* import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.onEach +import kotlinx.serialization.json.* internal class RunsApi(val requester: HttpRequester) : Runs { override suspend fun createRun(threadId: ThreadId, request: RunRequest, requestOptions: RequestOptions?): Run { @@ -123,7 +122,11 @@ internal class RunsApi(val requester: HttpRequester) : Runs { return requester .performSse { url(path = "${ApiPath.Threads}/${threadId.id}/runs/${runId.id}/submit_tool_outputs") - setBody(mapOf("tool_outputs" to output, "stream" to true)) + val bodyObject = buildJsonObject { + put("tool_outputs", output.toJsonArray()) + put("stream", JsonPrimitive(true)) + } + setBody(bodyObject) contentType(ContentType.Application.Json) accept(ContentType.Text.EventStream) beta("assistants", 2) @@ -132,6 +135,18 @@ internal class RunsApi(val requester: HttpRequester) : Runs { } } + // Need to manual convert to JsonObject as Kotlinx serialization fails when multiple data types are present in the same collection + // java.lang.IllegalStateException: Serializing collections of different element types is not yet supported. Selected serializers: [kotlin.collections.ArrayList, kotlin.Boolean] + // https://youtrack.jetbrains.com/issue/KTOR-3063/Support-serializing-collections-of-different-element-types + private fun List.toJsonArray(): JsonArray = buildJsonArray { + forEach { add(it.toJsonObject()) } + } + + private fun ToolOutput.toJsonObject(): JsonObject = buildJsonObject { + toolCallId?.id?.let { put("tool_call_id", JsonPrimitive(it)) } + output?.let { put("output", JsonPrimitive(it)) } + } + override suspend fun cancel(threadId: ThreadId, runId: RunId, requestOptions: RequestOptions?): Run { return requester.perform { it.post {