Skip to content

Commit 22fae7e

Browse files
GWealecopybara-github
authored andcommitted
feat(models): add get_function_calls and get_function_responses to LlmResponse
Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 908900779
1 parent 8286066 commit 22fae7e

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

src/google/adk/models/llm_response.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,24 @@ class LlmResponse(BaseModel):
148148
It can be used to identify and chain interactions for stateful conversations.
149149
"""
150150

151+
def get_function_calls(self) -> list[types.FunctionCall]:
152+
"""Returns the function calls in the response."""
153+
func_calls = []
154+
if self.content and self.content.parts:
155+
for part in self.content.parts:
156+
if part.function_call:
157+
func_calls.append(part.function_call)
158+
return func_calls
159+
160+
def get_function_responses(self) -> list[types.FunctionResponse]:
161+
"""Returns the function responses in the response."""
162+
func_responses = []
163+
if self.content and self.content.parts:
164+
for part in self.content.parts:
165+
if part.function_response:
166+
func_responses.append(part.function_response)
167+
return func_responses
168+
151169
@staticmethod
152170
def create(
153171
generate_content_response: types.GenerateContentResponse,

tests/unittests/models/test_llm_response.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,51 @@ def test_llm_response_create_includes_model_version():
349349
)
350350
response = LlmResponse.create(generate_content_response)
351351
assert response.model_version == 'gemini-2.5-flash'
352+
353+
354+
def test_get_function_calls_returns_calls_in_order():
355+
fc1 = types.FunctionCall(name='a', args={})
356+
fc2 = types.FunctionCall(name='b', args={'x': 1})
357+
response = LlmResponse(
358+
content=types.Content(
359+
parts=[
360+
types.Part(function_call=fc1),
361+
types.Part(text='ignored'),
362+
types.Part(function_call=fc2),
363+
]
364+
)
365+
)
366+
assert response.get_function_calls() == [fc1, fc2]
367+
368+
369+
def test_get_function_calls_empty_when_no_content():
370+
assert LlmResponse().get_function_calls() == []
371+
372+
373+
def test_get_function_calls_empty_when_no_parts():
374+
response = LlmResponse(content=types.Content(parts=None))
375+
assert response.get_function_calls() == []
376+
377+
378+
def test_get_function_responses_returns_responses_in_order():
379+
fr1 = types.FunctionResponse(name='a', response={'r': 1})
380+
fr2 = types.FunctionResponse(name='b', response={'r': 2})
381+
response = LlmResponse(
382+
content=types.Content(
383+
parts=[
384+
types.Part(function_response=fr1),
385+
types.Part(text='ignored'),
386+
types.Part(function_response=fr2),
387+
]
388+
)
389+
)
390+
assert response.get_function_responses() == [fr1, fr2]
391+
392+
393+
def test_get_function_responses_empty_when_no_content():
394+
assert LlmResponse().get_function_responses() == []
395+
396+
397+
def test_get_function_responses_empty_when_no_parts():
398+
response = LlmResponse(content=types.Content(parts=None))
399+
assert response.get_function_responses() == []

0 commit comments

Comments
 (0)