a2aproject / a2aproject/a2a-rs

a2acli: verify Agent Card capabilities before capability-gated operations

Abierto
#184 0 comentarios 0 reacciones 0 asignados Ver en GitHub
enhancement
Lenguaje dominante
Rust
Estrellas
75
Forks
19
Merge medio
11 h 27 min
PR fusionados (30 d)
21

Descripción

Part of #181 (Tier 2).

## Summary

`A2ACLI_VER_003` (Tier 2) requires the tool to **verify a capability on the Agent Card before invoking a capability-gated operation** — streaming, push notifications, or the extended card (§13.3).

`a2acli` reads `AgentCapabilities` only to render it. The three references in `a2acli/src/lib.rs` are all inside `impl TextRender for AgentCard`:

```rust
.field("Streaming", self.capabilities.streaming.unwrap_or(false))
.field("Push Notifications", self.capabilities.push_notifications.unwrap_or(false))
.field("Extended Card", self.capabilities.extended_agent_card.unwrap_or(false))
```

Nothing gates an operation on them. `send --stream` against an agent whose card declares `streaming: false` still opens a stream and relies on the server refusing it; `card get --extended` and the `task push-config` commands likewise attempt the call regardless of what the card advertises.

## Why

The current behavior is *safe* — #173 made the streaming path fall back to polling on `UNSUPPORTED_OPERATION`, and protocol errors are reported cleanly — but it is a round-trip and an error the card already told us to expect. The spec's point is that the card is the contract: if it says the capability is absent, the tool knows before it asks.

It also produces a better failure. "the agent card does not declare streaming" names the cause; a bare `UNSUPPORTED_OPERATION` from the server does not say whether the capability is absent, disabled, or unavailable right now.

## Scope

- [ ] Before `--stream` (on `send`) and before `task subscribe`, check `capabilities.streaming`.
- [ ] Before `card get --extended`, check `capabilities.extended_agent_card`.
- [ ] Before any `task push-config` subcommand, check `capabilities.push_notifications`.
- [ ] When the capability is absent: for `send --stream`, keep #173's behavior and fall back to the blocking poll path, with the reason on stderr — the caller asked for a result, not specifically for a stream. For the others, where there is no equivalent path, fail with the reason rather than making the call.
- [ ] Treat an absent (`None`) capability field as not declared, consistent with the card renderer's `unwrap_or(false)`.
- [ ] Keep every message credential-free and on stderr.
- [ ] Tests: an agent card declaring each capability `false` produces the pre-flight outcome without the corresponding RPC ever reaching the fixture server — assert on the server-side call record, not just on the CLI's output.

## Requirements closed

| ID | Requirement |
| --- | --- |
| `A2ACLI_VER_003` | Verifies a capability on the Agent Card before invoking a capability-gated operation (streaming, push, extended card) (§13.3) |

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.