Claude Agent SDK
Free · MITTurns Claude Agent SDK events into Candor messages, waiting approvals and usage. Pure, so it can run on every render; useClaudeAgent 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/claude-agent-sdk
Brings in: chat, safe-markdown · npm: @anthropic-ai/claude-agent-sdk@^0.3.318
Functions
fromClaudeAgentEvents(events: AgentEvent[], options: FromClaudeAgentOptions)Turns Claude Agent SDK events into Candor messages, waiting approvals and usage. Pure, so it can run on every render; useClaudeAgent calls it for you.
claudeQuestions(input: unknown)The questions in an AskUserQuestion call, ready for ClarifyingQuestions; undefined when the input isn't one. Option ids are their labels, which is what the SDK takes back.
claudePermissionResult(request: Answerable, answer: ClaudeApprovalAnswer)What to hand back to the SDK for a person's answer: the PermissionResult canUseTool resolves with. Pure, so it works wherever the answer lands (your own route, a queue, a workflow signal). Questions become AskUserQuestion's answers, keyed by question text, several choices joined with ", " and the person's own words used as they are. Only the suggestions the person picked are kept, and none when the request offers no "always allow".
claudeSuggestions(updates: PermissionUpdate[] | undefined)The SDK's suggested permission updates as plain parts PermissionPrompt shows, in the same order, so the indexes a person ticks are the ones alwaysAllow sends back.
Types
- ClaudePermissionMode
- How the agent's tool calls are approved, as the SDK names it: "default" (ask for anything not allowed already), "acceptEdits", "plan", "auto" (a classifier decides), "dontAsk" (deny what isn't allowed already) and "bypassPermissions". Kept open: a newer SDK's mode passes through as its name.
"default" | "acceptEdits" | "plan" | "auto" | "dontAsk" | "bypassPermissions" | (string & {})- ClaudeQuestion
- One of the agent's questions (the SDK's AskUserQuestion), shaped for ClarifyingQuestions. Options' ids are their labels.
{ /** The question's text, which is also how its answer is keyed back to the SDK. */ id: string kind: "choice" prompt: string /** The SDK's short header ("Library", "Approach"). */ tag?: string | undefined options: { id: string; label: string; detail?: string | undefined }[] multiple: boolean /** The SDK always lets the person answer in their own words. */ other: true }- ClaudeQuestionAnswer
- A person's answer to one ClaudeQuestion: the chosen labels, their own words, or both. Same shape as ClarifyingAnswer.
{ questionId: string; choice?: string[] | undefined; text?: string | undefined }- ClaudeApprovalAnswer
- How a person answered a permission request.
{ approved: boolean /** Why it was denied, sent to the agent. */ reason?: string | undefined /** The tool's input as the person edited it before allowing it. The tool runs with exactly this. */ updatedInput?: Record<string, unknown> | undefined /** Answers to the agent's questions, when the request is one (`questions`). */ answers?: ClaudeQuestionAnswer[] | undefined /** Which of the request's `su- CandorAgentEvent
- Events of Candor's own, mixed into the SDK's stream.
| { type: "candor_user"; id: string; text: string; references?: EntityRef[] | undefined } /** A tool call is waiting for a person to allow or deny it. */ | { type: "candor_approval" id: string toolUseId: string tool: string input: unknown /** The SDK's own sentence for the request, e.g. "Claude wants to edit notes.md". */ title?: string | undefined description?: string | undefined /** Why the SDK- AgentEvent
SDKMessage | CandorAgentEvent- ClaudeApproval
Omit<Extract<CandorAgentEvent, { type: "candor_approval" }>, "type">- ClaudeAgentUsage
- What the SDK measured for the session so far. Cost is its estimate, not a bill.
{ costUsd: number; inputTokens: number; outputTokens: number; turns: number }- FromClaudeAgentOptions
{ /** Who the agent is. Candor always names the agent. */ agent: AgentIdentity /** A request is open now: the last reply is still streaming and its approvals can be answered. */ running?: boolean | undefined /** A plain-words title for a tool call: "Read notes.md". */ toolTitle?: ((tool: string, input: unknown) => string | undefined) | undefined /** * The sources a tool's result supports, for the- ClaudeRecalledMemory
- A memory the SDK recalled for a reply: the file (or URL) it came from, and whose memory it is.
{ path: string; scope: "personal" | "team" | "organization"; content?: string | undefined }- ClaudeAgentState
{ messages: Message[] /** Tool calls waiting on a person, oldest first. Empty once the request has ended. */ approvals: ClaudeApproval[] /** Send it back with the next message to continue the same session (the SDK's `resume`). */ sessionId?: string | undefined usage?: ClaudeAgentUsage | undefined /** A passing problem the agent is handling itself, such as a retried API call. */ notice?: string | u- ClaudeSuggestion
- A "don't ask again" rule in plain parts, for PermissionPrompt's `suggestions`.
{ action: "allow" | "deny" | "ask" | "remove" | "mode" | "directories" | "other"; what: string; scope?: string | undefined }