Repository navigation
Description
🔴 Required Information
Describe the Bug:
When a remote agent asks for user input (input-required or auth-required), _create_mock_function_call_for_required_user_input replaces the prompt part with a mock function call and marks it long-running, so the caller sees the request for input. A prompt sent as a data part reaches it as the inline blob made by _compat.data_part_blob_bytes, and _extract_user_input_prompt reads that blob with data_part.get("data").
That matches the 0.3.x blob, which is the whole serialized DataPart ({"kind": "data", "data": {...}}). On a2a-sdk 1.x the blob is only the data itself, so:
- A data prompt is not turned into a function call. The event keeps the raw
<a2a_datapart_json>...</a2a_datapart_json>blob and has nolong_running_tool_ids, so the caller gets no request for input. - A data prompt that has its own
"data"key is turned into a function call with only that value as the prompt.
A text prompt is not affected, and on 0.3.x both cases work.
Steps to Reproduce:
- Install a2a-sdk 1.x.
- Run the code below.
Expected Behavior:
Each prompt becomes the mock function call, with the data part's data as the prompt.
{'input_required': 'Approve the refund?'} True
{'input_required': {'question': 'Approve the refund?'}} True
{'input_required': {'kind': 'approval', 'data': 'refund-42'}} True
Observed Behavior:
{'input_required': 'Approve the refund?'} True
b'<a2a_datapart_json>{"question": "Approve the refund?"}</a2a_datapart_json>' False
{'input_required': 'refund-42'} True
Environment Details:
- ADK Library Version (pip show google-adk): 2.13.0 (also on
mainat 6b01717) - a2a-sdk: 1.1.2
- Desktop OS: macOS
- Python Version (python -V): 3.14.7
Model Information:
- Are you using LiteLLM: No
- Which model is being used: N/A (no model call is needed to reproduce)
🟡 Optional Information
Additional Context:
test_convert_a2a_task_to_event_data_part_input_required passes on 1.x because it replaces the part converter with a mock that returns a blob in the 0.3.x layout, so the 1.x layout is never converted there.
Through RemoteA2aAgent and a Runner, the next user message still continues the same remote task, since that follows the task state. What is missing is the mock function call and long_running_tool_ids on the event.
Minimal Reproduction Code:
from a2a.types import Message
from a2a.types import Part
from a2a.types import Role
from a2a.types import Task
from a2a.types import TaskState
from a2a.types import TaskStatus
from google.adk.a2a.converters.to_adk_event import convert_a2a_task_to_event
from google.protobuf.json_format import ParseDict
from google.protobuf.struct_pb2 import Value
def input_required_task(part: Part) -> Task:
return Task(
id="task-1",
context_id="context-1",
status=TaskStatus(
state=TaskState.TASK_STATE_INPUT_REQUIRED,
message=Message(
message_id="m1", role=Role.ROLE_AGENT, parts=[part]
),
),
)
for part in (
Part(text="Approve the refund?"),
Part(data=ParseDict({"question": "Approve the refund?"}, Value())),
Part(data=ParseDict({"data": "refund-42", "kind": "approval"}, Value())),
):
event = convert_a2a_task_to_event(input_required_task(part), author="remote")
adk_part = event.content.parts[0]
print(
adk_part.function_call.args
if adk_part.function_call
else adk_part.inline_data.data,
bool(event.long_running_tool_ids),
)How often has this issue occurred?:
- Always (100%)
Activity