Skip to content

Commit 0a7f78a

Browse files
authored
[AI] Implement cached token count in usage metadata (#7647)
`UsageMetadata` now includes details about cached token usage.
1 parent 9f48ede commit 0a7f78a

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

firebase-ai/api.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,8 @@ package com.google.firebase.ai.type {
13731373

13741374
public final class UsageMetadata {
13751375
ctor @Deprecated public UsageMetadata(int promptTokenCount, Integer? candidatesTokenCount, int totalTokenCount, java.util.List<com.google.firebase.ai.type.ModalityTokenCount> promptTokensDetails, java.util.List<com.google.firebase.ai.type.ModalityTokenCount> candidatesTokensDetails, int thoughtsTokenCount);
1376+
method public java.util.List<com.google.firebase.ai.type.ModalityTokenCount> getCacheTokensDetails();
1377+
method public int getCachedContentTokenCount();
13761378
method public Integer? getCandidatesTokenCount();
13771379
method public java.util.List<com.google.firebase.ai.type.ModalityTokenCount> getCandidatesTokensDetails();
13781380
method public int getPromptTokenCount();
@@ -1381,6 +1383,8 @@ package com.google.firebase.ai.type {
13811383
method public int getToolUsePromptTokenCount();
13821384
method public java.util.List<com.google.firebase.ai.type.ModalityTokenCount> getToolUsePromptTokensDetails();
13831385
method public int getTotalTokenCount();
1386+
property public final java.util.List<com.google.firebase.ai.type.ModalityTokenCount> cacheTokensDetails;
1387+
property public final int cachedContentTokenCount;
13841388
property public final Integer? candidatesTokenCount;
13851389
property public final java.util.List<com.google.firebase.ai.type.ModalityTokenCount> candidatesTokensDetails;
13861390
property public final int promptTokenCount;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ internal constructor(
3838
public val promptTokenCount: Int,
3939
public val candidatesTokenCount: Int?,
4040
public val totalTokenCount: Int,
41+
public val cachedContentTokenCount: Int,
4142
public val promptTokensDetails: List<ModalityTokenCount>,
4243
public val candidatesTokensDetails: List<ModalityTokenCount>,
44+
public val cacheTokensDetails: List<ModalityTokenCount>,
4345
public val thoughtsTokenCount: Int,
4446
public val toolUsePromptTokenCount: Int,
4547
public val toolUsePromptTokensDetails: List<ModalityTokenCount>
@@ -57,8 +59,10 @@ internal constructor(
5759
promptTokenCount,
5860
candidatesTokenCount,
5961
totalTokenCount,
62+
0,
6063
promptTokensDetails,
6164
candidatesTokensDetails,
65+
emptyList(),
6266
thoughtsTokenCount,
6367
0,
6468
emptyList()
@@ -69,8 +73,10 @@ internal constructor(
6973
val promptTokenCount: Int? = null,
7074
val candidatesTokenCount: Int? = null,
7175
val totalTokenCount: Int? = null,
76+
val cachedContentTokenCount: Int? = null,
7277
val promptTokensDetails: List<ModalityTokenCount.Internal>? = null,
7378
val candidatesTokensDetails: List<ModalityTokenCount.Internal>? = null,
79+
val cacheTokensDetails: List<ModalityTokenCount.Internal>? = null,
7480
val thoughtsTokenCount: Int? = null,
7581
val toolUsePromptTokenCount: Int? = null,
7682
val toolUsePromptTokensDetails: List<ModalityTokenCount.Internal>? = null,
@@ -81,8 +87,10 @@ internal constructor(
8187
promptTokenCount ?: 0,
8288
candidatesTokenCount ?: 0,
8389
totalTokenCount ?: 0,
90+
cachedContentTokenCount ?: 0,
8491
promptTokensDetails = promptTokensDetails?.map { it.toPublic() } ?: emptyList(),
8592
candidatesTokensDetails = candidatesTokensDetails?.map { it.toPublic() } ?: emptyList(),
93+
cacheTokensDetails = cacheTokensDetails?.map { it.toPublic() } ?: emptyList(),
8694
thoughtsTokenCount ?: 0,
8795
toolUsePromptTokenCount ?: 0,
8896
toolUsePromptTokensDetails = toolUsePromptTokensDetails?.map { it.toPublic() }

firebase-ai/src/test/java/com/google/firebase/ai/VertexAIUnarySnapshotTests.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,27 @@ internal class VertexAIUnarySnapshotTests {
379379
}
380380
}
381381

382+
@Test
383+
fun `response includes implicit cached metadata`() =
384+
goldenVertexUnaryFile("unary-success-implicit-caching.json") {
385+
withTimeout(testTimeout) {
386+
val response = model.generateContent("prompt")
387+
388+
response.candidates.isEmpty() shouldBe false
389+
response.candidates.first().finishReason shouldBe FinishReason.STOP
390+
response.usageMetadata shouldNotBe null
391+
response.usageMetadata?.let {
392+
it.promptTokenCount shouldBe 12013
393+
it.candidatesTokenCount shouldBe 15
394+
it.cachedContentTokenCount shouldBe 11243
395+
it.cacheTokensDetails.first().let { count ->
396+
count.modality shouldBe ContentModality.TEXT
397+
count.tokenCount shouldBe 11243
398+
}
399+
}
400+
}
401+
}
402+
382403
@Test
383404
fun `properly translates json text`() =
384405
goldenVertexUnaryFile("unary-success-constraint-decoding-json.json") {

firebase-ai/update_responses.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# This script replaces mock response files for Vertex AI unit tests with a fresh
1818
# clone of the shared repository of Vertex AI test data.
1919

20-
RESPONSES_VERSION='v15.*' # The major version of mock responses to use
20+
RESPONSES_VERSION='v16.*' # The major version of mock responses to use
2121
REPO_NAME="vertexai-sdk-test-data"
2222
REPO_LINK="https://github.com/FirebaseExtended/$REPO_NAME.git"
2323

0 commit comments

Comments
 (0)