diff --git a/firebase-ai/api.txt b/firebase-ai/api.txt index b979c361b52..43ee5243d6a 100644 --- a/firebase-ai/api.txt +++ b/firebase-ai/api.txt @@ -210,6 +210,14 @@ package com.google.firebase.ai.type { property public final java.util.List citations; } + public final class CodeExecutionResultPart implements com.google.firebase.ai.type.Part { + ctor public CodeExecutionResultPart(String outcome, String output); + method public String getOutcome(); + method public String getOutput(); + property public final String outcome; + property public final String output; + } + public final class Content { ctor public Content(String? role = "user", java.util.List parts); ctor public Content(java.util.List parts); @@ -277,6 +285,14 @@ package com.google.firebase.ai.type { property public final int width; } + public final class ExecutableCodePart implements com.google.firebase.ai.type.Part { + ctor public ExecutableCodePart(String language, String code); + method public String getCode(); + method public String getLanguage(); + property public final String code; + property public final String language; + } + public final class FileDataPart implements com.google.firebase.ai.type.Part { ctor public FileDataPart(String uri, String mimeType); method public String getMimeType(); diff --git a/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt b/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt index 3e3e90636e5..5cabe593bd6 100644 --- a/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt +++ b/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt @@ -135,7 +135,8 @@ public class LiveServerToolCall(public val functionCalls: List toolCall.functionCalls.map { functionCall -> FunctionCallPart( name = functionCall.name, - args = functionCall.args.orEmpty().mapValues { it.value ?: JsonNull } + args = functionCall.args.orEmpty().mapValues { it.value ?: JsonNull }, + id = functionCall.id ) } ) diff --git a/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt b/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt index 1f84c18a53b..6e584fe2a50 100644 --- a/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt +++ b/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt @@ -152,7 +152,6 @@ internal constructor( while (true) { val response = session.incoming.tryReceive() if (response.isClosed || !startedReceiving.get()) break - response .getOrNull() ?.let { @@ -161,7 +160,6 @@ internal constructor( ) } ?.let { emit(it.toPublic()) } - yield() } } diff --git a/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt b/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt index bcc7e14b657..5f3e1bc12a9 100644 --- a/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt +++ b/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt @@ -39,6 +39,35 @@ public class TextPart(public val text: String) : Part { @Serializable internal data class Internal(val text: String) : InternalPart } +public class CodeExecutionResultPart(public val outcome: String, public val output: String) : Part { + + @Serializable + internal data class Internal( + @SerialName("codeExecutionResult") val codeExecutionResult: CodeExecutionResult + ) : InternalPart { + + @Serializable + internal data class CodeExecutionResult( + @SerialName("outcome") val outcome: String, + val output: String + ) + } +} + +public class ExecutableCodePart(public val language: String, public val code: String) : Part { + + @Serializable + internal data class Internal(@SerialName("executableCode") val executableCode: ExecutableCode) : + InternalPart { + + @Serializable + internal data class ExecutableCode( + @SerialName("language") val language: String, + val code: String + ) + } +} + /** * Represents image data sent to and received from requests. The image is converted client-side to * JPEG encoding at 80% quality before being sent to the server. @@ -176,6 +205,8 @@ internal object PartSerializer : val jsonObject = element.jsonObject return when { "text" in jsonObject -> TextPart.Internal.serializer() + "executableCode" in jsonObject -> ExecutableCodePart.Internal.serializer() + "codeExecutionResult" in jsonObject -> CodeExecutionResultPart.Internal.serializer() "functionCall" in jsonObject -> FunctionCallPart.Internal.serializer() "functionResponse" in jsonObject -> FunctionResponsePart.Internal.serializer() "inlineData" in jsonObject -> InlineDataPart.Internal.serializer() @@ -207,6 +238,12 @@ internal fun Part.toInternal(): InternalPart { ) is FileDataPart -> FileDataPart.Internal(FileDataPart.Internal.FileData(mimeType = mimeType, fileUri = uri)) + is ExecutableCodePart -> + ExecutableCodePart.Internal(ExecutableCodePart.Internal.ExecutableCode(language, code)) + is CodeExecutionResultPart -> + CodeExecutionResultPart.Internal( + CodeExecutionResultPart.Internal.CodeExecutionResult(outcome, output) + ) else -> throw com.google.firebase.ai.type.SerializationException( "The given subclass of Part (${javaClass.simpleName}) is not supported in the serialization yet." @@ -241,6 +278,10 @@ internal fun InternalPart.toPublic(): Part { is FunctionResponsePart.Internal -> FunctionResponsePart(functionResponse.name, functionResponse.response, functionResponse.id) is FileDataPart.Internal -> FileDataPart(fileData.mimeType, fileData.fileUri) + is ExecutableCodePart.Internal -> + ExecutableCodePart(executableCode.language, executableCode.code) + is CodeExecutionResultPart.Internal -> + CodeExecutionResultPart(codeExecutionResult.outcome, codeExecutionResult.output) else -> throw com.google.firebase.ai.type.SerializationException( "Unsupported part type \"${javaClass.simpleName}\" provided. This model may not be supported by this SDK."