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

Aperta
#2,327 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Python
Stelle
15.9k
Fork
1.4k
Merge medio
1g 17h
PR unite (30g)
163

Descrizione

## 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.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.