Skip to content

A2A message:stream against a deployed Agent Engine (reasoningEngines) target truncates after TASK_STATE_WORKING, or fails with 'append=True for nonexistent artifact_id' #6680

Description

@virktapvir

Describe the bug

Calling a genuinely deployed Vertex AI Agent Engine (reasoningEngines) resource via the A2A protocol's streaming endpoint either:

(a) silently stops after reporting TASK_STATE_WORKING, never delivering an artifact or completion event, or
(b) — after upgrading to a2a-sdk==1.1.2 / google-adk==2.6.3 on both client and server — fails with an explicit client-side error:

A2A request failed: append=True for nonexistent artifact_id='<uuid>' in task '<uuid>'.
The artifact must be created (append=False) before appending parts to it.

The non-streaming message:send call against the identical deployed target, same agent code, same question, completes successfully and returns the full answer every time. The bug is specific to streaming (message:stream) against a deployed Agent Engine target — the same code against a local A2A server (plain uvicorn, no Agent Engine) streams correctly with no truncation.

To Reproduce

  1. Deploy an ADK agent to Vertex AI Agent Engine via client.agent_engines.create(agent_engine=AdkApp(...)) (standard AdkApp wrapping, not a BYOD custom container).
  2. From a separate client process, call the deployed engine's A2A REST endpoint directly:
    from a2a.client.transports.rest import RestTransport
    from a2a.types import Message, Part, Role, SendMessageRequest
    
    # base_url = https://{region}-aiplatform.googleapis.com/v1beta1/{resource_name}/a2a
    transport = RestTransport(httpx_client=http, agent_card=None, url=base_url)
    message = Message(role=Role.ROLE_USER, message_id=..., context_id=..., parts=[Part(text="<any question that triggers a tool call>")])
    async for event in transport.send_message_streaming(SendMessageRequest(message=message)):
        print(event.WhichOneof("payload"))
  3. Observed sequence: task(state=SUBMITTED) -> status_update(state=SUBMITTED) -> status_update(state=WORKING) -> stream ends. No further events, no exception raised, no TASK_STATE_COMPLETED, no artifact.
  4. Server-side logging (Cloud Logging on the Agent Engine resource) confirms the agent completes its work in the same window (tool calls, model calls, etc. all succeed server-side) -- the completion event is simply never delivered to the streaming client.
  5. Calling the same deployed resource with message:send (non-streaming) instead, with an identical request, returns the complete, correct Task result immediately, every time.

Second failure mode (reproduced only after the 1.1.2/2.6.3 upgrade)

Using google.adk.agents.remote_a2a_agent.RemoteA2aAgent with ClientConfig(streaming=True), pointed at a second deployed Agent Engine agent that the first agent delegates to (orchestrator -> specialist, both independently deployed as their own reasoningEngines resources), on a2a-sdk==1.1.2 / google-adk==2.6.3 on both ends:

ERROR: A2A request failed: append=True for nonexistent artifact_id='...' in task '...'.
The artifact must be created (append=False) before appending parts to it.

Reproduced twice, on two separate calls with different task/artifact IDs, same failure shape both times. Using ClientConfig(streaming=False) for the identical delegation call works correctly every time (this is the workaround currently in place).

Versions tested (all four combinations)

Client Server (deployed) Result
a2a-sdk 1.1.1 / google-adk 2.5.0 a2a-sdk 1.1.1 / google-adk 2.5.0 Truncates after WORKING
a2a-sdk 1.1.2 / google-adk 2.6.3 a2a-sdk 1.1.1 / google-adk 2.5.0 (unchanged) Identical truncation
a2a-sdk 1.1.2 / google-adk 2.6.3 a2a-sdk 1.1.2 / google-adk 2.6.3 RestTransport raw call: identical truncation. RemoteA2aAgent delegation call: the "append=True for nonexistent artifact_id" error above

Expected behavior

message:stream against a deployed Agent Engine target should deliver the same events a message:send call resolves to, in the correct order, without a gap between WORKING and the final artifact/completion -- matching the behavior already observed against a local (non-Agent-Engine) A2A server with byte-identical agent code.

Environment

  • Deployment: google-cloud-aiplatform[agent_engines,adk], Vertex AI Agent Engine / Reasoning Engine, standard AdkApp wrapping (not BYOD custom container)
  • Python 3.12
  • a2a-sdk: 1.1.1 and 1.1.2 (both tested, both affected)
  • google-adk: 2.5.0 and 2.6.3 (both tested, both affected)

Additional context

This looks like it lives in Agent Engine's own REST-wrapped proxy layer between the client and the deployed container's A2A server, rather than in either Python library directly -- the identical agent code, unmodified, streams correctly end-to-end against a local (non-Agent-Engine) A2A server. Happy to share a minimal repro repo if useful.

Metadata

Metadata

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions