Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở Phù hợp với người mới
#7,334 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 5 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
84/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python
Lĩnh vực
api

Hướng nghiên cứu

Bắt đầu tại google/adk/a2a/agent/interceptors/new_integration_extension.py:43-51 và so sánh việc cập nhật context của nó với hành vi transport của a2a-sdk 1.x được mô tả trong issue. Giữ nguyên các tham số service hiện có, đồng thời đặt header A2A-Extensions vào nơi các transport HTTP và gRPC đọc nó, sau đó chạy bản tái hiện in-process được cung cấp và xác nhận rằng server đã ghi nhận header.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Python
Star
21.6k
Fork
4k
Merge trung bình
12 giờ 6 phút
Pull request đã merge (30 ngày)
4

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của google/adk-python

Tất cả issue của google/adk-python

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.