AG-UI Protocol
Endpoints
POST /v1/ag-ui/agents/:agent_id/runsGET /v1/ag-ui/threads/:id/messages
Request Model (RunAgentInput)
Required:
threadIdrunId
Core optional fields:
messagestoolscontextstateparentRunIdparentThreadIdmodelsystemPromptconfigforwardedProps
Minimal request:
{
"threadId": "thread-1",
"runId": "run-1",
"messages": [{ "role": "user", "content": "Plan my weekend" }],
"tools": []
}
Runtime Mapping
RunAgentInputis converted to internalRunRequest.model/systemPromptoverride resolved agent defaults for this run.configcan override tool execution mode and selected chat options.configoverrides are applied at runtime (tool execution mode, chat options) but not persisted to state.forwardedPropsis a pass-through field on the request struct.
Frontend tools
When tools[].execute = "frontend":
- backend registers runtime stub descriptors
- execution is suspended and returned as pending call
- client decisions are consumed as tool result (
resume) or denial (cancel)
Decision-only forwarding
If request has no new user input but contains interaction decisions, server first attempts to forward them to active run key (ag_ui + agent + thread + run).
Success response (202):
{
"status": "decision_forwarded",
"threadId": "thread-1",
"runId": "run-1"
}
Response Transport
content-type: text/event-streamdata:frames contain AG-UI protocol events- lifecycle includes events such as
RUN_STARTED,RUN_FINISHED
Tool progress example:
{
"type": "ACTIVITY_SNAPSHOT",
"messageId": "tool_call:call_123",
"activityType": "tool-call-progress",
"content": {
"type": "tool-call-progress",
"schema": "tool-call-progress.v1",
"node_id": "tool_call:call_123",
"parent_node_id": "tool_call:call_parent_1",
"parent_call_id": "call_parent_1",
"status": "running",
"progress": 0.4,
"message": "searching..."
},
"replace": true
}
Validation and Errors
- empty
threadId->400 - empty
runId->400 - unknown
agent_id->404
Error shape:
{ "error": "bad request: threadId cannot be empty" }