Skip to content

Commit 735402d

Browse files
google-genai-botcopybara-github
authored andcommitted
fix(flows): sort function_call.args when rendering cross-agent context
PiperOrigin-RevId: 965407299
1 parent 0c67410 commit 735402d

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

src/google/adk/flows/llm_flows/contents.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1112,11 +1112,17 @@ def _present_other_agent_message(
11121112
types.Part(text=f'[{event.author}] said: {part.text}')
11131113
)
11141114
elif part.function_call:
1115+
# Sort args by key so the rendered dict is deterministic across runs.
1116+
args = (
1117+
dict(sorted(part.function_call.args.items()))
1118+
if part.function_call.args
1119+
else part.function_call.args
1120+
)
11151121
content.parts.append(
11161122
types.Part(
11171123
text=(
11181124
f'[{event.author}] called tool `{part.function_call.name}`'
1119-
f' with parameters: {part.function_call.args}'
1125+
f' with parameters: {args}'
11201126
)
11211127
)
11221128
)

tests/unittests/flows/llm_flows/test_contents_other_agent.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,39 @@ async def test_other_agent_function_calls():
225225
]
226226

227227

228+
@pytest.mark.asyncio
229+
async def test_other_agent_function_call_args_are_sorted():
230+
"""Function call args are rendered in sorted key order for determinism."""
231+
agent = Agent(model="gemini-2.5-flash", name="current_agent")
232+
llm_request = LlmRequest(model="gemini-2.5-flash")
233+
invocation_context = await testing_utils.create_invocation_context(
234+
agent=agent
235+
)
236+
# Provide args in non-sorted insertion order (z, a, m) to prove the
237+
# rendered dict is re-ordered by key.
238+
function_call = types.FunctionCall(
239+
id="func_sort",
240+
name="tool",
241+
args={"z_key": "z_val", "a_key": "a_val", "m_key": "m_val"},
242+
)
243+
other_agent_event = Event(
244+
invocation_id="test_inv",
245+
author="other_agent",
246+
content=types.ModelContent([types.Part(function_call=function_call)]),
247+
)
248+
invocation_context.session.events = [other_agent_event]
249+
250+
async for _ in request_processor.run_async(invocation_context, llm_request):
251+
pass
252+
253+
assert llm_request.contents[0].parts[1] == types.Part(
254+
text=(
255+
"[other_agent] called tool `tool` with parameters:"
256+
" {'a_key': 'a_val', 'm_key': 'm_val', 'z_key': 'z_val'}"
257+
)
258+
)
259+
260+
228261
@pytest.mark.asyncio
229262
async def test_other_agent_function_responses():
230263
"""Test that function responses from other agents are properly formatted."""

0 commit comments

Comments
 (0)