AG-UI

Free · MIT

Turns AG-UI events into Candor messages, waiting approvals and usage. Pure (given now), so it can run on every render; useAgUi calls it for you.

Markdown

Preview

It's types and helpers, listed below.

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/ag-ui

Brings in: chat, safe-markdown, status · npm: @ag-ui/core@^1.0.3

Functions

fromAgUiEvents(events: AgUiEvent[], options: FromAgUiOptions)

Turns AG-UI events into Candor messages, waiting approvals and usage. Pure (given now), so it can run on every render; useAgUi calls it for you.

applyJsonPatch(document: unknown, patch: JsonPatch | unknown)

Applies an RFC 6902 JSON Patch to a JSON document, all or nothing. Pure: the document passed in is never changed, and the result shares nothing with the patch's values. A patch that fails (a path that doesn't resolve, a failed test, a malformed operation) returns ok: false with a plain reason.

Types

CandorAgUiEvent
Events of Candor's own, mixed into the AG-UI stream by useAgUi.
| { type: "candor_user"; id: string; text: string; references?: EntityRef[] | undefined } /** A person answered an interrupt; the next run resumes with it. */ | { type: "candor_answer"; interruptId: string; approved: boolean; reason?: string | undefined } /** The run failed outside the protocol's own events (the request, the stream). */ | { type: "candor_error"; message: string }
AgUiEvent
Event | CandorAgUiEvent
AgUiApproval
An interrupt waiting on a person.
{ /** The interrupt's id; answer it with `respond(id, …)`. */ id: string /** The agent's machine-readable reason, e.g. "tool_approval". */ reason: string /** The agent's own sentence for the request, when it sent one. */ message?: string | undefined /** A sentence to show: the agent's message, or a plain one naming the tool. */ title: string /** Set when the interrupt asks to run a tool call. */ t
AgUiUsage
Tokens the runs reported, summed. A count no run reported stays unknown. AG-UI reports no cost.
{ inputTokens?: number | undefined; outputTokens?: number | undefined }
FromAgUiOptions
{ /** Who the agent is. Candor always names the agent. */ agent: AgentIdentity /** A run is open now: the last reply is still streaming, and no interrupt can be answered yet. */ running?: boolean | undefined /** A plain-words title for a tool call: "Read notes.md". `input` is undefined until the arguments arrive. */ toolTitle?: ((tool: string, input: unknown) => string | undefined) | undefined /**
AgUiPlanStep
A plan step read from an activity whose content has `steps: [{ title, status }]`. The same shape as PlanStep, so it can go straight to a plan view.
{ id: string title: string status: RunStatus /** The step's own summary, when it sent one as text. */ summary?: string | undefined /** Why it failed: the agent's words, or a plain sentence saying it didn't say. Set only when status is "failed". */ failure?: string | undefined }
AgUiAgentActivityEntry
What an agent is doing, read from an activity whose content has `status` (and optionally `doing`, `since`, `agentId`). The same shape as AgentActivityEntry.
{ /** The app's own identity for the agent, never one taken from the content. */ agent: AgentIdentity doing?: string | undefined status: RunStatus since?: string | undefined }
AgUiActivity
An activity the agent reported: structured progress that isn't part of a reply.
{ /** The activity message's id. */ id: string /** The agent's own kind for it, e.g. "plan" or "search". An open string. */ type: string /** Its content as the agent sent it, after any patches. Data, never markup. */ content: Record<string, unknown> /** Set when an update to it couldn't be applied: the content is the last good one, and may be behind. */ outOfDate?: string | undefined /** Its `step
AgUiState
{ messages: Message[] /** Interrupts waiting on a person, oldest first. Empty while a run is open; expired ones are left out. */ approvals: AgUiApproval[] /** The thread the runs belong to. Send it back to continue the conversation. */ threadId?: string | undefined usage?: AgUiUsage | undefined /** Something the person should know that isn't part of a reply, such as an expired request. */ notice?:
JsonPatchResult
What applying a JSON Patch gave: the new document, or why it didn't apply (and then nothing changed).
{ ok: true; value: unknown } | { ok: false; reason: string }