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

RUN_CANCELLED missing from @ag-ui/core EventSchemas while adapter unions declare it; cancel is indistinguishable from provider failure

Abierto
#2,327 3 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Python
Estrellas
15.9k
Forks
1.4k
Merge medio
1 d 17 h
PR fusionados (30 d)
163

Descripción

## Context

We're evaluating AG-UI as the production wire for a music-production agent app (Mastra backend, assistant-ui frontend), with a bounded proof: our server emits AG-UI events over SSE, validated against `@ag-ui/core`'s own `EventSchemas`, consumed by `@ag-ui/client`'s `HttpAgent` (only `fetch` stubbed). Versions: `@ag-ui/core@0.0.57`, `@ag-ui/client@0.0.57`, `@assistant-ui/react-ag-ui@0.0.50`.

Four findings from that proof, receipts below — the first is the one that blocks us.

## 1. `RUN_CANCELLED` is rejected by `EventSchemas`, but adapter unions declare it

`@ag-ui/core@0.0.57`'s `EventSchemas` rejects a `RUN_CANCELLED` event with `invalid_union_discriminator`, while `@assistant-ui/react-ag-ui@0.0.50`'s own `AgUiEvent` union declares one — the two halves of the ecosystem disagree about whether the event exists.

Consequence: a server that cancels a run has no standard event to say so. The only conforming option is a coded `RUN_ERROR`.

## 2. `runAgent` resolves on `RUN_ERROR`, so cancellation is indistinguishable from provider failure

With cancel degraded to `RUN_ERROR`, `HttpAgent.runAgent` does **not** reject — it resolves. A caller cannot tell "the user stopped this" from "the model/provider blew up" unless it subscribes to the event stream and reads a non-standard `code` field. A first-class `RUN_CANCELLED` (or a typed reason on `RUN_FINISHED`) would fix both this and #1.

## 3. `HttpAgentConfig` has no `credentials` option

`requestInit()` emits only `{method, headers, body}`. Cookie-session auth (our case: same-site session cookie) requires replacing `fetch` wholesale. A `credentials?: RequestCredentials` passthrough would remove the workaround.

## 4. `THINKING_TEXT_MESSAGE_*` carries no `messageId`

Reasoning content that must stay id-addressable has to ride the id-keyed `REASONING_MESSAGE_*` channel instead, which materializes reasoning as a separate `role: "reasoning"` message rather than a part of the assistant turn (client-side consequence filed against assistant-ui separately).

Happy to provide the validation harness details or test cases for any of these.

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.