Skip to content

Commit d0fa299

Browse files
authored
Wrap citations inside CitationMetadata (#6276)
We were previously unwrapping Citations within CitationMetadata, but we've decided to better align with the proto. https://github.com/googleapis/googleapis/blob/7f9941f4ba22d6eb3bb7fa31f80aae3a1b3b957e/google/cloud/aiplatform/v1/content.proto#L346 b/368310789
1 parent 2326592 commit d0fa299

File tree

4 files changed

+35
-17
lines changed

4 files changed

+35
-17
lines changed

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/internal/util/conversions.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import android.graphics.Bitmap
2020
import android.graphics.BitmapFactory
2121
import android.util.Base64
2222
import com.google.firebase.vertexai.common.client.Schema
23-
import com.google.firebase.vertexai.common.server.CitationSources
2423
import com.google.firebase.vertexai.common.shared.Blob
2524
import com.google.firebase.vertexai.common.shared.FileData
2625
import com.google.firebase.vertexai.common.shared.FunctionCall
@@ -32,6 +31,7 @@ import com.google.firebase.vertexai.type.BlobPart
3231
import com.google.firebase.vertexai.type.BlockReason
3332
import com.google.firebase.vertexai.type.BlockThreshold
3433
import com.google.firebase.vertexai.type.Candidate
34+
import com.google.firebase.vertexai.type.Citation
3535
import com.google.firebase.vertexai.type.CitationMetadata
3636
import com.google.firebase.vertexai.type.Content
3737
import com.google.firebase.vertexai.type.CountTokensResponse
@@ -181,7 +181,7 @@ internal fun JSONObject.toInternal() = Json.decodeFromString<JsonObject>(toStrin
181181

182182
internal fun com.google.firebase.vertexai.common.server.Candidate.toPublic(): Candidate {
183183
val safetyRatings = safetyRatings?.map { it.toPublic() }.orEmpty()
184-
val citations = citationMetadata?.citationSources?.map { it.toPublic() }.orEmpty()
184+
val citations = citationMetadata?.toPublic()
185185
val finishReason = finishReason.toPublic()
186186

187187
return Candidate(
@@ -228,8 +228,11 @@ internal fun com.google.firebase.vertexai.common.shared.Part.toPublic(): Part {
228228
}
229229
}
230230

231-
internal fun CitationSources.toPublic() =
232-
CitationMetadata(startIndex = startIndex, endIndex = endIndex, uri = uri ?: "", license = license)
231+
internal fun com.google.firebase.vertexai.common.server.CitationSources.toPublic() =
232+
Citation(startIndex = startIndex, endIndex = endIndex, uri = uri, license = license)
233+
234+
internal fun com.google.firebase.vertexai.common.server.CitationMetadata.toPublic() =
235+
CitationMetadata(citationSources.map { it.toPublic() })
233236

234237
internal fun com.google.firebase.vertexai.common.server.SafetyRating.toPublic() =
235238
SafetyRating(

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/type/Candidate.kt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Candidate
2121
internal constructor(
2222
val content: Content,
2323
val safetyRatings: List<SafetyRating>,
24-
val citationMetadata: List<CitationMetadata>,
24+
val citationMetadata: CitationMetadata?,
2525
val finishReason: FinishReason?
2626
)
2727

@@ -37,15 +37,25 @@ internal constructor(
3737
)
3838

3939
/**
40-
* Provides citation metadata for sourcing of content provided by the model between a given
40+
* A collection of source attributions for a piece of content.
41+
*
42+
* @property citations A list of individual cited sources and the parts of the content to which they
43+
* apply.
44+
*/
45+
class CitationMetadata internal constructor(val citations: List<Citation>)
46+
47+
/**
48+
* Provides citation information for sourcing of content provided by the model between a given
4149
* [startIndex] and [endIndex].
4250
*
43-
* @property startIndex The beginning of the citation.
44-
* @property endIndex The end of the citation.
45-
* @property uri The URI of the cited work.
46-
* @property license The license under which the cited work is distributed.
51+
* @property startIndex The inclusive beginning of a sequence in a model response that derives from
52+
* a cited source.
53+
* @property endIndex The exclusive end of a sequence in a model response that derives from a cited
54+
* source.
55+
* @property uri A link to the cited source, if available.
56+
* @property license The license the cited source work is distributed under, if specified.
4757
*/
48-
class CitationMetadata
58+
class Citation
4959
internal constructor(
5060
val startIndex: Int = 0,
5161
val endIndex: Int,

firebase-vertexai/src/test/java/com/google/firebase/vertexai/StreamingSnapshotTests.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ internal class StreamingSnapshotTests {
169169

170170
withTimeout(testTimeout) {
171171
val responseList = responses.toList()
172-
responseList.any { it.candidates.any { it.citationMetadata.isNotEmpty() } } shouldBe true
172+
responseList.any {
173+
it.candidates.any { it.citationMetadata?.citations?.isNotEmpty() ?: false }
174+
} shouldBe true
173175
}
174176
}
175177

firebase-vertexai/src/test/java/com/google/firebase/vertexai/UnarySnapshotTests.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ internal class UnarySnapshotTests {
229229
val response = model.generateContent("prompt")
230230

231231
response.candidates.isEmpty() shouldBe false
232-
response.candidates.first().citationMetadata.size shouldBe 3
232+
response.candidates.first().citationMetadata?.citations?.size shouldBe 3
233233
}
234234
}
235235

@@ -240,11 +240,14 @@ internal class UnarySnapshotTests {
240240
val response = model.generateContent("prompt")
241241

242242
response.candidates.isEmpty() shouldBe false
243-
response.candidates.first().citationMetadata.isEmpty() shouldBe false
243+
response.candidates.first().citationMetadata?.citations?.isEmpty() shouldBe false
244244
// Verify the values in the citation source
245-
with(response.candidates.first().citationMetadata.first()) {
246-
license shouldBe null
247-
startIndex shouldBe 0
245+
val firstCitation = response.candidates.first().citationMetadata?.citations?.first()
246+
if (firstCitation != null) {
247+
with(firstCitation) {
248+
license shouldBe null
249+
startIndex shouldBe 0
250+
}
248251
}
249252
}
250253
}

0 commit comments

Comments
 (0)