Skip to main content

Events

AG-UI uses a streaming event-based architecture. Events are the units of communication from an agent backend to a frontend UI. In .NET, every protocol event derives from BaseEvent and has a type discriminator.

Event Type Constants

AGUIEventTypes defines the SCREAMING_SNAKE_CASE wire discriminators:
AGUIEventTypes.RunStarted; // "RUN_STARTED"
AGUIEventTypes.RunFinished; // "RUN_FINISHED"
AGUIEventTypes.RunError; // "RUN_ERROR"
AGUIEventTypes.StepStarted; // "STEP_STARTED"
AGUIEventTypes.StepFinished; // "STEP_FINISHED"
AGUIEventTypes.TextMessageStart; // "TEXT_MESSAGE_START"
AGUIEventTypes.TextMessageContent; // "TEXT_MESSAGE_CONTENT"
AGUIEventTypes.TextMessageEnd; // "TEXT_MESSAGE_END"
AGUIEventTypes.ToolCallStart; // "TOOL_CALL_START"
AGUIEventTypes.ToolCallArgs; // "TOOL_CALL_ARGS"
AGUIEventTypes.ToolCallEnd; // "TOOL_CALL_END"
AGUIEventTypes.ToolCallResult; // "TOOL_CALL_RESULT"
AGUIEventTypes.StateSnapshot; // "STATE_SNAPSHOT"
AGUIEventTypes.StateDelta; // "STATE_DELTA"
AGUIEventTypes.MessagesSnapshot; // "MESSAGES_SNAPSHOT"
AGUIEventTypes.ActivitySnapshot; // "ACTIVITY_SNAPSHOT"
AGUIEventTypes.ActivityDelta; // "ACTIVITY_DELTA"
AGUIEventTypes.ReasoningStart; // "REASONING_START"
AGUIEventTypes.ReasoningMessageStart; // "REASONING_MESSAGE_START"
AGUIEventTypes.ReasoningMessageContent; // "REASONING_MESSAGE_CONTENT"
AGUIEventTypes.ReasoningMessageEnd; // "REASONING_MESSAGE_END"
AGUIEventTypes.ReasoningMessageChunk; // "REASONING_MESSAGE_CHUNK"
AGUIEventTypes.ReasoningEnd; // "REASONING_END"
AGUIEventTypes.ReasoningEncryptedValue; // "REASONING_ENCRYPTED_VALUE"
AGUIEventTypes.Raw; // "RAW"
AGUIEventTypes.Custom; // "CUSTOM"

BaseEvent

All events inherit from BaseEvent.
public abstract class BaseEvent
{
    public abstract string Type { get; } // "type"
    public long? Timestamp { get; set; } // "timestamp"
    public JsonElement? RawEvent { get; set; } // "rawEvent"
}
C# propertyJSON fieldTypeDescription
TypetypestringEvent discriminator
Timestamptimestamplong?Optional event timestamp
RawEventrawEventJsonElement?Optional original event data

Lifecycle Events

Lifecycle events represent the run and step lifecycle.

RunStartedEvent

Signals the start of an agent run.
var evt = new RunStartedEvent
{
    ThreadId = "thread-1",
    RunId = "run-1",
    ParentRunId = "run-0",
    Input = input
};
C# propertyJSON fieldTypeDescription
Typetype"RUN_STARTED"Event discriminator
ThreadIdthreadIdstringConversation thread ID
RunIdrunIdstringAgent run ID
ParentRunIdparentRunIdstring?Optional parent run ID
InputinputRunAgentInput?Optional input payload for the run

RunFinishedEvent

Signals the completion of an agent run.
var evt = new RunFinishedEvent
{
    ThreadId = "thread-1",
    RunId = "run-1",
    Outcome = new RunFinishedSuccessOutcome()
};
C# propertyJSON fieldTypeDescription
Typetype"RUN_FINISHED"Event discriminator
ThreadIdthreadIdstringConversation thread ID
RunIdrunIdstringAgent run ID
ResultresultJsonElement?Optional run result
OutcomeoutcomeRunFinishedOutcome?Optional typed outcome
RunFinishedOutcome is a polymorphic value with type: "success" or type: "interrupt". RunFinishedInterruptOutcome carries interrupts, an IList<AGUIInterrupt>.

RunErrorEvent

Signals an error during an agent run.
var evt = new RunErrorEvent
{
    Message = "The model request failed.",
    Code = "model_error"
};
C# propertyJSON fieldTypeDescription
Typetype"RUN_ERROR"Event discriminator
MessagemessagestringError message
Codecodestring?Optional error code

StepStartedEvent

Signals the start of a named step.
var evt = new StepStartedEvent { StepName = "plan" };
C# propertyJSON fieldTypeDescription
Typetype"STEP_STARTED"Event discriminator
StepNamestepNamestringStep name

StepFinishedEvent

Signals the completion of a named step.
var evt = new StepFinishedEvent { StepName = "plan" };
C# propertyJSON fieldTypeDescription
Typetype"STEP_FINISHED"Event discriminator
StepNamestepNamestringStep name

Text Message Events

Text message events stream assistant text as a start/content/end sequence.

TextMessageStartEvent

var evt = new TextMessageStartEvent
{
    MessageId = "msg-1",
    Role = AGUIRoles.Assistant,
    Name = "assistant"
};
C# propertyJSON fieldTypeDescription
Typetype"TEXT_MESSAGE_START"Event discriminator
MessageIdmessageIdstringMessage ID
RolerolestringMessage role, typically "assistant"
Namenamestring?Optional sender name

TextMessageContentEvent

var evt = new TextMessageContentEvent
{
    MessageId = "msg-1",
    Delta = "Hello"
};
C# propertyJSON fieldTypeDescription
Typetype"TEXT_MESSAGE_CONTENT"Event discriminator
MessageIdmessageIdstringMessage ID from the start event
DeltadeltastringText delta

TextMessageEndEvent

var evt = new TextMessageEndEvent { MessageId = "msg-1" };
C# propertyJSON fieldTypeDescription
Typetype"TEXT_MESSAGE_END"Event discriminator
MessageIdmessageIdstringMessage ID from the start event

Tool Call Events

Tool call events stream tool invocation arguments and optional server-side results.

ToolCallStartEvent

var evt = new ToolCallStartEvent
{
    ParentMessageId = "msg-1",
    ToolCallId = "call-1",
    ToolCallName = "get_weather"
};
C# propertyJSON fieldTypeDescription
Typetype"TOOL_CALL_START"Event discriminator
ParentMessageIdparentMessageIdstring?Optional parent assistant message ID
ToolCallIdtoolCallIdstringTool call ID
ToolCallNametoolCallNamestringTool name

ToolCallArgsEvent

var evt = new ToolCallArgsEvent
{
    ToolCallId = "call-1",
    Delta = """{"city":"Seattle"}"""
};
C# propertyJSON fieldTypeDescription
Typetype"TOOL_CALL_ARGS"Event discriminator
ToolCallIdtoolCallIdstringTool call ID
DeltadeltastringArgument JSON chunk

ToolCallEndEvent

var evt = new ToolCallEndEvent { ToolCallId = "call-1" };
C# propertyJSON fieldTypeDescription
Typetype"TOOL_CALL_END"Event discriminator
ToolCallIdtoolCallIdstringTool call ID

ToolCallResultEvent

var evt = new ToolCallResultEvent
{
    MessageId = "tool-msg-1",
    ToolCallId = "call-1",
    Content = """{"temperature":72}""",
    Role = AGUIRoles.Tool
};
C# propertyJSON fieldTypeDescription
Typetype"TOOL_CALL_RESULT"Event discriminator
MessageIdmessageIdstringTool result message ID
ToolCallIdtoolCallIdstringTool call ID
ContentcontentstringTool result content
Rolerolestring?Optional role, typically "tool"

State Management Events

State events synchronize frontend state and message history.

StateSnapshotEvent

Provides a complete state snapshot.
var evt = new StateSnapshotEvent
{
    Snapshot = JsonDocument.Parse("""{"draft":"hello"}""").RootElement.Clone()
};
C# propertyJSON fieldTypeDescription
Typetype"STATE_SNAPSHOT"Event discriminator
SnapshotsnapshotJsonElementComplete state value

StateDeltaEvent

Provides incremental state changes, commonly as JSON Patch operations.
var evt = new StateDeltaEvent
{
    Delta = JsonDocument.Parse("""
        [{ "op": "replace", "path": "/draft", "value": "hello world" }]
        """).RootElement.Clone()
};
C# propertyJSON fieldTypeDescription
Typetype"STATE_DELTA"Event discriminator
DeltadeltaJsonElementState delta payload

MessagesSnapshotEvent

Replaces the frontend conversation history with the server’s view.
var evt = new MessagesSnapshotEvent
{
    Messages =
    [
        new AGUIUserMessage { Id = "user-1", Content = "Hello" }
    ]
};
C# propertyJSON fieldTypeDescription
Typetype"MESSAGES_SNAPSHOT"Event discriminator
MessagesmessagesIList<AGUIMessage>Complete message list

Reasoning Events

Reasoning events expose a model or agent reasoning stream. They can create and update AGUIReasoningMessage entries in message history.

ReasoningStartEvent

var evt = new ReasoningStartEvent { MessageId = "reasoning-1" };
C# propertyJSON fieldTypeDescription
Typetype"REASONING_START"Event discriminator
MessageIdmessageIdstringReasoning phase ID

ReasoningMessageStartEvent

var evt = new ReasoningMessageStartEvent
{
    MessageId = "reasoning-1",
    Role = AGUIRoles.Reasoning
};
C# propertyJSON fieldTypeDescription
Typetype"REASONING_MESSAGE_START"Event discriminator
MessageIdmessageIdstringReasoning message ID
RolerolestringDefaults to "reasoning"

ReasoningMessageContentEvent

var evt = new ReasoningMessageContentEvent
{
    MessageId = "reasoning-1",
    Delta = "Checking constraints..."
};
C# propertyJSON fieldTypeDescription
Typetype"REASONING_MESSAGE_CONTENT"Event discriminator
MessageIdmessageIdstringReasoning message ID
DeltadeltastringReasoning content delta

ReasoningMessageEndEvent

var evt = new ReasoningMessageEndEvent { MessageId = "reasoning-1" };
C# propertyJSON fieldTypeDescription
Typetype"REASONING_MESSAGE_END"Event discriminator
MessageIdmessageIdstringReasoning message ID

ReasoningMessageChunkEvent

Compact reasoning message chunk event with optional fields.
var evt = new ReasoningMessageChunkEvent
{
    MessageId = "reasoning-1",
    Delta = "Partial reasoning..."
};
C# propertyJSON fieldTypeDescription
Typetype"REASONING_MESSAGE_CHUNK"Event discriminator
MessageIdmessageIdstring?Optional reasoning message ID
Deltadeltastring?Optional reasoning content delta

ReasoningEndEvent

var evt = new ReasoningEndEvent { MessageId = "reasoning-1" };
C# propertyJSON fieldTypeDescription
Typetype"REASONING_END"Event discriminator
MessageIdmessageIdstringReasoning phase ID

ReasoningEncryptedValueEvent

Attaches an encrypted value to a message or tool call.
var evt = new ReasoningEncryptedValueEvent
{
    Subtype = "message",
    EntityId = "reasoning-1",
    EncryptedValue = "opaque-token"
};
C# propertyJSON fieldTypeDescription
Typetype"REASONING_ENCRYPTED_VALUE"Event discriminator
SubtypesubtypestringEntity subtype, such as "message" or "tool-call"
EntityIdentityIdstringMessage or tool call ID
EncryptedValueencryptedValuestringOpaque encrypted value

Activity Events

Activity events carry structured progress state for UI renderers.

ActivitySnapshotEvent

var evt = new ActivitySnapshotEvent
{
    MessageId = "activity-1",
    ActivityType = "PLAN",
    Content = JsonDocument.Parse("""{"status":"running"}""").RootElement.Clone(),
    Replace = true
};
C# propertyJSON fieldTypeDescription
Typetype"ACTIVITY_SNAPSHOT"Event discriminator
MessageIdmessageIdstringActivity message ID
ActivityTypeactivityTypestringActivity discriminator
ContentcontentJsonElementStructured activity content
Replacereplacebool?Optional replace/merge hint

ActivityDeltaEvent

var evt = new ActivityDeltaEvent
{
    MessageId = "activity-1",
    ActivityType = "PLAN",
    Patch = JsonDocument.Parse("""
        [{ "op": "replace", "path": "/status", "value": "done" }]
        """).RootElement.Clone()
};
C# propertyJSON fieldTypeDescription
Typetype"ACTIVITY_DELTA"Event discriminator
MessageIdmessageIdstringActivity message ID
ActivityTypeactivityTypestringActivity discriminator
PatchpatchJsonElementActivity JSON Patch payload

Special Events

RawEvent

Passes through unprocessed external data.
var evt = new RawEvent
{
    Event = JsonDocument.Parse("""{"provider":"example","event":"token"}""").RootElement.Clone(),
    Source = "provider"
};
C# propertyJSON fieldTypeDescription
Typetype"RAW"Event discriminator
EventeventJsonElementRaw payload
Sourcesourcestring?Optional source identifier

CustomEvent

Carries application-specific data.
var evt = new CustomEvent
{
    Name = "progress",
    Value = JsonDocument.Parse("""{"percent":50}""").RootElement.Clone()
};
C# propertyJSON fieldTypeDescription
Typetype"CUSTOM"Event discriminator
NamenamestringCustom event name
ValuevalueJsonElement?Optional custom payload

Serialization

BaseEvent uses a discriminator-based JSON converter keyed on the type field. All concrete event types are registered in AGUIJsonSerializerContext.
BaseEvent evt = new TextMessageContentEvent
{
    MessageId = "msg-1",
    Delta = "Hello"
};

var json = JsonSerializer.Serialize(
    evt,
    AGUIJsonSerializerContext.Default.BaseEvent);