@@ -239,3 +239,81 @@ def test_llm_response_create_with_partial_logprobs_result():
239
239
assert len (response .logprobs_result .top_candidates ) == 0
240
240
assert response .logprobs_result .chosen_candidates [0 ].token == 'Hello'
241
241
assert response .logprobs_result .chosen_candidates [1 ].token == ' world'
242
+
243
+
244
+ def test_llm_response_create_with_citation_metadata ():
245
+ """Test LlmResponse.create() extracts citation_metadata from candidate."""
246
+ citation_metadata = types .CitationMetadata (
247
+ citations = [
248
+ types .Citation (
249
+ start_index = 0 ,
250
+ end_index = 10 ,
251
+ uri = 'https://example.com' ,
252
+ )
253
+ ]
254
+ )
255
+
256
+ generate_content_response = types .GenerateContentResponse (
257
+ candidates = [
258
+ types .Candidate (
259
+ content = types .Content (parts = [types .Part (text = 'Response text' )]),
260
+ finish_reason = types .FinishReason .STOP ,
261
+ citation_metadata = citation_metadata ,
262
+ )
263
+ ]
264
+ )
265
+
266
+ response = LlmResponse .create (generate_content_response )
267
+
268
+ assert response .citation_metadata == citation_metadata
269
+ assert response .content .parts [0 ].text == 'Response text'
270
+
271
+
272
+ def test_llm_response_create_without_citation_metadata ():
273
+ """Test LlmResponse.create() handles missing citation_metadata gracefully."""
274
+ generate_content_response = types .GenerateContentResponse (
275
+ candidates = [
276
+ types .Candidate (
277
+ content = types .Content (parts = [types .Part (text = 'Response text' )]),
278
+ finish_reason = types .FinishReason .STOP ,
279
+ citation_metadata = None ,
280
+ )
281
+ ]
282
+ )
283
+
284
+ response = LlmResponse .create (generate_content_response )
285
+
286
+ assert response .citation_metadata is None
287
+ assert response .content .parts [0 ].text == 'Response text'
288
+
289
+
290
+ def test_llm_response_create_error_case_with_citation_metadata ():
291
+ """Test LlmResponse.create() includes citation_metadata in error cases."""
292
+ citation_metadata = types .CitationMetadata (
293
+ citations = [
294
+ types .Citation (
295
+ start_index = 0 ,
296
+ end_index = 10 ,
297
+ uri = 'https://example.com' ,
298
+ )
299
+ ]
300
+ )
301
+
302
+ generate_content_response = types .GenerateContentResponse (
303
+ candidates = [
304
+ types .Candidate (
305
+ content = None , # No content - blocked case
306
+ finish_reason = types .FinishReason .RECITATION ,
307
+ finish_message = 'Response blocked due to recitation triggered' ,
308
+ citation_metadata = citation_metadata ,
309
+ )
310
+ ]
311
+ )
312
+
313
+ response = LlmResponse .create (generate_content_response )
314
+
315
+ assert response .citation_metadata == citation_metadata
316
+ assert response .error_code == types .FinishReason .RECITATION
317
+ assert (
318
+ response .error_message == 'Response blocked due to recitation triggered'
319
+ )
0 commit comments