AG-UI
Free · MITTurns 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.
Preview
It's types and helpers, listed below.
Install
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 }