Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions python/a2ui_a2a/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ This installs `a2ui-agent-sdk` and `a2a-sdk` as dependencies.
when the client asks for it. `get_a2ui_extension_uri` and
`A2UI_EXTENSION_BASE_URI` give the extension URI for a protocol version.
- Part helpers: `create_a2ui_part`, `is_a2ui_part` and `get_a2ui_datapart`
wrap and unwrap A2UI messages in A2A `DataPart`s. `parse_response_to_parts`,
`parse_stream_chunk_to_parts`, `stream_response_to_parts` and
`parse_content_to_parts` turn model output into A2A parts.
wrap and unwrap A2UI messages in A2A `DataPart`s. `to_a2a_parts` converts
the parts that `A2uiRequestProcessor.parse_response()` returns, and
`stream_response_to_parts` reads a streamed response through a
`ResponseStream`, such as one from `A2uiRequestProcessor.open_stream()`.
Both leave validation errors to the caller. `parse_content_to_parts`
parses a whole response with a `Parser`, such as
`A2uiRequestProcessor.parser`, and logs and drops one that fails. A canvas
agent passes it the `RendererState` it keeps with `state=`.

```python
from a2ui.a2a import create_a2ui_part, get_a2ui_agent_extension
Expand Down
7 changes: 7 additions & 0 deletions python/a2ui_agent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased

- Add `A2UI_RENDERER_CAPABILITIES_KEY` (`"a2uiRendererCapabilities"`) to
`a2ui.constants`, the message metadata key under which the v1.0 A2A
extension sends the renderer capabilities. v0.8 and v0.9 use
`A2UI_CLIENT_CAPABILITIES_KEY`.
- Add `RendererState` to `a2ui.utils`. A `RendererState` is the agent's mirror
of the surfaces a renderer holds: it wraps one `MessageProcessor` and checks
each outbound message against everything sent before it, so a canvas agent
Expand Down Expand Up @@ -83,6 +87,9 @@
per response are removed. To migrate:
- `Parser.parse_chunk(chunk, wrapped)`: open a stream with
`parser.open_stream(wrapped=...)` and call `feed(chunk)`, then `close()`.
- `A2uiRequestProcessor.create_parser()`: use the `processor.parser`
property, which returns the one parser the processor reuses, or
`processor.parse_response` and `processor.open_stream`.
- The `parser` property of `DirectJsonFormat`, `ExpressFormat`,
`ElementalFormat` and `AtomFormat`: use `create_parser()`.
- `validate_payload(..., surface_catalog_ids=...)`: check the payload
Expand Down
23 changes: 14 additions & 9 deletions python/a2ui_agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ The following directories contain the base protocol logic, parsing, and schema o
### Processor & Catalog Configuration (`src/a2ui/processor`)

- **`generator.py`**: Defines `A2uiGenerator`, the main entry point for configuring an agent's catalogs and default inference format factory.
- **`processor.py`**: Defines `A2uiRequestProcessor`, which binds the active catalogs negotiated for a request to an inference format and exposes prompt generation and response parsing.
- **`processor.py`**: Defines `A2uiRequestProcessor`, which binds the active catalogs negotiated for a request to an inference format and exposes prompt generation and response parsing. An agent creates one for each request with `A2uiGenerator.create_processor`, from the capabilities that the client sent.
- **`catalog_config.py`**: Defines `CatalogConfig`, which binds a `Catalog` (or loads one from a path via `CatalogConfig.from_path`) with an optional sequence of `CatalogTransformer` instances into `transformed_catalog`.
- **`catalog_providers.py`**: Defines `CatalogProvider`, `FileSystemCatalogProvider`, and `InMemoryCatalogProvider` for loading catalogs.

### Constants (`src/a2ui/constants.py`)

- Protocol and SDK string constants such as `A2UI_OPEN_TAG`,
`A2UI_CLOSE_TAG` and `A2UI_CLIENT_CAPABILITIES_KEY`. Protocol versions are
`A2UI_CLOSE_TAG`, `A2UI_CLIENT_CAPABILITIES_KEY` and
`A2UI_RENDERER_CAPABILITIES_KEY`. Protocol versions are
`a2ui.core.schema.ProtocolVersion` members. The
module has no dependencies, so callers that only need a constant can import
`a2ui.constants` without loading the rest of the SDK.
Expand All @@ -44,17 +45,21 @@ The following directories contain the base protocol logic, parsing, and schema o
`prune_common_types_schema` reduce the protocol schemas to the allowed
messages and the common types that are referenced.
- **`renderer_state.py`**: `RendererState` is the agent's mirror of the
surfaces a renderer holds, and checks each outbound message against
everything sent before it. `validate_payload` checks one payload the way a
renderer holding the catalogs would, on a short-lived `RendererState`, and
raises `A2uiValidationError` if the renderer would reject it.
surfaces a renderer holds. It wraps one `MessageProcessor` and checks each
outbound message against everything sent before it. A chat agent uses a new
state per turn, which is what a parser does when it is given none. A canvas
agent keeps one state for the whole conversation. `validate_payload` checks
one payload the way a renderer holding the catalogs would, on a short-lived
`RendererState`, and raises `A2uiValidationError` if the renderer would
reject it.

### Parser (`src/a2ui/parser`)

- **`parser.py`**: Defines the `Parser` abstract base class (`wrap`, `unwrap`, `compile`, `decompile`, `parse_response`, and `parse_chunk` for formats whose `supports_streaming` is true).
- **`parser.py`**: Defines the `Parser` abstract base class. A format implements `compile` and `decompile`, which translate between its notation and A2UI messages, and `wrap` and `unwrap`, which handle its tags. The base class reads model responses with `parse_response`. `open_stream` reads a response chunk by chunk; the base class raises `NotImplementedError`, and only formats that stream, whose `supports_streaming` is true, implement it. Both check every message against a `RendererState`. A parser holds no per-response state, so one parser can be reused across turns.
- **`response_stream.py`**: Defines the `ResponseStream` that `open_stream` returns.
- **`response_part.py`**: Defines `ResponsePart` (`TextPart` / `A2uiPart`) and `RawResponsePart` (`RawA2uiPart`).
- **`lexer.py`**: Defines `BlockLexer` for sentinel-tag tokenization (`<a2ui-json>...</a2ui-json>`).
- **`errors.py`**: Defines `A2uiParseError` and `A2uiTargetNotFoundError`.
- **`errors.py`**: Defines `A2uiCompilationError` and its subclasses `A2uiCompilationParseError` and `A2uiCompilationValidationError`.
- **`messages.py`**: `to_message_models` and `to_message_dicts` convert between message dictionaries and typed models.
- **`payload_fixer.py`**: Utilities to automatically correct common LLM output
issues in A2UI payloads.
Expand All @@ -63,7 +68,7 @@ The following directories contain the base protocol logic, parsing, and schema o

- **`prompt/generator.py`**: Defines the `PromptGenerator` (`A2uiPromptGenerator`) abstract base class (`generate_base_rules`, `generate_catalog_instructions`, `generate_examples`, `generate`).
- **`inference_format.py`**: Defines `InferenceFormat` and `InferenceFormatFactory`.
- **`inference_formats/`**: Format implementations and factories for Direct JSON (`direct_json/`), Express (`express/`), and experimental Elemental and Atom (`experimental/`) formats. Direct JSON is the format that streams: `DirectJsonParser.parse_chunk` heals the partial JSON of each chunk (`direct_json/json_reader.py`) and emits the messages that are ready.
- **`inference_formats/`**: Format implementations and factories for Direct JSON (`direct_json/`), Express (`express/`), and experimental Elemental and Atom (`experimental/`) formats. Direct JSON is the format that streams: the stream from `DirectJsonParser.open_stream` heals the partial JSON of each chunk (`direct_json/json_reader.py`) and emits the messages that are ready.

## Agent framework integrations

Expand Down
Loading
Loading