Skip to content

Commit

Permalink
Make common parse lenient (google-gemini#179)
Browse files Browse the repository at this point in the history
Per [b/346812151](https://b.corp.google.com/issues/346812151),

This updates the json parser in common to be lenient in its decoding.
Otherwise, it can not properly decode json literals such as:
```json
{
   "result": true
}
```

A test has been added to track this change as well.
  • Loading branch information
daymxn authored and PatilShreyas committed Sep 21, 2024
1 parent b4b4aba commit 8ce5d39
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions .changes/common/distribution-doll-drop-bridge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"type":"PATCH","changes":["Make JSON decoding lenient. This should fix issues with JSON literals."]}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import kotlinx.serialization.json.Json
internal val JSON = Json {
ignoreUnknownKeys = true
prettyPrint = false
isLenient = true
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.google.ai.client.generativeai.common.shared.FunctionCallPart
import com.google.ai.client.generativeai.common.shared.HarmCategory
import com.google.ai.client.generativeai.common.shared.TextPart
import com.google.ai.client.generativeai.common.util.goldenUnaryFile
import com.google.ai.client.generativeai.common.util.shouldNotBeNullOrEmpty
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.collections.shouldNotBeEmpty
import io.kotest.matchers.nulls.shouldNotBeNull
Expand Down Expand Up @@ -313,4 +314,21 @@ internal class UnarySnapshotTests {
callPart.functionCall.args["season"] shouldBe null
}
}

@Test
fun `function call contains json literal`() =
goldenUnaryFile("success-function-call-json-literal.json") {
withTimeout(testTimeout) {
val response = apiController.generateContent(textGenerateContentRequest("prompt"))
val content = response.candidates.shouldNotBeNullOrEmpty().first().content
val callPart =
content.let {
it.shouldNotBeNull()
it.parts.shouldNotBeEmpty()
it.parts.first().shouldBeInstanceOf<FunctionCallPart>()
}

callPart.functionCall.args["current"] shouldBe "true"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import dev.shreyaspatil.ai.client.generativeai.common.RequestOptions
import dev.shreyaspatil.ai.client.generativeai.common.server.Candidate
import dev.shreyaspatil.ai.client.generativeai.common.shared.Content
import dev.shreyaspatil.ai.client.generativeai.common.shared.TextPart
import io.kotest.matchers.collections.shouldNotBeEmpty
import io.kotest.matchers.nulls.shouldNotBeNull
import io.ktor.client.engine.mock.MockEngine
import io.ktor.client.engine.mock.respond
import io.ktor.http.HttpHeaders
Expand Down Expand Up @@ -183,3 +185,14 @@ internal fun loadGoldenFile(path: String): File = loadResourceFile("golden-files

/** Loads a file from the test resources directory. */
internal fun loadResourceFile(path: String) = File("src/test/resources/$path")

/**
* Ensures that a collection is neither null or empty.
*
* Syntax sugar for [shouldNotBeNull] and [shouldNotBeEmpty].
*/
inline fun <reified T : Any> Collection<T>?.shouldNotBeNullOrEmpty(): Collection<T> {
shouldNotBeNull()
shouldNotBeEmpty()
return this
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"candidates": [
{
"content": {
"parts": [
{
"functionCall": {
"name": "functionName",
"args": {
"original_title": "String",
"current": true
}
}
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0,
"safetyRatings": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"probability": "NEGLIGIBLE"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"probability": "NEGLIGIBLE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"probability": "NEGLIGIBLE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"probability": "NEGLIGIBLE"
}
]
}
],
"usageMetadata": {
"promptTokenCount": 774,
"candidatesTokenCount": 4176,
"totalTokenCount": 4950
}
}

0 comments on commit 8ce5d39

Please sign in to comment.