Back to Copilotkit

AG-UI Protocol Specification -- Event Type Reference

skills/copilotkit-agui/references/protocol-spec.md

1.58.025.1 KB
Original Source

AG-UI Protocol Specification -- Event Type Reference

Complete reference for all AG-UI event types, derived from @ag-ui/core Zod schemas.

Base Event Fields

All events extend BaseEventSchema and share these fields:

FieldTypeRequiredDescription
typeEventType (string enum)YesEvent type discriminator
timestampnumberNoUnix timestamp (ms) when event was created
rawEventanyNoOriginal event data if transformed from another format

Events use .passthrough() so additional fields are preserved through parsing.


Lifecycle Events

RUN_STARTED

Emitted first when an agent begins processing. Establishes the run context.

FieldTypeRequiredDescription
type"RUN_STARTED"Yes
threadIdstringYesConversation thread ID
runIdstringYesUnique run ID
parentRunIdstringNoLineage pointer for branching/time travel
inputRunAgentInputNoThe exact agent input payload for this run
json
{
  "type": "RUN_STARTED",
  "threadId": "thread-abc",
  "runId": "run-123"
}

RUN_FINISHED

Emitted when an agent run completes successfully. No further events for this run after this.

FieldTypeRequiredDescription
type"RUN_FINISHED"Yes
threadIdstringYesConversation thread ID
runIdstringYesRun ID matching RUN_STARTED
resultanyNoOutput data from the run
json
{
  "type": "RUN_FINISHED",
  "threadId": "thread-abc",
  "runId": "run-123",
  "result": { "summary": "Task completed" }
}

RUN_ERROR

Emitted when an agent encounters an unrecoverable error. Terminates the run.

FieldTypeRequiredDescription
type"RUN_ERROR"Yes
messagestringYesError description
codestringNoError code (e.g., "abort", "timeout")
json
{
  "type": "RUN_ERROR",
  "message": "Model API rate limited",
  "code": "rate_limit"
}

STEP_STARTED

Emitted when a named step/phase begins within a run. Optional but recommended for progress visibility.

FieldTypeRequiredDescription
type"STEP_STARTED"Yes
stepNamestringYesName of the step (e.g., node name, function name)
json
{
  "type": "STEP_STARTED",
  "stepName": "retrieve_documents"
}

STEP_FINISHED

Emitted when a named step completes. Must match a corresponding STEP_STARTED.

FieldTypeRequiredDescription
type"STEP_FINISHED"Yes
stepNamestringYesName of the step
json
{
  "type": "STEP_FINISHED",
  "stepName": "retrieve_documents"
}

Text Message Events

TEXT_MESSAGE_START

Begins a new streaming text message.

FieldTypeRequiredDescription
type"TEXT_MESSAGE_START"Yes
messageIdstringYesUnique message ID
role"developer" | "system" | "assistant" | "user"NoDefaults to "assistant"
namestringNoOptional sender name
json
{
  "type": "TEXT_MESSAGE_START",
  "messageId": "msg-1",
  "role": "assistant"
}

TEXT_MESSAGE_CONTENT

Delivers a chunk of text content. Multiple events build the complete message.

FieldTypeRequiredDescription
type"TEXT_MESSAGE_CONTENT"Yes
messageIdstringYesMust match TEXT_MESSAGE_START.messageId
deltastringYesText chunk (must be non-empty)
json
{
  "type": "TEXT_MESSAGE_CONTENT",
  "messageId": "msg-1",
  "delta": "Hello, how can "
}

TEXT_MESSAGE_END

Signals that a text message is complete. No more content for this messageId.

FieldTypeRequiredDescription
type"TEXT_MESSAGE_END"Yes
messageIdstringYesMust match TEXT_MESSAGE_START.messageId
json
{
  "type": "TEXT_MESSAGE_END",
  "messageId": "msg-1"
}

TEXT_MESSAGE_CHUNK (Convenience)

Auto-expands into TEXT_MESSAGE_START / TEXT_MESSAGE_CONTENT / TEXT_MESSAGE_END via the client's transformChunks pipeline. Simplifies backend implementation.

FieldTypeRequiredDescription
type"TEXT_MESSAGE_CHUNK"Yes
messageIdstringNoRequired on first chunk; links subsequent chunks
role"developer" | "system" | "assistant" | "user"NoRole for the message
deltastringNoText content chunk
namestringNoOptional sender name

The client transformer handles lifecycle:

  • First chunk with a new messageId emits TEXT_MESSAGE_START
  • Each chunk with delta emits TEXT_MESSAGE_CONTENT
  • TEXT_MESSAGE_END is emitted when the stream switches to a new messageId or completes
json
{
  "type": "TEXT_MESSAGE_CHUNK",
  "messageId": "msg-1",
  "role": "assistant",
  "delta": "Hello!"
}

Tool Call Events

TOOL_CALL_START

Begins a new tool invocation.

FieldTypeRequiredDescription
type"TOOL_CALL_START"Yes
toolCallIdstringYesUnique ID for this tool call
toolCallNamestringYesName of the tool being called
parentMessageIdstringNoLinks tool call to a parent assistant message
json
{
  "type": "TOOL_CALL_START",
  "toolCallId": "tc-1",
  "toolCallName": "searchDatabase",
  "parentMessageId": "msg-1"
}

TOOL_CALL_ARGS

Streams argument data for a tool call. Arguments are JSON fragments that concatenate to form the complete arguments object.

FieldTypeRequiredDescription
type"TOOL_CALL_ARGS"Yes
toolCallIdstringYesMust match TOOL_CALL_START.toolCallId
deltastringYesArgument JSON fragment
json
{
  "type": "TOOL_CALL_ARGS",
  "toolCallId": "tc-1",
  "delta": "{\"query\": \"recent orders\"}"
}

TOOL_CALL_END

Signals that a tool call's arguments are complete.

FieldTypeRequiredDescription
type"TOOL_CALL_END"Yes
toolCallIdstringYesMust match TOOL_CALL_START.toolCallId
json
{
  "type": "TOOL_CALL_END",
  "toolCallId": "tc-1"
}

TOOL_CALL_RESULT

Delivers the result of a tool execution. Sent after the tool has been executed (typically by the client/frontend).

FieldTypeRequiredDescription
type"TOOL_CALL_RESULT"Yes
messageIdstringYesMessage ID for this result in conversation history
toolCallIdstringYesMust match the corresponding TOOL_CALL_START.toolCallId
contentstringYesTool execution output
role"tool"NoDefaults to "tool"
json
{
  "type": "TOOL_CALL_RESULT",
  "messageId": "msg-tool-1",
  "toolCallId": "tc-1",
  "content": "{\"results\": [{\"orderId\": \"123\"}]}",
  "role": "tool"
}

TOOL_CALL_CHUNK (Convenience)

Auto-expands into TOOL_CALL_START / TOOL_CALL_ARGS / TOOL_CALL_END via the client's transformChunks pipeline.

FieldTypeRequiredDescription
type"TOOL_CALL_CHUNK"Yes
toolCallIdstringNoRequired on first chunk
toolCallNamestringNoRequired on first chunk
parentMessageIdstringNoLinks to parent message
deltastringNoArgument JSON fragment
json
{
  "type": "TOOL_CALL_CHUNK",
  "toolCallId": "tc-1",
  "toolCallName": "searchDatabase",
  "delta": "{\"query\":"
}

State Management Events

STATE_SNAPSHOT

Delivers a complete replacement of the agent's state. Frontend should discard existing state and use this snapshot.

FieldTypeRequiredDescription
type"STATE_SNAPSHOT"Yes
snapshotanyYesComplete state object
json
{
  "type": "STATE_SNAPSHOT",
  "snapshot": {
    "documents": [],
    "currentStep": "planning",
    "progress": 0
  }
}

STATE_DELTA

Delivers incremental state updates as RFC 6902 JSON Patch operations. Applied to current state using fast-json-patch.

FieldTypeRequiredDescription
type"STATE_DELTA"Yes
deltaArray<JsonPatchOp>YesArray of JSON Patch operations

JSON Patch operations:

  • { "op": "add", "path": "/key", "value": ... }
  • { "op": "replace", "path": "/key", "value": ... }
  • { "op": "remove", "path": "/key" }
  • { "op": "move", "path": "/to", "from": "/from" }
  • { "op": "copy", "path": "/to", "from": "/from" }
  • { "op": "test", "path": "/key", "value": ... }
json
{
  "type": "STATE_DELTA",
  "delta": [
    { "op": "replace", "path": "/currentStep", "value": "executing" },
    { "op": "replace", "path": "/progress", "value": 0.5 }
  ]
}

MESSAGES_SNAPSHOT

Delivers a complete snapshot of the conversation message history. Uses edit-based merge: existing messages present in the snapshot are replaced, activity messages are preserved, messages not in the snapshot are removed, and new messages from the snapshot are appended.

FieldTypeRequiredDescription
type"MESSAGES_SNAPSHOT"Yes
messagesMessage[]YesArray of message objects
json
{
  "type": "MESSAGES_SNAPSHOT",
  "messages": [
    { "id": "m1", "role": "user", "content": "Hello" },
    { "id": "m2", "role": "assistant", "content": "Hi there!" }
  ]
}

Activity Events

ACTIVITY_SNAPSHOT

Delivers a complete snapshot of an activity (structured progress update displayed between chat messages).

FieldTypeRequiredDescription
type"ACTIVITY_SNAPSHOT"Yes
messageIdstringYesActivity message ID
activityTypestringYesDiscriminator (e.g., "PLAN", "SEARCH", "CODE")
contentRecord<string, any>YesStructured activity data
replacebooleanNoDefaults to true. If false, ignored when message exists
json
{
  "type": "ACTIVITY_SNAPSHOT",
  "messageId": "activity-1",
  "activityType": "SEARCH",
  "content": {
    "query": "CopilotKit setup",
    "results": [],
    "status": "searching"
  }
}

ACTIVITY_DELTA

Applies JSON Patch updates to an existing activity message's content.

FieldTypeRequiredDescription
type"ACTIVITY_DELTA"Yes
messageIdstringYesMust match an existing activity message
activityTypestringYesActivity discriminator
patchArray<JsonPatchOp>YesRFC 6902 JSON Patch operations
json
{
  "type": "ACTIVITY_DELTA",
  "messageId": "activity-1",
  "activityType": "SEARCH",
  "patch": [
    { "op": "replace", "path": "/status", "value": "complete" },
    {
      "op": "add",
      "path": "/results/0",
      "value": { "title": "Getting Started" }
    }
  ]
}

Reasoning Events

REASONING_START

Marks the beginning of a reasoning process (chain-of-thought).

FieldTypeRequiredDescription
type"REASONING_START"Yes
messageIdstringYesReasoning context ID
json
{
  "type": "REASONING_START",
  "messageId": "reasoning-1"
}

REASONING_MESSAGE_START

Begins a streaming reasoning message (visible portion of chain-of-thought).

FieldTypeRequiredDescription
type"REASONING_MESSAGE_START"Yes
messageIdstringYesMessage ID
role"reasoning"YesAlways "reasoning"
json
{
  "type": "REASONING_MESSAGE_START",
  "messageId": "reasoning-msg-1",
  "role": "reasoning"
}

REASONING_MESSAGE_CONTENT

Delivers a chunk of reasoning text.

FieldTypeRequiredDescription
type"REASONING_MESSAGE_CONTENT"Yes
messageIdstringYesMust match REASONING_MESSAGE_START.messageId
deltastringYesReasoning text chunk (must be non-empty)
json
{
  "type": "REASONING_MESSAGE_CONTENT",
  "messageId": "reasoning-msg-1",
  "delta": "Let me think about this..."
}

REASONING_MESSAGE_END

Signals a reasoning message is complete.

FieldTypeRequiredDescription
type"REASONING_MESSAGE_END"Yes
messageIdstringYesMust match REASONING_MESSAGE_START.messageId
json
{
  "type": "REASONING_MESSAGE_END",
  "messageId": "reasoning-msg-1"
}

REASONING_MESSAGE_CHUNK (Convenience)

Auto-expands into REASONING_MESSAGE_START / CONTENT / END via client transformer.

FieldTypeRequiredDescription
type"REASONING_MESSAGE_CHUNK"Yes
messageIdstringNoRequired on first chunk
deltastringNoReasoning text chunk
json
{
  "type": "REASONING_MESSAGE_CHUNK",
  "messageId": "reasoning-msg-1",
  "delta": "Analyzing the request..."
}

REASONING_END

Marks the end of a reasoning process.

FieldTypeRequiredDescription
type"REASONING_END"Yes
messageIdstringYesMust match REASONING_START.messageId
json
{
  "type": "REASONING_END",
  "messageId": "reasoning-1"
}

REASONING_ENCRYPTED_VALUE

Attaches encrypted chain-of-thought to a message or tool call. Used for zero-data-retention (ZDR) scenarios where reasoning must be preserved across turns but not exposed to the client.

FieldTypeRequiredDescription
type"REASONING_ENCRYPTED_VALUE"Yes
subtype"message" | "tool-call"YesEntity type this reasoning belongs to
entityIdstringYesID of the message or tool call
encryptedValuestringYesOpaque encrypted content blob
json
{
  "type": "REASONING_ENCRYPTED_VALUE",
  "subtype": "message",
  "entityId": "msg-1",
  "encryptedValue": "eyJhbGciOiJSU0..."
}

Custom / Extension Events

RAW

Passthrough container for events from external systems.

FieldTypeRequiredDescription
type"RAW"Yes
eventanyYesOriginal event data
sourcestringNoSource system identifier
json
{
  "type": "RAW",
  "event": { "vendor_type": "langchain_event", "data": {} },
  "source": "langchain"
}

CUSTOM

Application-specific extension events with named semantics.

FieldTypeRequiredDescription
type"CUSTOM"Yes
namestringYesCustom event name
valueanyYesEvent payload
json
{
  "type": "CUSTOM",
  "name": "citation",
  "value": { "url": "https://example.com", "title": "Reference" }
}

Deprecated Events (Remove in 1.0.0)

These THINKING events are replaced by REASONING events:

DeprecatedReplacement
THINKING_STARTREASONING_START
THINKING_ENDREASONING_END
THINKING_TEXT_MESSAGE_STARTREASONING_MESSAGE_START
THINKING_TEXT_MESSAGE_CONTENTREASONING_MESSAGE_CONTENT
THINKING_TEXT_MESSAGE_ENDREASONING_MESSAGE_END

The client SDK includes BackwardCompatibility_0_0_45 middleware that auto-converts these.


Transport Encoding

SSE (Server-Sent Events)

Default transport. Content-Type: text/event-stream.

Each event is encoded as:

data: <JSON>\n\n

The @ag-ui/encoder EventEncoder class produces this format:

typescript
import { EventEncoder } from "@ag-ui/encoder";

const encoder = new EventEncoder();
const sseString = encoder.encode(event); // "data: {...}\n\n"

Binary (Protobuf)

Optional binary transport using @ag-ui/proto. Content-Type: application/x-ag-ui.

Each message is length-prefixed: 4-byte big-endian uint32 length header followed by protobuf-encoded message bytes.

The EventEncoder auto-detects format from the Accept header:

typescript
const encoder = new EventEncoder({ accept: req.headers.accept });
encoder.getContentType(); // "text/event-stream" or "application/x-ag-ui"
encoder.encodeBinary(event); // Uint8Array (SSE bytes or protobuf)

Type Definitions (RunAgentInput)

The input payload sent to the agent on each run:

FieldTypeRequiredDescription
threadIdstringYesConversation thread ID
runIdstringYesUnique run ID
parentRunIdstringNoParent run for branching
stateanyYesCurrent state
messagesMessage[]YesConversation history
toolsTool[]YesAvailable tools
contextContext[]YesAdditional context
forwardedPropsanyYesPass-through properties

Message Types

Messages are discriminated by role:

RoleFieldsDescription
developerid, role, content, name?, encryptedValue?Developer/system instructions
systemid, role, content, name?, encryptedValue?System messages
assistantid, role, content?, toolCalls?, name?, encryptedValue?Agent responses
userid, role, content (string or InputContent[]), name?User messages (supports multimodal)
toolid, role, content, toolCallId, error?, encryptedValue?Tool results
activityid, role, activityType, content (Record)Activity progress
reasoningid, role, content, encryptedValue?Reasoning/thinking content

Tool Definition

typescript
interface Tool {
  name: string; // Tool name
  description: string; // Human-readable description
  parameters: any; // JSON Schema for parameters
}

InputContent (Multimodal)

User messages can contain mixed content:

  • TextInputContent: { type: "text", text: string }
  • BinaryInputContent: { type: "binary", mimeType: string, id?: string, url?: string, data?: string, filename?: string } (requires at least one of id, url, or data)