Skip to content

A2UIResponseParser

autogen.agents.experimental.a2ui.response_parser.A2UIResponseParser #

A2UIResponseParser(version_string, delimiter=A2UI_DEFAULT_DELIMITER, server_to_client_schema=None, schema_registry=None, component_schemas=None, catalog_id=None)

Parses and validates A2UI JSON from agent responses.

Looks for a delimiter in the agent's response text, extracts the JSON array after it, and optionally validates against the A2UI schema.

Source code in autogen/agents/experimental/a2ui/response_parser.py
def __init__(
    self,
    version_string: str,
    delimiter: str = A2UI_DEFAULT_DELIMITER,
    server_to_client_schema: dict[str, Any] | None = None,
    schema_registry: Any | None = None,
    component_schemas: dict[str, dict[str, Any]] | None = None,
    catalog_id: str | None = None,
) -> None:
    self._delimiter = delimiter
    self._schema = server_to_client_schema
    self._registry = schema_registry
    self._version_string = version_string
    self._component_schemas = component_schemas or {}
    self._catalog_id = catalog_id

parse #

parse(response)

Extract text and A2UI operations from an agent response.

PARAMETER DESCRIPTION
response

The full agent response string.

TYPE: str

RETURNS DESCRIPTION
A2UIParseResult

An A2UIParseResult with the text, operations, and any errors.

Source code in autogen/agents/experimental/a2ui/response_parser.py
def parse(self, response: str) -> A2UIParseResult:
    """Extract text and A2UI operations from an agent response.

    Args:
        response: The full agent response string.

    Returns:
        An A2UIParseResult with the text, operations, and any errors.
    """
    if self._delimiter not in response:
        return A2UIParseResult(
            text=response.strip(),
            operations=[],
            has_a2ui=False,
        )

    text_part, json_part = response.split(self._delimiter, 1)
    json_part = strip_markdown_fences(json_part)

    if not json_part:
        return A2UIParseResult(
            text=text_part.strip(),
            operations=[],
            has_a2ui=False,
        )

    try:
        parsed = json.loads(json_part)
    except json.JSONDecodeError as e:
        return A2UIParseResult(
            text=text_part.strip(),
            operations=[],
            has_a2ui=True,
            raw_json=json_part,
            parse_error=f"Invalid JSON: {e}",
        )

    # Normalize: accept both a single object and an array
    if isinstance(parsed, dict):
        parsed = [parsed]

    if not isinstance(parsed, list):
        return A2UIParseResult(
            text=text_part.strip(),
            operations=[],
            has_a2ui=True,
            raw_json=json_part,
            parse_error=f"Expected JSON array or object, got {type(parsed).__name__}",
        )

    return A2UIParseResult(
        text=text_part.strip(),
        operations=parsed,
        has_a2ui=True,
        raw_json=json_part,
    )

format_validation_error #

format_validation_error(parse_result, validation_result)

Format validation errors as feedback for the LLM to self-correct.

PARAMETER DESCRIPTION
parse_result

The parsed response that failed validation.

TYPE: A2UIParseResult

validation_result

The validation result with error details.

TYPE: A2UIValidationResult

RETURNS DESCRIPTION
str

A feedback message instructing the LLM to fix the errors.

Source code in autogen/agents/experimental/a2ui/response_parser.py
def format_validation_error(
    self,
    parse_result: A2UIParseResult,
    validation_result: A2UIValidationResult,
) -> str:
    """Format validation errors as feedback for the LLM to self-correct.

    Args:
        parse_result: The parsed response that failed validation.
        validation_result: The validation result with error details.

    Returns:
        A feedback message instructing the LLM to fix the errors.
    """
    lines = ["Your A2UI output had validation errors:"]
    for error in validation_result.errors:
        lines.append(f"- {error}")
    if parse_result.parse_error:
        lines.append(f"- JSON parse error: {parse_result.parse_error}")
    lines.append("")
    lines.append(
        "Please fix these errors and regenerate the A2UI JSON. "
        f'Make sure each message includes "version": "{self._version_string}" and all required properties.'
    )
    return "\n".join(lines)

validate #

validate(operations)

Validate A2UI operations against the server_to_client schema.

PARAMETER DESCRIPTION
operations

List of A2UI operation dicts to validate.

TYPE: list[dict[str, Any]]

RETURNS DESCRIPTION
A2UIValidationResult

An A2UIValidationResult indicating validity and any errors.

Source code in autogen/agents/experimental/a2ui/response_parser.py
@require_optional_import(["jsonschema"], "a2ui")
def validate(self, operations: list[dict[str, Any]]) -> A2UIValidationResult:
    """Validate A2UI operations against the server_to_client schema.

    Args:
        operations: List of A2UI operation dicts to validate.

    Returns:
        An A2UIValidationResult indicating validity and any errors.
    """
    if self._schema is None:
        return A2UIValidationResult(is_valid=True)

    errors: list[str] = []

    if self._registry is not None:
        validator_cls = jsonschema.validators.validator_for(self._schema)
        validator = validator_cls(self._schema, registry=self._registry)
    else:
        validator = None

    for i, op in enumerate(operations):
        try:
            if validator is not None:
                validator.validate(op)
            else:
                jsonschema.validate(instance=op, schema=self._schema)
        except jsonschema.ValidationError:
            # Try to produce per-component errors for updateComponents
            comp_errors = self._drill_into_components(op)
            if comp_errors:
                errors.extend(f"Operation {i}: {ce}" for ce in comp_errors)
            else:
                # Fall back to re-validating for the top-level message
                try:
                    if validator is not None:
                        validator.validate(op)
                    else:
                        jsonschema.validate(instance=op, schema=self._schema)
                except jsonschema.ValidationError as e2:
                    errors.append(f"Operation {i}: {e2.message}")

    return A2UIValidationResult(
        is_valid=len(errors) == 0,
        errors=errors,
    )