Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[A2A] RemoteA2aAgent(use_legacy=False): extension header written to state['http_kwargs'], ignored by a2a-sdk 1.x transports

Aperta Adatta ai principianti
#7,334 2 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 5 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
84/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
api

Direzione di ricerca

Inizia in google/adk/a2a/agent/interceptors/new_integration_extension.py:43-51 e confronta il suo aggiornamento del contesto con il comportamento del trasporto di a2a-sdk 1.x descritto nell’issue. Mantieni i parametri di servizio esistenti e posiziona l’header A2A-Extensions nel punto in cui viene letto dai trasporti HTTP e gRPC, quindi esegui la riproduzione in-process fornita e conferma che il server acquisisca l’header.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Describe the Bug

With RemoteA2aAgent(use_legacy=False), ADK installs a request interceptor that is supposed to negotiate the new A2A-ADK integration extension (the one documented as the a2a-extension / v2 A2aAgentExecutor). The interceptor (google/adk/a2a/agent/interceptors/new_integration_extension.py:43-51, same code on main @ eb1a002 and on 2.7.1–2.10.0) writes the A2A-Extensions header into:

params.client_call_context.state['http_kwargs']

But on a2a-sdk 1.x, HTTP transports build outbound headers exclusively from ClientCallContext.service_parameters (a2a/client/transports/http_helpers.py:46-47 in 1.1.2):

if context and context.service_parameters:
    http_kwargs['headers'] = context.service_parameters.copy()

Nothing in a2a-sdk 1.x reads client_call_context.state['http_kwargs'], so the extension header never reaches the server. The server therefore keeps running the legacy executor even though the client asked for the new integration. (The gRPC transport likewise reads service_parameters, a2a/client/transports/grpc.py:304-305.)

For reference, a2a-sdk 1.x's own auth interceptor writes Authorization into context.service_parameters (a2a/client/auth/interceptor.py:47-84), which is the convention downstream users follow too.

Steps to Reproduce

Self-contained, in-process, no network or credentials:

import asyncio

import httpx
from google.adk.a2a.utils.agent_to_a2a import to_a2a
from google.adk.agents import LlmAgent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
from google.adk.models.base_llm import BaseLlm
from google.adk.models.llm_response import LlmResponse
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types

CAPTURED: dict[str, str] = {}


class CaptureMiddleware:
    def __init__(self, app):
        self.app = app

    async def __call__(self, scope, receive, send):
        if scope["type"] == "http":
            headers = {k.decode().lower(): v.decode() for k, v in scope["headers"]}
            if "a2a-extensions" in headers:
                CAPTURED[headers["a2a-extensions"]] = headers["a2a-extensions"]
        await self.app(scope, receive, send)


class Scripted(BaseLlm):
    async def generate_content_async(self, req, stream=False):
        yield LlmResponse(content=types.Content(role="model", parts=[types.Part(text="ok")]))


async def main():
    server = to_a2a(LlmAgent(name="remote", model=Scripted(model="x"), instruction="x"))
    async with server.router.lifespan_context(server):
        remote = RemoteA2aAgent(
            name="remote",
            agent_card="http://localhost:8000/.well-known/agent-card.json",
            use_legacy=False,
            httpx_client=httpx.AsyncClient(
                transport=httpx.ASGITransport(app=CaptureMiddleware(server))
            ),
        )
        runner = Runner(
            app_name="caller",
            agent=remote,
            session_service=InMemorySessionService(),
            auto_create_session=True,
        )
        async for _ in runner.run_async(
            user_id="u", session_id="s",
            new_message=types.Content(role="user", parts=[types.Part(text="hi")]),
        ):
            pass
    print("A2A-Extensions seen by server:", CAPTURED or "NOT RECEIVED")


asyncio.run(main())

Observed Behavior

A2A-Extensions seen by server: NOT RECEIVED

Adding a custom request_interceptors entry that puts the header into params.client_call_context.service_parameters instead makes the server receive it, which confirms the interceptor pipeline runs and the failure is specifically the state['http_kwargs'] write target.

Expected Behavior

RemoteA2aAgent(use_legacy=False) causes the A2A-Extensions: https://google.github.io/adk-docs/a2a/a2a-extension/ header to actually reach the remote server on a2a-sdk 1.x.

Environment Details

  • google-adk: 2.7.1 (pinned in my project); the interceptor source hasn't been updated since
  • a2a-sdk: 1.1.2, 1.1.5 also affected
  • Python: 3.14
  • OS: macOS 15

Impact / Suggested direction

Impact is silent: no error, the server just keeps legacy behavior. This specifically blocks use_legacy=False from doing anything on the 1.x client stack, and it masks verification of the v2-executor bugs tracked in #7247 / #6343 (their suggested workaround of activating the v2 path via use_legacy=False is a no-op on a2a-sdk 1.x).

Suggested fix: in new_integration_extension.py, write the header into params.client_call_context.service_parameters (initializing ClientCallContext if absent) and merge with any existing mapping.

Lingua principale
Python
Stelle
21.6k
Fork
4k
Merge medio
12h 6m
PR unite (30g)
4

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di google/adk-python

Tutte le issue di google/adk-python

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.