google / google/adk-python

build_agent_card(): agent_registry cards stay streaming:false after #6673, and the streaming= parameter becomes unreachable

未关闭
#6,778 4 条评论 0 个 reaction 已指派 2 人 已被 @wuliang229 认领 在 GitHub 查看
agent config needs review
主要语言
Python
星标
21.5k
派生
4k
平均合并
1 天 22 小时
30 天内合并 PR
31

描述

Splitting this out of #6672 as suggested there, so it does not block #6673.

Two things, one root cause. In `_compat.build_agent_card()`:

```python
default_capabilities = {"streaming": streaming, "push_notifications": False}
...
"capabilities": _as_dict(capabilities) or default_capabilities,
```

The `streaming=` parameter only reaches the card through `default_capabilities`, and that is consulted only when `capabilities` is falsy. The two call sites take different branches, and #6673 changes which branch each one takes.

### 1. Cards built through `agent_registry` stay `streaming: false`

`src/google/adk/integrations/agent_registry/agent_registry.py:640` passes neither `capabilities` nor `streaming`:

```python
agent_card = _compat.build_agent_card(
name=name,
description=description,
version=version,
url=url,
protocol_binding=getattr(binding, "value", binding),
protocol_version=protocol_version,
skills=skills,
default_input_modes=["text"],
default_output_modes=["text"],
)
```

So it falls to `default_capabilities`, where `streaming` defaults to `False`. #6673 changes `AgentCardBuilder`'s default, which this call site does not go through, so a card built here advertises `streaming: false` after that fix as well as before it.

### 2. `streaming=` becomes unreachable

`src/google/adk/a2a/utils/agent_card_builder.py:85` passes `capabilities=self._capabilities` (line 94) and never passes `streaming=`. #6673 changes that field to:

```python
self._capabilities = capabilities or AgentCapabilities(streaming=True)
```

which is always truthy, so `_as_dict(capabilities)` wins and `default_capabilities` is never evaluated from this caller. Together with (1), no call site in the repository can reach the `streaming=` parameter, and a caller who sets it gets no effect and no warning.

### Reproduced

`google-adk 2.6.1`, `a2a-sdk 1.1.2`, Python 3.13.5, clean venv. `build_agent_card` is byte-identical between 2.6.1 and current main, so this applies to main.

```python
from google.adk.a2a import _compat
from a2a.types import AgentCapabilities

binding = getattr(_compat.TP_HTTP_JSON, "value", _compat.TP_HTTP_JSON)
common = dict(name="x", description="d", version="1", url="http://h/a",
skills=[], default_input_modes=["text"],
default_output_modes=["text"])

# the agent_registry call shape
card = _compat.build_agent_card(protocol_binding=binding, **common)
print(card.capabilities.streaming) # False

# streaming= is honoured, but only when capabilities is absent
card = _compat.build_agent_card(protocol_binding=binding, streaming=True, **common)
print(card.capabilities.streaming) # True

# once capabilities is passed, which is what #6673 makes the default, it is ignored
card = _compat.build_agent_card(protocol_binding=binding,
capabilities=AgentCapabilities(streaming=True),
streaming=False, **common)
print(card.capabilities.streaming) # True, streaming= had no effect
```

### Possible shapes

1. Thread `capabilities` through the `agent_registry` call site the way `AgentCardBuilder` does, and drop `streaming=` from `build_agent_card` once nothing reaches it.
2. Keep `streaming=` and make it compose rather than fall back, so it applies on top of a passed `capabilities`. This changes the meaning of an existing parameter for anyone already passing both.
3. Keep `streaming=` and document it as the no-capabilities convenience path only.

I have not opened a pull request because (2) changes the behaviour of an existing parameter and (1) removes public surface, so the choice looks like yours rather than mine. Happy to send whichever you prefer.

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。