ag-ui-protocol / ag-ui-protocol/ag-ui

[adk-middleware] No agent-facing way to emit a named CustomEvent

Open
#1,915 0 comments 0 reactions 0 assignees View on GitHub
Feature Request
Dominant language
Python
Stars
15.9k
Forks
1.4k
Avg merge
1d 17h
Merged PRs (30d)
163

Description

### Summary

The ADK middleware (`ag_ui_adk`) has no supported way for an ADK agent to emit a **named** AG-UI [`CustomEvent`](https://docs.ag-ui.com/concepts/events#custom). The protocol and `ag-ui-protocol` SDK fully support `CustomEvent`, but the middleware only ever constructs them for its own internal features - there's no hook from agent code to say "emit `CustomEvent(name=…, value=…)`."

### Environment
- `ag_ui_adk` 0.6.3
- `ag-ui-protocol` 0.1.18
- `google-adk` 1.34.0

### Details

Every `CustomEvent(...)` the middleware constructs is internal:

| Location | `name=` | Trigger |
|----------|---------|---------|
| `event_translator.py:896`, `:1015`, `client_proxy_tool.py:285` | `PredictState` | predictive-state feature |
| `event_translator.py:432` | `adk_metadata` | `adk_event.custom_data` |

The one generic-looking path is unreachable:

```python
# event_translator.py
if hasattr(adk_event, 'custom_data') and adk_event.custom_data:
yield CustomEvent(type=EventType.CUSTOM, name="adk_metadata", value=adk_event.custom_data)
```

`google.adk.events.Event` has no `custom_data` field, and the model is configured `extra="ignore"`, so an agent can't set it:

```python
>>> from google.adk.events import Event
>>> e = Event(author="x", invocation_id="i")
>>> e.custom_data = {"k": "v"}
ValueError: "Event" object has no field "custom_data"
```

So `hasattr(...)` is always `False` for real ADK events, and even if it weren't, the event `name` is hardcoded to `"adk_metadata"` rather than a caller-chosen name.

The only agent-controllable output that reaches the client is `EventActions.state_delta`, which the translator turns into a `STATE_DELTA` event — never a `CustomEvent`.

### Use case

Agents need to signal app-specific moments to the client over the protocol's intended channel — e.g. `conversation_complete`, `resume_validated`, `payment_required`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.