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

[Feature]: Add AGUIStreamOptions.IncludeRawEvents to make rawEvent attachment opt-out (.NET)

Đang mở
#2,297 1 bình luận 1 reaction 0 người được giao Xem trên GitHub
enhancement
Ngôn ngữ chính
Python
Star
15.9k
Fork
1.4k
Merge trung bình
1 ngày 17 giờ
Pull request đã merge (30 ngày)
163

Mô tả

### Pre-flight Checklist

- [x] I have searched existing issues and this hasn't been requested yet.

### Problem or Motivation

`AsAGUIEventStreamAsync` serializes every `ChatResponseUpdate` and attaches it as `rawEvent` to each event derived from it (`TEXT_MESSAGE_*`, `TOOL_CALL_*`, `REASONING_ENCRYPTED_VALUE`). There is no way to turn it off.

Measured on this repo's own `Step*` server baselines: `rawEvent` is **66% of the wire** (425,009 → 145,716 bytes when stripped; `TEXT_MESSAGE_CONTENT` +213%, `TOOL_CALL_END` +648%). It rides protobuf as well as SSE.

Nothing reads it. The .NET client's only `RawEvent` reference is the *event type* (`EventStreamConverter.cs:341`); the TS client only writes the field on its own error events (`transform/http.ts:72`).

It is also a .NET-only divergence: no TS or Python server populates `rawEvent` (Python declares `raw_event: Optional[Any] = None` and never sets it), and `agui-cross-sdk-parity/SKILL.md:27` makes TypeScript canonical for wire format.

### Proposed Solution

An init-only `bool IncludeRawEvents` on `AGUIStreamOptions`, default `true` so nothing changes. Guard the serialization, not the assignment, so opting out also recovers the per-update CPU and allocations (`ChatResponseUpdateAGUIExtensions.cs:200`):

```csharp
JsonElement? raw = options.IncludeRawEvents
? JsonSerializer.SerializeToElement(chatResponse, jsonSerializerOptions.GetTypeInfo(typeof(ChatResponseUpdate)))
: null;
```

Every `Create` already takes `JsonElement?`, so this widens one internal signature (`ReasoningMessageTracker.EmitEncryptedValue`). Events the caller supplies — via `RawRepresentation` or a `Map*` callback — keep their own `RawEvent`. Event sequence is unchanged, so this is not a protocol change.

### Alternatives Considered

**A host-side stream filter** that nulls `RawEvent` before the formatter. Works (verified, −61% on a short stream) but still pays the serialization, must be reimplemented per host, and can't tell an SDK-attached payload from a deliberate one.

**Defaulting to `false`.** Arguably correct long-term — it is what puts .NET in parity — but flipping it breaks anyone reading the field and moves every baseline. Better as a separate, deliberate change.

**Emitting `BaseEvent`s via `RawRepresentation`** to hit the short-circuit above line 200. Avoids the serialization entirely, but means reimplementing text/tool/reasoning tracking.

### Additional Context

_No response_

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.