Description
LongRunningFunctions._mark_long_running_function_call decides the A2A task state for a long-running function call. For an End-User-Credential (auth) request it should set auth_required; otherwise input_required. It reads the function name from the wrong place:
# src/google/adk/a2a/converters/long_running_functions.py:163
if a2a_part.root.metadata.get("name") == REQUEST_EUC_FUNCTION_CALL_NAME:
For a function-call DataPart, the name lives in a2a_part.root.data (the FunctionCall dump — see part_converter.convert_genai_part_to_a2a_part, data=part.function_call.model_dump(...)). The metadata dict only holds the ADK adk_type / adk_is_long_running keys, so metadata.get("name") is always None. The EUC branch is therefore never taken and an auth request is mislabeled input_required instead of auth_required. The sibling converter event_converter.py:504 does the equivalent check correctly with part.root.data.get("name").
Reproduction
from google.genai import types as genai_types
from google.adk.a2a.converters.part_converter import convert_genai_part_to_a2a_part
from google.adk.a2a.converters.long_running_functions import LongRunningFunctions
from google.adk.flows.llm_flows.functions import REQUEST_EUC_FUNCTION_CALL_NAME
part = convert_genai_part_to_a2a_part(
genai_types.Part(function_call=genai_types.FunctionCall(
id="c1", name=REQUEST_EUC_FUNCTION_CALL_NAME, args={}))
)
lrf = LongRunningFunctions()
lrf._mark_long_running_function_call(part)
print(lrf._task_state) # TaskState.input_required (bug; expected auth_required)
print(part.root.data.get("name"), part.root.metadata.get("name"))
# adk_request_credential None
Fix
Read the name from data, matching event_converter.py:
if a2a_part.root.data.get("name") == REQUEST_EUC_FUNCTION_CALL_NAME:
Happy to send a small PR (with a regression test).
Description
LongRunningFunctions._mark_long_running_function_calldecides the A2A task state for a long-running function call. For an End-User-Credential (auth) request it should setauth_required; otherwiseinput_required. It reads the function name from the wrong place:For a function-call
DataPart, the name lives ina2a_part.root.data(theFunctionCalldump — seepart_converter.convert_genai_part_to_a2a_part,data=part.function_call.model_dump(...)). Themetadatadict only holds the ADKadk_type/adk_is_long_runningkeys, sometadata.get("name")is alwaysNone. The EUC branch is therefore never taken and an auth request is mislabeledinput_requiredinstead ofauth_required. The sibling converterevent_converter.py:504does the equivalent check correctly withpart.root.data.get("name").Reproduction
Fix
Read the name from
data, matchingevent_converter.py:Happy to send a small PR (with a regression test).