Skip to content

AI SDK v6 Protocol

The AI SDK v6 adapter translates Awaken’s internal AgentEvent stream into the Vercel AI SDK v6 UI Message Stream format. This allows any AI SDK-compatible frontend (useChat, useAssistant) to consume agent output without custom parsing or a custom frontend transport adapter. Awaken-specific data-* parts are optional metadata for richer consoles; ordinary chat UIs may ignore them.

POST /v1/ai-sdk/chat
{
"messages": [
{
"id": "msg-1",
"role": "user",
"parts": [{ "type": "text", "text": "Hello" }]
}
],
"threadId": "optional-thread-id",
"agentId": "optional-agent-id"
}
FieldTypeRequiredDescription
messagesUIMessage[]yesAI SDK v6 UI messages. text and file parts become runtime content; tool/data/source parts are UI state and are not sent to the model.
threadIdstringnoExisting thread to continue. Omit to create a new thread.
agentIdstringnoTarget agent. Uses the default agent when omitted.

file parts may use hosted URLs or Data URLs. Images, audio, video, PDFs, and text-like documents are converted to runtime ContentBlocks. The selected model must advertise compatible input modalities when modalities are enforced.

SSE stream (text/event-stream). Each line is a JSON-encoded UIStreamEvent.

RouteMethodDescription
/v1/ai-sdk/threads/:thread_id/runsPOSTStart a thread-scoped run.
/v1/ai-sdk/agents/:agent_id/runsPOSTStart an agent-scoped run.
/v1/ai-sdk/agent-previews/runsPOSTRun a draft AgentSpec against the current registries without persisting it.
/v1/ai-sdk/chat/:thread_id/streamGETReconnect to an active SSE stream by thread ID.
/v1/ai-sdk/threads/:thread_id/streamGETAlias for thread stream reconnect.
/v1/ai-sdk/threads/:thread_id/replayGETReplay durable protocol frames for a thread.
/v1/ai-sdk/chat/:thread_id/replayGETAlias for durable protocol replay.
/v1/ai-sdk/threads/:thread_id/messagesGETRetrieve thread message history.
/v1/ai-sdk/threads/:thread_id/cancelPOSTCancel the active or queued run on a thread.
/v1/ai-sdk/threads/:thread_id/interruptPOSTInterrupt a thread, supersede queued work, and cancel the active run.

Replay routes require a configured ProtocolReplayLog. They accept ?cursor= or Last-Event-ID, plus ?limit= (default 100, max 500), and return SSE frames with the protocol replay cursor as the SSE id. Missing replay storage returns 503; malformed cursors return 400; expired cursors return 410 Gone.

The AiSdkEncoder is a stateful transcoder that converts AgentEvent variants into UIStreamEvent variants. It tracks open text blocks and reasoning blocks across tool-call boundaries.

AgentEventUIStreamEvent(s)
RunStartMessageStart + Data("run-info", ...)
TextDeltaTextStart (if block not open) + TextDelta
ReasoningDeltaReasoningStart (if block not open) + ReasoningDelta
ReasoningEncryptedValueReasoningStart (if not open) + ReasoningDelta
ToolCallStartClose open text/reasoning blocks, then ToolCallStart
ToolCallDeltaToolCallDelta
ToolCallDoneToolCallEnd
StepStart(no direct mapping)
StepEnd(no direct mapping)
InferenceCompleteData("inference-complete", ...)
MessagesSnapshotData("messages-snapshot", ...)
StateSnapshotData("state-snapshot", ...)
StateDeltaData("state-delta", ...)
ActivitySnapshotData("activity-snapshot", ...)
ActivityDeltaData("activity-delta", ...)
RunFinishClose open blocks, Data("finish", ...), Finish

The wire format uses the type field as a discriminant, serialized in kebab-case:

  • start — message lifecycle start, carries optional messageId and messageMetadata
  • text-start, text-delta, text-end — text block lifecycle with content ID
  • reasoning-start, reasoning-delta, reasoning-end — reasoning block lifecycle
  • tool-call-start, tool-call-delta, tool-call-end — tool call lifecycle
  • data — arbitrary named data events (state snapshots, activity, inference metadata)
  • finish — terminal event with finish reason and usage summary

The encoder automatically manages text block open/close boundaries:

  1. First TextDelta opens a text block (TextStart).
  2. Subsequent deltas append to the open block.
  3. When a ToolCallStart arrives, the encoder closes any open text or reasoning block before emitting tool events.
  4. After tool execution completes, new text deltas open a fresh block with an incremented ID.

This ensures the frontend receives well-formed block boundaries even though the runtime emits flat delta events.