@dawn-ai/ag-ui

Use this when

Use this package when a web client speaks AG-UI and your Dawn route emits Dawn stream chunks. Most applications should start with AG-UI and Web Clients; use this reference when you are wiring a custom transport or client adapter.

Install and import

bash
pnpm add @dawn-ai/ag-ui
ts
import { fromRunAgentInput, toAguiEvents } from "@dawn-ai/ag-ui"
import { encodeAgUiSse } from "@dawn-ai/ag-ui/sse"

In a React client, and only there, import the renderers from the ./react subpath:

tsx
import { dawnActivityRenderers } from "@dawn-ai/ag-ui/react"

Compatibility and audience

SurfaceRuntimePurityAudienceStability
@dawn-ai/ag-uiedge-safenot-claimedintegrationsupported
@dawn-ai/ag-ui/sseedge-safenot-claimedintegrationsupported
@dawn-ai/ag-ui/reactnode-onlynot-claimedapplicationsupported
@dawn-ai/ag-ui/react/styles.cssn/an/aintegrationsupported

The adapter translates protocol data; it does not authenticate a caller or make client-supplied thread, run, state, tool, or context data authoritative.

@dawn-ai/ag-ui/react is the client-side entry: it ships ready-made CopilotKit renderers for Dawn's built-in orchestration activities, and React and @copilotkit/react-core are optional peer dependencies, so a server-only consumer that imports only the root or /sse entry installs neither. Its runtime is recorded as node-only because Dawn's edge guard requires an import graph free of unguarded Node globals, and React's own JSX runtime reaches for process.env.NODE_ENV. The entry is meant for browser bundles, where an application bundler substitutes that value as usual; it simply cannot carry Dawn's stricter edge-safe claim.

Public exports

@dawn-ai/ag-ui

ExportResponsibility
createCounterIdFactoryCreate deterministic IDs for tests and reproducible adapters.
createDefaultIdFactoryCreate unique runtime event IDs.
DAWN_PLAN_ACTIVITY_TYPEIdentify Dawn plan activity snapshots as dawn.plan.
DAWN_SUBAGENT_ACTIVITY_TYPEIdentify Dawn subagent activity snapshots as dawn.subagent.
DawnPlanActivityContentDescribe the complete public plan snapshot.
DawnSubagentActivityContentDescribe allowlisted subagent progress.
IdFactoryDefine event-ID generation.
DawnMessageDescribe a normalized inbound message.
DawnRunInputDescribe normalized Dawn run input.
fromRunAgentInputTranslate AG-UI run input to Dawn input.
DawnInterruptEnvelopeDescribe a Dawn interrupt payload.
DawnResumeRequestDescribe one resume decision.
AguiOutboundEventName events emitted by the outbound mapper.
ToAguiOptionsConfigure outbound event IDs.
toAguiEventsTranslate a Dawn stream into AG-UI events.
DawnAgentStreamChunkDescribe accepted Dawn stream chunks.
RunContextSupply thread and run IDs for outbound events.

@dawn-ai/ag-ui/sse

ExportResponsibility
encodeAgUiSseEncode one AG-UI event as an SSE frame.

@dawn-ai/ag-ui/react

ExportResponsibility
dawnActivityRenderersRegister both built-in Dawn activity renderers with CopilotKit's renderActivityMessages.
dawnPlanActivityRendererRegister only the plan activity renderer.
dawnSubagentActivityRendererRegister only the subagent activity renderer.
PlanActivityCardPresent one plan snapshot from its content.
SubagentActivityCardPresent one subagent snapshot from its content.
ActivityChecklistPresent a todo list from todos, truncated at limit.
planActivityContentSchemaValidate plan activity content in a custom renderer.
subagentActivityContentSchemaValidate subagent activity content in a custom renderer.
SubagentActivityContentOutputDescribe parsed subagent content, which admits an explicit undefined todos.
DawnActivityClassNamesName the per-part classes a card appends to its defaults (customization rung 2).
DawnActivityComponentsName the leaf slots (TodoRow, ToolRow) a card lets a consumer replace (customization rung 3).
DawnTodoRowPropsDescribe the props passed to a replacement TodoRow.
DawnToolRowPropsDescribe the props passed to a replacement ToolRow.
cxJoin a package default class with an optional consumer class (customization rung 4: what an ejected card imports in place of its internal ./parts.js path).

dawnActivityRenderers is the drop-in default; the two individual renderers exist for clients that register only one of them or mix them with their own. The cards are plain React components and need no CopilotKit. SubagentActivityContentOutput is wider than the published DawnSubagentActivityContent in exactly one way: this package compiles with exactOptionalPropertyTypes and zod does not, so a parsed value can carry an explicit todos: undefined. ActivityChecklist, PlanActivityCard, and SubagentActivityCard all accept optional classNames and components props built from these two types; see @dawn-ai/ag-ui/react/styles.css below for rung 1 and the package README for a runnable example of every rung.

@dawn-ai/ag-ui/react/styles.css

This subpath exposes the activity cards' default appearance as a stylesheet asset. It has no TypeScript export inventory, runtime compatibility classification, or purity claim; a bundler resolves it and it is never evaluated as JavaScript. Import it once, wherever your application imports its global CSS:

ts
import "@dawn-ai/ag-ui/react/styles.css"

The sheet is optional — the cards render without it — and every rule that styles an element is scoped to the dawn-activity prefix, so it cannot restyle the rest of an application; it additionally declares --dawn-activity-* custom properties on :root. Restyle it by overriding its custom properties in your own CSS: --dawn-activity-surface, --dawn-activity-border, --dawn-activity-text, --dawn-activity-muted, --dawn-activity-running, --dawn-activity-complete, --dawn-activity-failed, --dawn-activity-radius, --dawn-activity-gap, and --dawn-activity-font-size. A dark palette applies under prefers-color-scheme: dark; setting data-dawn-theme="light" or data-dawn-theme="dark" on the root element pins one explicitly (the selectors match only :root, not an arbitrary ancestor).

Key contracts

Activity identifiers and payloads

ts
export declare const DAWN_PLAN_ACTIVITY_TYPE: "dawn.plan"
ts
export declare const DAWN_SUBAGENT_ACTIVITY_TYPE: "dawn.subagent"
ts
export interface DawnPlanActivityContent {
  readonly todos: ReadonlyArray<{
    readonly content: string
    readonly status: "pending" | "in_progress" | "completed"
  }>
}
ts
export interface DawnSubagentActivityContent {
  readonly name: string
  readonly depth: number
  readonly status: "running" | "completed" | "failed"
  readonly todos?: DawnPlanActivityContent["todos"]
  readonly tools: ReadonlyArray<{
    readonly name: string
    readonly status: "running" | "completed" | "incomplete"
  }>
  readonly totalToolCount: number
  readonly error?: string
}

Behavior contract ag-ui.activities.plan-snapshot

A valid plan update becomes a complete replacement snapshot with activity type dawn.plan and the stable message ID dawn:plan:<runId> without breaking an open assistant text message.

Behavior contract ag-ui.activities.subagent-privacy

A subagent snapshot exposes allowlisted progress only: name, depth, status, optional todos, at most five tool name/status summaries, the total tool count, and an error capped at 400 characters. It never includes child prompts, prose, tool inputs, tool outputs, final answers, route IDs, call IDs, or raw runtime IDs.

ToAguiOptions

Supply an IdFactory when emitted IDs must be deterministic. Production integrations normally accept the default factory.

ts
export interface ToAguiOptions {
  readonly idFactory?: IdFactory
}

Fields: @dawn-ai/ag-ui#.:ToAguiOptions

FieldTypeRequiredDescription
readonly idFactoryIdFactorynoOverride outbound event-ID generation.

Inbound and outbound calls

ts
export interface DawnRunInput {
  readonly messages: DawnMessage[]
  readonly resume?: DawnResumeRequest[]
  readonly raw: RunAgentInput
}

Fields: @dawn-ai/ag-ui#.:DawnRunInput

FieldTypeRequiredDescription
readonly messagesDawnMessage[]yesSupply normalized messages.
readonly resumeDawnResumeRequest[]noSupply normalized resume decisions.
readonly rawRunAgentInputyesPreserve the untouched AG-UI input.
ts
export interface RunContext {
  readonly threadId: string
  readonly runId: string
}
ts
export declare function fromRunAgentInput(input: RunAgentInput): DawnRunInput
ts
export declare function toAguiEvents(
  chunks: AsyncIterable<DawnAgentStreamChunk>,
  ctx: RunContext,
  options?: ToAguiOptions,
): AsyncGenerator<AguiOutboundEvent>
ts
export declare function encodeAgUiSse(event: BaseEvent, accept?: string): string

Behavior contract ag-ui.outbound.errors-as-events

toAguiEvents turns an upstream throw into a final RUN_ERROR event and closes an open text frame instead of throwing to the consumer.

Behavior contract ag-ui.inbound.lossless-input

fromRunAgentInput maps supported messages and resume entries into Dawn shapes, omits resume for an empty array, and preserves the untouched AG-UI input under raw for tools, state, and context.

Stream boundaries

Unknown chunk kinds are ignored after closing an open text frame. A stream that ends without done still finishes successfully. Interrupts are accumulated in the RUN_FINISHED outcome; after an interrupt, later non-interrupt chunks are suppressed until the outcome. A malformed interrupt terminates with RUN_ERROR.

fromRunAgentInput() normalizes messages and resume entries. It preserves the original input as raw, leaving tools, state, and context for application-owned validation and policy.

ts
import { type DawnAgentStreamChunk, toAguiEvents } from "@dawn-ai/ag-ui"
import { encodeAgUiSse } from "@dawn-ai/ag-ui/sse"
 
async function* aguiFrames(chunks: AsyncIterable<DawnAgentStreamChunk>) {
  for await (const event of toAguiEvents(chunks, { threadId: "thread-1", runId: "run-1" })) {
    yield encodeAgUiSse(event)
  }
}

Continue with AG-UI and Web Clients, Embed the Runtime, and Security Architecture.