Chat
Free · MITThe data a Candor thread renders.
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/chat
Brings in: status
Types
- AgentRole
- What an agent does: "assistant", "coder", "reviewer"… The app registers each role's glyph and hue (AgentRolesProvider).
string- AgentIdentity
{ id: string /** The displayed name, e.g. "Architect agent". Never derived from model output. */ name: string role: AgentRole specialty?: string | undefined }- MessageAuthor
| { role: "user"; name?: string | undefined } | { role: "agent"; agent: AgentIdentity } /** A person on the app's own team (support staff, a reviewer), not the user: shown by name, with their team. */ | { role: "person"; name: string; team?: string | undefined } /** System lines are the app's own strings, never model text. */ | { role: "system" }- EntityKind
- What kind of thing an entity is: "record", "table", "workflow"… Any string; the app registers each kind's icon and noun (see EntityKindsProvider), and presets cover common systems (e.g. Salesforce).
string- EntityRef
{ kind: EntityKind /** The identifier, e.g. "orders.status" or "billing.invoice.due_date". */ name: string /** A friendlier label when there is one, e.g. "Region". */ label?: string | undefined /** Where it lives, when more than one place is in scope, e.g. "Shop staging". */ location?: string | undefined }- InlineNode
| { kind: "text"; text: string } | { kind: "strong"; text: string } | { kind: "em"; text: string } | { kind: "code"; text: string } /** A value read from the environment (a count, a setting). Shown with its source on hover. */ | { kind: "measured"; text: string; source?: string | undefined } /** @deprecated Renamed `measured`; still rendered the same way until 2.0. */ | { kind: "orgData"; text: st- SourceKind
- "document", "web", "query", "code", "data", "workflow", "knowledge", or the app's own; unknown kinds read as "Source".
string- MessageSource
{ id: string /** The [n] shown inline. Assigned by the service, so it is stable across renders. */ marker: number kind: SourceKind label: string /** An inert excerpt shown in the popover. Text only. */ snippet?: string | undefined /** Where it came from in a human sense: "Docs · Sales process v3", "Query on orders". */ origin?: string | undefined provisional?: boolean | undefined }- ToolSource
- A source a tool's result supports, without the id and [n] an adapter assigns.
Omit<MessageSource, "id" | "marker"> & { /** Makes two results naming the same thing one source; defaults to `kind` and `label`. */ key?: string | undefined }- ReasoningEntry
| (ReasoningBase & { basis: "verified"; evidence: string }) | (ReasoningBase & { basis: "believed" | "assumed"; assumption: string })- ToolCall
{ id: string /** The tool's name, for people who want it: "metadata.describe". */ tool: string /** What it did, in plain words: "Read Account's fields". */ title: string status: RunStatus /** Shown when expanded. Text only; long values scroll. */ input?: string | undefined output?: string | undefined outputLanguage?: PayloadLanguage | undefined /** e.g. "1.2s". Absent while running; never estimate- PayloadLanguage
- The block's language, e.g. "json", "sql", "python", "text". Shown as a label; never executed or highlighted as HTML.
string- MessageBlock
| { kind: "paragraph"; nodes: InlineNode[] } /** * Text exactly as someone typed it: line breaks and spacing kept, nothing parsed. For a person's own words, so * `*this*` stays `*this*` and a pasted list keeps its lines. */ | { kind: "plain"; text: string } /** A heading inside a reply. Levels are relative to the message, 1 the largest; the page's own headings sit above. */ | { kind: "heading"; le- MessageStatus
"streaming" | "complete" | "interrupted" | "failed"- Message
{ id: string author: MessageAuthor /** When it was sent. Absent when the source doesn't say; then no time is shown. */ createdAt?: string | undefined status: MessageStatus blocks: MessageBlock[] reasoning?: ReasoningEntry[] | undefined /** How long the agent spent before answering, e.g. "6s". Only once known. */ thoughtFor?: string | undefined sources?: MessageSource[] | undefined /** Shown under- ComposerScope
- Where the next message's work lands.
{ account?: string | undefined; environment: string; detail?: string | undefined; production: boolean }- MentionOption
{ id: string /** The heading it sits under in the menu, e.g. "Files", "People". Groups appear in the order first used. */ group: string entity?: EntityRef | undefined label: string description?: string | undefined }- SlashCommand
{ id: string name: string description: string /** e.g. "<object>" — shown after the name. */ args?: string | undefined }- Attachment
{ id: string name: string /** In bytes. */ size?: number | undefined /** e.g. "image/png", "application/pdf": picks the icon, and allows an image preview. */ mediaType?: string | undefined /** A thumbnail your app serves (or a blob: URL), shown for images. Never a URL from model output. */ previewUrl?: string | undefined /** 0–1 while uploading; absent when done. */ progress?: number | undefined e- PromptSuggestion
{ id: string; text: string }