@pgege/kaboo-react 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/copilotkit.ts","../src/integrations/KabooInlineCards.tsx","../src/hooks/useActivity.ts","../src/context/ActivityProvider.tsx","../src/components/AgentCard.tsx","../src/formatters/output.ts","../src/components/MarkdownContent.tsx","../src/components/Timeline.tsx","../src/components/ToolRow.tsx","../src/formatters/input.ts","../src/components/MiniTable.tsx","../src/components/AskUserSummary.tsx","../src/components/InterruptRenderer.tsx","../src/context/InterruptBridge.tsx","../src/formatters/askUser.ts","../src/hooks/useDrill.ts","../src/context/DrillContext.tsx","../src/utils/groups.ts","../src/integrations/KabooToolRender.tsx","../src/integrations/KabooAssistantMessage.tsx","../src/context/TurnBinding.tsx","../src/integrations/KabooMessageView.tsx","../src/integrations/KabooInterruptHandler.tsx","../src/integrations/KabooAskUser.tsx"],"sourcesContent":["export { KabooInlineCards } from \"./integrations/KabooInlineCards\";\nexport { KabooAssistantMessage } from \"./integrations/KabooAssistantMessage\";\nexport { KabooMessageView } from \"./integrations/KabooMessageView\";\nexport { KabooInterruptHandler } from \"./integrations/KabooInterruptHandler\";\nexport type { KabooInterruptHandlerProps } from \"./integrations/KabooInterruptHandler\";\nexport { KabooAskUser } from \"./integrations/KabooAskUser\";\nexport { KabooToolRender } from \"./integrations/KabooToolRender\";\n","import { useRenderTool } from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { findGroupForCard } from \"../utils/groups\";\nimport { KabooToolRender } from \"./KabooToolRender\";\n\n/**\n * Permissive Standard Schema. `useRenderTool` requires a `parameters` schema for\n * named tools, but the schema is type-only — at render time CopilotKit parses the\n * raw tool arguments directly and never validates against it. This shim satisfies\n * the type without pulling in a schema library (e.g. zod).\n */\nconst ANY_PARAMETERS = {\n \"~standard\": {\n version: 1 as const,\n vendor: \"kaboo\",\n validate: (value: unknown) => ({ value }),\n },\n};\n\n/**\n * Renders {@link AgentCard}s inline in the chat for **delegate** sub-agents.\n *\n * Every delegate group is spawned by a delegate tool call and carries its\n * `toolCallId`. We register a v2 tool renderer per such agent so CopilotKit\n * places the card at the tool-call position in the assistant turn, correlated\n * by `(agentName, toolCallId)`.\n *\n * First-class swarm/graph entries have no delegating tool call, so their member\n * cards are rendered by {@link KabooMessageView} / {@link KabooAssistantMessage}\n * instead, anchored to the assistant turn. Groups carrying a `toolCallId` are\n * excluded there, so the two paths never double-render the same group.\n */\nexport function KabooInlineCards() {\n const { groups } = useActivity();\n\n const toolAgentNames = new Set<string>();\n for (const group of Object.values(groups)) {\n if (group.agentName && group.toolCallId) toolAgentNames.add(group.agentName);\n }\n\n return (\n <>\n {Array.from(toolAgentNames).map((agentName) => (\n <InlineCardAction key={agentName} agentName={agentName} />\n ))}\n <KabooToolRender />\n </>\n );\n}\n\nfunction InlineCardAction({ agentName }: { agentName: string }) {\n useRenderTool({\n name: agentName,\n parameters: ANY_PARAMETERS,\n render: ({ toolCallId, parameters, result, status }) => (\n <InlineCardRenderer\n agentName={agentName}\n toolCallId={toolCallId}\n input={(parameters as { input?: string } | undefined)?.input}\n result={typeof result === \"string\" ? result : undefined}\n actionStatus={status}\n />\n ),\n });\n\n return null;\n}\n\nfunction InlineCardRenderer({\n agentName,\n toolCallId,\n input,\n result,\n actionStatus,\n}: {\n agentName: string;\n toolCallId: string;\n input?: string;\n result?: string;\n actionStatus?: string;\n}) {\n const { groups } = useActivity();\n const entry = findGroupForCard(groups, agentName, toolCallId);\n\n if (!entry) {\n return <div className=\"kaboo-agent-card-empty\">Loading {agentName}...</div>;\n }\n\n return (\n <AgentCard\n groupId={entry[0]}\n group={entry[1]}\n input={input}\n result={result}\n actionStatus={actionStatus}\n />\n );\n}\n","import { useContext } from \"react\";\nimport { ActivityContext } from \"../context/ActivityProvider\";\nimport type { ActivityState } from \"../types\";\n\n/**\n * Reads the current {@link ActivityState} (all activity groups for the thread)\n * from the nearest {@link KabooActivityProvider}. Re-renders on each new\n * `ACTIVITY_SNAPSHOT`.\n *\n * @example\n * ```tsx\n * import { useActivity } from \"@pgege/kaboo-react\";\n *\n * function GroupCount() {\n * const { groups } = useActivity();\n * return <span>{Object.keys(groups).length} agents</span>;\n * }\n * ```\n */\nexport function useActivity(): ActivityState {\n return useContext(ActivityContext);\n}\n","import { useState, useEffect, createContext, type ReactNode, type ReactElement } from \"react\";\nimport { useAgent } from \"@copilotkit/react-core/v2\";\nimport type { ActivityState } from \"../types\";\n\nconst EMPTY: ActivityState = { groups: {} };\n\n/**\n * A map of custom renderers for structured agent output, keyed by the output\n * schema name. When a group carries `structuredOutput` and a matching\n * `outputSchemaName`, its renderer is used instead of the default JSON view.\n *\n * @example\n * ```tsx\n * import type { StructuredRenderers } from \"@pgege/kaboo-react\";\n *\n * const renderers: StructuredRenderers = {\n * WeatherReport: (data) => <div>{String(data.summary)}</div>,\n * };\n * ```\n */\nexport type StructuredRenderers = Record<string, (data: Record<string, unknown>) => ReactElement>;\n\n/** React context carrying the raw activity snapshot; read it via {@link useActivity}. */\nexport const ActivityContext = createContext<ActivityState>(EMPTY);\n/** React context carrying the {@link StructuredRenderers} map for structured output. */\nexport const StructuredRenderersContext = createContext<StructuredRenderers>({});\n\n/** Props for {@link KabooActivityProvider}. */\nexport interface KabooActivityProviderProps {\n /**\n * CopilotKit agent id whose activity snapshots to consume. Omit to use the\n * provider's default agent. Agent and thread scoping come from CopilotKit.\n */\n agentId?: string;\n /** Renderers for structured agent outputs, keyed by output schema name. */\n structuredRenderers?: StructuredRenderers;\n /** The subtree that reads activity via {@link useActivity}. */\n children: ReactNode;\n}\n\n/**\n * Reads kaboo's hierarchical activity from the AG-UI run stream. The backend\n * emits it as `ACTIVITY_SNAPSHOT` events interleaved on `/invocations`, so we\n * subscribe to the CopilotKit agent instead of a separate SSE endpoint.\n *\n * Included automatically by {@link KabooProvider}; mount it yourself only when\n * composing providers by hand under an existing `<CopilotKit>`.\n *\n * @example\n * ```tsx\n * import { KabooActivityProvider, ActivityPanel } from \"@pgege/kaboo-react\";\n *\n * function Activity({ agent }: { agent: string }) {\n * return (\n * <KabooActivityProvider agentId={agent}>\n * <ActivityPanel />\n * </KabooActivityProvider>\n * );\n * }\n * ```\n */\nexport function KabooActivityProvider({ agentId, structuredRenderers, children }: KabooActivityProviderProps) {\n const { agent } = useAgent(agentId ? { agentId } : undefined);\n const [state, setState] = useState<ActivityState>(EMPTY);\n\n useEffect(() => {\n if (!agent) return;\n const { unsubscribe } = agent.subscribe({\n onActivitySnapshotEvent: ({ event }) => {\n setState(event.content as unknown as ActivityState);\n },\n });\n return unsubscribe;\n }, [agent]);\n\n return (\n <ActivityContext.Provider value={state}>\n <StructuredRenderersContext.Provider value={structuredRenderers ?? {}}>\n {children}\n </StructuredRenderersContext.Provider>\n </ActivityContext.Provider>\n );\n}\n","import { useState, useEffect, useRef, useContext } from \"react\";\nimport type { StreamGroup } from \"../types\";\nimport { isControlOnlyStatus, normalizeResult } from \"../formatters/output\";\nimport { MarkdownContent } from \"./MarkdownContent\";\nimport { Timeline } from \"./Timeline\";\nimport { useDrill } from \"../hooks/useDrill\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { StructuredRenderersContext } from \"../context/ActivityProvider\";\nimport { directChildren, partitionChildrenByToolCall } from \"../utils/groups\";\n\n/** Props for {@link AgentCard}. */\nexport interface AgentCardProps {\n /** Id of the group this card renders. */\n groupId: string;\n /** The activity group to render. */\n group: StreamGroup;\n /** Task/input text to show, overriding the group's own `task`. */\n input?: string;\n /** Raw tool result to render as the card's answer, when provided by the host. */\n result?: string;\n /** Host-provided action status (e.g. `\"complete\"`) used to mark the card done. */\n actionStatus?: string;\n /**\n * When true, the card renders its `directChildren` inline as nested\n * {@link AgentCard}s (recursively). Used by the first-class swarm/graph inline\n * renderer to show the whole member tree without the drill navigation. Left\n * off (default) for the delegate path and the drill views, which surface\n * children through their own navigation.\n */\n showChildren?: boolean;\n}\n\n/**\n * Card for a single agent run: title, status badge, task, chronological timeline\n * (text + tool rows), result/structured output, and a \"View details\" drill\n * button. Delegated sub-agents are interleaved at their tool-call position; with\n * `showChildren` the card renders its whole child tree inline.\n *\n * @example\n * ```tsx\n * import { AgentCard, useActivity } from \"@pgege/kaboo-react\";\n *\n * function FirstCard() {\n * const { groups } = useActivity();\n * const [id, group] = Object.entries(groups)[0] ?? [];\n * return id ? <AgentCard groupId={id} group={group} /> : null;\n * }\n * ```\n */\nexport function AgentCard({ groupId, group, input, result, actionStatus, showChildren }: AgentCardProps) {\n const { drillIn } = useDrill();\n const { groups } = useActivity();\n const structuredRenderers = useContext(StructuredRenderersContext);\n const childEntries = showChildren ? directChildren(groups, groupId) : [];\n const isDone = group.status === \"completed\" || actionStatus === \"complete\";\n const isInterrupted = group.status === \"interrupted\" && group.interrupt;\n const [expanded, setExpanded] = useState(true);\n const prevDone = useRef(isDone);\n const bodyRef = useRef<HTMLDivElement>(null);\n\n // Keep cards that captured a human-in-the-loop `ask_user` expanded on\n // completion so the answered Q&A stays visible, matching the top-level path.\n // Cards with no interaction still auto-collapse to keep deep trees tidy.\n const hasInteraction = group.tools.some((t) => t.toolName === \"ask_user\");\n useEffect(() => {\n if (!prevDone.current && isDone && !hasInteraction) setExpanded(false);\n prevDone.current = isDone;\n }, [isDone, hasInteraction]);\n\n // A resolved HITL interrupt leaves the delegate tool result as a bare control\n // echo (e.g. {\"status\":\"approved\"} or {\"status\":\"cancelled\"}). That is not the\n // agent's answer — the gated action is already shown in the timeline and the\n // reply streams separately — so never render the raw echo as the card's result.\n const resultText = isControlOnlyStatus(result) ? null : normalizeResult(result);\n const displayTask = input ?? group.task ?? undefined;\n // Only the chat-reply agent's text is already shown in the chat bubble, so we\n // strip text from just that card to avoid duplicating the answer (R4). Every\n // other member keeps its findings text. The drill views keep the full\n // timeline regardless.\n const timeline =\n showChildren && group.isChatReply\n ? (group.timeline ?? []).filter((e) => e.type === \"tool\")\n : (group.timeline ?? []);\n\n useEffect(() => {\n if (expanded && !isDone && bodyRef.current) {\n bodyRef.current.scrollTop = bodyRef.current.scrollHeight;\n }\n }, [expanded, isDone, timeline]);\n\n // Interleave delegated children at their delegating tool-call position so a\n // sub-agent's card stays in order with the parent's surrounding text, instead\n // of being dumped in a trailing block after the summary.\n const { byToolCall: childByToolCall, leftover: leftoverChildren } =\n partitionChildrenByToolCall(childEntries, timeline);\n const renderToolCard = (toolUseId: string) => {\n const entry = childByToolCall.get(toolUseId);\n if (!entry) return null;\n return <AgentCard groupId={entry[0]} group={entry[1]} showChildren />;\n };\n\n const hasContent =\n timeline.length > 0 || resultText || childEntries.length > 0 || !!displayTask;\n\n const cardClass = `kaboo-agent-card${isDone ? \" kaboo-agent-card-done\" : \"\"}`;\n\n return (\n <div className={cardClass}>\n <div className=\"kaboo-agent-card-header\" onClick={() => setExpanded(!expanded)}>\n <div className=\"kaboo-agent-card-title-area\">\n <div className=\"kaboo-agent-card-title-row\">\n <span className=\"kaboo-agent-card-title\">{group.title}</span>\n <span className={`kaboo-status-badge ${isDone ? \"kaboo-status-done\" : isInterrupted ? \"kaboo-status-interrupted\" : \"kaboo-status-active\"}`}>\n {isDone ? (\n <svg width={10} height={10} viewBox=\"0 0 16 16\">\n <path d=\"M3.5 8.5L6.5 11.5L12.5 4.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ) : isInterrupted ? (\n <svg width={10} height={10} viewBox=\"0 0 16 16\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 4.5v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"8\" cy=\"11\" r=\"0.75\" fill=\"currentColor\" />\n </svg>\n ) : (\n <svg width={10} height={10} viewBox=\"0 0 16 16\">\n <circle cx=\"8\" cy=\"8\" r=\"5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeDasharray=\"22\" strokeDashoffset=\"6\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 8 8\" to=\"360 8 8\" dur=\"0.8s\" repeatCount=\"indefinite\" />\n </circle>\n </svg>\n )}\n {isDone ? \"done\" : isInterrupted ? \"needs input\" : \"working...\"}\n </span>\n </div>\n <div className=\"kaboo-agent-card-subtitle\">{group.agentName}</div>\n </div>\n\n {group.tools.length > 0 && (\n <span className={`kaboo-tool-count ${isDone ? \"kaboo-tool-count-done\" : \"\"}`}>\n {group.tools.length} tool{group.tools.length !== 1 ? \"s\" : \"\"}\n </span>\n )}\n\n <svg\n width={14} height={14} viewBox=\"0 0 16 16\"\n className={`kaboo-chevron ${expanded ? \"kaboo-chevron-open\" : \"\"}`}\n >\n <path d=\"M4 6l4 4 4-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </div>\n\n {!expanded && displayTask && (\n <div className=\"kaboo-agent-card-collapsed\">\n <strong>Task:</strong> {displayTask}\n </div>\n )}\n\n {expanded && (\n <div ref={bodyRef} className=\"kaboo-agent-card-body\">\n {displayTask && (\n <div className=\"kaboo-agent-card-task\">\n <strong>Task:</strong> {displayTask}\n </div>\n )}\n\n {timeline.length > 0 && (\n <div className=\"kaboo-agent-card-timeline\">\n <Timeline timeline={timeline} active={!isDone} variant=\"card\" renderToolCard={renderToolCard} />\n </div>\n )}\n\n {resultText && (\n <div className=\"kaboo-agent-card-result\">\n <MarkdownContent text={resultText} />\n </div>\n )}\n\n {group.structuredOutput && group.outputSchemaName && (() => {\n const Renderer = structuredRenderers[group.outputSchemaName!];\n if (Renderer) {\n return <Renderer {...group.structuredOutput!} />;\n }\n return (\n <details className=\"kaboo-agent-card-structured\">\n <summary className=\"kaboo-agent-card-structured-summary\">\n Structured output ({group.outputSchemaName})\n </summary>\n <pre className=\"kaboo-agent-card-structured-pre\">\n {JSON.stringify(group.structuredOutput, null, 2)}\n </pre>\n </details>\n );\n })()}\n\n {leftoverChildren.length > 0 && (\n <div className=\"kaboo-agent-card-children\">\n {leftoverChildren.map(([childId, child]) => (\n <AgentCard\n key={childId}\n groupId={childId}\n group={child}\n showChildren\n />\n ))}\n </div>\n )}\n\n {!displayTask && !hasContent && (\n <div className=\"kaboo-agent-card-empty\">Working...</div>\n )}\n </div>\n )}\n\n {hasContent && (\n <button\n className=\"kaboo-drill-btn\"\n onClick={(e) => { e.stopPropagation(); drillIn(groupId); }}\n >\n <span>View details</span>\n <svg width={12} height={12} viewBox=\"0 0 16 16\">\n <path d=\"M6 4l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n )}\n </div>\n );\n}\n","/**\n * Parses a raw tool result into a renderable shape: `rows` (for tabular JSON —\n * either `{ rows: [...] }` or a top-level array of objects) or `text` (a\n * `key: value` rendering of an object, or the raw string when it isn't JSON).\n *\n * @example\n * ```ts\n * import { formatToolResult } from \"@pgege/kaboo-react\";\n *\n * const { rows } = formatToolResult('{\"rows\":[{\"id\":\"1\"}]}');\n * // rows?.length === 1\n * ```\n */\nexport function formatToolResult(raw: string): {\n /** Row-shaped result for a table view, or `null` when not tabular. */\n rows: Record<string, string>[] | null;\n /** Text rendering of the result when it is not tabular. */\n text: string;\n} {\n try {\n const parsed = JSON.parse(raw);\n if (parsed.rows && Array.isArray(parsed.rows) && parsed.rows.length > 0) {\n return { rows: parsed.rows as Record<string, string>[], text: \"\" };\n }\n if (Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0] === \"object\") {\n return { rows: parsed as Record<string, string>[], text: \"\" };\n }\n if (typeof parsed === \"object\" && parsed !== null) {\n const entries = Object.entries(parsed as Record<string, unknown>)\n .filter(([, v]) => v != null)\n .map(([k, v]) => `${k}: ${typeof v === \"string\" ? v : JSON.stringify(v)}`);\n return { rows: null, text: entries.join(\"\\n\") };\n }\n return { rows: null, text: String(parsed) };\n } catch {\n return { rows: null, text: raw };\n }\n}\n\nfunction unwrapJson(raw: unknown): unknown {\n let value: unknown = raw;\n for (let i = 0; i < 2 && typeof value === \"string\"; i++) {\n const trimmed = (value as string).trim();\n if (trimmed === \"\") return value;\n try {\n value = JSON.parse(trimmed);\n } catch {\n break;\n }\n }\n return value;\n}\n\nfunction statusIsCancelled(status: unknown): boolean {\n if (typeof status !== \"string\") return false;\n const s = status.toLowerCase();\n return s === \"cancelled\" || s === \"canceled\" || s === \"rejected\" || s === \"declined\";\n}\n\nfunction statusIsControl(status: unknown): boolean {\n if (typeof status !== \"string\") return false;\n const s = status.toLowerCase();\n return statusIsCancelled(status) || s === \"approved\" || s === \"accepted\";\n}\n\n/**\n * True when a tool result signals a human rejection/decline rather than real\n * output — the gated-tool reject message, the ask_user decline note, or a bare\n * HITL control payload like `{\"status\":\"cancelled\"}` (tolerating one extra layer\n * of string encoding). Used to render a \"cancelled\" state instead of \"done\".\n */\nexport function isCancelledResult(raw: unknown): boolean {\n if (raw == null) return false;\n const text = typeof raw === \"string\" ? raw : JSON.stringify(raw);\n if (/user rejected this action/i.test(text)) return true;\n if (/user declined to answer/i.test(text)) return true;\n const value = unwrapJson(text);\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return statusIsCancelled((value as Record<string, unknown>).status);\n }\n return false;\n}\n\n/**\n * True when a result is ONLY a HITL control payload (a lone `status` field\n * carrying an interrupt-resolution echo like `{\"status\":\"approved\"}` or\n * `{\"status\":\"cancelled\"}`), with no real tool output. The owning agent's card\n * already shows the gated action in order, so the inline wildcard renderer and\n * the card skip this stray raw payload rather than dumping JSON.\n */\nexport function isControlOnlyStatus(raw: unknown): boolean {\n if (raw == null) return false;\n const value = unwrapJson(typeof raw === \"string\" ? raw : JSON.stringify(raw));\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const keys = Object.keys(value as Record<string, unknown>);\n return keys.length === 1 && keys[0] === \"status\" &&\n statusIsControl((value as Record<string, unknown>).status);\n }\n return false;\n}\n\n/**\n * Normalizes a raw result string for display: unwraps one layer of JSON string\n * encoding, converts escaped `\\n` into real newlines, and returns `null` for\n * empty/undefined input.\n *\n * @example\n * ```ts\n * import { normalizeResult } from \"@pgege/kaboo-react\";\n *\n * normalizeResult('\"line one\\\\nline two\"');\n * // \"line one\\nline two\"\n * ```\n */\nexport function normalizeResult(result: string | undefined): string | null {\n if (!result) return null;\n let text = typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n if (text.startsWith('\"') && text.endsWith('\"')) {\n try {\n text = JSON.parse(text);\n } catch { /* keep as-is */ }\n }\n text = text.replace(/\\\\n/g, \"\\n\");\n return text || null;\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * Minimal, dependency-free markdown renderer used for agent text: supports\n * `#`/`##`/`###` headings, `-`/`*` list items, `**bold**` inline, and blank-line\n * spacing. Intentionally small — it is not a full CommonMark implementation.\n *\n * @example\n * ```tsx\n * import { MarkdownContent } from \"@pgege/kaboo-react\";\n *\n * function Example() {\n * return <MarkdownContent text={\"# Title\\n\\nSome **bold** text.\"} />;\n * }\n * ```\n */\nexport function MarkdownContent({ text }: { text: string }) {\n const lines = text.split(\"\\n\");\n return (\n <div className=\"kaboo-md\">\n {lines.map((line, i) => {\n if (line.startsWith(\"# \") && !line.startsWith(\"## \")) {\n return <h2 key={i} className=\"kaboo-md-h2\">{line.slice(2)}</h2>;\n }\n if (line.startsWith(\"## \")) {\n return <h3 key={i} className=\"kaboo-md-h3\">{line.slice(3)}</h3>;\n }\n if (line.startsWith(\"### \")) {\n return <h4 key={i} className=\"kaboo-md-h4\">{line.slice(4)}</h4>;\n }\n if (line.startsWith(\"- \") || line.startsWith(\"* \")) {\n return <li key={i} className=\"kaboo-md-li\">{renderInline(line.slice(2))}</li>;\n }\n if (line.trim() === \"\") {\n return <div key={i} className=\"kaboo-md-spacer\" />;\n }\n return <p key={i} className=\"kaboo-md-p\">{renderInline(line)}</p>;\n })}\n </div>\n );\n}\n\nfunction renderInline(text: string) {\n const parts: (string | ReactNode)[] = [];\n let remaining = text;\n let key = 0;\n\n while (remaining.length > 0) {\n const boldMatch = remaining.match(/\\*\\*(.+?)\\*\\*/);\n if (boldMatch && boldMatch.index !== undefined) {\n if (boldMatch.index > 0) {\n parts.push(remaining.slice(0, boldMatch.index));\n }\n parts.push(<strong key={key++}>{boldMatch[1]}</strong>);\n remaining = remaining.slice(boldMatch.index + boldMatch[0].length);\n continue;\n }\n parts.push(remaining);\n break;\n }\n\n return <>{parts}</>;\n}\n","import { Fragment, type ReactNode } from \"react\";\nimport type { TimelineEntry, ToolCall } from \"../types\";\nimport { ToolRow } from \"./ToolRow\";\nimport { MarkdownContent } from \"./MarkdownContent\";\nimport { AskUserSummary } from \"./AskUserSummary\";\nimport { InterruptRenderer } from \"./InterruptRenderer\";\nimport { useInterruptFor } from \"../context/InterruptBridge\";\nimport { normalizeQuestions, parseAnswers, type AskUserParams } from \"../formatters/askUser\";\nimport { isCancelledResult } from \"../formatters/output\";\n\n/**\n * Renders an `ask_user` tool call in one place at its chronological tool\n * position — the live interactive form while it's pending, then the durable Q&A\n * summary once answered. Both look identical at every depth (top-level card or a\n * nested drill), so the human-in-the-loop prompt never floats out of order in a\n * separate slot. The live form is claimed by matching an open interrupt's\n * `toolCallId` to this tool; if none matches (already answered, or a different\n * agent's prompt) nothing interactive is drawn here.\n */\nfunction AskUserTimelineRow({ tool }: { tool: ToolCall }) {\n const interrupt = useInterruptFor(tool.toolUseId);\n const questions = normalizeQuestions(tool.toolInput as AskUserParams | undefined);\n const answers = parseAnswers(tool.toolResult);\n\n if (answers) {\n if (questions.length === 0) return null;\n return <AskUserSummary questions={questions} answers={answers} />;\n }\n\n if (interrupt && interrupt.reason.type === \"form\") {\n return (\n <InterruptRenderer\n reason={interrupt.reason}\n toolCallId={interrupt.toolCallId}\n onResolve={interrupt.onResolve}\n onCancel={interrupt.onCancel}\n />\n );\n }\n\n // Resolved without answers (the user dismissed the prompt): keep it visible in\n // order as a declined Q&A rather than silently dropping it.\n if (questions.length > 0 && isCancelledResult(tool.toolResult)) {\n return <AskUserSummary questions={questions} answers={{}} declined />;\n }\n\n return null;\n}\n\n/**\n * A regular tool row that also surfaces its own approval gate inline. When a\n * gated tool is awaiting approval it has an open interrupt anchored to this\n * tool-call id; the Approve/Reject prompt renders directly under the row so it\n * sits at the request it governs. With N tools gated in parallel each row owns\n * its own card and resolves independently.\n */\nfunction ToolTimelineRow({ tool }: { tool: ToolCall }) {\n const interrupt = useInterruptFor(tool.toolUseId);\n return (\n <>\n <ToolRow tool={tool} />\n {interrupt && interrupt.reason.type === \"approval\" && (\n <InterruptRenderer\n reason={interrupt.reason}\n toolCallId={interrupt.toolCallId}\n onResolve={interrupt.onResolve}\n onCancel={interrupt.onCancel}\n />\n )}\n </>\n );\n}\n\n/** Props for {@link Timeline}. */\nexport interface TimelineProps {\n /** The interleaved text/tool entries to render, in order. */\n timeline: TimelineEntry[];\n /** When true, a blinking cursor is shown after the last text segment. */\n active: boolean;\n /** Visual variant selecting the text container class. */\n variant?: \"card\" | \"drill\";\n /**\n * Optional hook to render a delegating tool call as its spawned sub-agent\n * card, interleaved at its chronological position. Returns the card node for a\n * given tool-call id, or `null`/`undefined` to fall back to the tool row. Keeps\n * a delegated agent's work in order relative to the parent's surrounding text.\n */\n renderToolCard?: (toolUseId: string) => ReactNode | null | undefined;\n}\n\n/**\n * Chronological render of interleaved text segments and tool calls. Shared by\n * {@link AgentCard} and {@link DrillDetailView} so the two stay in sync.\n */\nexport function Timeline({ timeline, active, variant = \"card\", renderToolCard }: TimelineProps) {\n const textClass =\n variant === \"drill\" ? \"kaboo-drill-tokens-content\" : \"kaboo-agent-card-tokens\";\n\n return (\n <>\n {timeline.map((entry, i) => {\n if (entry.type === \"tool\") {\n const key = entry.tool.toolUseId || i;\n const card = renderToolCard?.(entry.tool.toolUseId);\n if (card) return <Fragment key={key}>{card}</Fragment>;\n if (entry.tool.toolName === \"ask_user\") {\n return <AskUserTimelineRow key={key} tool={entry.tool} />;\n }\n return <ToolTimelineRow key={key} tool={entry.tool} />;\n }\n const isLast = i === timeline.length - 1;\n return (\n <div key={`text-${i}`} className={textClass}>\n <MarkdownContent text={entry.text} />\n {active && isLast && <span className=\"kaboo-blink-cursor\" />}\n </div>\n );\n })}\n </>\n );\n}\n","import { useState } from \"react\";\nimport type { ToolCall } from \"../types\";\nimport { formatToolInput } from \"../formatters/input\";\nimport { formatToolResult, isCancelledResult } from \"../formatters/output\";\nimport { MiniTable } from \"./MiniTable\";\n\n/**\n * Renders a single {@link ToolCall} as a collapsible row: status icon, label, an\n * input summary, and — when expanded — the formatted result (a {@link MiniTable}\n * for tabular JSON, otherwise text). Used inside the {@link Timeline}.\n *\n * @example\n * ```tsx\n * import { ToolRow } from \"@pgege/kaboo-react\";\n * import type { ToolCall } from \"@pgege/kaboo-react\";\n *\n * const tool: ToolCall = {\n * toolUseId: \"t1\",\n * toolName: \"run_sql\",\n * toolInput: { query: \"select 1\" },\n * status: \"done\",\n * };\n *\n * function Example() {\n * return <ToolRow tool={tool} />;\n * }\n * ```\n */\nexport function ToolRow({ tool }: { tool: ToolCall }) {\n const [open, setOpen] = useState(false);\n const cancelled = tool.status === \"cancelled\" || isCancelledResult(tool.toolResult);\n const isDone = tool.status !== \"running\";\n const label = tool.toolLabel || tool.toolName;\n const { summary: inputSummary } = formatToolInput(tool.toolInput);\n\n return (\n <div className=\"kaboo-tool-row\">\n <div className=\"kaboo-tool-row-header\" onClick={() => setOpen(!open)}>\n {tool.status === \"running\" ? (\n <svg width={10} height={10} viewBox=\"0 0 16 16\" className=\"kaboo-icon-shrink\">\n <circle\n cx=\"8\" cy=\"8\" r=\"5\"\n fill=\"none\" className=\"kaboo-tool-spinner\" strokeWidth=\"2\"\n strokeDasharray=\"22\" strokeDashoffset=\"6\"\n >\n <animateTransform\n attributeName=\"transform\" type=\"rotate\"\n from=\"0 8 8\" to=\"360 8 8\" dur=\"0.8s\" repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n ) : (\n <svg width={10} height={10} viewBox=\"0 0 10 10\" className=\"kaboo-icon-shrink\">\n <circle\n cx=\"5\" cy=\"5\" r=\"3\"\n className={\n cancelled\n ? \"kaboo-tool-dot-cancelled\"\n : tool.status === \"error\"\n ? \"kaboo-tool-dot-error\"\n : \"kaboo-tool-dot-success\"\n }\n />\n </svg>\n )}\n <span className=\"kaboo-tool-row-label\">{label}</span>\n {isDone && (\n <span className=\"kaboo-tool-row-status\">\n {cancelled ? \"cancelled\" : tool.status === \"error\" ? \"error\" : \"done\"}\n </span>\n )}\n <svg\n width={14} height={14} viewBox=\"0 0 16 16\"\n className={`kaboo-chevron ${open ? \"kaboo-chevron-open\" : \"\"}`}\n >\n <path d=\"M4 6l4 4 4-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </div>\n\n {!open && inputSummary && (\n <div className=\"kaboo-tool-row-summary\">\n {inputSummary.length > 80 ? inputSummary.slice(0, 80) + \"...\" : inputSummary}\n </div>\n )}\n\n {open && (\n <div className=\"kaboo-tool-row-detail\">\n {inputSummary && (\n <div className=\"kaboo-tool-input\">{inputSummary}</div>\n )}\n {tool.toolResult && <ToolResultBlock raw={tool.toolResult} cancelled={cancelled} />}\n </div>\n )}\n </div>\n );\n}\n\nfunction ToolResultBlock({ raw, cancelled }: { raw: string; cancelled?: boolean }) {\n if (cancelled) {\n const { text } = formatToolResult(raw);\n const message = /user (rejected|declined)/i.test(text) ? text : \"Declined by user.\";\n return <div className=\"kaboo-tool-result kaboo-tool-result-cancelled\">{message}</div>;\n }\n const { rows, text } = formatToolResult(raw);\n if (rows) {\n return (\n <div className=\"kaboo-tool-result kaboo-tool-result-table\">\n <MiniTable rows={rows} />\n </div>\n );\n }\n return <div className=\"kaboo-tool-result\">{text}</div>;\n}\n","/**\n * Condenses arbitrary tool input into a short one-line `summary` for a tool row.\n * Prefers well-known fields (`query`/`table_name`/`url`), unwraps single-key\n * objects, and otherwise joins `key: value` pairs. `detail` is reserved for\n * future expansion and is currently always `null`.\n *\n * @example\n * ```ts\n * import { formatToolInput } from \"@pgege/kaboo-react\";\n *\n * const { summary } = formatToolInput({ query: \"select 1\" });\n * // summary === \"select 1\"\n * ```\n */\nexport function formatToolInput(input: unknown): {\n /** One-line summary suitable for a tool row. */\n summary: string;\n /** Reserved for future detail expansion; currently always `null`. */\n detail: string | null;\n} {\n if (input == null) return { summary: \"\", detail: null };\n if (typeof input === \"string\") return { summary: input, detail: null };\n\n const obj = input as Record<string, unknown>;\n\n if (obj.query && typeof obj.query === \"string\") {\n return { summary: String(obj.query).trim(), detail: null };\n }\n if (obj.table_name && typeof obj.table_name === \"string\") {\n return { summary: obj.table_name as string, detail: null };\n }\n if (obj.url && typeof obj.url === \"string\") {\n return { summary: obj.url as string, detail: null };\n }\n\n const keys = Object.keys(obj);\n if (keys.length === 1) {\n const val = obj[keys[0]];\n return { summary: typeof val === \"string\" ? val : JSON.stringify(val), detail: null };\n }\n\n const parts = keys\n .filter((k) => obj[k] != null && obj[k] !== \"\")\n .map((k) => {\n const v = obj[k];\n return `${k}: ${typeof v === \"string\" ? v : JSON.stringify(v)}`;\n });\n return { summary: parts.join(\", \"), detail: null };\n}\n","/**\n * Compact table for row-shaped tool results. Columns are inferred from the first\n * row's keys; underscores in headers become spaces. Renders at most `maxRows`\n * rows with a \"+N more\" footer, and nothing at all for an empty list.\n *\n * @example\n * ```tsx\n * import { MiniTable } from \"@pgege/kaboo-react\";\n *\n * function Example() {\n * return <MiniTable rows={[{ id: \"1\", name: \"Ada\" }]} maxRows={5} />;\n * }\n * ```\n */\nexport function MiniTable({ rows, maxRows = 8 }: { rows: Record<string, string>[]; maxRows?: number }) {\n if (rows.length === 0) return null;\n const cols = Object.keys(rows[0]);\n const display = rows.slice(0, maxRows);\n const remaining = rows.length - maxRows;\n\n return (\n <div style={{ overflowX: \"auto\" }}>\n <table className=\"kaboo-mini-table\">\n <thead>\n <tr>\n {cols.map((c) => (\n <th key={c}>{c.replace(/_/g, \" \")}</th>\n ))}\n </tr>\n </thead>\n <tbody>\n {display.map((row, i) => (\n <tr key={i}>\n {cols.map((c) => (\n <td key={c}>{String(row[c] ?? \"\")}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n {remaining > 0 && (\n <div className=\"kaboo-mini-table-overflow\">\n +{remaining} more row{remaining !== 1 ? \"s\" : \"\"}\n </div>\n )}\n </div>\n );\n}\n","import type { ReactElement } from \"react\";\nimport type { FormQuestion } from \"../types\";\n\nfunction formatAnswer(value: unknown): string {\n if (value == null) return \"\";\n if (Array.isArray(value)) return value.map((v) => String(v)).join(\", \");\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Read-only, durable record of an answered `ask_user` prompt. Rendered from the\n * tool call that lives permanently in the transcript, so the question(s) and the\n * user's answer stay visible inline (in chat order) after the interrupt resolves.\n */\nexport function AskUserSummary({\n questions,\n answers,\n declined = false,\n}: {\n questions: FormQuestion[];\n answers: Record<string, unknown>;\n /** Render as a declined prompt: no answers were given (the user dismissed it). */\n declined?: boolean;\n}): ReactElement {\n return (\n <div className=\"kaboo-askuser\">\n {questions.map((q, idx) => {\n const answer = answers[q.question];\n const hasAnswer = answer != null && formatAnswer(answer) !== \"\";\n return (\n <div key={idx} className=\"kaboo-askuser-qa\">\n <div className=\"kaboo-askuser-question\">{q.question}</div>\n <div\n className={`kaboo-askuser-answer ${hasAnswer ? \"\" : declined ? \"kaboo-askuser-answer-declined\" : \"kaboo-askuser-answer-empty\"}`}\n >\n {hasAnswer ? formatAnswer(answer) : declined ? \"Declined by user\" : \"No answer\"}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import { useState, type ReactElement } from \"react\";\nimport type { InterruptReason, InterruptRendererProps, FormQuestion } from \"../types\";\n\nfunction ApprovalVariant({ reason, onResolve, onCancel }: InterruptRendererProps): ReactElement {\n const [responded, setResponded] = useState(false);\n if (reason.type !== \"approval\") return <></>;\n\n if (responded) {\n return <div className=\"kaboo-interrupt-responded\">Response submitted</div>;\n }\n\n return (\n <div className=\"kaboo-interrupt kaboo-interrupt-approval\">\n <div className=\"kaboo-interrupt-header\">\n <svg width={16} height={16} viewBox=\"0 0 16 16\" className=\"kaboo-interrupt-icon\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 4.5v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"8\" cy=\"11\" r=\"0.75\" fill=\"currentColor\" />\n </svg>\n <span className=\"kaboo-interrupt-message\">{reason.message}</span>\n </div>\n {reason.tool_input != null && (\n <details className=\"kaboo-interrupt-details\">\n <summary>View input</summary>\n <pre className=\"kaboo-interrupt-pre\">\n {JSON.stringify(reason.tool_input, null, 2)}\n </pre>\n </details>\n )}\n <div className=\"kaboo-interrupt-actions\">\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-approve\"\n onClick={() => { setResponded(true); onResolve({ status: \"approved\" }); }}\n >\n Approve\n </button>\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-reject\"\n onClick={() => { setResponded(true); onCancel(); }}\n >\n Reject\n </button>\n </div>\n </div>\n );\n}\n\n/** Drop any option the agent labelled \"Other\" — the UI adds its own free-text row. */\nfunction withoutOther(options: string[] | undefined): string[] {\n return (options ?? []).filter((o) => o.trim().toLowerCase() !== \"other\");\n}\n\n/**\n * Build the resume payload as a `{question: answer}` map — the single answer\n * representation shared by the model (which reads it as JSON) and the durable\n * Q&A card (which parses the same tool result). Keyed by question text (not\n * index) so both consumers read it without extra correlation state.\n */\nfunction buildAnswerPayload(\n questions: FormQuestion[],\n answers: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n questions.forEach((q, idx) => {\n out[q.question] = answers[String(idx)] ?? \"\";\n });\n return out;\n}\n\nfunction RadioInput({\n question,\n value,\n onChange,\n}: {\n question: FormQuestion;\n value: string;\n onChange: (v: string) => void;\n}): ReactElement {\n const [otherText, setOtherText] = useState(\"\");\n const [isOther, setIsOther] = useState(false);\n const options = withoutOther(question.options);\n\n return (\n <div className=\"kaboo-interrupt-radio-group\">\n {options.map((opt) => (\n <label key={opt} className={`kaboo-interrupt-option ${value === opt && !isOther ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"radio\"\n name={question.question}\n checked={value === opt && !isOther}\n onChange={() => { setIsOther(false); onChange(opt); }}\n className=\"kaboo-interrupt-radio\"\n />\n <span>{opt}</span>\n </label>\n ))}\n <div className={`kaboo-interrupt-option kaboo-interrupt-option-other ${isOther ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"radio\"\n name={question.question}\n checked={isOther}\n onChange={() => { setIsOther(true); onChange(otherText); }}\n className=\"kaboo-interrupt-radio\"\n />\n <input\n type=\"text\"\n className=\"kaboo-interrupt-text-input kaboo-interrupt-other-input\"\n placeholder=\"Other (type your own answer)…\"\n value={otherText}\n onChange={(e) => { setOtherText(e.target.value); setIsOther(true); onChange(e.target.value); }}\n onFocus={() => { setIsOther(true); onChange(otherText); }}\n />\n </div>\n </div>\n );\n}\n\nfunction CheckboxInput({\n question,\n value,\n onChange,\n}: {\n question: FormQuestion;\n value: string[];\n onChange: (v: string[]) => void;\n}): ReactElement {\n const [otherText, setOtherText] = useState(\"\");\n const options = withoutOther(question.options);\n\n const toggle = (opt: string) => {\n const next = value.includes(opt) ? value.filter((v) => v !== opt) : [...value, opt];\n onChange(next);\n };\n\n const otherSelected = otherText !== \"\" && value.includes(otherText);\n\n return (\n <div className=\"kaboo-interrupt-checkbox-group\">\n {options.map((opt) => (\n <label key={opt} className={`kaboo-interrupt-option ${value.includes(opt) ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"checkbox\"\n checked={value.includes(opt)}\n onChange={() => toggle(opt)}\n className=\"kaboo-interrupt-checkbox\"\n />\n <span>{opt}</span>\n </label>\n ))}\n <div className={`kaboo-interrupt-option kaboo-interrupt-option-other ${otherSelected ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"checkbox\"\n checked={otherSelected}\n onChange={() => {\n if (otherSelected) onChange(value.filter((v) => v !== otherText));\n else if (otherText) onChange([...value, otherText]);\n }}\n className=\"kaboo-interrupt-checkbox\"\n />\n <input\n type=\"text\"\n className=\"kaboo-interrupt-text-input kaboo-interrupt-other-input\"\n placeholder=\"Other (type your own answer)…\"\n value={otherText}\n onChange={(e) => {\n const prev = otherText;\n const nextText = e.target.value;\n setOtherText(nextText);\n const filtered = value.filter((v) => v !== prev);\n onChange(nextText ? [...filtered, nextText] : filtered);\n }}\n />\n </div>\n </div>\n );\n}\n\nfunction TextInput({\n value,\n onChange,\n}: {\n value: string;\n onChange: (v: string) => void;\n}): ReactElement {\n return (\n <textarea\n className=\"kaboo-interrupt-textarea\"\n placeholder=\"Type your answer...\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n rows={3}\n autoFocus\n />\n );\n}\n\nfunction FormVariant({ reason, onResolve, onCancel }: InterruptRendererProps): ReactElement {\n const questions = reason.type === \"form\" ? reason.questions : [];\n const isSingle = questions.length === 1;\n const [step, setStep] = useState(0);\n const [answers, setAnswers] = useState<Record<string, unknown>>({});\n const [responded, setResponded] = useState(false);\n\n if (responded) {\n return <div className=\"kaboo-interrupt-responded\">Response submitted</div>;\n }\n\n const setAnswer = (idx: number, val: unknown) => {\n setAnswers((prev) => ({ ...prev, [String(idx)]: val }));\n };\n\n const current = questions[step];\n if (!current) return <></>;\n\n const renderQuestion = (q: FormQuestion, idx: number) => {\n if (q.type === \"radio\") {\n return (\n <RadioInput\n question={q}\n value={(answers[String(idx)] as string) ?? \"\"}\n onChange={(v) => setAnswer(idx, v)}\n />\n );\n }\n if (q.type === \"checkbox\") {\n return (\n <CheckboxInput\n question={q}\n value={(answers[String(idx)] as string[]) ?? []}\n onChange={(v) => setAnswer(idx, v)}\n />\n );\n }\n return (\n <TextInput\n value={(answers[String(idx)] as string) ?? \"\"}\n onChange={(v) => setAnswer(idx, v)}\n />\n );\n };\n\n const isLast = step === questions.length - 1;\n\n return (\n <div className=\"kaboo-interrupt kaboo-interrupt-form\">\n {!isSingle && (\n <div className=\"kaboo-interrupt-progress\">\n {step + 1} of {questions.length}\n </div>\n )}\n <div className=\"kaboo-interrupt-question\">\n {current.question}\n </div>\n {renderQuestion(current, step)}\n <div className=\"kaboo-interrupt-actions\">\n {!isSingle && step > 0 && (\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-back\"\n onClick={() => setStep(step - 1)}\n >\n Back\n </button>\n )}\n {isLast ? (\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-approve\"\n onClick={() => {\n setResponded(true);\n onResolve(buildAnswerPayload(questions, answers));\n }}\n >\n Submit\n </button>\n ) : (\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-next\"\n onClick={() => setStep(step + 1)}\n >\n Next\n </button>\n )}\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-reject\"\n onClick={() => { setResponded(true); onCancel(); }}\n >\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * Default human-in-the-loop interrupt UI. Renders an Approve/Reject panel for an\n * {@link ApprovalReason} and a (optionally multi-step) form with radio/checkbox/\n * text inputs for a {@link FormReason}, calling `onResolve`/`onCancel` with the\n * answer payload. Override per type via `interruptRenderers` on\n * {@link KabooProvider}.\n *\n * @example\n * ```tsx\n * import { InterruptRenderer } from \"@pgege/kaboo-react\";\n * import type { InterruptReason } from \"@pgege/kaboo-react\";\n *\n * const reason: InterruptReason = {\n * type: \"approval\",\n * message: \"Run this query?\",\n * tool_name: \"run_sql\",\n * };\n *\n * function Example() {\n * return (\n * <InterruptRenderer\n * reason={reason}\n * onResolve={() => {}}\n * onCancel={() => {}}\n * />\n * );\n * }\n * ```\n */\nexport function InterruptRenderer(props: InterruptRendererProps): ReactElement {\n if (props.reason.type === \"approval\") {\n return <ApprovalVariant {...props} />;\n }\n return <FormVariant {...props} />;\n}\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\nimport type { InterruptReason } from \"../types\";\n\n/**\n * An open interrupt published onto the InterruptBridge so an owning agent card\n * can render its prompt inline (rather than only in the chat slot). Carries the\n * reason plus resolve/cancel callbacks bound to this specific interrupt id.\n */\nexport interface ActiveInterrupt {\n /**\n * Unique interrupt id (from the AG-UI interrupt). Distinguishes concurrent\n * gates that may share a single tool-call id (e.g. two parallel sub-agent\n * gates re-keyed onto one delegating call), so each resolves independently.\n */\n id: string;\n /** Why the run paused, and what input it needs. */\n reason: InterruptReason;\n /** Resume the run with the user's answer/approval payload. */\n onResolve: (payload: unknown) => void;\n /** Cancel/reject this gate, resuming the run without a positive answer. */\n onCancel: () => void;\n /**\n * The originating tool-call id, when the interrupt was raised by a tool (e.g.\n * `ask_user` or a gated tool). Lets the owning agent card render the live\n * prompt inline at its tool-call position, so the prompt sits in chronological\n * order rather than in a separate top-level slot.\n */\n toolCallId?: string;\n}\n\ninterface InterruptBridgeValue {\n /** Every open interrupt from the current run, in emission order. */\n active: ActiveInterrupt[];\n publish: (interrupts: ActiveInterrupt[]) => void;\n}\n\nconst InterruptBridgeContext = createContext<InterruptBridgeValue>({\n active: [],\n publish: () => {},\n});\n\n/**\n * Holds the set of currently open interrupts so any tool row can claim and\n * render its own gate inline (see {@link useInterruptFor}). Included\n * automatically by {@link KabooProvider}.\n *\n * @example\n * ```tsx\n * import { InterruptBridgeProvider } from \"@pgege/kaboo-react\";\n *\n * function Providers({ children }: { children: React.ReactNode }) {\n * return <InterruptBridgeProvider>{children}</InterruptBridgeProvider>;\n * }\n * ```\n */\nexport function InterruptBridgeProvider({ children }: { children: ReactNode }) {\n const [active, setActive] = useState<ActiveInterrupt[]>([]);\n const publish = useCallback((interrupts: ActiveInterrupt[]) => {\n setActive(interrupts);\n }, []);\n\n return (\n <InterruptBridgeContext.Provider value={{ active, publish }}>\n {children}\n </InterruptBridgeContext.Provider>\n );\n}\n\n/**\n * Reads the InterruptBridge: the list of open interrupts plus `publish`. Most\n * consumers want {@link useInterruptFor} instead; use this to inspect or drive\n * the whole set.\n *\n * @example\n * ```tsx\n * import { useInterruptBridge } from \"@pgege/kaboo-react\";\n *\n * function OpenGateCount() {\n * const { active } = useInterruptBridge();\n * return <span>{active.length} open</span>;\n * }\n * ```\n */\nexport function useInterruptBridge(): {\n /** Every open interrupt from the current run, in emission order. */\n active: ActiveInterrupt[];\n /** Replace the set of interrupts published to the bridge. */\n publish: (interrupts: ActiveInterrupt[]) => void;\n} {\n return useContext(InterruptBridgeContext);\n}\n\n/**\n * The first open interrupt anchored to a given tool-call id, or `undefined`.\n * Lets a tool row claim and render its own gate inline while N concurrent gates\n * are open, each anchored to a distinct tool call.\n */\nexport function useInterruptFor(\n toolCallId: string | undefined,\n): ActiveInterrupt | undefined {\n const { active } = useInterruptBridge();\n if (!toolCallId) return undefined;\n return active.find((i) => i.toolCallId === toolCallId);\n}\n\n/**\n * Publishes the current set of open interrupts to the bridge so each owning\n * agent card can render its prompt inline at the matching tool-call position.\n * CopilotKit surfaces every open interrupt at once, so this takes the full list\n * and keeps the latest resolve/cancel callbacks in a ref — their per-render\n * identity churn must not re-publish (only the interrupt set should).\n */\nexport function InterruptBridgePublisher({\n interrupts,\n}: {\n interrupts: ActiveInterrupt[];\n}): null {\n const { publish } = useInterruptBridge();\n const listRef = useRef(interrupts);\n listRef.current = interrupts;\n\n const key = interrupts\n .map((i) => `${i.id}:${i.toolCallId ?? \"\"}:${JSON.stringify(i.reason)}`)\n .join(\"|\");\n\n useEffect(() => {\n publish(\n listRef.current.map((i) => ({\n id: i.id,\n reason: i.reason,\n toolCallId: i.toolCallId,\n onResolve: (payload: unknown) =>\n listRef.current.find((x) => x.id === i.id)?.onResolve(payload),\n onCancel: () => listRef.current.find((x) => x.id === i.id)?.onCancel(),\n })),\n );\n return () => publish([]);\n }, [key, publish]);\n\n return null;\n}\n","import type { FormQuestion } from \"../types\";\n\nexport interface AskUserParams {\n question?: string;\n options?: string[];\n input_type?: FormQuestion[\"type\"];\n questions?: Array<{ question?: string; type?: FormQuestion[\"type\"]; options?: string[] }>;\n}\n\n/**\n * Normalise `ask_user` tool input (multi-question `questions` array or a single\n * `question`) into a flat {@link FormQuestion} list. Shared by the top-level\n * renderer and the nested-timeline renderer so an `ask_user` looks identical at\n * every depth.\n */\nexport function normalizeQuestions(params: AskUserParams | undefined): FormQuestion[] {\n if (!params) return [];\n if (Array.isArray(params.questions)) {\n return params.questions.map((q) => ({\n question: q.question ?? \"\",\n type: q.type ?? (q.options ? \"radio\" : \"text\"),\n options: q.options,\n }));\n }\n if (typeof params.question === \"string\") {\n return [\n {\n question: params.question,\n type: params.input_type ?? (params.options ? \"radio\" : \"text\"),\n options: params.options,\n },\n ];\n }\n return [];\n}\n\n/**\n * Parse the `ask_user` tool result into a `{question: answer}` map. The result\n * is the JSON the tool emitted (see `ask_user._format_answer`); we tolerate up\n * to one extra layer of string encoding. Non-answers (empty, or the plain-text\n * \"no answer\"/\"declined\" notes) yield `null` so no card is rendered.\n */\nexport function parseAnswers(result: unknown): Record<string, unknown> | null {\n let value: unknown = result;\n for (let i = 0; i < 2 && typeof value === \"string\"; i++) {\n const trimmed = value.trim();\n if (trimmed === \"\") return null;\n try {\n value = JSON.parse(trimmed);\n } catch {\n return null;\n }\n }\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const obj = value as Record<string, unknown>;\n return Object.keys(obj).length > 0 ? obj : null;\n }\n return null;\n}\n","import { useContext } from \"react\";\nimport { DrillContext } from \"../context/DrillContext\";\nimport type { DrillState } from \"../types\";\n\n/**\n * Reads the drill-down navigation state ({@link DrillState}) from the nearest\n * {@link DrillProvider}: the current path plus `drillIn`/`drillUp`/`drillToRoot`/\n * `drillToLevel`.\n *\n * @example\n * ```tsx\n * import { useDrill } from \"@pgege/kaboo-react\";\n *\n * function BackButton() {\n * const { drillUp, activeDrill } = useDrill();\n * if (!activeDrill) return null;\n * return <button onClick={drillUp}>Back</button>;\n * }\n * ```\n */\nexport function useDrill(): DrillState {\n return useContext(DrillContext);\n}\n","import { useState, useCallback, createContext, type ReactNode } from \"react\";\nimport type { DrillState } from \"../types\";\n\nconst NOOP = () => {};\n\nexport const DrillContext = createContext<DrillState>({\n drillPath: [],\n activeDrill: null,\n drillIn: NOOP,\n drillUp: NOOP,\n drillToRoot: NOOP,\n drillToLevel: NOOP,\n});\n\n/**\n * Provides drill-down navigation state ({@link DrillState}) to the activity\n * components below it. Included automatically by {@link KabooProvider}; only\n * mount it yourself if you compose the providers by hand.\n *\n * @example\n * ```tsx\n * import { DrillProvider, GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n *\n * function Panel() {\n * return (\n * <DrillProvider>\n * <GlassTabs />\n * <DrillDetailView />\n * </DrillProvider>\n * );\n * }\n * ```\n */\nexport function DrillProvider({ children }: { children: ReactNode }) {\n const [drillPath, setDrillPath] = useState<string[]>([]);\n\n const drillIn = useCallback((groupId: string) => {\n setDrillPath((prev) => [...prev, groupId]);\n }, []);\n\n const drillUp = useCallback(() => {\n setDrillPath((prev) => prev.slice(0, -1));\n }, []);\n\n const drillToRoot = useCallback(() => {\n setDrillPath([]);\n }, []);\n\n const drillToLevel = useCallback((level: number) => {\n setDrillPath((prev) => prev.slice(0, level + 1));\n }, []);\n\n const activeDrill = drillPath.length > 0 ? drillPath[drillPath.length - 1] : null;\n\n return (\n <DrillContext.Provider value={{ drillPath, activeDrill, drillIn, drillUp, drillToRoot, drillToLevel }}>\n {children}\n </DrillContext.Provider>\n );\n}\n","import type { StreamGroup, TimelineEntry } from \"../types\";\n\n/** A `[groupId, group]` pair, as returned by the group-hierarchy helpers. */\nexport type GroupEntry = [string, StreamGroup];\n\n/**\n * Stable per-turn key for a group. Prefers the server-stamped `turnId` (stable\n * across an interrupt/resume), falling back to `runId` for older streams that\n * don't carry one. `null` when neither is present.\n */\nexport function groupTurnKey(g: StreamGroup): string | null {\n return g.turnId ?? g.runId ?? null;\n}\n\n/**\n * Split child groups into those anchored to a delegating tool call present in\n * *timeline* (keyed by that tool-call id, so they can be interleaved at their\n * chronological position) and the leftover (swarm/graph members and any child\n * whose spawning tool call isn't in this timeline), which render in a trailing\n * section. Keeps a delegated sub-agent's card at the point it was delegated,\n * instead of after the parent's summary text.\n */\nexport function partitionChildrenByToolCall(\n childEntries: GroupEntry[],\n timeline: TimelineEntry[],\n): { byToolCall: Map<string, GroupEntry>; leftover: GroupEntry[] } {\n const toolUseIds = new Set(\n timeline.filter((e) => e.type === \"tool\").map((e) => e.tool.toolUseId),\n );\n const byToolCall = new Map<string, GroupEntry>();\n const leftover: GroupEntry[] = [];\n for (const [id, g] of childEntries) {\n if (g.toolCallId && toolUseIds.has(g.toolCallId)) {\n byToolCall.set(g.toolCallId, [id, g]);\n } else {\n leftover.push([id, g]);\n }\n }\n return { byToolCall, leftover };\n}\n\n/**\n * Top-level groups are those without a parent. Uses the explicit\n * `parentGroup` field rather than parsing dot-paths out of the group id, so\n * group names are free to contain any characters.\n *\n * @example\n * ```ts\n * import { topLevelGroups } from \"@pgege/kaboo-react\";\n *\n * function rootCount(groups: Parameters<typeof topLevelGroups>[0]) {\n * return topLevelGroups(groups).length;\n * }\n * ```\n */\nexport function topLevelGroups(\n groups: Record<string, StreamGroup>,\n): GroupEntry[] {\n return Object.entries(groups).filter(([, g]) => g.parentGroup == null);\n}\n\n/**\n * Direct children of `parentId` (one level deep) via the `parentGroup` field.\n *\n * @example\n * ```ts\n * import { directChildren } from \"@pgege/kaboo-react\";\n *\n * function childCount(\n * groups: Parameters<typeof directChildren>[0],\n * parentId: string,\n * ) {\n * return directChildren(groups, parentId).length;\n * }\n * ```\n */\nexport function directChildren(\n groups: Record<string, StreamGroup>,\n parentId: string,\n): GroupEntry[] {\n return Object.entries(groups).filter(([, g]) => g.parentGroup === parentId);\n}\n\n/**\n * Root groups to render inline in the chat for a first-class swarm/graph entry.\n *\n * These are member runs that are NOT spawned by a delegate tool call (no\n * `toolCallId`, so they can't be anchored via CopilotKit's tool renderer) and\n * that sit at the top of the visible tree — either genuinely parentless, or\n * parented by the entry orchestration whose own group is filtered out of the\n * stream (so its parent id is absent from the map). Delegate sub-agent groups\n * always carry a `toolCallId` and are therefore excluded, preserving the\n * tool-call-anchored path.\n *\n * A plain-agent entry group (`inlineChatOwner`) is also excluded: its text and\n * tools are already rendered inline by the host, so it enriches those tool rows\n * without ever becoming its own card.\n */\nexport function chatRootGroups(\n groups: Record<string, StreamGroup>,\n): GroupEntry[] {\n return Object.entries(groups).filter(\n ([, g]) =>\n !g.toolCallId &&\n !g.inlineChatOwner &&\n (g.parentGroup == null || groups[g.parentGroup] === undefined),\n );\n}\n\n/**\n * The most recent `runId` among the given entries (insertion order = arrival\n * order), or `null` when none carry a run id. Used to scope inline cards to the\n * current turn.\n */\nexport function latestRunId(entries: GroupEntry[]): string | null {\n let latest: string | null = null;\n for (const [, g] of entries) {\n if (g.runId) latest = g.runId;\n }\n return latest;\n}\n\n/**\n * True when a still-pending tool call with the given tool-call id exists in some\n * group's timeline. That tool row is the chronological home for the live prompt\n * (an `ask_user` form or a gated-tool approval), so the owning agent card\n * renders it inline there — and the top-level / drill interrupt slots suppress\n * it to avoid a duplicate that would float out of order. Returns `false` (no\n * anchor) when no such tool is present, so those slots still render the prompt\n * as a fallback.\n */\nexport function pendingToolAnchorExists(\n groups: Record<string, StreamGroup>,\n toolCallId: string | undefined,\n): boolean {\n if (!toolCallId) return false;\n for (const g of Object.values(groups)) {\n for (const t of g.tools) {\n if (t.toolUseId === toolCallId && t.toolResult == null) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Correlate an inline chat card to its activity group by the delegate tool call\n * that spawned it. A group carries the AG-UI `toolCallId` of the coordinator's\n * delegating call (stamped server-side); the same id is exposed by CopilotKit's\n * v2 tool renderer, so matching on `(agentName, toolCallId)` is stable across\n * re-renders and independent of arrival order.\n */\nexport function findGroupForCard(\n groups: Record<string, StreamGroup>,\n agentName: string,\n toolCallId: string,\n): GroupEntry | undefined {\n return Object.entries(groups).find(\n ([, g]) => g.agentName === agentName && g.toolCallId === toolCallId,\n );\n}\n","import { useDefaultRenderTool } from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { ToolRow } from \"../components/ToolRow\";\nimport { isControlOnlyStatus } from \"../formatters/output\";\nimport type { StreamGroup, ToolCall } from \"../types\";\n\nfunction findTool(\n groups: Record<string, StreamGroup>,\n toolCallId: string,\n): ToolCall | undefined {\n for (const group of Object.values(groups)) {\n const match = group.tools.find((t) => t.toolUseId === toolCallId);\n if (match) return match;\n }\n return undefined;\n}\n\n/** A tool call whose name/id spawned a delegate sub-agent group is owned by\n * {@link KabooInlineCards} (renders an AgentCard). Detect it so the wildcard\n * doesn't briefly render it as a plain tool row before that card registers. */\nfunction isDelegateSpawn(\n groups: Record<string, StreamGroup>,\n name: string,\n toolCallId: string,\n): boolean {\n for (const group of Object.values(groups)) {\n if (!group.toolCallId) continue;\n if (group.toolCallId === toolCallId || group.agentName === name) return true;\n }\n return false;\n}\n\n/**\n * Wildcard (`\"*\"`) tool-call renderer: persists any plain tool call inline in\n * the chat transcript. Tools with a dedicated renderer (`ask_user`, delegate\n * sub-agents) take precedence and never reach this fallback — and delegate\n * spawns are skipped explicitly to avoid a flash before their AgentCard\n * registers.\n *\n * The rich record (label, formatted result, error status) is sourced from the\n * activity store by tool-call id; a minimal record built from the raw render\n * props is used while the group is still catching up, so the card never\n * disappears once the tool resolves.\n */\nexport function KabooToolRender() {\n const { groups } = useActivity();\n\n useDefaultRenderTool(\n {\n render: ({ name, toolCallId, parameters, status, result }) => {\n if (isDelegateSpawn(groups, name, toolCallId)) return <></>;\n const fromActivity = findTool(groups, toolCallId);\n // A bare HITL control echo (e.g. {\"status\":\"approved\"} or\n // {\"status\":\"cancelled\"}) is the interrupt-resolution payload, not real\n // tool output. Keep the tool row (a real gated call must never vanish),\n // but drop the echo as the result so we don't dump raw JSON — the real\n // output arrives via the activity store once the resumed tool finishes.\n const controlEcho = !fromActivity && isControlOnlyStatus(result);\n const tool: ToolCall =\n fromActivity ?? {\n toolUseId: toolCallId,\n toolName: name,\n toolInput: parameters,\n toolResult:\n controlEcho || typeof result !== \"string\" ? undefined : result,\n status: status === \"complete\" ? \"success\" : \"running\",\n };\n return (\n <div className=\"kaboo-inline-tool\">\n <ToolRow tool={tool} />\n </div>\n );\n },\n },\n [groups],\n );\n\n return null;\n}\n","import {\n CopilotChatAssistantMessage,\n type CopilotChatAssistantMessageProps,\n} from \"@copilotkit/react-core/v2\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { useTurnBinding } from \"../context/TurnBinding\";\n\n/**\n * Drop-in replacement for CopilotKit's assistant-message renderer that prepends\n * a first-class swarm/graph turn's member cards ABOVE the assistant's text —\n * inside the chat transcript, as part of the same turn.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * ```tsx\n * <CopilotChat messageView={{ assistantMessage: KabooAssistantMessage }} />\n * ```\n *\n * This is used instead of `renderCustomMessages` because the `CopilotKit`\n * convenience provider hard-overrides that prop; the `messageView`/\n * `assistantMessage` slot is the supported customization surface and is not\n * clobbered.\n *\n * Which cards to show is decided by the turn binding (provided by\n * {@link KabooMessageView}), which resolves each reply message to its turn's\n * member cards — robust to an interrupt/resume splitting the turn across\n * multiple runIds. Delegate cards keep their tool-call path (they carry a\n * `toolCallId` and are excluded from `chatRootGroups`).\n */\nexport function KabooAssistantMessage(props: CopilotChatAssistantMessageProps) {\n const { message } = props;\n const { rootsByMessageId } = useTurnBinding();\n const messageId = (message as { id?: string })?.id;\n const mine = messageId ? rootsByMessageId.get(messageId) ?? [] : [];\n\n return (\n <>\n {mine.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {mine.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n <CopilotChatAssistantMessage {...props} />\n </>\n );\n}\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { GroupEntry } from \"../utils/groups\";\n\n/**\n * Binds each assistant reply message to the swarm/graph member cards its turn\n * produced, so those cards render *inside* that message (above its reply text)\n * in one chronological block — and a turn's cards never bleed onto a different\n * turn's reply.\n *\n * The mapping is by turn, not `runId`: an interrupt/resume changes the `runId`\n * mid-turn, so a reply's `runId` may only match the `chat_output` member while\n * earlier members carry the pre-resume `runId`. Both, however, share the\n * server-stamped `turnId` ({@link groupTurnKey}). {@link KabooMessageView}\n * resolves each reply message → its run → that run's `turnId`, then collects all\n * roots of that turn — so every member binds to the right reply regardless of\n * how many runs the turn spanned.\n *\n * `rootsByMessageId` holds the resolved cards per assistant message id; a turn\n * whose reply hasn't streamed yet isn't in the map — {@link KabooMessageView}\n * renders those roots live beneath the transcript instead.\n */\nexport interface TurnBinding {\n rootsByMessageId: Map<string, GroupEntry[]>;\n}\n\nconst TurnBindingContext = createContext<TurnBinding>({\n rootsByMessageId: new Map(),\n});\n\nexport function TurnBindingProvider({\n value,\n children,\n}: {\n value: TurnBinding;\n children: ReactNode;\n}) {\n return (\n <TurnBindingContext.Provider value={value}>\n {children}\n </TurnBindingContext.Provider>\n );\n}\n\nexport function useTurnBinding(): TurnBinding {\n return useContext(TurnBindingContext);\n}\n","import {\n CopilotChatMessageView,\n CopilotChatAssistantMessage,\n useCopilotKit,\n useCopilotChatConfiguration,\n type CopilotChatMessageViewProps,\n} from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { chatRootGroups, groupTurnKey, type GroupEntry } from \"../utils/groups\";\nimport { TurnBindingProvider } from \"../context/TurnBinding\";\nimport { KabooAssistantMessage } from \"./KabooAssistantMessage\";\n\nfunction KabooMessageViewImpl(props: CopilotChatMessageViewProps) {\n const { groups } = useActivity();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId;\n const threadId = config?.threadId;\n\n return (\n <CopilotChatMessageView\n {...props}\n assistantMessage={\n KabooAssistantMessage as unknown as typeof CopilotChatAssistantMessage\n }\n >\n {({ messages, messageElements, interruptElement, isRunning }) => {\n const roots = chatRootGroups(groups);\n\n // Bucket this turn's member cards by their stable turn key, and map each\n // AG-UI run to its turn key so a reply (whose run may be the post-resume\n // one) resolves to the whole turn — not just its chat_output member.\n const rootsByTurn = new Map<string, GroupEntry[]>();\n for (const entry of roots) {\n const key = groupTurnKey(entry[1]);\n if (!key) continue;\n const bucket = rootsByTurn.get(key);\n if (bucket) bucket.push(entry);\n else rootsByTurn.set(key, [entry]);\n }\n const runToTurn = new Map<string, string>();\n for (const g of Object.values(groups)) {\n const key = groupTurnKey(g);\n if (g.runId && key) runToTurn.set(g.runId, key);\n }\n\n // Resolve each assistant reply → its run → its turn's roots. A turn\n // whose reply hasn't streamed yet stays unbound and renders live below.\n const rootsByMessageId = new Map<string, GroupEntry[]>();\n const boundTurns = new Set<string>();\n const list = messages as Array<{ id?: string; role?: string }>;\n for (const m of list) {\n if (m?.role !== \"assistant\" || !m.id) continue;\n const runId =\n agentId && threadId\n ? copilotkit.getRunIdForMessage(agentId, threadId, m.id)\n : undefined;\n const key = runId ? runToTurn.get(runId) ?? runId : undefined;\n if (!key) continue;\n const turnRoots = rootsByTurn.get(key);\n if (turnRoots) {\n rootsByMessageId.set(m.id, turnRoots);\n boundTurns.add(key);\n }\n }\n\n const pending = roots.filter(([, g]) => {\n const key = groupTurnKey(g);\n return !key || !boundTurns.has(key);\n });\n const showStartCursor = isRunning && pending.length === 0;\n\n return (\n <TurnBindingProvider value={{ rootsByMessageId }}>\n {messageElements}\n {pending.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {pending.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n {interruptElement}\n {showStartCursor && <CopilotChatMessageView.Cursor />}\n </TurnBindingProvider>\n );\n }}\n </CopilotChatMessageView>\n );\n}\n\n/**\n * Drop-in replacement for `CopilotChat`'s `messageView` that renders swarm/graph\n * member cards **live, inside the chat, from the moment the first agent starts**\n * — not only once the final answer streams.\n *\n * Why this exists: cards attached purely to the assistant message\n * ({@link KabooAssistantMessage}) can't appear until an assistant bubble exists,\n * which for a swarm/graph is when the `chat_output` node streams — i.e. at the\n * very end. During the earlier nodes (planner, researcher, …) there is no\n * assistant message, so the chat would show only a spinner while real work is\n * happening.\n *\n * This view renders the normal message list (with {@link KabooAssistantMessage}\n * for settled turns) and, beneath it, an \"in-progress\" block for any run whose\n * activity groups have appeared but which has **no assistant bubble yet**. As\n * soon as the run's assistant message mounts, that run becomes \"covered\" and its\n * cards render inside the message instead — so there's a seamless hand-off with\n * no duplication.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * @example\n * ```tsx\n * import { CopilotChat } from \"@copilotkit/react-core/v2\";\n * import { KabooMessageView } from \"@pgege/kaboo-react/copilotkit\";\n *\n * function Chat() {\n * return <CopilotChat messageView={KabooMessageView} />;\n * }\n * ```\n */\nexport const KabooMessageView = Object.assign(KabooMessageViewImpl, {\n /**\n * The streaming cursor slot, re-exported from CopilotKit so `KabooMessageView`\n * is a drop-in `messageView` (the slot expects a component carrying `Cursor`).\n */\n Cursor: CopilotChatMessageView.Cursor,\n});\n","import type { ReactElement } from \"react\";\nimport { useInterrupt } from \"@copilotkit/react-core/v2\";\nimport { InterruptRenderer } from \"../components/InterruptRenderer\";\nimport {\n InterruptBridgePublisher,\n type ActiveInterrupt,\n} from \"../context/InterruptBridge\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { pendingToolAnchorExists } from \"../utils/groups\";\nimport { KabooAskUser } from \"./KabooAskUser\";\nimport type { InterruptReason, InterruptRendererProps } from \"../types\";\n\n/**\n * Chat-level fallback slot for one interrupt. Renders the prompt UI unless the\n * owning agent card already renders it inline at its pending tool-call position\n * (see {@link pendingToolAnchorExists}) — in that case this returns nothing so\n * the prompt stays in chronological order inside the card instead of floating on\n * top of the turn's cards. Prompts with no on-screen tool anchor render here.\n */\nfunction ChatInterruptSlot({\n interrupt,\n Renderer,\n}: {\n interrupt: ActiveInterrupt;\n Renderer: React.ComponentType<InterruptRendererProps>;\n}): ReactElement | null {\n const { groups } = useActivity();\n if (pendingToolAnchorExists(groups, interrupt.toolCallId)) {\n return null;\n }\n return (\n <Renderer\n reason={interrupt.reason}\n toolCallId={interrupt.toolCallId}\n onResolve={interrupt.onResolve}\n onCancel={interrupt.onCancel}\n />\n );\n}\n\n/** Props for {@link KabooInterruptHandler}. */\nexport interface KabooInterruptHandlerProps {\n /** Restrict handling to a single CopilotKit agent (optional). */\n agentId?: string;\n /** Per-interrupt-type renderer overrides. */\n renderers?: Partial<\n Record<InterruptReason[\"type\"], React.ComponentType<InterruptRendererProps>>\n >;\n /**\n * Also publish the active interrupts to the InterruptBridge so each renders\n * inside the drill-down detail view (not just the chat). Defaults to `true`;\n * requires an `InterruptBridgeProvider` (included in `KabooProvider`).\n */\n bridge?: boolean;\n}\n\n/**\n * Ready-made human-in-the-loop interrupt handler. CopilotKit surfaces every open\n * interrupt of a run at once (e.g. two gated tools called in parallel); we render\n * one card per interrupt and resolve each independently by its own id. The client\n * accumulates the per-id responses and only resumes the run once every open\n * interrupt has been answered — so resolving with `intr.id` (never the bare\n * `resolve()`, which would only ever answer the first) is what keeps N parallel\n * gates from wedging. Prompts anchored to an on-screen tool render inline at that\n * tool's position; the rest fall back to the chat slot.\n */\nexport function KabooInterruptHandler({\n agentId,\n renderers,\n bridge = true,\n}: KabooInterruptHandlerProps): ReactElement | null {\n useInterrupt({\n ...(agentId ? { agentId } : {}),\n render: ({ interrupts, resolve, cancel }) => {\n const active: ActiveInterrupt[] = (interrupts ?? [])\n .map((intr): ActiveInterrupt | null => {\n const reason = (intr?.metadata ?? intr?.reason) as\n | InterruptReason\n | undefined;\n if (!reason || !reason.type) return null;\n return {\n id: intr.id,\n reason,\n toolCallId: (intr as { toolCallId?: string }).toolCallId,\n onResolve: (payload: unknown) => resolve(payload, intr.id),\n onCancel: () => cancel(intr.id),\n };\n })\n .filter((x): x is ActiveInterrupt => x !== null);\n\n if (active.length === 0) {\n return <></>;\n }\n\n return (\n <>\n {bridge && <InterruptBridgePublisher interrupts={active} />}\n {active.map((a) => (\n <ChatInterruptSlot\n key={a.id}\n interrupt={a}\n Renderer={renderers?.[a.reason.type] ?? InterruptRenderer}\n />\n ))}\n </>\n );\n },\n });\n\n return <KabooAskUser agentId={agentId} />;\n}\n","import { useRenderTool } from \"@copilotkit/react-core/v2\";\nimport { AskUserSummary } from \"../components/AskUserSummary\";\nimport { normalizeQuestions, parseAnswers, type AskUserParams } from \"../formatters/askUser\";\nimport type { FormQuestion } from \"../types\";\n\n/**\n * Permissive Standard Schema. `useRenderTool` requires a `parameters` schema but\n * never validates against it at render time (it parses the raw tool args). This\n * shim satisfies the type without pulling in a schema library.\n */\nconst ANY_PARAMETERS = {\n \"~standard\": {\n version: 1 as const,\n vendor: \"kaboo\",\n validate: (value: unknown) => ({ value }),\n },\n};\n\n/**\n * Renders answered `ask_user` prompts inline in the chat, anchored to the tool\n * call. The tool call is a permanent part of the transcript, so the question and\n * the user's answer persist in chronological order after the interrupt resolves.\n *\n * While the prompt is still pending (no result yet), this renders nothing — the\n * live interactive form is supplied by {@link KabooInterruptHandler}'s\n * `useInterrupt` render.\n */\nexport function KabooAskUser({ agentId }: { agentId?: string }) {\n useRenderTool({\n name: \"ask_user\",\n ...(agentId ? { agentId } : {}),\n parameters: ANY_PARAMETERS,\n render: ({ parameters, result }) => {\n const questions = normalizeQuestions(parameters as AskUserParams | undefined);\n if (questions.length === 0) return <></>;\n\n return <AskUserCard questions={questions} result={result} />;\n },\n });\n\n return null;\n}\n\n/**\n * Renders the answered Q&A once the tool result carries answers. While the\n * prompt is still pending the result is empty, so nothing is drawn here and the\n * live interactive form (from `useInterrupt`) owns the UI. The tool result is\n * the single source of truth, so the card also survives a reload/replay.\n */\nfunction AskUserCard({\n questions,\n result,\n}: {\n questions: FormQuestion[];\n result: unknown;\n}) {\n const answers = parseAnswers(result);\n if (!answers) return <></>;\n return <AskUserSummary questions={questions} answers={answers} />;\n}\n"],"mappings":"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","names":["import_v2","import_react","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","text","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_v2","import_jsx_runtime","import_jsx_runtime","import_v2","import_react","import_jsx_runtime","import_jsx_runtime","import_v2","import_jsx_runtime","import_v2","import_v2","import_jsx_runtime","ANY_PARAMETERS","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/copilotkit.ts","../src/integrations/KabooInlineCards.tsx","../src/hooks/useActivity.ts","../src/context/ActivityProvider.tsx","../src/components/AgentCard.tsx","../src/formatters/output.ts","../src/components/MarkdownContent.tsx","../src/components/Timeline.tsx","../src/components/ToolRow.tsx","../src/formatters/input.ts","../src/components/MiniTable.tsx","../src/components/AskUserSummary.tsx","../src/components/InterruptRenderer.tsx","../src/context/InterruptBridge.tsx","../src/formatters/askUser.ts","../src/hooks/useDrill.ts","../src/context/DrillContext.tsx","../src/utils/groups.ts","../src/integrations/KabooToolRender.tsx","../src/integrations/KabooAssistantMessage.tsx","../src/context/TurnBinding.tsx","../src/integrations/KabooMessageView.tsx","../src/integrations/KabooUserMessage.tsx","../src/references/ReferencesProvider.tsx","../src/integrations/KabooInterruptHandler.tsx","../src/integrations/KabooAskUser.tsx"],"sourcesContent":["export { KabooInlineCards } from \"./integrations/KabooInlineCards\";\nexport { KabooAssistantMessage } from \"./integrations/KabooAssistantMessage\";\nexport { KabooMessageView } from \"./integrations/KabooMessageView\";\nexport { KabooUserMessage } from \"./integrations/KabooUserMessage\";\nexport { KabooInterruptHandler } from \"./integrations/KabooInterruptHandler\";\nexport type { KabooInterruptHandlerProps } from \"./integrations/KabooInterruptHandler\";\nexport { KabooAskUser } from \"./integrations/KabooAskUser\";\nexport { KabooToolRender } from \"./integrations/KabooToolRender\";\n","import { useRenderTool } from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { findGroupForCard } from \"../utils/groups\";\nimport { KabooToolRender } from \"./KabooToolRender\";\n\n/**\n * Permissive Standard Schema. `useRenderTool` requires a `parameters` schema for\n * named tools, but the schema is type-only — at render time CopilotKit parses the\n * raw tool arguments directly and never validates against it. This shim satisfies\n * the type without pulling in a schema library (e.g. zod).\n */\nconst ANY_PARAMETERS = {\n \"~standard\": {\n version: 1 as const,\n vendor: \"kaboo\",\n validate: (value: unknown) => ({ value }),\n },\n};\n\n/**\n * Renders {@link AgentCard}s inline in the chat for **delegate** sub-agents.\n *\n * Every delegate group is spawned by a delegate tool call and carries its\n * `toolCallId`. We register a v2 tool renderer per such agent so CopilotKit\n * places the card at the tool-call position in the assistant turn, correlated\n * by `(agentName, toolCallId)`.\n *\n * First-class swarm/graph entries have no delegating tool call, so their member\n * cards are rendered by {@link KabooMessageView} / {@link KabooAssistantMessage}\n * instead, anchored to the assistant turn. Groups carrying a `toolCallId` are\n * excluded there, so the two paths never double-render the same group.\n */\nexport function KabooInlineCards() {\n const { groups } = useActivity();\n\n const toolAgentNames = new Set<string>();\n for (const group of Object.values(groups)) {\n if (group.agentName && group.toolCallId) toolAgentNames.add(group.agentName);\n }\n\n return (\n <>\n {Array.from(toolAgentNames).map((agentName) => (\n <InlineCardAction key={agentName} agentName={agentName} />\n ))}\n <KabooToolRender />\n </>\n );\n}\n\nfunction InlineCardAction({ agentName }: { agentName: string }) {\n useRenderTool({\n name: agentName,\n parameters: ANY_PARAMETERS,\n render: ({ toolCallId, parameters, result, status }) => (\n <InlineCardRenderer\n agentName={agentName}\n toolCallId={toolCallId}\n input={(parameters as { input?: string } | undefined)?.input}\n result={typeof result === \"string\" ? result : undefined}\n actionStatus={status}\n />\n ),\n });\n\n return null;\n}\n\nfunction InlineCardRenderer({\n agentName,\n toolCallId,\n input,\n result,\n actionStatus,\n}: {\n agentName: string;\n toolCallId: string;\n input?: string;\n result?: string;\n actionStatus?: string;\n}) {\n const { groups } = useActivity();\n const entry = findGroupForCard(groups, agentName, toolCallId);\n\n if (!entry) {\n return <div className=\"kaboo-agent-card-empty\">Loading {agentName}...</div>;\n }\n\n return (\n <AgentCard\n groupId={entry[0]}\n group={entry[1]}\n input={input}\n result={result}\n actionStatus={actionStatus}\n />\n );\n}\n","import { useContext } from \"react\";\nimport { ActivityContext } from \"../context/ActivityProvider\";\nimport type { ActivityState } from \"../types\";\n\n/**\n * Reads the current {@link ActivityState} (all activity groups for the thread)\n * from the nearest {@link KabooActivityProvider}. Re-renders on each new\n * `ACTIVITY_SNAPSHOT`.\n *\n * @example\n * ```tsx\n * import { useActivity } from \"@pgege/kaboo-react\";\n *\n * function GroupCount() {\n * const { groups } = useActivity();\n * return <span>{Object.keys(groups).length} agents</span>;\n * }\n * ```\n */\nexport function useActivity(): ActivityState {\n return useContext(ActivityContext);\n}\n","import { useState, useEffect, createContext, type ReactNode, type ReactElement } from \"react\";\nimport { useAgent } from \"@copilotkit/react-core/v2\";\nimport type { ActivityState } from \"../types\";\n\nconst EMPTY: ActivityState = { groups: {} };\n\n/**\n * A map of custom renderers for structured agent output, keyed by the output\n * schema name. When a group carries `structuredOutput` and a matching\n * `outputSchemaName`, its renderer is used instead of the default JSON view.\n *\n * @example\n * ```tsx\n * import type { StructuredRenderers } from \"@pgege/kaboo-react\";\n *\n * const renderers: StructuredRenderers = {\n * WeatherReport: (data) => <div>{String(data.summary)}</div>,\n * };\n * ```\n */\nexport type StructuredRenderers = Record<string, (data: Record<string, unknown>) => ReactElement>;\n\n/** React context carrying the raw activity snapshot; read it via {@link useActivity}. */\nexport const ActivityContext = createContext<ActivityState>(EMPTY);\n/** React context carrying the {@link StructuredRenderers} map for structured output. */\nexport const StructuredRenderersContext = createContext<StructuredRenderers>({});\n\n/** Props for {@link KabooActivityProvider}. */\nexport interface KabooActivityProviderProps {\n /**\n * CopilotKit agent id whose activity snapshots to consume. Omit to use the\n * provider's default agent. Agent and thread scoping come from CopilotKit.\n */\n agentId?: string;\n /** Renderers for structured agent outputs, keyed by output schema name. */\n structuredRenderers?: StructuredRenderers;\n /** The subtree that reads activity via {@link useActivity}. */\n children: ReactNode;\n}\n\n/**\n * Reads kaboo's hierarchical activity from the AG-UI run stream. The backend\n * emits it as `ACTIVITY_SNAPSHOT` events interleaved on `/invocations`, so we\n * subscribe to the CopilotKit agent instead of a separate SSE endpoint.\n *\n * Included automatically by {@link KabooProvider}; mount it yourself only when\n * composing providers by hand under an existing `<CopilotKit>`.\n *\n * @example\n * ```tsx\n * import { KabooActivityProvider, ActivityPanel } from \"@pgege/kaboo-react\";\n *\n * function Activity({ agent }: { agent: string }) {\n * return (\n * <KabooActivityProvider agentId={agent}>\n * <ActivityPanel />\n * </KabooActivityProvider>\n * );\n * }\n * ```\n */\nexport function KabooActivityProvider({ agentId, structuredRenderers, children }: KabooActivityProviderProps) {\n const { agent } = useAgent(agentId ? { agentId } : undefined);\n const [state, setState] = useState<ActivityState>(EMPTY);\n\n useEffect(() => {\n if (!agent) return;\n const { unsubscribe } = agent.subscribe({\n onActivitySnapshotEvent: ({ event }) => {\n setState(event.content as unknown as ActivityState);\n },\n });\n return unsubscribe;\n }, [agent]);\n\n return (\n <ActivityContext.Provider value={state}>\n <StructuredRenderersContext.Provider value={structuredRenderers ?? {}}>\n {children}\n </StructuredRenderersContext.Provider>\n </ActivityContext.Provider>\n );\n}\n","import { useState, useEffect, useRef, useContext } from \"react\";\nimport type { StreamGroup } from \"../types\";\nimport { isControlOnlyStatus, normalizeResult } from \"../formatters/output\";\nimport { MarkdownContent } from \"./MarkdownContent\";\nimport { Timeline } from \"./Timeline\";\nimport { useDrill } from \"../hooks/useDrill\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { StructuredRenderersContext } from \"../context/ActivityProvider\";\nimport { directChildren, partitionChildrenByToolCall } from \"../utils/groups\";\n\n/** Props for {@link AgentCard}. */\nexport interface AgentCardProps {\n /** Id of the group this card renders. */\n groupId: string;\n /** The activity group to render. */\n group: StreamGroup;\n /** Task/input text to show, overriding the group's own `task`. */\n input?: string;\n /** Raw tool result to render as the card's answer, when provided by the host. */\n result?: string;\n /** Host-provided action status (e.g. `\"complete\"`) used to mark the card done. */\n actionStatus?: string;\n /**\n * When true, the card renders its `directChildren` inline as nested\n * {@link AgentCard}s (recursively). Used by the first-class swarm/graph inline\n * renderer to show the whole member tree without the drill navigation. Left\n * off (default) for the delegate path and the drill views, which surface\n * children through their own navigation.\n */\n showChildren?: boolean;\n}\n\n/**\n * Card for a single agent run: title, status badge, task, chronological timeline\n * (text + tool rows), result/structured output, and a \"View details\" drill\n * button. Delegated sub-agents are interleaved at their tool-call position; with\n * `showChildren` the card renders its whole child tree inline.\n *\n * @example\n * ```tsx\n * import { AgentCard, useActivity } from \"@pgege/kaboo-react\";\n *\n * function FirstCard() {\n * const { groups } = useActivity();\n * const [id, group] = Object.entries(groups)[0] ?? [];\n * return id ? <AgentCard groupId={id} group={group} /> : null;\n * }\n * ```\n */\nexport function AgentCard({ groupId, group, input, result, actionStatus, showChildren }: AgentCardProps) {\n const { drillIn } = useDrill();\n const { groups } = useActivity();\n const structuredRenderers = useContext(StructuredRenderersContext);\n const childEntries = showChildren ? directChildren(groups, groupId) : [];\n const isDone = group.status === \"completed\" || actionStatus === \"complete\";\n const isInterrupted = group.status === \"interrupted\" && group.interrupt;\n const [expanded, setExpanded] = useState(true);\n const prevDone = useRef(isDone);\n const bodyRef = useRef<HTMLDivElement>(null);\n\n // Keep cards that captured a human-in-the-loop `ask_user` expanded on\n // completion so the answered Q&A stays visible, matching the top-level path.\n // Cards with no interaction still auto-collapse to keep deep trees tidy.\n const hasInteraction = group.tools.some((t) => t.toolName === \"ask_user\");\n useEffect(() => {\n if (!prevDone.current && isDone && !hasInteraction) setExpanded(false);\n prevDone.current = isDone;\n }, [isDone, hasInteraction]);\n\n // A resolved HITL interrupt leaves the delegate tool result as a bare control\n // echo (e.g. {\"status\":\"approved\"} or {\"status\":\"cancelled\"}). That is not the\n // agent's answer — the gated action is already shown in the timeline and the\n // reply streams separately — so never render the raw echo as the card's result.\n const resultText = isControlOnlyStatus(result) ? null : normalizeResult(result);\n const displayTask = input ?? group.task ?? undefined;\n // Only the chat-reply agent's text is already shown in the chat bubble, so we\n // strip text from just that card to avoid duplicating the answer (R4). Every\n // other member keeps its findings text. The drill views keep the full\n // timeline regardless.\n const timeline =\n showChildren && group.isChatReply\n ? (group.timeline ?? []).filter((e) => e.type === \"tool\")\n : (group.timeline ?? []);\n\n useEffect(() => {\n if (expanded && !isDone && bodyRef.current) {\n bodyRef.current.scrollTop = bodyRef.current.scrollHeight;\n }\n }, [expanded, isDone, timeline]);\n\n // Interleave delegated children at their delegating tool-call position so a\n // sub-agent's card stays in order with the parent's surrounding text, instead\n // of being dumped in a trailing block after the summary.\n const { byToolCall: childByToolCall, leftover: leftoverChildren } =\n partitionChildrenByToolCall(childEntries, timeline);\n const renderToolCard = (toolUseId: string) => {\n const entry = childByToolCall.get(toolUseId);\n if (!entry) return null;\n return <AgentCard groupId={entry[0]} group={entry[1]} showChildren />;\n };\n\n const hasContent =\n timeline.length > 0 || resultText || childEntries.length > 0 || !!displayTask;\n\n const cardClass = `kaboo-agent-card${isDone ? \" kaboo-agent-card-done\" : \"\"}`;\n\n return (\n <div className={cardClass}>\n <div className=\"kaboo-agent-card-header\" onClick={() => setExpanded(!expanded)}>\n <div className=\"kaboo-agent-card-title-area\">\n <div className=\"kaboo-agent-card-title-row\">\n <span className=\"kaboo-agent-card-title\">{group.title}</span>\n <span className={`kaboo-status-badge ${isDone ? \"kaboo-status-done\" : isInterrupted ? \"kaboo-status-interrupted\" : \"kaboo-status-active\"}`}>\n {isDone ? (\n <svg width={10} height={10} viewBox=\"0 0 16 16\">\n <path d=\"M3.5 8.5L6.5 11.5L12.5 4.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ) : isInterrupted ? (\n <svg width={10} height={10} viewBox=\"0 0 16 16\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 4.5v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"8\" cy=\"11\" r=\"0.75\" fill=\"currentColor\" />\n </svg>\n ) : (\n <svg width={10} height={10} viewBox=\"0 0 16 16\">\n <circle cx=\"8\" cy=\"8\" r=\"5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeDasharray=\"22\" strokeDashoffset=\"6\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 8 8\" to=\"360 8 8\" dur=\"0.8s\" repeatCount=\"indefinite\" />\n </circle>\n </svg>\n )}\n {isDone ? \"done\" : isInterrupted ? \"needs input\" : \"working...\"}\n </span>\n </div>\n <div className=\"kaboo-agent-card-subtitle\">{group.agentName}</div>\n </div>\n\n {group.tools.length > 0 && (\n <span className={`kaboo-tool-count ${isDone ? \"kaboo-tool-count-done\" : \"\"}`}>\n {group.tools.length} tool{group.tools.length !== 1 ? \"s\" : \"\"}\n </span>\n )}\n\n <svg\n width={14} height={14} viewBox=\"0 0 16 16\"\n className={`kaboo-chevron ${expanded ? \"kaboo-chevron-open\" : \"\"}`}\n >\n <path d=\"M4 6l4 4 4-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </div>\n\n {!expanded && displayTask && (\n <div className=\"kaboo-agent-card-collapsed\">\n <strong>Task:</strong> {displayTask}\n </div>\n )}\n\n {expanded && (\n <div ref={bodyRef} className=\"kaboo-agent-card-body\">\n {displayTask && (\n <div className=\"kaboo-agent-card-task\">\n <strong>Task:</strong> {displayTask}\n </div>\n )}\n\n {timeline.length > 0 && (\n <div className=\"kaboo-agent-card-timeline\">\n <Timeline timeline={timeline} active={!isDone} variant=\"card\" renderToolCard={renderToolCard} />\n </div>\n )}\n\n {resultText && (\n <div className=\"kaboo-agent-card-result\">\n <MarkdownContent text={resultText} />\n </div>\n )}\n\n {group.structuredOutput && group.outputSchemaName && (() => {\n const Renderer = structuredRenderers[group.outputSchemaName!];\n if (Renderer) {\n return <Renderer {...group.structuredOutput!} />;\n }\n return (\n <details className=\"kaboo-agent-card-structured\">\n <summary className=\"kaboo-agent-card-structured-summary\">\n Structured output ({group.outputSchemaName})\n </summary>\n <pre className=\"kaboo-agent-card-structured-pre\">\n {JSON.stringify(group.structuredOutput, null, 2)}\n </pre>\n </details>\n );\n })()}\n\n {leftoverChildren.length > 0 && (\n <div className=\"kaboo-agent-card-children\">\n {leftoverChildren.map(([childId, child]) => (\n <AgentCard\n key={childId}\n groupId={childId}\n group={child}\n showChildren\n />\n ))}\n </div>\n )}\n\n {!displayTask && !hasContent && (\n <div className=\"kaboo-agent-card-empty\">Working...</div>\n )}\n </div>\n )}\n\n {hasContent && (\n <button\n className=\"kaboo-drill-btn\"\n onClick={(e) => { e.stopPropagation(); drillIn(groupId); }}\n >\n <span>View details</span>\n <svg width={12} height={12} viewBox=\"0 0 16 16\">\n <path d=\"M6 4l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n )}\n </div>\n );\n}\n","/**\n * Parses a raw tool result into a renderable shape: `rows` (for tabular JSON —\n * either `{ rows: [...] }` or a top-level array of objects) or `text` (a\n * `key: value` rendering of an object, or the raw string when it isn't JSON).\n *\n * @example\n * ```ts\n * import { formatToolResult } from \"@pgege/kaboo-react\";\n *\n * const { rows } = formatToolResult('{\"rows\":[{\"id\":\"1\"}]}');\n * // rows?.length === 1\n * ```\n */\nexport function formatToolResult(raw: string): {\n /** Row-shaped result for a table view, or `null` when not tabular. */\n rows: Record<string, string>[] | null;\n /** Text rendering of the result when it is not tabular. */\n text: string;\n} {\n try {\n const parsed = JSON.parse(raw);\n if (parsed.rows && Array.isArray(parsed.rows) && parsed.rows.length > 0) {\n return { rows: parsed.rows as Record<string, string>[], text: \"\" };\n }\n if (Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0] === \"object\") {\n return { rows: parsed as Record<string, string>[], text: \"\" };\n }\n if (typeof parsed === \"object\" && parsed !== null) {\n const entries = Object.entries(parsed as Record<string, unknown>)\n .filter(([, v]) => v != null)\n .map(([k, v]) => `${k}: ${typeof v === \"string\" ? v : JSON.stringify(v)}`);\n return { rows: null, text: entries.join(\"\\n\") };\n }\n return { rows: null, text: String(parsed) };\n } catch {\n return { rows: null, text: raw };\n }\n}\n\nfunction unwrapJson(raw: unknown): unknown {\n let value: unknown = raw;\n for (let i = 0; i < 2 && typeof value === \"string\"; i++) {\n const trimmed = (value as string).trim();\n if (trimmed === \"\") return value;\n try {\n value = JSON.parse(trimmed);\n } catch {\n break;\n }\n }\n return value;\n}\n\nfunction statusIsCancelled(status: unknown): boolean {\n if (typeof status !== \"string\") return false;\n const s = status.toLowerCase();\n return s === \"cancelled\" || s === \"canceled\" || s === \"rejected\" || s === \"declined\";\n}\n\nfunction statusIsControl(status: unknown): boolean {\n if (typeof status !== \"string\") return false;\n const s = status.toLowerCase();\n return statusIsCancelled(status) || s === \"approved\" || s === \"accepted\";\n}\n\n/**\n * True when a tool result signals a human rejection/decline rather than real\n * output — the gated-tool reject message, the ask_user decline note, or a bare\n * HITL control payload like `{\"status\":\"cancelled\"}` (tolerating one extra layer\n * of string encoding). Used to render a \"cancelled\" state instead of \"done\".\n */\nexport function isCancelledResult(raw: unknown): boolean {\n if (raw == null) return false;\n const text = typeof raw === \"string\" ? raw : JSON.stringify(raw);\n if (/user rejected this action/i.test(text)) return true;\n if (/user declined to answer/i.test(text)) return true;\n const value = unwrapJson(text);\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n return statusIsCancelled((value as Record<string, unknown>).status);\n }\n return false;\n}\n\n/**\n * True when a result is ONLY a HITL control payload (a lone `status` field\n * carrying an interrupt-resolution echo like `{\"status\":\"approved\"}` or\n * `{\"status\":\"cancelled\"}`), with no real tool output. The owning agent's card\n * already shows the gated action in order, so the inline wildcard renderer and\n * the card skip this stray raw payload rather than dumping JSON.\n */\nexport function isControlOnlyStatus(raw: unknown): boolean {\n if (raw == null) return false;\n const value = unwrapJson(typeof raw === \"string\" ? raw : JSON.stringify(raw));\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const keys = Object.keys(value as Record<string, unknown>);\n return keys.length === 1 && keys[0] === \"status\" &&\n statusIsControl((value as Record<string, unknown>).status);\n }\n return false;\n}\n\n/**\n * Normalizes a raw result string for display: unwraps one layer of JSON string\n * encoding, converts escaped `\\n` into real newlines, and returns `null` for\n * empty/undefined input.\n *\n * @example\n * ```ts\n * import { normalizeResult } from \"@pgege/kaboo-react\";\n *\n * normalizeResult('\"line one\\\\nline two\"');\n * // \"line one\\nline two\"\n * ```\n */\nexport function normalizeResult(result: string | undefined): string | null {\n if (!result) return null;\n let text = typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n if (text.startsWith('\"') && text.endsWith('\"')) {\n try {\n text = JSON.parse(text);\n } catch { /* keep as-is */ }\n }\n text = text.replace(/\\\\n/g, \"\\n\");\n return text || null;\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * Minimal, dependency-free markdown renderer used for agent text: supports\n * `#`/`##`/`###` headings, `-`/`*` list items, `**bold**` inline, and blank-line\n * spacing. Intentionally small — it is not a full CommonMark implementation.\n *\n * @example\n * ```tsx\n * import { MarkdownContent } from \"@pgege/kaboo-react\";\n *\n * function Example() {\n * return <MarkdownContent text={\"# Title\\n\\nSome **bold** text.\"} />;\n * }\n * ```\n */\nexport function MarkdownContent({ text }: { text: string }) {\n const lines = text.split(\"\\n\");\n return (\n <div className=\"kaboo-md\">\n {lines.map((line, i) => {\n if (line.startsWith(\"# \") && !line.startsWith(\"## \")) {\n return <h2 key={i} className=\"kaboo-md-h2\">{line.slice(2)}</h2>;\n }\n if (line.startsWith(\"## \")) {\n return <h3 key={i} className=\"kaboo-md-h3\">{line.slice(3)}</h3>;\n }\n if (line.startsWith(\"### \")) {\n return <h4 key={i} className=\"kaboo-md-h4\">{line.slice(4)}</h4>;\n }\n if (line.startsWith(\"- \") || line.startsWith(\"* \")) {\n return <li key={i} className=\"kaboo-md-li\">{renderInline(line.slice(2))}</li>;\n }\n if (line.trim() === \"\") {\n return <div key={i} className=\"kaboo-md-spacer\" />;\n }\n return <p key={i} className=\"kaboo-md-p\">{renderInline(line)}</p>;\n })}\n </div>\n );\n}\n\nfunction renderInline(text: string) {\n const parts: (string | ReactNode)[] = [];\n let remaining = text;\n let key = 0;\n\n while (remaining.length > 0) {\n const boldMatch = remaining.match(/\\*\\*(.+?)\\*\\*/);\n if (boldMatch && boldMatch.index !== undefined) {\n if (boldMatch.index > 0) {\n parts.push(remaining.slice(0, boldMatch.index));\n }\n parts.push(<strong key={key++}>{boldMatch[1]}</strong>);\n remaining = remaining.slice(boldMatch.index + boldMatch[0].length);\n continue;\n }\n parts.push(remaining);\n break;\n }\n\n return <>{parts}</>;\n}\n","import { Fragment, type ReactNode } from \"react\";\nimport type { TimelineEntry, ToolCall } from \"../types\";\nimport { ToolRow } from \"./ToolRow\";\nimport { MarkdownContent } from \"./MarkdownContent\";\nimport { AskUserSummary } from \"./AskUserSummary\";\nimport { InterruptRenderer } from \"./InterruptRenderer\";\nimport { useInterruptFor } from \"../context/InterruptBridge\";\nimport { normalizeQuestions, parseAnswers, type AskUserParams } from \"../formatters/askUser\";\nimport { isCancelledResult } from \"../formatters/output\";\n\n/**\n * Renders an `ask_user` tool call in one place at its chronological tool\n * position — the live interactive form while it's pending, then the durable Q&A\n * summary once answered. Both look identical at every depth (top-level card or a\n * nested drill), so the human-in-the-loop prompt never floats out of order in a\n * separate slot. The live form is claimed by matching an open interrupt's\n * `toolCallId` to this tool; if none matches (already answered, or a different\n * agent's prompt) nothing interactive is drawn here.\n */\nfunction AskUserTimelineRow({ tool }: { tool: ToolCall }) {\n const interrupt = useInterruptFor(tool.toolUseId);\n const questions = normalizeQuestions(tool.toolInput as AskUserParams | undefined);\n const answers = parseAnswers(tool.toolResult);\n\n if (answers) {\n if (questions.length === 0) return null;\n return <AskUserSummary questions={questions} answers={answers} />;\n }\n\n if (interrupt && interrupt.reason.type === \"form\") {\n return (\n <InterruptRenderer\n reason={interrupt.reason}\n toolCallId={interrupt.toolCallId}\n onResolve={interrupt.onResolve}\n onCancel={interrupt.onCancel}\n />\n );\n }\n\n // Resolved without answers (the user dismissed the prompt): keep it visible in\n // order as a declined Q&A rather than silently dropping it.\n if (questions.length > 0 && isCancelledResult(tool.toolResult)) {\n return <AskUserSummary questions={questions} answers={{}} declined />;\n }\n\n return null;\n}\n\n/**\n * A regular tool row that also surfaces its own approval gate inline. When a\n * gated tool is awaiting approval it has an open interrupt anchored to this\n * tool-call id; the Approve/Reject prompt renders directly under the row so it\n * sits at the request it governs. With N tools gated in parallel each row owns\n * its own card and resolves independently.\n */\nfunction ToolTimelineRow({ tool }: { tool: ToolCall }) {\n const interrupt = useInterruptFor(tool.toolUseId);\n return (\n <>\n <ToolRow tool={tool} />\n {interrupt && interrupt.reason.type === \"approval\" && (\n <InterruptRenderer\n reason={interrupt.reason}\n toolCallId={interrupt.toolCallId}\n onResolve={interrupt.onResolve}\n onCancel={interrupt.onCancel}\n />\n )}\n </>\n );\n}\n\n/** Props for {@link Timeline}. */\nexport interface TimelineProps {\n /** The interleaved text/tool entries to render, in order. */\n timeline: TimelineEntry[];\n /** When true, a blinking cursor is shown after the last text segment. */\n active: boolean;\n /** Visual variant selecting the text container class. */\n variant?: \"card\" | \"drill\";\n /**\n * Optional hook to render a delegating tool call as its spawned sub-agent\n * card, interleaved at its chronological position. Returns the card node for a\n * given tool-call id, or `null`/`undefined` to fall back to the tool row. Keeps\n * a delegated agent's work in order relative to the parent's surrounding text.\n */\n renderToolCard?: (toolUseId: string) => ReactNode | null | undefined;\n}\n\n/**\n * Chronological render of interleaved text segments and tool calls. Shared by\n * {@link AgentCard} and {@link DrillDetailView} so the two stay in sync.\n */\nexport function Timeline({ timeline, active, variant = \"card\", renderToolCard }: TimelineProps) {\n const textClass =\n variant === \"drill\" ? \"kaboo-drill-tokens-content\" : \"kaboo-agent-card-tokens\";\n\n return (\n <>\n {timeline.map((entry, i) => {\n if (entry.type === \"tool\") {\n const key = entry.tool.toolUseId || i;\n const card = renderToolCard?.(entry.tool.toolUseId);\n if (card) return <Fragment key={key}>{card}</Fragment>;\n if (entry.tool.toolName === \"ask_user\") {\n return <AskUserTimelineRow key={key} tool={entry.tool} />;\n }\n return <ToolTimelineRow key={key} tool={entry.tool} />;\n }\n const isLast = i === timeline.length - 1;\n return (\n <div key={`text-${i}`} className={textClass}>\n <MarkdownContent text={entry.text} />\n {active && isLast && <span className=\"kaboo-blink-cursor\" />}\n </div>\n );\n })}\n </>\n );\n}\n","import { useState } from \"react\";\nimport type { ToolCall } from \"../types\";\nimport { formatToolInput } from \"../formatters/input\";\nimport { formatToolResult, isCancelledResult } from \"../formatters/output\";\nimport { MiniTable } from \"./MiniTable\";\n\n/**\n * Renders a single {@link ToolCall} as a collapsible row: status icon, label, an\n * input summary, and — when expanded — the formatted result (a {@link MiniTable}\n * for tabular JSON, otherwise text). Used inside the {@link Timeline}.\n *\n * @example\n * ```tsx\n * import { ToolRow } from \"@pgege/kaboo-react\";\n * import type { ToolCall } from \"@pgege/kaboo-react\";\n *\n * const tool: ToolCall = {\n * toolUseId: \"t1\",\n * toolName: \"run_sql\",\n * toolInput: { query: \"select 1\" },\n * status: \"done\",\n * };\n *\n * function Example() {\n * return <ToolRow tool={tool} />;\n * }\n * ```\n */\nexport function ToolRow({ tool }: { tool: ToolCall }) {\n const [open, setOpen] = useState(false);\n const cancelled = tool.status === \"cancelled\" || isCancelledResult(tool.toolResult);\n const isDone = tool.status !== \"running\";\n const label = tool.toolLabel || tool.toolName;\n const { summary: inputSummary } = formatToolInput(tool.toolInput);\n\n return (\n <div className=\"kaboo-tool-row\">\n <div className=\"kaboo-tool-row-header\" onClick={() => setOpen(!open)}>\n {tool.status === \"running\" ? (\n <svg width={10} height={10} viewBox=\"0 0 16 16\" className=\"kaboo-icon-shrink\">\n <circle\n cx=\"8\" cy=\"8\" r=\"5\"\n fill=\"none\" className=\"kaboo-tool-spinner\" strokeWidth=\"2\"\n strokeDasharray=\"22\" strokeDashoffset=\"6\"\n >\n <animateTransform\n attributeName=\"transform\" type=\"rotate\"\n from=\"0 8 8\" to=\"360 8 8\" dur=\"0.8s\" repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n ) : (\n <svg width={10} height={10} viewBox=\"0 0 10 10\" className=\"kaboo-icon-shrink\">\n <circle\n cx=\"5\" cy=\"5\" r=\"3\"\n className={\n cancelled\n ? \"kaboo-tool-dot-cancelled\"\n : tool.status === \"error\"\n ? \"kaboo-tool-dot-error\"\n : \"kaboo-tool-dot-success\"\n }\n />\n </svg>\n )}\n <span className=\"kaboo-tool-row-label\">{label}</span>\n {isDone && (\n <span className=\"kaboo-tool-row-status\">\n {cancelled ? \"cancelled\" : tool.status === \"error\" ? \"error\" : \"done\"}\n </span>\n )}\n <svg\n width={14} height={14} viewBox=\"0 0 16 16\"\n className={`kaboo-chevron ${open ? \"kaboo-chevron-open\" : \"\"}`}\n >\n <path d=\"M4 6l4 4 4-4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </div>\n\n {!open && inputSummary && (\n <div className=\"kaboo-tool-row-summary\">\n {inputSummary.length > 80 ? inputSummary.slice(0, 80) + \"...\" : inputSummary}\n </div>\n )}\n\n {open && (\n <div className=\"kaboo-tool-row-detail\">\n {inputSummary && (\n <div className=\"kaboo-tool-input\">{inputSummary}</div>\n )}\n {tool.toolResult && <ToolResultBlock raw={tool.toolResult} cancelled={cancelled} />}\n </div>\n )}\n </div>\n );\n}\n\nfunction ToolResultBlock({ raw, cancelled }: { raw: string; cancelled?: boolean }) {\n if (cancelled) {\n const { text } = formatToolResult(raw);\n const message = /user (rejected|declined)/i.test(text) ? text : \"Declined by user.\";\n return <div className=\"kaboo-tool-result kaboo-tool-result-cancelled\">{message}</div>;\n }\n const { rows, text } = formatToolResult(raw);\n if (rows) {\n return (\n <div className=\"kaboo-tool-result kaboo-tool-result-table\">\n <MiniTable rows={rows} />\n </div>\n );\n }\n return <div className=\"kaboo-tool-result\">{text}</div>;\n}\n","/**\n * Condenses arbitrary tool input into a short one-line `summary` for a tool row.\n * Prefers well-known fields (`query`/`table_name`/`url`), unwraps single-key\n * objects, and otherwise joins `key: value` pairs. `detail` is reserved for\n * future expansion and is currently always `null`.\n *\n * @example\n * ```ts\n * import { formatToolInput } from \"@pgege/kaboo-react\";\n *\n * const { summary } = formatToolInput({ query: \"select 1\" });\n * // summary === \"select 1\"\n * ```\n */\nexport function formatToolInput(input: unknown): {\n /** One-line summary suitable for a tool row. */\n summary: string;\n /** Reserved for future detail expansion; currently always `null`. */\n detail: string | null;\n} {\n if (input == null) return { summary: \"\", detail: null };\n if (typeof input === \"string\") return { summary: input, detail: null };\n\n const obj = input as Record<string, unknown>;\n\n if (obj.query && typeof obj.query === \"string\") {\n return { summary: String(obj.query).trim(), detail: null };\n }\n if (obj.table_name && typeof obj.table_name === \"string\") {\n return { summary: obj.table_name as string, detail: null };\n }\n if (obj.url && typeof obj.url === \"string\") {\n return { summary: obj.url as string, detail: null };\n }\n\n const keys = Object.keys(obj);\n if (keys.length === 1) {\n const val = obj[keys[0]];\n return { summary: typeof val === \"string\" ? val : JSON.stringify(val), detail: null };\n }\n\n const parts = keys\n .filter((k) => obj[k] != null && obj[k] !== \"\")\n .map((k) => {\n const v = obj[k];\n return `${k}: ${typeof v === \"string\" ? v : JSON.stringify(v)}`;\n });\n return { summary: parts.join(\", \"), detail: null };\n}\n","/**\n * Compact table for row-shaped tool results. Columns are inferred from the first\n * row's keys; underscores in headers become spaces. Renders at most `maxRows`\n * rows with a \"+N more\" footer, and nothing at all for an empty list.\n *\n * @example\n * ```tsx\n * import { MiniTable } from \"@pgege/kaboo-react\";\n *\n * function Example() {\n * return <MiniTable rows={[{ id: \"1\", name: \"Ada\" }]} maxRows={5} />;\n * }\n * ```\n */\nexport function MiniTable({ rows, maxRows = 8 }: { rows: Record<string, string>[]; maxRows?: number }) {\n if (rows.length === 0) return null;\n const cols = Object.keys(rows[0]);\n const display = rows.slice(0, maxRows);\n const remaining = rows.length - maxRows;\n\n return (\n <div style={{ overflowX: \"auto\" }}>\n <table className=\"kaboo-mini-table\">\n <thead>\n <tr>\n {cols.map((c) => (\n <th key={c}>{c.replace(/_/g, \" \")}</th>\n ))}\n </tr>\n </thead>\n <tbody>\n {display.map((row, i) => (\n <tr key={i}>\n {cols.map((c) => (\n <td key={c}>{String(row[c] ?? \"\")}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n {remaining > 0 && (\n <div className=\"kaboo-mini-table-overflow\">\n +{remaining} more row{remaining !== 1 ? \"s\" : \"\"}\n </div>\n )}\n </div>\n );\n}\n","import type { ReactElement } from \"react\";\nimport type { FormQuestion } from \"../types\";\n\nfunction formatAnswer(value: unknown): string {\n if (value == null) return \"\";\n if (Array.isArray(value)) return value.map((v) => String(v)).join(\", \");\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Read-only, durable record of an answered `ask_user` prompt. Rendered from the\n * tool call that lives permanently in the transcript, so the question(s) and the\n * user's answer stay visible inline (in chat order) after the interrupt resolves.\n */\nexport function AskUserSummary({\n questions,\n answers,\n declined = false,\n}: {\n questions: FormQuestion[];\n answers: Record<string, unknown>;\n /** Render as a declined prompt: no answers were given (the user dismissed it). */\n declined?: boolean;\n}): ReactElement {\n return (\n <div className=\"kaboo-askuser\">\n {questions.map((q, idx) => {\n const answer = answers[q.question];\n const hasAnswer = answer != null && formatAnswer(answer) !== \"\";\n return (\n <div key={idx} className=\"kaboo-askuser-qa\">\n <div className=\"kaboo-askuser-question\">{q.question}</div>\n <div\n className={`kaboo-askuser-answer ${hasAnswer ? \"\" : declined ? \"kaboo-askuser-answer-declined\" : \"kaboo-askuser-answer-empty\"}`}\n >\n {hasAnswer ? formatAnswer(answer) : declined ? \"Declined by user\" : \"No answer\"}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import { useState, type ReactElement } from \"react\";\nimport type { InterruptReason, InterruptRendererProps, FormQuestion } from \"../types\";\n\nfunction ApprovalVariant({ reason, onResolve, onCancel }: InterruptRendererProps): ReactElement {\n const [responded, setResponded] = useState(false);\n if (reason.type !== \"approval\") return <></>;\n\n if (responded) {\n return <div className=\"kaboo-interrupt-responded\">Response submitted</div>;\n }\n\n return (\n <div className=\"kaboo-interrupt kaboo-interrupt-approval\">\n <div className=\"kaboo-interrupt-header\">\n <svg width={16} height={16} viewBox=\"0 0 16 16\" className=\"kaboo-interrupt-icon\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 4.5v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"8\" cy=\"11\" r=\"0.75\" fill=\"currentColor\" />\n </svg>\n <span className=\"kaboo-interrupt-message\">{reason.message}</span>\n </div>\n {reason.tool_input != null && (\n <details className=\"kaboo-interrupt-details\">\n <summary>View input</summary>\n <pre className=\"kaboo-interrupt-pre\">\n {JSON.stringify(reason.tool_input, null, 2)}\n </pre>\n </details>\n )}\n <div className=\"kaboo-interrupt-actions\">\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-approve\"\n onClick={() => { setResponded(true); onResolve({ status: \"approved\" }); }}\n >\n Approve\n </button>\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-reject\"\n onClick={() => { setResponded(true); onCancel(); }}\n >\n Reject\n </button>\n </div>\n </div>\n );\n}\n\n/** Drop any option the agent labelled \"Other\" — the UI adds its own free-text row. */\nfunction withoutOther(options: string[] | undefined): string[] {\n return (options ?? []).filter((o) => o.trim().toLowerCase() !== \"other\");\n}\n\n/**\n * Build the resume payload as a `{question: answer}` map — the single answer\n * representation shared by the model (which reads it as JSON) and the durable\n * Q&A card (which parses the same tool result). Keyed by question text (not\n * index) so both consumers read it without extra correlation state.\n */\nfunction buildAnswerPayload(\n questions: FormQuestion[],\n answers: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n questions.forEach((q, idx) => {\n out[q.question] = answers[String(idx)] ?? \"\";\n });\n return out;\n}\n\nfunction RadioInput({\n question,\n value,\n onChange,\n}: {\n question: FormQuestion;\n value: string;\n onChange: (v: string) => void;\n}): ReactElement {\n const [otherText, setOtherText] = useState(\"\");\n const [isOther, setIsOther] = useState(false);\n const options = withoutOther(question.options);\n\n return (\n <div className=\"kaboo-interrupt-radio-group\">\n {options.map((opt) => (\n <label key={opt} className={`kaboo-interrupt-option ${value === opt && !isOther ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"radio\"\n name={question.question}\n checked={value === opt && !isOther}\n onChange={() => { setIsOther(false); onChange(opt); }}\n className=\"kaboo-interrupt-radio\"\n />\n <span>{opt}</span>\n </label>\n ))}\n <div className={`kaboo-interrupt-option kaboo-interrupt-option-other ${isOther ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"radio\"\n name={question.question}\n checked={isOther}\n onChange={() => { setIsOther(true); onChange(otherText); }}\n className=\"kaboo-interrupt-radio\"\n />\n <input\n type=\"text\"\n className=\"kaboo-interrupt-text-input kaboo-interrupt-other-input\"\n placeholder=\"Other (type your own answer)…\"\n value={otherText}\n onChange={(e) => { setOtherText(e.target.value); setIsOther(true); onChange(e.target.value); }}\n onFocus={() => { setIsOther(true); onChange(otherText); }}\n />\n </div>\n </div>\n );\n}\n\nfunction CheckboxInput({\n question,\n value,\n onChange,\n}: {\n question: FormQuestion;\n value: string[];\n onChange: (v: string[]) => void;\n}): ReactElement {\n const [otherText, setOtherText] = useState(\"\");\n const options = withoutOther(question.options);\n\n const toggle = (opt: string) => {\n const next = value.includes(opt) ? value.filter((v) => v !== opt) : [...value, opt];\n onChange(next);\n };\n\n const otherSelected = otherText !== \"\" && value.includes(otherText);\n\n return (\n <div className=\"kaboo-interrupt-checkbox-group\">\n {options.map((opt) => (\n <label key={opt} className={`kaboo-interrupt-option ${value.includes(opt) ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"checkbox\"\n checked={value.includes(opt)}\n onChange={() => toggle(opt)}\n className=\"kaboo-interrupt-checkbox\"\n />\n <span>{opt}</span>\n </label>\n ))}\n <div className={`kaboo-interrupt-option kaboo-interrupt-option-other ${otherSelected ? \"kaboo-interrupt-option-selected\" : \"\"}`}>\n <input\n type=\"checkbox\"\n checked={otherSelected}\n onChange={() => {\n if (otherSelected) onChange(value.filter((v) => v !== otherText));\n else if (otherText) onChange([...value, otherText]);\n }}\n className=\"kaboo-interrupt-checkbox\"\n />\n <input\n type=\"text\"\n className=\"kaboo-interrupt-text-input kaboo-interrupt-other-input\"\n placeholder=\"Other (type your own answer)…\"\n value={otherText}\n onChange={(e) => {\n const prev = otherText;\n const nextText = e.target.value;\n setOtherText(nextText);\n const filtered = value.filter((v) => v !== prev);\n onChange(nextText ? [...filtered, nextText] : filtered);\n }}\n />\n </div>\n </div>\n );\n}\n\nfunction TextInput({\n value,\n onChange,\n}: {\n value: string;\n onChange: (v: string) => void;\n}): ReactElement {\n return (\n <textarea\n className=\"kaboo-interrupt-textarea\"\n placeholder=\"Type your answer...\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n rows={3}\n autoFocus\n />\n );\n}\n\nfunction FormVariant({ reason, onResolve, onCancel }: InterruptRendererProps): ReactElement {\n const questions = reason.type === \"form\" ? reason.questions : [];\n const isSingle = questions.length === 1;\n const [step, setStep] = useState(0);\n const [answers, setAnswers] = useState<Record<string, unknown>>({});\n const [responded, setResponded] = useState(false);\n\n if (responded) {\n return <div className=\"kaboo-interrupt-responded\">Response submitted</div>;\n }\n\n const setAnswer = (idx: number, val: unknown) => {\n setAnswers((prev) => ({ ...prev, [String(idx)]: val }));\n };\n\n const current = questions[step];\n if (!current) return <></>;\n\n const renderQuestion = (q: FormQuestion, idx: number) => {\n if (q.type === \"radio\") {\n return (\n <RadioInput\n question={q}\n value={(answers[String(idx)] as string) ?? \"\"}\n onChange={(v) => setAnswer(idx, v)}\n />\n );\n }\n if (q.type === \"checkbox\") {\n return (\n <CheckboxInput\n question={q}\n value={(answers[String(idx)] as string[]) ?? []}\n onChange={(v) => setAnswer(idx, v)}\n />\n );\n }\n return (\n <TextInput\n value={(answers[String(idx)] as string) ?? \"\"}\n onChange={(v) => setAnswer(idx, v)}\n />\n );\n };\n\n const isLast = step === questions.length - 1;\n\n return (\n <div className=\"kaboo-interrupt kaboo-interrupt-form\">\n {!isSingle && (\n <div className=\"kaboo-interrupt-progress\">\n {step + 1} of {questions.length}\n </div>\n )}\n <div className=\"kaboo-interrupt-question\">\n {current.question}\n </div>\n {renderQuestion(current, step)}\n <div className=\"kaboo-interrupt-actions\">\n {!isSingle && step > 0 && (\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-back\"\n onClick={() => setStep(step - 1)}\n >\n Back\n </button>\n )}\n {isLast ? (\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-approve\"\n onClick={() => {\n setResponded(true);\n onResolve(buildAnswerPayload(questions, answers));\n }}\n >\n Submit\n </button>\n ) : (\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-next\"\n onClick={() => setStep(step + 1)}\n >\n Next\n </button>\n )}\n <button\n className=\"kaboo-interrupt-btn kaboo-interrupt-btn-reject\"\n onClick={() => { setResponded(true); onCancel(); }}\n >\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * Default human-in-the-loop interrupt UI. Renders an Approve/Reject panel for an\n * {@link ApprovalReason} and a (optionally multi-step) form with radio/checkbox/\n * text inputs for a {@link FormReason}, calling `onResolve`/`onCancel` with the\n * answer payload. Override per type via `interruptRenderers` on\n * {@link KabooProvider}.\n *\n * @example\n * ```tsx\n * import { InterruptRenderer } from \"@pgege/kaboo-react\";\n * import type { InterruptReason } from \"@pgege/kaboo-react\";\n *\n * const reason: InterruptReason = {\n * type: \"approval\",\n * message: \"Run this query?\",\n * tool_name: \"run_sql\",\n * };\n *\n * function Example() {\n * return (\n * <InterruptRenderer\n * reason={reason}\n * onResolve={() => {}}\n * onCancel={() => {}}\n * />\n * );\n * }\n * ```\n */\nexport function InterruptRenderer(props: InterruptRendererProps): ReactElement {\n if (props.reason.type === \"approval\") {\n return <ApprovalVariant {...props} />;\n }\n return <FormVariant {...props} />;\n}\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\nimport type { InterruptReason } from \"../types\";\n\n/**\n * An open interrupt published onto the InterruptBridge so an owning agent card\n * can render its prompt inline (rather than only in the chat slot). Carries the\n * reason plus resolve/cancel callbacks bound to this specific interrupt id.\n */\nexport interface ActiveInterrupt {\n /**\n * Unique interrupt id (from the AG-UI interrupt). Distinguishes concurrent\n * gates that may share a single tool-call id (e.g. two parallel sub-agent\n * gates re-keyed onto one delegating call), so each resolves independently.\n */\n id: string;\n /** Why the run paused, and what input it needs. */\n reason: InterruptReason;\n /** Resume the run with the user's answer/approval payload. */\n onResolve: (payload: unknown) => void;\n /** Cancel/reject this gate, resuming the run without a positive answer. */\n onCancel: () => void;\n /**\n * The originating tool-call id, when the interrupt was raised by a tool (e.g.\n * `ask_user` or a gated tool). Lets the owning agent card render the live\n * prompt inline at its tool-call position, so the prompt sits in chronological\n * order rather than in a separate top-level slot.\n */\n toolCallId?: string;\n}\n\ninterface InterruptBridgeValue {\n /** Every open interrupt from the current run, in emission order. */\n active: ActiveInterrupt[];\n publish: (interrupts: ActiveInterrupt[]) => void;\n}\n\nconst InterruptBridgeContext = createContext<InterruptBridgeValue>({\n active: [],\n publish: () => {},\n});\n\n/**\n * Holds the set of currently open interrupts so any tool row can claim and\n * render its own gate inline (see {@link useInterruptFor}). Included\n * automatically by {@link KabooProvider}.\n *\n * @example\n * ```tsx\n * import { InterruptBridgeProvider } from \"@pgege/kaboo-react\";\n *\n * function Providers({ children }: { children: React.ReactNode }) {\n * return <InterruptBridgeProvider>{children}</InterruptBridgeProvider>;\n * }\n * ```\n */\nexport function InterruptBridgeProvider({ children }: { children: ReactNode }) {\n const [active, setActive] = useState<ActiveInterrupt[]>([]);\n const publish = useCallback((interrupts: ActiveInterrupt[]) => {\n setActive(interrupts);\n }, []);\n\n return (\n <InterruptBridgeContext.Provider value={{ active, publish }}>\n {children}\n </InterruptBridgeContext.Provider>\n );\n}\n\n/**\n * Reads the InterruptBridge: the list of open interrupts plus `publish`. Most\n * consumers want {@link useInterruptFor} instead; use this to inspect or drive\n * the whole set.\n *\n * @example\n * ```tsx\n * import { useInterruptBridge } from \"@pgege/kaboo-react\";\n *\n * function OpenGateCount() {\n * const { active } = useInterruptBridge();\n * return <span>{active.length} open</span>;\n * }\n * ```\n */\nexport function useInterruptBridge(): {\n /** Every open interrupt from the current run, in emission order. */\n active: ActiveInterrupt[];\n /** Replace the set of interrupts published to the bridge. */\n publish: (interrupts: ActiveInterrupt[]) => void;\n} {\n return useContext(InterruptBridgeContext);\n}\n\n/**\n * The first open interrupt anchored to a given tool-call id, or `undefined`.\n * Lets a tool row claim and render its own gate inline while N concurrent gates\n * are open, each anchored to a distinct tool call.\n */\nexport function useInterruptFor(\n toolCallId: string | undefined,\n): ActiveInterrupt | undefined {\n const { active } = useInterruptBridge();\n if (!toolCallId) return undefined;\n return active.find((i) => i.toolCallId === toolCallId);\n}\n\n/**\n * Publishes the current set of open interrupts to the bridge so each owning\n * agent card can render its prompt inline at the matching tool-call position.\n * CopilotKit surfaces every open interrupt at once, so this takes the full list\n * and keeps the latest resolve/cancel callbacks in a ref — their per-render\n * identity churn must not re-publish (only the interrupt set should).\n */\nexport function InterruptBridgePublisher({\n interrupts,\n}: {\n interrupts: ActiveInterrupt[];\n}): null {\n const { publish } = useInterruptBridge();\n const listRef = useRef(interrupts);\n listRef.current = interrupts;\n\n const key = interrupts\n .map((i) => `${i.id}:${i.toolCallId ?? \"\"}:${JSON.stringify(i.reason)}`)\n .join(\"|\");\n\n useEffect(() => {\n publish(\n listRef.current.map((i) => ({\n id: i.id,\n reason: i.reason,\n toolCallId: i.toolCallId,\n onResolve: (payload: unknown) =>\n listRef.current.find((x) => x.id === i.id)?.onResolve(payload),\n onCancel: () => listRef.current.find((x) => x.id === i.id)?.onCancel(),\n })),\n );\n return () => publish([]);\n }, [key, publish]);\n\n return null;\n}\n","import type { FormQuestion } from \"../types\";\n\nexport interface AskUserParams {\n question?: string;\n options?: string[];\n input_type?: FormQuestion[\"type\"];\n questions?: Array<{ question?: string; type?: FormQuestion[\"type\"]; options?: string[] }>;\n}\n\n/**\n * Normalise `ask_user` tool input (multi-question `questions` array or a single\n * `question`) into a flat {@link FormQuestion} list. Shared by the top-level\n * renderer and the nested-timeline renderer so an `ask_user` looks identical at\n * every depth.\n */\nexport function normalizeQuestions(params: AskUserParams | undefined): FormQuestion[] {\n if (!params) return [];\n if (Array.isArray(params.questions)) {\n return params.questions.map((q) => ({\n question: q.question ?? \"\",\n type: q.type ?? (q.options ? \"radio\" : \"text\"),\n options: q.options,\n }));\n }\n if (typeof params.question === \"string\") {\n return [\n {\n question: params.question,\n type: params.input_type ?? (params.options ? \"radio\" : \"text\"),\n options: params.options,\n },\n ];\n }\n return [];\n}\n\n/**\n * Parse the `ask_user` tool result into a `{question: answer}` map. The result\n * is the JSON the tool emitted (see `ask_user._format_answer`); we tolerate up\n * to one extra layer of string encoding. Non-answers (empty, or the plain-text\n * \"no answer\"/\"declined\" notes) yield `null` so no card is rendered.\n */\nexport function parseAnswers(result: unknown): Record<string, unknown> | null {\n let value: unknown = result;\n for (let i = 0; i < 2 && typeof value === \"string\"; i++) {\n const trimmed = value.trim();\n if (trimmed === \"\") return null;\n try {\n value = JSON.parse(trimmed);\n } catch {\n return null;\n }\n }\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const obj = value as Record<string, unknown>;\n return Object.keys(obj).length > 0 ? obj : null;\n }\n return null;\n}\n","import { useContext } from \"react\";\nimport { DrillContext } from \"../context/DrillContext\";\nimport type { DrillState } from \"../types\";\n\n/**\n * Reads the drill-down navigation state ({@link DrillState}) from the nearest\n * {@link DrillProvider}: the current path plus `drillIn`/`drillUp`/`drillToRoot`/\n * `drillToLevel`.\n *\n * @example\n * ```tsx\n * import { useDrill } from \"@pgege/kaboo-react\";\n *\n * function BackButton() {\n * const { drillUp, activeDrill } = useDrill();\n * if (!activeDrill) return null;\n * return <button onClick={drillUp}>Back</button>;\n * }\n * ```\n */\nexport function useDrill(): DrillState {\n return useContext(DrillContext);\n}\n","import { useState, useCallback, createContext, type ReactNode } from \"react\";\nimport type { DrillState } from \"../types\";\n\nconst NOOP = () => {};\n\nexport const DrillContext = createContext<DrillState>({\n drillPath: [],\n activeDrill: null,\n drillIn: NOOP,\n drillUp: NOOP,\n drillToRoot: NOOP,\n drillToLevel: NOOP,\n});\n\n/**\n * Provides drill-down navigation state ({@link DrillState}) to the activity\n * components below it. Included automatically by {@link KabooProvider}; only\n * mount it yourself if you compose the providers by hand.\n *\n * @example\n * ```tsx\n * import { DrillProvider, GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n *\n * function Panel() {\n * return (\n * <DrillProvider>\n * <GlassTabs />\n * <DrillDetailView />\n * </DrillProvider>\n * );\n * }\n * ```\n */\nexport function DrillProvider({ children }: { children: ReactNode }) {\n const [drillPath, setDrillPath] = useState<string[]>([]);\n\n const drillIn = useCallback((groupId: string) => {\n setDrillPath((prev) => [...prev, groupId]);\n }, []);\n\n const drillUp = useCallback(() => {\n setDrillPath((prev) => prev.slice(0, -1));\n }, []);\n\n const drillToRoot = useCallback(() => {\n setDrillPath([]);\n }, []);\n\n const drillToLevel = useCallback((level: number) => {\n setDrillPath((prev) => prev.slice(0, level + 1));\n }, []);\n\n const activeDrill = drillPath.length > 0 ? drillPath[drillPath.length - 1] : null;\n\n return (\n <DrillContext.Provider value={{ drillPath, activeDrill, drillIn, drillUp, drillToRoot, drillToLevel }}>\n {children}\n </DrillContext.Provider>\n );\n}\n","import type { StreamGroup, TimelineEntry } from \"../types\";\n\n/** A `[groupId, group]` pair, as returned by the group-hierarchy helpers. */\nexport type GroupEntry = [string, StreamGroup];\n\n/**\n * Stable per-turn key for a group. Prefers the server-stamped `turnId` (stable\n * across an interrupt/resume), falling back to `runId` for older streams that\n * don't carry one. `null` when neither is present.\n */\nexport function groupTurnKey(g: StreamGroup): string | null {\n return g.turnId ?? g.runId ?? null;\n}\n\n/**\n * Split child groups into those anchored to a delegating tool call present in\n * *timeline* (keyed by that tool-call id, so they can be interleaved at their\n * chronological position) and the leftover (swarm/graph members and any child\n * whose spawning tool call isn't in this timeline), which render in a trailing\n * section. Keeps a delegated sub-agent's card at the point it was delegated,\n * instead of after the parent's summary text.\n */\nexport function partitionChildrenByToolCall(\n childEntries: GroupEntry[],\n timeline: TimelineEntry[],\n): { byToolCall: Map<string, GroupEntry>; leftover: GroupEntry[] } {\n const toolUseIds = new Set(\n timeline.filter((e) => e.type === \"tool\").map((e) => e.tool.toolUseId),\n );\n const byToolCall = new Map<string, GroupEntry>();\n const leftover: GroupEntry[] = [];\n for (const [id, g] of childEntries) {\n if (g.toolCallId && toolUseIds.has(g.toolCallId)) {\n byToolCall.set(g.toolCallId, [id, g]);\n } else {\n leftover.push([id, g]);\n }\n }\n return { byToolCall, leftover };\n}\n\n/**\n * Top-level groups are those without a parent. Uses the explicit\n * `parentGroup` field rather than parsing dot-paths out of the group id, so\n * group names are free to contain any characters.\n *\n * @example\n * ```ts\n * import { topLevelGroups } from \"@pgege/kaboo-react\";\n *\n * function rootCount(groups: Parameters<typeof topLevelGroups>[0]) {\n * return topLevelGroups(groups).length;\n * }\n * ```\n */\nexport function topLevelGroups(\n groups: Record<string, StreamGroup>,\n): GroupEntry[] {\n return Object.entries(groups).filter(([, g]) => g.parentGroup == null);\n}\n\n/**\n * Direct children of `parentId` (one level deep) via the `parentGroup` field.\n *\n * @example\n * ```ts\n * import { directChildren } from \"@pgege/kaboo-react\";\n *\n * function childCount(\n * groups: Parameters<typeof directChildren>[0],\n * parentId: string,\n * ) {\n * return directChildren(groups, parentId).length;\n * }\n * ```\n */\nexport function directChildren(\n groups: Record<string, StreamGroup>,\n parentId: string,\n): GroupEntry[] {\n return Object.entries(groups).filter(([, g]) => g.parentGroup === parentId);\n}\n\n/**\n * Root groups to render inline in the chat for a first-class swarm/graph entry.\n *\n * These are member runs that are NOT spawned by a delegate tool call (no\n * `toolCallId`, so they can't be anchored via CopilotKit's tool renderer) and\n * that sit at the top of the visible tree — either genuinely parentless, or\n * parented by the entry orchestration whose own group is filtered out of the\n * stream (so its parent id is absent from the map). Delegate sub-agent groups\n * always carry a `toolCallId` and are therefore excluded, preserving the\n * tool-call-anchored path.\n *\n * A plain-agent entry group (`inlineChatOwner`) is also excluded: its text and\n * tools are already rendered inline by the host, so it enriches those tool rows\n * without ever becoming its own card.\n */\nexport function chatRootGroups(\n groups: Record<string, StreamGroup>,\n): GroupEntry[] {\n return Object.entries(groups).filter(\n ([, g]) =>\n !g.toolCallId &&\n !g.inlineChatOwner &&\n (g.parentGroup == null || groups[g.parentGroup] === undefined),\n );\n}\n\n/**\n * The most recent `runId` among the given entries (insertion order = arrival\n * order), or `null` when none carry a run id. Used to scope inline cards to the\n * current turn.\n */\nexport function latestRunId(entries: GroupEntry[]): string | null {\n let latest: string | null = null;\n for (const [, g] of entries) {\n if (g.runId) latest = g.runId;\n }\n return latest;\n}\n\n/**\n * True when a still-pending tool call with the given tool-call id exists in some\n * group's timeline. That tool row is the chronological home for the live prompt\n * (an `ask_user` form or a gated-tool approval), so the owning agent card\n * renders it inline there — and the top-level / drill interrupt slots suppress\n * it to avoid a duplicate that would float out of order. Returns `false` (no\n * anchor) when no such tool is present, so those slots still render the prompt\n * as a fallback.\n */\nexport function pendingToolAnchorExists(\n groups: Record<string, StreamGroup>,\n toolCallId: string | undefined,\n): boolean {\n if (!toolCallId) return false;\n for (const g of Object.values(groups)) {\n for (const t of g.tools) {\n if (t.toolUseId === toolCallId && t.toolResult == null) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * Correlate an inline chat card to its activity group by the delegate tool call\n * that spawned it. A group carries the AG-UI `toolCallId` of the coordinator's\n * delegating call (stamped server-side); the same id is exposed by CopilotKit's\n * v2 tool renderer, so matching on `(agentName, toolCallId)` is stable across\n * re-renders and independent of arrival order.\n */\nexport function findGroupForCard(\n groups: Record<string, StreamGroup>,\n agentName: string,\n toolCallId: string,\n): GroupEntry | undefined {\n return Object.entries(groups).find(\n ([, g]) => g.agentName === agentName && g.toolCallId === toolCallId,\n );\n}\n","import { useDefaultRenderTool } from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { ToolRow } from \"../components/ToolRow\";\nimport { isControlOnlyStatus } from \"../formatters/output\";\nimport type { StreamGroup, ToolCall } from \"../types\";\n\nfunction findTool(\n groups: Record<string, StreamGroup>,\n toolCallId: string,\n): ToolCall | undefined {\n for (const group of Object.values(groups)) {\n const match = group.tools.find((t) => t.toolUseId === toolCallId);\n if (match) return match;\n }\n return undefined;\n}\n\n/** A tool call whose name/id spawned a delegate sub-agent group is owned by\n * {@link KabooInlineCards} (renders an AgentCard). Detect it so the wildcard\n * doesn't briefly render it as a plain tool row before that card registers. */\nfunction isDelegateSpawn(\n groups: Record<string, StreamGroup>,\n name: string,\n toolCallId: string,\n): boolean {\n for (const group of Object.values(groups)) {\n if (!group.toolCallId) continue;\n if (group.toolCallId === toolCallId || group.agentName === name) return true;\n }\n return false;\n}\n\n/**\n * Wildcard (`\"*\"`) tool-call renderer: persists any plain tool call inline in\n * the chat transcript. Tools with a dedicated renderer (`ask_user`, delegate\n * sub-agents) take precedence and never reach this fallback — and delegate\n * spawns are skipped explicitly to avoid a flash before their AgentCard\n * registers.\n *\n * The rich record (label, formatted result, error status) is sourced from the\n * activity store by tool-call id; a minimal record built from the raw render\n * props is used while the group is still catching up, so the card never\n * disappears once the tool resolves.\n */\nexport function KabooToolRender() {\n const { groups } = useActivity();\n\n useDefaultRenderTool(\n {\n render: ({ name, toolCallId, parameters, status, result }) => {\n if (isDelegateSpawn(groups, name, toolCallId)) return <></>;\n const fromActivity = findTool(groups, toolCallId);\n // A bare HITL control echo (e.g. {\"status\":\"approved\"} or\n // {\"status\":\"cancelled\"}) is the interrupt-resolution payload, not real\n // tool output. Keep the tool row (a real gated call must never vanish),\n // but drop the echo as the result so we don't dump raw JSON — the real\n // output arrives via the activity store once the resumed tool finishes.\n const controlEcho = !fromActivity && isControlOnlyStatus(result);\n const tool: ToolCall =\n fromActivity ?? {\n toolUseId: toolCallId,\n toolName: name,\n toolInput: parameters,\n toolResult:\n controlEcho || typeof result !== \"string\" ? undefined : result,\n status: status === \"complete\" ? \"success\" : \"running\",\n };\n return (\n <div className=\"kaboo-inline-tool\">\n <ToolRow tool={tool} />\n </div>\n );\n },\n },\n [groups],\n );\n\n return null;\n}\n","import {\n CopilotChatAssistantMessage,\n type CopilotChatAssistantMessageProps,\n} from \"@copilotkit/react-core/v2\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { useTurnBinding } from \"../context/TurnBinding\";\n\n/**\n * Drop-in replacement for CopilotKit's assistant-message renderer that prepends\n * a first-class swarm/graph turn's member cards ABOVE the assistant's text —\n * inside the chat transcript, as part of the same turn.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * ```tsx\n * <CopilotChat messageView={{ assistantMessage: KabooAssistantMessage }} />\n * ```\n *\n * This is used instead of `renderCustomMessages` because the `CopilotKit`\n * convenience provider hard-overrides that prop; the `messageView`/\n * `assistantMessage` slot is the supported customization surface and is not\n * clobbered.\n *\n * Which cards to show is decided by the turn binding (provided by\n * {@link KabooMessageView}), which resolves each reply message to its turn's\n * member cards — robust to an interrupt/resume splitting the turn across\n * multiple runIds. Delegate cards keep their tool-call path (they carry a\n * `toolCallId` and are excluded from `chatRootGroups`).\n */\nexport function KabooAssistantMessage(props: CopilotChatAssistantMessageProps) {\n const { message } = props;\n const { rootsByMessageId } = useTurnBinding();\n const messageId = (message as { id?: string })?.id;\n const mine = messageId ? rootsByMessageId.get(messageId) ?? [] : [];\n\n return (\n <>\n {mine.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {mine.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n <CopilotChatAssistantMessage {...props} />\n </>\n );\n}\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { GroupEntry } from \"../utils/groups\";\n\n/**\n * Binds each assistant reply message to the swarm/graph member cards its turn\n * produced, so those cards render *inside* that message (above its reply text)\n * in one chronological block — and a turn's cards never bleed onto a different\n * turn's reply.\n *\n * The mapping is by turn, not `runId`: an interrupt/resume changes the `runId`\n * mid-turn, so a reply's `runId` may only match the `chat_output` member while\n * earlier members carry the pre-resume `runId`. Both, however, share the\n * server-stamped `turnId` ({@link groupTurnKey}). {@link KabooMessageView}\n * resolves each reply message → its run → that run's `turnId`, then collects all\n * roots of that turn — so every member binds to the right reply regardless of\n * how many runs the turn spanned.\n *\n * `rootsByMessageId` holds the resolved cards per assistant message id; a turn\n * whose reply hasn't streamed yet isn't in the map — {@link KabooMessageView}\n * renders those roots live beneath the transcript instead.\n */\nexport interface TurnBinding {\n rootsByMessageId: Map<string, GroupEntry[]>;\n}\n\nconst TurnBindingContext = createContext<TurnBinding>({\n rootsByMessageId: new Map(),\n});\n\nexport function TurnBindingProvider({\n value,\n children,\n}: {\n value: TurnBinding;\n children: ReactNode;\n}) {\n return (\n <TurnBindingContext.Provider value={value}>\n {children}\n </TurnBindingContext.Provider>\n );\n}\n\nexport function useTurnBinding(): TurnBinding {\n return useContext(TurnBindingContext);\n}\n","import {\n CopilotChatMessageView,\n CopilotChatAssistantMessage,\n CopilotChatUserMessage,\n useCopilotKit,\n useCopilotChatConfiguration,\n type CopilotChatMessageViewProps,\n} from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { chatRootGroups, groupTurnKey, type GroupEntry } from \"../utils/groups\";\nimport { TurnBindingProvider } from \"../context/TurnBinding\";\nimport { KabooAssistantMessage } from \"./KabooAssistantMessage\";\nimport { KabooUserMessage } from \"./KabooUserMessage\";\n\nfunction KabooMessageViewImpl(props: CopilotChatMessageViewProps) {\n const { groups } = useActivity();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId;\n const threadId = config?.threadId;\n\n return (\n <CopilotChatMessageView\n {...props}\n assistantMessage={\n KabooAssistantMessage as unknown as typeof CopilotChatAssistantMessage\n }\n userMessage={KabooUserMessage as unknown as typeof CopilotChatUserMessage}\n >\n {({ messages, messageElements, interruptElement, isRunning }) => {\n const roots = chatRootGroups(groups);\n\n // Bucket this turn's member cards by their stable turn key, and map each\n // AG-UI run to its turn key so a reply (whose run may be the post-resume\n // one) resolves to the whole turn — not just its chat_output member.\n const rootsByTurn = new Map<string, GroupEntry[]>();\n for (const entry of roots) {\n const key = groupTurnKey(entry[1]);\n if (!key) continue;\n const bucket = rootsByTurn.get(key);\n if (bucket) bucket.push(entry);\n else rootsByTurn.set(key, [entry]);\n }\n const runToTurn = new Map<string, string>();\n for (const g of Object.values(groups)) {\n const key = groupTurnKey(g);\n if (g.runId && key) runToTurn.set(g.runId, key);\n }\n\n // Resolve each assistant reply → its run → its turn's roots. A turn\n // whose reply hasn't streamed yet stays unbound and renders live below.\n const rootsByMessageId = new Map<string, GroupEntry[]>();\n const boundTurns = new Set<string>();\n const list = messages as Array<{ id?: string; role?: string }>;\n for (const m of list) {\n if (m?.role !== \"assistant\" || !m.id) continue;\n const runId =\n agentId && threadId\n ? copilotkit.getRunIdForMessage(agentId, threadId, m.id)\n : undefined;\n const key = runId ? runToTurn.get(runId) ?? runId : undefined;\n if (!key) continue;\n const turnRoots = rootsByTurn.get(key);\n if (turnRoots) {\n rootsByMessageId.set(m.id, turnRoots);\n boundTurns.add(key);\n }\n }\n\n const pending = roots.filter(([, g]) => {\n const key = groupTurnKey(g);\n return !key || !boundTurns.has(key);\n });\n const showStartCursor = isRunning && pending.length === 0;\n\n return (\n <TurnBindingProvider value={{ rootsByMessageId }}>\n {messageElements}\n {pending.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {pending.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n {interruptElement}\n {showStartCursor && <CopilotChatMessageView.Cursor />}\n </TurnBindingProvider>\n );\n }}\n </CopilotChatMessageView>\n );\n}\n\n/**\n * Drop-in replacement for `CopilotChat`'s `messageView` that renders swarm/graph\n * member cards **live, inside the chat, from the moment the first agent starts**\n * — not only once the final answer streams.\n *\n * Why this exists: cards attached purely to the assistant message\n * ({@link KabooAssistantMessage}) can't appear until an assistant bubble exists,\n * which for a swarm/graph is when the `chat_output` node streams — i.e. at the\n * very end. During the earlier nodes (planner, researcher, …) there is no\n * assistant message, so the chat would show only a spinner while real work is\n * happening.\n *\n * This view renders the normal message list (with {@link KabooAssistantMessage}\n * for settled turns) and, beneath it, an \"in-progress\" block for any run whose\n * activity groups have appeared but which has **no assistant bubble yet**. As\n * soon as the run's assistant message mounts, that run becomes \"covered\" and its\n * cards render inside the message instead — so there's a seamless hand-off with\n * no duplication.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * @example\n * ```tsx\n * import { CopilotChat } from \"@copilotkit/react-core/v2\";\n * import { KabooMessageView } from \"@pgege/kaboo-react/copilotkit\";\n *\n * function Chat() {\n * return <CopilotChat messageView={KabooMessageView} />;\n * }\n * ```\n */\nexport const KabooMessageView = Object.assign(KabooMessageViewImpl, {\n /**\n * The streaming cursor slot, re-exported from CopilotKit so `KabooMessageView`\n * is a drop-in `messageView` (the slot expects a component carrying `Cursor`).\n */\n Cursor: CopilotChatMessageView.Cursor,\n});\n","import type { ReactNode } from \"react\";\nimport {\n CopilotChatUserMessage,\n type CopilotChatUserMessageProps,\n} from \"@copilotkit/react-core/v2\";\nimport { useReferences } from \"../references/ReferencesProvider\";\nimport type { PendingReference } from \"../references/types\";\n\n// CopilotKit's own wrapper/bubble classes, replicated so our custom layout\n// (via the children render-prop) matches the native user message exactly.\nconst WRAP_CLASS =\n \"copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\";\nconst BUBBLE_CLASS =\n \"cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:inline-block cpk:whitespace-pre-wrap\";\n\nconst AtIcon = (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94\" />\n </svg>\n);\nconst FileIcon = (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 2v6h6\" />\n </svg>\n);\n\n/** A media/document/image content part on a user message. */\ninterface FilePart {\n kind: \"image\" | \"audio\" | \"video\" | \"document\";\n src: string;\n filename: string;\n}\n\n/** Text of a user message (string content, or joined text parts). */\nfunction messageText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((p) =>\n p && typeof p === \"object\" && (p as { type?: string }).type === \"text\"\n ? String((p as { text?: string }).text ?? \"\")\n : \"\",\n )\n .filter(Boolean)\n .join(\"\\n\");\n}\n\n/** Extract renderable file parts (with a resolved src) from message content. */\nfunction fileParts(content: unknown): FilePart[] {\n if (!Array.isArray(content)) return [];\n const out: FilePart[] = [];\n for (const part of content) {\n const type = (part as { type?: string })?.type;\n if (type !== \"image\" && type !== \"audio\" && type !== \"video\" && type !== \"document\") continue;\n const source = (part as { source?: { type?: string; value?: string; mimeType?: string } }).source;\n if (!source?.value) continue;\n const src =\n source.type === \"url\" ? source.value : `data:${source.mimeType ?? \"\"};base64,${source.value}`;\n const meta = (part as { metadata?: { filename?: string } }).metadata;\n out.push({ kind: type, src, filename: meta?.filename ?? source.mimeType ?? \"file\" });\n }\n return out;\n}\n\n/** Non-interactive object-reference chip (`@name`). */\nfunction ObjectChip({ reference, inline }: { reference: PendingReference; inline?: boolean }) {\n return (\n <span\n className={`kaboo-chip kaboo-chip-object kaboo-msg-chip${inline ? \" kaboo-msg-chip-inline\" : \"\"}`}\n title={reference.name}\n >\n <span className=\"kaboo-chip-ic\">{AtIcon}</span>\n <span className=\"kaboo-chip-label\">{reference.name}</span>\n </span>\n );\n}\n\n/** Non-interactive file chip: image preview or document icon + filename. */\nfunction FileChip({ file }: { file: FilePart }) {\n return (\n <span className=\"kaboo-chip kaboo-chip-attachment kaboo-msg-chip\" title={file.filename}>\n {file.kind === \"image\" ? (\n <img className=\"kaboo-chip-thumb\" src={file.src} alt={file.filename} />\n ) : (\n <span className=\"kaboo-chip-ic\">{FileIcon}</span>\n )}\n <span className=\"kaboo-chip-label\">{file.filename}</span>\n </span>\n );\n}\n\n/** Split text on inline reference tokens (`@name`), rendering each as a chip. */\nfunction renderInline(text: string, refs: PendingReference[]): ReactNode[] {\n if (refs.length === 0) return [text];\n const tokens = refs\n .map((ref) => ({ ref, token: `@${ref.name}` }))\n .sort((a, b) => b.token.length - a.token.length);\n const out: ReactNode[] = [];\n let i = 0;\n let key = 0;\n while (i < text.length) {\n const hit = tokens.find((t) => text.startsWith(t.token, i));\n if (hit) {\n out.push(<ObjectChip key={key++} reference={hit.ref} inline />);\n i += hit.token.length;\n continue;\n }\n let next = text.length;\n for (const t of tokens) {\n const idx = text.indexOf(t.token, i + 1);\n if (idx !== -1 && idx < next) next = idx;\n }\n out.push(text.slice(i, next));\n i = next;\n }\n return out;\n}\n\n/**\n * Drop-in replacement for `CopilotChatMessageView`'s `userMessage` slot that\n * renders every reference the user sent as a **non-interactive chip**, so a\n * reference reads as a reference rather than plain text:\n *\n * - object references cited inline (`@name`) render as chips *within* the text;\n * - files and objects added via the `+` tray render as a chip row above the\n * bubble (files show a thumbnail/icon + filename).\n *\n * Object references ride `state.kaboo_references` (not the message content), so\n * they come from the per-message registry on {@link useReferences}; files come\n * from the message's media parts.\n */\nexport function KabooUserMessage(props: CopilotChatUserMessageProps) {\n const { messageReferences } = useReferences();\n const message = props.message as { id?: string; content?: unknown } | undefined;\n const id = message?.id;\n const objectRefs = (id ? messageReferences[id] : undefined) ?? [];\n const text = messageText(message?.content);\n const files = fileParts(message?.content);\n\n const inlineRefs = objectRefs.filter((r) => text.includes(`@${r.name}`));\n const trayRefs = objectRefs.filter((r) => !text.includes(`@${r.name}`));\n const hasChipRow = files.length > 0 || trayRefs.length > 0;\n\n const MessageRenderer = ({ content, className }: { content: string; className?: string }) => (\n <div className={className ? `${BUBBLE_CLASS} ${className}` : BUBBLE_CLASS}>\n {renderInline(content, inlineRefs)}\n </div>\n );\n\n return (\n <CopilotChatUserMessage\n {...props}\n messageRenderer={MessageRenderer as unknown as typeof CopilotChatUserMessage.MessageRenderer}\n >\n {({ messageRenderer, toolbar }) => (\n <div data-copilotkit data-message-id={id} className={`${WRAP_CLASS} kaboo-user-message`}>\n {hasChipRow && (\n <div className=\"kaboo-msg-refs\">\n {files.map((f, i) => (\n <FileChip key={`f${i}`} file={f} />\n ))}\n {trayRefs.map((r) => (\n <ObjectChip key={r.id} reference={r} />\n ))}\n </div>\n )}\n {messageRenderer}\n {toolbar}\n </div>\n )}\n </CopilotChatUserMessage>\n );\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useAgent } from \"@copilotkit/react-core/v2\";\nimport type { PendingReference } from \"./serialize\";\nimport { objectToStateEntry, withReferenceState } from \"./serialize\";\nimport type { ReferenceProvider } from \"./types\";\n\n/** Value exposed by {@link useReferences}. */\nexport interface ReferencesContextValue {\n /** Registered `@` providers (upload built-in + app-defined). */\n providers: ReferenceProvider[];\n /** References currently staged on the composer. */\n pending: PendingReference[];\n /** Stage a reference (deduped by id). */\n addReference: (ref: PendingReference) => void;\n /** Remove a staged reference by id. */\n removeReference: (id: string) => void;\n /** Clear all staged references (call after a message is sent). */\n clearReferences: () => void;\n /**\n * Object references sent with each user message, keyed by message id. Object\n * references ride `state.kaboo_references` rather than the message content, so\n * they'd otherwise be invisible in the sent bubble — this lets the user\n * message renderer show them as chips.\n */\n messageReferences: Record<string, PendingReference[]>;\n /** Record the object references attached to a sent user message. */\n recordMessageReferences: (messageId: string, refs: PendingReference[]) => void;\n}\n\nconst ReferencesContext = createContext<ReferencesContextValue>({\n providers: [],\n pending: [],\n addReference: () => {},\n removeReference: () => {},\n clearReferences: () => {},\n messageReferences: {},\n recordMessageReferences: () => {},\n});\n\n/** Props for {@link ReferencesProvider}. */\nexport interface ReferencesProviderProps {\n /** The `@` provider registry. File upload is not implicit — pass `uploadProvider()`. */\n providers?: ReferenceProvider[];\n /**\n * Sync staged object-transport references into the bound agent's\n * `state.kaboo_references` as they change, so a plain `<CopilotChat>` send\n * still carries them. Default `true`. Attachment references travel on the\n * message itself and are unaffected.\n */\n syncObjectStateTo?: string | false;\n /** The subtree that can stage and read references. */\n children: ReactNode;\n}\n\n/**\n * Holds the `@` reference registry and the composer's staged references, and\n * (by default) mirrors object references into the agent's AG-UI state. Mounted\n * automatically by {@link KabooProvider}; read it via {@link useReferences}.\n */\nexport function ReferencesProvider({\n providers = [],\n syncObjectStateTo = false,\n children,\n}: ReferencesProviderProps) {\n const [pending, setPending] = useState<PendingReference[]>([]);\n const [messageReferences, setMessageReferences] = useState<\n Record<string, PendingReference[]>\n >({});\n\n const addReference = useCallback((ref: PendingReference) => {\n setPending((prev) =>\n prev.some((r) => r.id === ref.id) ? prev : [...prev, ref],\n );\n }, []);\n const removeReference = useCallback((id: string) => {\n setPending((prev) => prev.filter((r) => r.id !== id));\n }, []);\n const clearReferences = useCallback(() => setPending([]), []);\n const recordMessageReferences = useCallback(\n (messageId: string, refs: PendingReference[]) => {\n if (refs.length === 0) return;\n setMessageReferences((prev) => ({ ...prev, [messageId]: refs }));\n },\n [],\n );\n\n const value = useMemo(\n () => ({\n providers,\n pending,\n addReference,\n removeReference,\n clearReferences,\n messageReferences,\n recordMessageReferences,\n }),\n [\n providers,\n pending,\n addReference,\n removeReference,\n clearReferences,\n messageReferences,\n recordMessageReferences,\n ],\n );\n\n return (\n <ReferencesContext.Provider value={value}>\n {syncObjectStateTo !== false && (\n <ReferenceStateSync agentId={syncObjectStateTo} pending={pending} />\n )}\n {children}\n </ReferencesContext.Provider>\n );\n}\n\n/**\n * Mirrors staged object-transport references into the bound agent's\n * `state.kaboo_references`. Mounted by {@link ReferencesProvider} when\n * `syncObjectStateTo` is set.\n */\nexport function ReferenceStateSync({\n agentId,\n pending,\n}: {\n agentId?: string;\n pending: PendingReference[];\n}): null {\n const { agent } = useAgent(agentId ? { agentId } : undefined);\n const objectRefs = useMemo(\n () =>\n pending\n .filter((r): r is Extract<PendingReference, { transport: \"object\" }> => r.transport === \"object\")\n .map(objectToStateEntry),\n [pending],\n );\n const key = JSON.stringify(objectRefs);\n useEffect(() => {\n if (!agent || typeof agent.setState !== \"function\") return;\n agent.setState(withReferenceState(agent.state as Record<string, unknown>, objectRefs));\n // key drives the effect; agent.state is read fresh above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, key]);\n return null;\n}\n\n/**\n * Access the `@` reference registry and staged references.\n *\n * @example\n * ```tsx\n * const { providers, pending, addReference } = useReferences();\n * ```\n */\nexport function useReferences(): ReferencesContextValue {\n return useContext(ReferencesContext);\n}\n","import type { ReactElement } from \"react\";\nimport { useInterrupt } from \"@copilotkit/react-core/v2\";\nimport { InterruptRenderer } from \"../components/InterruptRenderer\";\nimport {\n InterruptBridgePublisher,\n type ActiveInterrupt,\n} from \"../context/InterruptBridge\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { pendingToolAnchorExists } from \"../utils/groups\";\nimport { KabooAskUser } from \"./KabooAskUser\";\nimport type { InterruptReason, InterruptRendererProps } from \"../types\";\n\n/**\n * Chat-level fallback slot for one interrupt. Renders the prompt UI unless the\n * owning agent card already renders it inline at its pending tool-call position\n * (see {@link pendingToolAnchorExists}) — in that case this returns nothing so\n * the prompt stays in chronological order inside the card instead of floating on\n * top of the turn's cards. Prompts with no on-screen tool anchor render here.\n */\nfunction ChatInterruptSlot({\n interrupt,\n Renderer,\n}: {\n interrupt: ActiveInterrupt;\n Renderer: React.ComponentType<InterruptRendererProps>;\n}): ReactElement | null {\n const { groups } = useActivity();\n if (pendingToolAnchorExists(groups, interrupt.toolCallId)) {\n return null;\n }\n return (\n <Renderer\n reason={interrupt.reason}\n toolCallId={interrupt.toolCallId}\n onResolve={interrupt.onResolve}\n onCancel={interrupt.onCancel}\n />\n );\n}\n\n/** Props for {@link KabooInterruptHandler}. */\nexport interface KabooInterruptHandlerProps {\n /** Restrict handling to a single CopilotKit agent (optional). */\n agentId?: string;\n /** Per-interrupt-type renderer overrides. */\n renderers?: Partial<\n Record<InterruptReason[\"type\"], React.ComponentType<InterruptRendererProps>>\n >;\n /**\n * Also publish the active interrupts to the InterruptBridge so each renders\n * inside the drill-down detail view (not just the chat). Defaults to `true`;\n * requires an `InterruptBridgeProvider` (included in `KabooProvider`).\n */\n bridge?: boolean;\n}\n\n/**\n * Ready-made human-in-the-loop interrupt handler. CopilotKit surfaces every open\n * interrupt of a run at once (e.g. two gated tools called in parallel); we render\n * one card per interrupt and resolve each independently by its own id. The client\n * accumulates the per-id responses and only resumes the run once every open\n * interrupt has been answered — so resolving with `intr.id` (never the bare\n * `resolve()`, which would only ever answer the first) is what keeps N parallel\n * gates from wedging. Prompts anchored to an on-screen tool render inline at that\n * tool's position; the rest fall back to the chat slot.\n */\nexport function KabooInterruptHandler({\n agentId,\n renderers,\n bridge = true,\n}: KabooInterruptHandlerProps): ReactElement | null {\n useInterrupt({\n ...(agentId ? { agentId } : {}),\n render: ({ interrupts, resolve, cancel }) => {\n const active: ActiveInterrupt[] = (interrupts ?? [])\n .map((intr): ActiveInterrupt | null => {\n const reason = (intr?.metadata ?? intr?.reason) as\n | InterruptReason\n | undefined;\n if (!reason || !reason.type) return null;\n return {\n id: intr.id,\n reason,\n toolCallId: (intr as { toolCallId?: string }).toolCallId,\n onResolve: (payload: unknown) => resolve(payload, intr.id),\n onCancel: () => cancel(intr.id),\n };\n })\n .filter((x): x is ActiveInterrupt => x !== null);\n\n if (active.length === 0) {\n return <></>;\n }\n\n return (\n <>\n {bridge && <InterruptBridgePublisher interrupts={active} />}\n {active.map((a) => (\n <ChatInterruptSlot\n key={a.id}\n interrupt={a}\n Renderer={renderers?.[a.reason.type] ?? InterruptRenderer}\n />\n ))}\n </>\n );\n },\n });\n\n return <KabooAskUser agentId={agentId} />;\n}\n","import { useRenderTool } from \"@copilotkit/react-core/v2\";\nimport { AskUserSummary } from \"../components/AskUserSummary\";\nimport { normalizeQuestions, parseAnswers, type AskUserParams } from \"../formatters/askUser\";\nimport type { FormQuestion } from \"../types\";\n\n/**\n * Permissive Standard Schema. `useRenderTool` requires a `parameters` schema but\n * never validates against it at render time (it parses the raw tool args). This\n * shim satisfies the type without pulling in a schema library.\n */\nconst ANY_PARAMETERS = {\n \"~standard\": {\n version: 1 as const,\n vendor: \"kaboo\",\n validate: (value: unknown) => ({ value }),\n },\n};\n\n/**\n * Renders answered `ask_user` prompts inline in the chat, anchored to the tool\n * call. The tool call is a permanent part of the transcript, so the question and\n * the user's answer persist in chronological order after the interrupt resolves.\n *\n * While the prompt is still pending (no result yet), this renders nothing — the\n * live interactive form is supplied by {@link KabooInterruptHandler}'s\n * `useInterrupt` render.\n */\nexport function KabooAskUser({ agentId }: { agentId?: string }) {\n useRenderTool({\n name: \"ask_user\",\n ...(agentId ? { agentId } : {}),\n parameters: ANY_PARAMETERS,\n render: ({ parameters, result }) => {\n const questions = normalizeQuestions(parameters as AskUserParams | undefined);\n if (questions.length === 0) return <></>;\n\n return <AskUserCard questions={questions} result={result} />;\n },\n });\n\n return null;\n}\n\n/**\n * Renders the answered Q&A once the tool result carries answers. While the\n * prompt is still pending the result is empty, so nothing is drawn here and the\n * live interactive form (from `useInterrupt`) owns the UI. The tool result is\n * the single source of truth, so the card also survives a reload/replay.\n */\nfunction AskUserCard({\n questions,\n result,\n}: {\n questions: FormQuestion[];\n result: unknown;\n}) {\n const answers = parseAnswers(result);\n if (!answers) return <></>;\n return <AskUserSummary questions={questions} answers={answers} />;\n}\n"],"mappings":"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","names":["import_v2","import_react","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","text","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_v2","import_jsx_runtime","import_jsx_runtime","import_v2","import_react","import_jsx_runtime","import_jsx_runtime","import_v2","import_v2","import_react","import_v2","import_jsx_runtime","import_jsx_runtime","renderInline","import_jsx_runtime","import_v2","import_v2","import_jsx_runtime","ANY_PARAMETERS","import_jsx_runtime"]}