Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions firebase-ai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

- [feature] Added support for code execution.
- [feature] Introduced `MissingPermissionsException`, which is thrown when the necessary permissions
have not been granted by the user.
- [feature] Added helper functions to `LiveSession` to allow developers to track the status of the
Expand All @@ -12,8 +13,7 @@
model's internal reasoning process.
- [fixed] Fixed an issue causing the accessor methods in `GenerateContentResponse` to throw an
exception when the response contained no candidates.
- [changed] Added better description for requests which fail due to the Gemini API not being
configured.
- [changed] Added better description for requests which fail due to the Gemini API not being configured.

* [changed] Added a `dilation` parameter to `ImagenMaskReference.generateMaskAndPadForOutpainting`
(#7260)
Expand Down
3 changes: 3 additions & 0 deletions firebase-ai/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ package com.google.firebase.ai.type {

public final class CodeExecutionResultPart implements com.google.firebase.ai.type.Part {
ctor public CodeExecutionResultPart(String outcome, String output);
method public boolean executionSucceeded();
method public String getOutcome();
method public String getOutput();
method public boolean isThought();
Expand Down Expand Up @@ -1199,12 +1200,14 @@ package com.google.firebase.ai.type {
}

public final class Tool {
method public static com.google.firebase.ai.type.Tool codeExecution();
method public static com.google.firebase.ai.type.Tool functionDeclarations(java.util.List<com.google.firebase.ai.type.FunctionDeclaration> functionDeclarations);
method public static com.google.firebase.ai.type.Tool googleSearch(com.google.firebase.ai.type.GoogleSearch googleSearch = com.google.firebase.ai.type.GoogleSearch());
field public static final com.google.firebase.ai.type.Tool.Companion Companion;
}

public static final class Tool.Companion {
method public com.google.firebase.ai.type.Tool codeExecution();
method public com.google.firebase.ai.type.Tool functionDeclarations(java.util.List<com.google.firebase.ai.type.FunctionDeclaration> functionDeclarations);
method public com.google.firebase.ai.type.Tool googleSearch(com.google.firebase.ai.type.GoogleSearch googleSearch = com.google.firebase.ai.type.GoogleSearch());
}
Expand Down
21 changes: 16 additions & 5 deletions firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ internal constructor(
) : InternalPart
}

/**
* Represents the code execution result from the model.
* @property outcome The result of the execution.
* @property output The stdout from the code execution, or an error message if it failed.
* @property isThought Indicates whether the response is a thought.
*/
public class CodeExecutionResultPart
internal constructor(
public val outcome: String,
Expand All @@ -63,21 +69,26 @@ internal constructor(

public constructor(outcome: String, output: String) : this(outcome, output, false, null)

/** Indicates if the code execution was successful */
public fun executionSucceeded(): Boolean = (outcome.lowercase() == "outcome_ok")

@Serializable
internal data class Internal(
@SerialName("codeExecutionResult") val codeExecutionResult: CodeExecutionResult,
val thought: Boolean? = null,
val thoughtSignature: String? = null
) : InternalPart {

@Serializable
internal data class CodeExecutionResult(
@SerialName("outcome") val outcome: String,
val output: String
)
@Serializable internal data class CodeExecutionResult(val outcome: String, val output: String)
}
}

/**
* Represents the code that is executed by the model.
* @property language The programming language of the code.
* @property code The source code to be executed.
* @property isThought Indicates whether the response is a thought.
*/
public class ExecutableCodePart
internal constructor(
public val language: String,
Expand Down
16 changes: 12 additions & 4 deletions firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Tool.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import kotlinx.serialization.json.JsonObject
public class Tool
internal constructor(
internal val functionDeclarations: List<FunctionDeclaration>?,
internal val googleSearch: GoogleSearch?
internal val googleSearch: GoogleSearch?,
internal val codeExecution: JsonObject?,
) {
internal fun toInternal() =
Internal(
functionDeclarations?.map { it.toInternal() } ?: emptyList(),
googleSearch = this.googleSearch?.toInternal()
googleSearch = this.googleSearch?.toInternal(),
codeExecution = this.codeExecution
)
@Serializable
internal data class Internal(
Expand All @@ -49,7 +51,13 @@ internal constructor(
*/
@JvmStatic
public fun functionDeclarations(functionDeclarations: List<FunctionDeclaration>): Tool {
return Tool(functionDeclarations, null)
return Tool(functionDeclarations, null, null)
}

/** Creates a [Tool] instance that allows the model to use Code Execution. */
@JvmStatic
public fun codeExecution(): Tool {
return Tool(null, null, JsonObject(emptyMap()))
}

/**
Expand All @@ -70,7 +78,7 @@ internal constructor(
*/
@JvmStatic
public fun googleSearch(googleSearch: GoogleSearch = GoogleSearch()): Tool {
return Tool(null, googleSearch)
return Tool(null, googleSearch, null)
}
}
}
10 changes: 10 additions & 0 deletions firebase-ai/src/test/java/com/google/firebase/ai/type/ToolTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal class ToolTest {

tool.googleSearch.shouldNotBeNull()
tool.functionDeclarations.shouldBeNull()
tool.codeExecution.shouldBeNull()
}

@Test
Expand All @@ -36,5 +37,14 @@ internal class ToolTest {

tool.functionDeclarations?.first() shouldBe functionDeclaration
tool.googleSearch.shouldBeNull()
tool.codeExecution.shouldBeNull()
}

@Test
fun `codeExecution() creates a tool with code execution`() {
val tool = Tool.codeExecution()
tool.codeExecution.shouldNotBeNull()
tool.functionDeclarations.shouldBeNull()
tool.googleSearch.shouldBeNull()
}
}
Loading