@@ -239,3 +239,81 @@ def test_llm_response_create_with_partial_logprobs_result():
239239 assert len (response .logprobs_result .top_candidates ) == 0
240240 assert response .logprobs_result .chosen_candidates [0 ].token == 'Hello'
241241 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