Skip to content

Commit e4d8bdc

Browse files
authored
Merge branch 'main' into ep/bidi-compile-tests
2 parents 39a9bc8 + 2b23887 commit e4d8bdc

File tree

11 files changed

+356
-247
lines changed

11 files changed

+356
-247
lines changed

firebase-ai/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@
1313
* [fixed] Fixed an issue with `LiveContentResponse` audio data not being present when the model was
1414
interrupted or the turn completed. (#6870)
1515
* [fixed] Fixed an issue with `LiveSession` not converting exceptions to `FirebaseVertexAIException`. (#6870)
16+
* * [changed] **Breaking Change**: Removed the `LiveContentResponse.Status` class, and instead have nested the status
17+
fields as properties of `LiveContentResponse`. (#6906)
18+
* [changed] **Breaking Change**: Removed the `LiveContentResponse` class, and instead have provided subclasses
19+
of `LiveServerMessage` that match the responses from the model. (#6910)
20+
* [feature] Added support for the `id` field on `FunctionResponsePart` and `FunctionCallPart`. (#6910)
21+
* [feature] Add support for specifying response modalities in `GenerationConfig`. (#6921)
22+
* [feature] Added a helper field for getting all the `InlineDataPart` from a `GenerateContentResponse`. (#6922)
23+

firebase-ai/api.txt

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ package com.google.firebase.ai.java {
127127
@com.google.firebase.ai.type.PublicPreviewAPI public abstract class LiveSessionFutures {
128128
method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> close();
129129
method public static final com.google.firebase.ai.java.LiveSessionFutures from(com.google.firebase.ai.type.LiveSession session);
130-
method public abstract org.reactivestreams.Publisher<com.google.firebase.ai.type.LiveContentResponse> receive();
130+
method public abstract org.reactivestreams.Publisher<com.google.firebase.ai.type.LiveServerMessage> receive();
131131
method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> send(com.google.firebase.ai.type.Content content);
132132
method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> send(String text);
133133
method public abstract com.google.common.util.concurrent.ListenableFuture<kotlin.Unit> sendFunctionResponse(java.util.List<com.google.firebase.ai.type.FunctionResponsePart> functionList);
@@ -293,9 +293,12 @@ package com.google.firebase.ai.type {
293293

294294
public final class FunctionCallPart implements com.google.firebase.ai.type.Part {
295295
ctor public FunctionCallPart(String name, java.util.Map<java.lang.String,? extends kotlinx.serialization.json.JsonElement> args);
296+
ctor public FunctionCallPart(String name, java.util.Map<java.lang.String,? extends kotlinx.serialization.json.JsonElement> args, String? id = null);
296297
method public java.util.Map<java.lang.String,kotlinx.serialization.json.JsonElement> getArgs();
298+
method public String? getId();
297299
method public String getName();
298300
property public final java.util.Map<java.lang.String,kotlinx.serialization.json.JsonElement> args;
301+
property public final String? id;
299302
property public final String name;
300303
}
301304

@@ -320,8 +323,11 @@ package com.google.firebase.ai.type {
320323

321324
public final class FunctionResponsePart implements com.google.firebase.ai.type.Part {
322325
ctor public FunctionResponsePart(String name, kotlinx.serialization.json.JsonObject response);
326+
ctor public FunctionResponsePart(String name, kotlinx.serialization.json.JsonObject response, String? id = null);
327+
method public String? getId();
323328
method public String getName();
324329
method public kotlinx.serialization.json.JsonObject getResponse();
330+
property public final String? id;
325331
property public final String name;
326332
property public final kotlinx.serialization.json.JsonObject response;
327333
}
@@ -330,11 +336,13 @@ package com.google.firebase.ai.type {
330336
ctor public GenerateContentResponse(java.util.List<com.google.firebase.ai.type.Candidate> candidates, com.google.firebase.ai.type.PromptFeedback? promptFeedback, com.google.firebase.ai.type.UsageMetadata? usageMetadata);
331337
method public java.util.List<com.google.firebase.ai.type.Candidate> getCandidates();
332338
method public java.util.List<com.google.firebase.ai.type.FunctionCallPart> getFunctionCalls();
339+
method public java.util.List<com.google.firebase.ai.type.InlineDataPart> getInlineDataParts();
333340
method public com.google.firebase.ai.type.PromptFeedback? getPromptFeedback();
334341
method public String? getText();
335342
method public com.google.firebase.ai.type.UsageMetadata? getUsageMetadata();
336343
property public final java.util.List<com.google.firebase.ai.type.Candidate> candidates;
337344
property public final java.util.List<com.google.firebase.ai.type.FunctionCallPart> functionCalls;
345+
property public final java.util.List<com.google.firebase.ai.type.InlineDataPart> inlineDataParts;
338346
property public final com.google.firebase.ai.type.PromptFeedback? promptFeedback;
339347
property public final String? text;
340348
property public final com.google.firebase.ai.type.UsageMetadata? usageMetadata;
@@ -352,6 +360,7 @@ package com.google.firebase.ai.type {
352360
field public Integer? maxOutputTokens;
353361
field public Float? presencePenalty;
354362
field public String? responseMimeType;
363+
field public java.util.List<com.google.firebase.ai.type.ResponseModality>? responseModalities;
355364
field public com.google.firebase.ai.type.Schema? responseSchema;
356365
field public java.util.List<java.lang.String>? stopSequences;
357366
field public Float? temperature;
@@ -576,30 +585,6 @@ package com.google.firebase.ai.type {
576585
public final class InvalidStateException extends com.google.firebase.ai.type.FirebaseAIException {
577586
}
578587

579-
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveContentResponse {
580-
method public com.google.firebase.ai.type.Content? getData();
581-
method public java.util.List<com.google.firebase.ai.type.FunctionCallPart>? getFunctionCalls();
582-
method public int getStatus();
583-
method public String? getText();
584-
property public final com.google.firebase.ai.type.Content? data;
585-
property public final java.util.List<com.google.firebase.ai.type.FunctionCallPart>? functionCalls;
586-
property public final int status;
587-
property public final String? text;
588-
}
589-
590-
@kotlin.jvm.JvmInline public static final value class LiveContentResponse.Status {
591-
field public static final com.google.firebase.ai.type.LiveContentResponse.Status.Companion Companion;
592-
}
593-
594-
public static final class LiveContentResponse.Status.Companion {
595-
method public int getINTERRUPTED();
596-
method public int getNORMAL();
597-
method public int getTURN_COMPLETE();
598-
property public final int INTERRUPTED;
599-
property public final int NORMAL;
600-
property public final int TURN_COMPLETE;
601-
}
602-
603588
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveGenerationConfig {
604589
field public static final com.google.firebase.ai.type.LiveGenerationConfig.Companion Companion;
605590
}
@@ -635,9 +620,40 @@ package com.google.firebase.ai.type {
635620
method public static com.google.firebase.ai.type.LiveGenerationConfig liveGenerationConfig(kotlin.jvm.functions.Function1<? super com.google.firebase.ai.type.LiveGenerationConfig.Builder,kotlin.Unit> init);
636621
}
637622

623+
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerContent implements com.google.firebase.ai.type.LiveServerMessage {
624+
ctor public LiveServerContent(com.google.firebase.ai.type.Content? content, boolean interrupted, boolean turnComplete, boolean generationComplete);
625+
method public com.google.firebase.ai.type.Content? getContent();
626+
method public boolean getGenerationComplete();
627+
method public boolean getInterrupted();
628+
method public boolean getTurnComplete();
629+
property public final com.google.firebase.ai.type.Content? content;
630+
property public final boolean generationComplete;
631+
property public final boolean interrupted;
632+
property public final boolean turnComplete;
633+
}
634+
635+
@com.google.firebase.ai.type.PublicPreviewAPI public interface LiveServerMessage {
636+
}
637+
638+
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerSetupComplete implements com.google.firebase.ai.type.LiveServerMessage {
639+
ctor public LiveServerSetupComplete();
640+
}
641+
642+
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerToolCall implements com.google.firebase.ai.type.LiveServerMessage {
643+
ctor public LiveServerToolCall(java.util.List<com.google.firebase.ai.type.FunctionCallPart> functionCalls);
644+
method public java.util.List<com.google.firebase.ai.type.FunctionCallPart> getFunctionCalls();
645+
property public final java.util.List<com.google.firebase.ai.type.FunctionCallPart> functionCalls;
646+
}
647+
648+
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerToolCallCancellation implements com.google.firebase.ai.type.LiveServerMessage {
649+
ctor public LiveServerToolCallCancellation(java.util.List<java.lang.String> functionIds);
650+
method public java.util.List<java.lang.String> getFunctionIds();
651+
property public final java.util.List<java.lang.String> functionIds;
652+
}
653+
638654
@com.google.firebase.ai.type.PublicPreviewAPI public final class LiveSession {
639655
method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
640-
method public kotlinx.coroutines.flow.Flow<com.google.firebase.ai.type.LiveContentResponse> receive();
656+
method public kotlinx.coroutines.flow.Flow<com.google.firebase.ai.type.LiveServerMessage> receive();
641657
method public suspend Object? send(com.google.firebase.ai.type.Content content, kotlin.coroutines.Continuation<? super kotlin.Unit>);
642658
method public suspend Object? send(String text, kotlin.coroutines.Continuation<? super kotlin.Unit>);
643659
method public suspend Object? sendFunctionResponse(java.util.List<com.google.firebase.ai.type.FunctionResponsePart> functionList, kotlin.coroutines.Continuation<? super kotlin.Unit>);

firebase-ai/src/main/kotlin/com/google/firebase/ai/java/LiveSessionFutures.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import com.google.common.util.concurrent.ListenableFuture
2323
import com.google.firebase.ai.type.Content
2424
import com.google.firebase.ai.type.FunctionCallPart
2525
import com.google.firebase.ai.type.FunctionResponsePart
26-
import com.google.firebase.ai.type.LiveContentResponse
26+
import com.google.firebase.ai.type.LiveServerMessage
2727
import com.google.firebase.ai.type.LiveSession
2828
import com.google.firebase.ai.type.MediaData
2929
import com.google.firebase.ai.type.PublicPreviewAPI
@@ -135,16 +135,16 @@ public abstract class LiveSessionFutures internal constructor() {
135135
*
136136
* Call [close] to stop receiving responses from the model.
137137
*
138-
* @return A [Publisher] which will emit [LiveContentResponse] from the model.
138+
* @return A [Publisher] which will emit [LiveServerMessage] from the model.
139139
*
140140
* @throws [SessionAlreadyReceivingException] when the session is already receiving.
141141
* @see stopReceiving
142142
*/
143-
public abstract fun receive(): Publisher<LiveContentResponse>
143+
public abstract fun receive(): Publisher<LiveServerMessage>
144144

145145
private class FuturesImpl(private val session: LiveSession) : LiveSessionFutures() {
146146

147-
override fun receive(): Publisher<LiveContentResponse> = session.receive().asPublisher()
147+
override fun receive(): Publisher<LiveServerMessage> = session.receive().asPublisher()
148148

149149
override fun close(): ListenableFuture<Unit> =
150150
SuspendToFutureAdapter.launchFuture { session.close() }

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ public class GenerateContentResponse(
4444
candidates.first().content.parts.filterIsInstance<FunctionCallPart>()
4545
}
4646

47+
/**
48+
* Convenience field representing all the [InlineDataPart]s in the first candidate, if they exist.
49+
*
50+
* This also includes any [ImagePart], but they will be represented as [InlineDataPart] instead.
51+
*/
52+
public val inlineDataParts: List<InlineDataPart> by lazy {
53+
candidates.first().content.parts.let { parts ->
54+
parts.filterIsInstance<ImagePart>().map { it.toInlineDataPart() } +
55+
parts.filterIsInstance<InlineDataPart>()
56+
}
57+
}
58+
4759
@Serializable
4860
internal data class Internal(
4961
val candidates: List<Candidate.Internal>? = null,

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ import kotlinx.serialization.Serializable
7575
* Refer to the
7676
* [Control generated output](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/control-generated-output)
7777
* guide for more details.
78+
*
79+
* @property responseModalities The format of data in which the model should respond with.
7880
*/
7981
public class GenerationConfig
8082
private constructor(
@@ -88,6 +90,7 @@ private constructor(
8890
internal val stopSequences: List<String>?,
8991
internal val responseMimeType: String?,
9092
internal val responseSchema: Schema?,
93+
internal val responseModalities: List<ResponseModality>?,
9194
) {
9295

9396
/**
@@ -115,6 +118,9 @@ private constructor(
115118
* @property responseMimeType See [GenerationConfig.responseMimeType].
116119
*
117120
* @property responseSchema See [GenerationConfig.responseSchema].
121+
*
122+
* @property responseModalities See [GenerationConfig.responseModalities].
123+
*
118124
* @see [generationConfig]
119125
*/
120126
public class Builder {
@@ -128,6 +134,7 @@ private constructor(
128134
@JvmField public var stopSequences: List<String>? = null
129135
@JvmField public var responseMimeType: String? = null
130136
@JvmField public var responseSchema: Schema? = null
137+
@JvmField public var responseModalities: List<ResponseModality>? = null
131138

132139
/** Create a new [GenerationConfig] with the attached arguments. */
133140
public fun build(): GenerationConfig =
@@ -142,6 +149,7 @@ private constructor(
142149
frequencyPenalty = frequencyPenalty,
143150
responseMimeType = responseMimeType,
144151
responseSchema = responseSchema,
152+
responseModalities = responseModalities
145153
)
146154
}
147155

@@ -156,7 +164,8 @@ private constructor(
156164
frequencyPenalty = frequencyPenalty,
157165
presencePenalty = presencePenalty,
158166
responseMimeType = responseMimeType,
159-
responseSchema = responseSchema?.toInternal()
167+
responseSchema = responseSchema?.toInternal(),
168+
responseModalities = responseModalities?.map { it.toInternal() }
160169
)
161170

162171
@Serializable
@@ -171,6 +180,7 @@ private constructor(
171180
@SerialName("presence_penalty") val presencePenalty: Float? = null,
172181
@SerialName("frequency_penalty") val frequencyPenalty: Float? = null,
173182
@SerialName("response_schema") val responseSchema: Schema.Internal? = null,
183+
@SerialName("response_modalities") val responseModalities: List<String>? = null
174184
)
175185

176186
public companion object {

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

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)