Skip to content

Commit 4e98e90

Browse files
committed
Actually parse the thought contents
1 parent c628ffe commit 4e98e90

File tree

1 file changed

+63
-32
lines changed
  • firebase-ai/src/main/kotlin/com/google/firebase/ai/type

1 file changed

+63
-32
lines changed

firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,17 @@ public interface Part {
3737

3838
/** Represents text or string based data sent to and received from requests. */
3939
public class TextPart
40-
private constructor(public val text: String, public override val isThought: Boolean = false) :
40+
internal constructor(public val text: String, public override val isThought: Boolean = false) :
4141
Part {
4242

4343
public constructor(text: String) : this(text, false)
4444

45-
@Serializable internal data class Internal(val text: String) : InternalPart
45+
@Serializable
46+
internal data class Internal(val text: String, val thought: Boolean? = null) : InternalPart
4647
}
4748

4849
public class CodeExecutionResultPart
49-
private constructor(
50+
internal constructor(
5051
public val outcome: String,
5152
public val output: String,
5253
public override val isThought: Boolean = false
@@ -62,13 +63,14 @@ private constructor(
6263
@Serializable
6364
internal data class CodeExecutionResult(
6465
@SerialName("outcome") val outcome: String,
65-
val output: String
66+
val output: String,
67+
val thought: Boolean? = null
6668
)
6769
}
6870
}
6971

7072
public class ExecutableCodePart
71-
private constructor(
73+
internal constructor(
7274
public val language: String,
7375
public val code: String,
7476
public override val isThought: Boolean = false
@@ -83,7 +85,8 @@ private constructor(
8385
@Serializable
8486
internal data class ExecutableCode(
8587
@SerialName("language") val language: String,
86-
val code: String
88+
val code: String,
89+
val thought: Boolean? = null
8790
)
8891
}
8992
}
@@ -95,15 +98,16 @@ private constructor(
9598
* @param image [Bitmap] to convert into a [Part]
9699
*/
97100
public class ImagePart
98-
private constructor(public val image: Bitmap, public override val isThought: Boolean = false) :
101+
internal constructor(public val image: Bitmap, public override val isThought: Boolean = false) :
99102
Part {
100103

101104
public constructor(image: Bitmap) : this(image, false)
102105

103106
internal fun toInlineDataPart() =
104107
InlineDataPart(
105108
android.util.Base64.decode(encodeBitmapToBase64Jpeg(image), BASE_64_FLAGS),
106-
"image/jpeg"
109+
"image/jpeg",
110+
isThought
107111
)
108112
}
109113

@@ -115,7 +119,7 @@ private constructor(public val image: Bitmap, public override val isThought: Boo
115119
* [Vertex AI documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/send-multimodal-prompts#media_requirements)
116120
*/
117121
public class InlineDataPart
118-
private constructor(
122+
internal constructor(
119123
public val inlineData: ByteArray,
120124
public val mimeType: String,
121125
public override val isThought: Boolean = false
@@ -128,7 +132,11 @@ private constructor(
128132
InternalPart {
129133

130134
@Serializable
131-
internal data class InlineData(@SerialName("mimeType") val mimeType: String, val data: Base64)
135+
internal data class InlineData(
136+
@SerialName("mimeType") val mimeType: String,
137+
val data: Base64,
138+
val thought: Boolean? = null
139+
)
132140
}
133141
}
134142

@@ -141,7 +149,7 @@ private constructor(
141149
* have a matching `id` field.
142150
*/
143151
public class FunctionCallPart
144-
private constructor(
152+
internal constructor(
145153
public val name: String,
146154
public val args: Map<String, JsonElement>,
147155
public val id: String? = null,
@@ -162,7 +170,8 @@ private constructor(
162170
internal data class FunctionCall(
163171
val name: String,
164172
val args: Map<String, JsonElement?>? = null,
165-
val id: String? = null
173+
val id: String? = null,
174+
val thought: Boolean? = null
166175
)
167176
}
168177
}
@@ -175,7 +184,7 @@ private constructor(
175184
* @param id Matching `id` for a [FunctionCallPart], if one was provided.
176185
*/
177186
public class FunctionResponsePart
178-
private constructor(
187+
internal constructor(
179188
public val name: String,
180189
public val response: JsonObject,
181190
public val id: String? = null,
@@ -196,12 +205,13 @@ private constructor(
196205
internal data class FunctionResponse(
197206
val name: String,
198207
val response: JsonObject,
199-
val id: String? = null
208+
val id: String? = null,
209+
val thought: Boolean? = null
200210
)
201211
}
202212

203213
internal fun toInternalFunctionCall(): Internal.FunctionResponse {
204-
return Internal.FunctionResponse(name, response, id)
214+
return Internal.FunctionResponse(name, response, id, isThought)
205215
}
206216
}
207217

@@ -214,7 +224,7 @@ private constructor(
214224
* [Firebase documentation](https://firebase.google.com/docs/vertex-ai/input-file-requirements).
215225
*/
216226
public class FileDataPart
217-
private constructor(
227+
internal constructor(
218228
public val uri: String,
219229
public val mimeType: String,
220230
public override val isThought: Boolean = false
@@ -229,6 +239,7 @@ private constructor(
229239
internal data class FileData(
230240
@SerialName("mime_type") val mimeType: String,
231241
@SerialName("file_uri") val fileUri: String,
242+
val thought: Boolean? = null
232243
)
233244
}
234245
}
@@ -270,31 +281,36 @@ internal object PartSerializer :
270281

271282
internal fun Part.toInternal(): InternalPart {
272283
return when (this) {
273-
is TextPart -> TextPart.Internal(text)
284+
is TextPart -> TextPart.Internal(text, isThought)
274285
is ImagePart ->
275286
InlineDataPart.Internal(
276-
InlineDataPart.Internal.InlineData("image/jpeg", encodeBitmapToBase64Jpeg(image))
287+
InlineDataPart.Internal.InlineData("image/jpeg", encodeBitmapToBase64Jpeg(image), isThought)
277288
)
278289
is InlineDataPart ->
279290
InlineDataPart.Internal(
280291
InlineDataPart.Internal.InlineData(
281292
mimeType,
282-
android.util.Base64.encodeToString(inlineData, BASE_64_FLAGS)
293+
android.util.Base64.encodeToString(inlineData, BASE_64_FLAGS),
294+
isThought
283295
)
284296
)
285297
is FunctionCallPart ->
286-
FunctionCallPart.Internal(FunctionCallPart.Internal.FunctionCall(name, args, id))
298+
FunctionCallPart.Internal(FunctionCallPart.Internal.FunctionCall(name, args, id, isThought))
287299
is FunctionResponsePart ->
288300
FunctionResponsePart.Internal(
289-
FunctionResponsePart.Internal.FunctionResponse(name, response, id)
301+
FunctionResponsePart.Internal.FunctionResponse(name, response, id, isThought)
290302
)
291303
is FileDataPart ->
292-
FileDataPart.Internal(FileDataPart.Internal.FileData(mimeType = mimeType, fileUri = uri))
304+
FileDataPart.Internal(
305+
FileDataPart.Internal.FileData(mimeType = mimeType, fileUri = uri, thought = isThought)
306+
)
293307
is ExecutableCodePart ->
294-
ExecutableCodePart.Internal(ExecutableCodePart.Internal.ExecutableCode(language, code))
308+
ExecutableCodePart.Internal(
309+
ExecutableCodePart.Internal.ExecutableCode(language, code, isThought)
310+
)
295311
is CodeExecutionResultPart ->
296312
CodeExecutionResultPart.Internal(
297-
CodeExecutionResultPart.Internal.CodeExecutionResult(outcome, output)
313+
CodeExecutionResultPart.Internal.CodeExecutionResult(outcome, output, isThought)
298314
)
299315
else ->
300316
throw com.google.firebase.ai.type.SerializationException(
@@ -312,28 +328,43 @@ private fun encodeBitmapToBase64Jpeg(input: Bitmap): String {
312328

313329
internal fun InternalPart.toPublic(): Part {
314330
return when (this) {
315-
is TextPart.Internal -> TextPart(text)
331+
is TextPart.Internal -> TextPart(text, thought ?: false)
316332
is InlineDataPart.Internal -> {
317333
val data = android.util.Base64.decode(inlineData.data, BASE_64_FLAGS)
318334
if (inlineData.mimeType.contains("image")) {
319-
ImagePart(decodeBitmapFromImage(data))
335+
ImagePart(decodeBitmapFromImage(data), inlineData.thought ?: false)
320336
} else {
321-
InlineDataPart(data, inlineData.mimeType)
337+
InlineDataPart(data, inlineData.mimeType, inlineData.thought ?: false)
322338
}
323339
}
324340
is FunctionCallPart.Internal ->
325341
FunctionCallPart(
326342
functionCall.name,
327343
functionCall.args.orEmpty().mapValues { it.value ?: JsonNull },
328-
functionCall.id
344+
functionCall.id,
345+
functionCall.thought ?: false
329346
)
330347
is FunctionResponsePart.Internal ->
331-
FunctionResponsePart(functionResponse.name, functionResponse.response, functionResponse.id)
332-
is FileDataPart.Internal -> FileDataPart(fileData.mimeType, fileData.fileUri)
348+
FunctionResponsePart(
349+
functionResponse.name,
350+
functionResponse.response,
351+
functionResponse.id,
352+
functionResponse.thought ?: false
353+
)
354+
is FileDataPart.Internal ->
355+
FileDataPart(fileData.mimeType, fileData.fileUri, fileData.thought ?: false)
333356
is ExecutableCodePart.Internal ->
334-
ExecutableCodePart(executableCode.language, executableCode.code)
357+
ExecutableCodePart(
358+
executableCode.language,
359+
executableCode.code,
360+
executableCode.thought ?: false
361+
)
335362
is CodeExecutionResultPart.Internal ->
336-
CodeExecutionResultPart(codeExecutionResult.outcome, codeExecutionResult.output)
363+
CodeExecutionResultPart(
364+
codeExecutionResult.outcome,
365+
codeExecutionResult.output,
366+
codeExecutionResult.thought ?: false
367+
)
337368
else ->
338369
throw com.google.firebase.ai.type.SerializationException(
339370
"Unsupported part type \"${javaClass.simpleName}\" provided. This model may not be supported by this SDK."

0 commit comments

Comments
 (0)