Skip to content

Commit

Permalink
fix: Expected start of the object '{', but had 'EOF' instead at path:…
Browse files Browse the repository at this point in the history
… - chatgpt will return empty line.

 - need check if json or not - fun isJsonResponse(line: String) = line.startsWith("{") && line.endsWith("}")
  • Loading branch information
hanrw committed Jun 4, 2024
1 parent 1b36506 commit c829fa5
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ interface HttpRequester {
* Note: [HttpResponse] instance shouldn't be passed outside of [block].
*/
suspend fun <T : Any> streamRequest(
info: TypeInfo,
builder: HttpRequestBuilder.() -> Unit,
block: suspend (response: HttpResponse) -> T,
)
Expand All @@ -43,7 +42,7 @@ inline fun <reified T : Any> HttpRequester.streamRequest(
noinline builder: HttpRequestBuilder.() -> Unit,
): Flow<T> {
return flow {
streamRequest(typeInfo<T>(), builder) { response ->
streamRequest(builder) { response ->
streamEventsFrom(response)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ suspend inline fun <reified T> FlowCollector<T>.streamEventsFrom(response: HttpR
STREAM_PREFIX
)
)
isJsonResponse(line) -> json.decodeFromString(line) // Ollama - response is a json object without `data:` prefix

else -> json.decodeFromString(line) // Ollama - response is a json object without `data:` prefix
// If ChatGPT returns an empty line or any other response, continue to the next line.
else -> break
}
emit(value)
}
Expand All @@ -42,4 +44,6 @@ fun json(): Json {

fun isStreamResponse(line: String) = line.startsWith(STREAM_PREFIX)

fun endStreamResponse(line: String) = line.startsWith(STREAM_END_TOKEN)
fun endStreamResponse(line: String) = line.startsWith(STREAM_END_TOKEN)

fun isJsonResponse(line: String) = line.startsWith("{") && line.endsWith("}")
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class DefaultHttpRequester(private val httpClient: HttpClient) : HttpRequester {
}

override suspend fun <T : Any> streamRequest(
info: TypeInfo,
builder: HttpRequestBuilder.() -> Unit,
block: suspend (response: HttpResponse) -> T,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ class DefaultHttpRequesterTest : AutoCloseKoinTest() {
}

@Test
fun `should throw RateLimitException when status code is unknown`(): Unit = runBlocking {
val mockResponse = """
fun `should throw RateLimitException when status code is unknown`(): Unit =
runBlocking {
val mockResponse = """
{
"error": {
"code": null,
Expand All @@ -104,19 +105,19 @@ class DefaultHttpRequesterTest : AutoCloseKoinTest() {
""".trimIndent()


httpClient = mockHttpClient(
mockResponse = mockResponse,
mockHttpStatusCode = HttpStatusCode.InternalServerError
)
httpClient = mockHttpClient(
mockResponse = mockResponse,
mockHttpStatusCode = HttpStatusCode.InternalServerError
)

val requester = HttpRequester.default(httpClient)
val requester = HttpRequester.default(httpClient)

assertThrows<UnknownAPIException> {
requester.performRequest<String> {
url(path = "/v1/chat/completions")
assertThrows<UnknownAPIException> {
requester.performRequest<String> {
url(path = "/v1/chat/completions")
}
}
}
}

@Test
fun `should throw RateLimitException when status code is 429`(): Unit = runBlocking {
Expand Down Expand Up @@ -198,6 +199,21 @@ class DefaultHttpRequesterTest : AutoCloseKoinTest() {
}
}

@Test
fun `should not return chat stream completion response when it's empty response`() = runTest {

httpClient = mockHttpClient("")

val requester = DefaultHttpRequester(httpClient)

requester.streamRequest<StreamResponse> {
url(path = "/v1/chat/completions")
}.test(timeout = 10.seconds) {
expectNoEvents()
cancel()
}
}

@Test
fun `should return chat stream completion response`() = runTest {
val mockResponse = StreamResponse("some-content")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tddworks.openai.api.chat.api

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
Expand All @@ -17,6 +18,8 @@ data class ChatCompletionChunk(
val `object`: String,
val created: Long,
val model: String,
@SerialName("system_fingerprint")
val systemFingerprint: String? = null,
val choices: List<ChatChunk>,
) {
companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import kotlin.jvm.JvmInline
data class ChatChunk(
val delta: ChatDelta,
val index: Int,
val logprobs: String? = null,
@SerialName("finish_reason")
val finishReason: String?,
) {
Expand Down

0 comments on commit c829fa5

Please sign in to comment.