@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/index.ts","../src/context/ActivityProvider.tsx","../src/context/DrillContext.tsx","../src/context/KabooProvider.tsx","../src/context/InterruptBridge.tsx","../src/integrations/KabooInterruptHandler.tsx","../src/components/InterruptRenderer.tsx","../src/hooks/useActivity.ts","../src/utils/groups.ts","../src/integrations/KabooAskUser.tsx","../src/components/AskUserSummary.tsx","../src/formatters/askUser.ts","../src/integrations/KabooInlineCards.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/hooks/useDrill.ts","../src/integrations/KabooToolRender.tsx","../src/components/ActivityPanel.tsx","../src/components/GlassTabs.tsx","../src/components/DrillDetailView.tsx"],"sourcesContent":["export type {\n ToolCall, TimelineEntry, StreamGroup, ActivityState, DrillState,\n FormQuestion, ApprovalReason, FormReason, InterruptReason,\n InterruptData, InterruptRendererProps,\n} from \"./types\";\n\nexport { KabooActivityProvider, StructuredRenderersContext } from \"./context/ActivityProvider\";\nexport type { KabooActivityProviderProps, StructuredRenderers } from \"./context/ActivityProvider\";\nexport { DrillProvider } from \"./context/DrillContext\";\nexport { KabooProvider } from \"./context/KabooProvider\";\nexport type { KabooProviderProps } from \"./context/KabooProvider\";\nexport {\n InterruptBridgeProvider,\n InterruptBridgePublisher,\n useInterruptBridge,\n useInterruptFor,\n} from \"./context/InterruptBridge\";\nexport type { ActiveInterrupt } from \"./context/InterruptBridge\";\n\nexport { useActivity } from \"./hooks/useActivity\";\nexport { useDrill } from \"./hooks/useDrill\";\nexport { topLevelGroups, directChildren } from \"./utils/groups\";\nexport type { GroupEntry } from \"./utils/groups\";\n\nexport { ActivityPanel } from \"./components/ActivityPanel\";\nexport { AgentCard } from \"./components/AgentCard\";\nexport type { AgentCardProps } from \"./components/AgentCard\";\nexport { ToolRow } from \"./components/ToolRow\";\nexport { MiniTable } from \"./components/MiniTable\";\nexport { GlassTabs } from \"./components/GlassTabs\";\nexport { DrillDetailView } from \"./components/DrillDetailView\";\nexport { MarkdownContent } from \"./components/MarkdownContent\";\nexport { InterruptRenderer } from \"./components/InterruptRenderer\";\nexport { Timeline } from \"./components/Timeline\";\nexport type { TimelineProps } from \"./components/Timeline\";\n\nexport { formatToolInput } from \"./formatters/input\";\nexport { formatToolResult, normalizeResult } from \"./formatters/output\";\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, 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 { ReactNode } from \"react\";\nimport { CopilotKit, type CopilotKitProps } from \"@copilotkit/react-core/v2\";\nimport { KabooActivityProvider, type StructuredRenderers } from \"./ActivityProvider\";\nimport { DrillProvider } from \"./DrillContext\";\nimport { InterruptBridgeProvider } from \"./InterruptBridge\";\nimport { KabooInterruptHandler, type KabooInterruptHandlerProps } from \"../integrations/KabooInterruptHandler\";\nimport { KabooInlineCards } from \"../integrations/KabooInlineCards\";\n\n/** Props for {@link KabooProvider}. */\nexport interface KabooProviderProps {\n /** URL of the CopilotKit runtime endpoint (e.g. `/api/copilotkit`). */\n runtimeUrl: string;\n /** CopilotKit agent id to run (the workflow entry agent). */\n agent: string;\n /** Conversation id. Scopes both the run and its activity. */\n threadId?: string;\n /** Renderers for structured agent outputs, keyed by output schema name. */\n structuredRenderers?: StructuredRenderers;\n /** Per-interrupt-type renderer overrides for the built-in HITL handler. */\n interruptRenderers?: KabooInterruptHandlerProps[\"renderers\"];\n /** Skip auto-mounting the built-in {@link KabooInterruptHandler}. */\n disableInterruptHandler?: boolean;\n /** Skip auto-mounting the built-in {@link KabooInlineCards}. */\n disableInlineCards?: boolean;\n /** Extra props forwarded to the underlying `<CopilotKit>`. */\n copilotKitProps?: Partial<Omit<CopilotKitProps, \"children\" | \"runtimeUrl\" | \"agent\" | \"threadId\">>;\n /** Your app subtree, rendered inside all kaboo contexts. */\n children: ReactNode;\n}\n\n/**\n * Batteries-included CopilotKit plugin. Renders `<CopilotKit>` and nests every\n * kaboo context (activity -> drill -> interrupt bridge) plus the built-in HITL\n * and inline-card handlers, so integrators drop this once near the root and use\n * only kaboo-react. Activity rides the AG-UI run stream, so there is no separate\n * activity endpoint to configure.\n *\n * @example\n * ```tsx\n * import { CopilotChat } from \"@copilotkit/react-core/v2\";\n * import { KabooProvider, GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n * import { KabooMessageView } from \"@pgege/kaboo-react/copilotkit\";\n * import \"@pgege/kaboo-react/styles.css\";\n *\n * function App({ agent, threadId }: { agent: string; threadId: string }) {\n * return (\n * <KabooProvider runtimeUrl=\"/api/copilotkit\" agent={agent} threadId={threadId}>\n * <GlassTabs />\n * <CopilotChat messageView={KabooMessageView} />\n * <DrillDetailView />\n * </KabooProvider>\n * );\n * }\n * ```\n */\nexport function KabooProvider({\n runtimeUrl,\n agent,\n threadId,\n structuredRenderers,\n interruptRenderers,\n disableInterruptHandler = false,\n disableInlineCards = false,\n copilotKitProps,\n children,\n}: KabooProviderProps) {\n return (\n <CopilotKit\n runtimeUrl={runtimeUrl}\n agent={agent}\n threadId={threadId}\n useSingleEndpoint={false}\n {...copilotKitProps}\n >\n <KabooActivityProvider agentId={agent} structuredRenderers={structuredRenderers}>\n <DrillProvider>\n <InterruptBridgeProvider>\n {!disableInterruptHandler && (\n <KabooInterruptHandler agentId={agent} renderers={interruptRenderers} />\n )}\n {!disableInlineCards && <KabooInlineCards />}\n {children}\n </InterruptBridgeProvider>\n </DrillProvider>\n </KabooActivityProvider>\n </CopilotKit>\n );\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 { 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 { 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 { 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 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 { 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","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 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 { 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 { 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 { 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 { 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 { useActivity } from \"../hooks/useActivity\";\nimport { useDrill } from \"../hooks/useDrill\";\nimport { topLevelGroups, directChildren } from \"../utils/groups\";\nimport { AgentCard } from \"./AgentCard\";\n\n/**\n * Standalone panel that renders the current activity tree as a list of\n * {@link AgentCard}s — top-level groups at the root, or the drilled-in group's\n * children. Use it when you want the hierarchical activity view outside the chat\n * transcript (the in-chat view is handled by `KabooMessageView`). Renders\n * nothing when there is no activity.\n *\n * @example\n * ```tsx\n * import { ActivityPanel } from \"@pgege/kaboo-react\";\n *\n * function Sidebar() {\n * return (\n * <aside>\n * <ActivityPanel />\n * </aside>\n * );\n * }\n * ```\n */\nexport function ActivityPanel() {\n const { groups } = useActivity();\n const { activeDrill } = useDrill();\n\n if (Object.keys(groups).length === 0) return null;\n\n // A plain-agent entry group (`inlineChatOwner`) is rendered inline by the host\n // chat, so it must not also appear as a root card here — it only enriches\n // those inline tool rows. Nested/sub-agent drilling is unaffected.\n const filtered = activeDrill\n ? directChildren(groups, activeDrill)\n : topLevelGroups(groups).filter(([, g]) => !g.inlineChatOwner);\n\n if (filtered.length === 0 && activeDrill) {\n const exact = groups[activeDrill];\n if (exact) {\n return (\n <div className=\"kaboo-activity-panel\">\n <AgentCard groupId={activeDrill} group={exact} />\n </div>\n );\n }\n }\n\n return (\n <div className=\"kaboo-activity-panel\">\n {filtered.map(([id, group]) => (\n <AgentCard key={id} groupId={id} group={group} />\n ))}\n </div>\n );\n}\n","import { useActivity } from \"../hooks/useActivity\";\nimport { useDrill } from \"../hooks/useDrill\";\n\n/**\n * Breadcrumb navigation for the drill-down path: a \"Chat\" root followed by one\n * crumb per drilled-in group. Clicking a crumb jumps to that level; the current\n * (last) crumb is disabled. Renders nothing at the root. Pair with\n * {@link DrillDetailView}.\n *\n * @example\n * ```tsx\n * import { GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n *\n * function DrillArea() {\n * return (\n * <>\n * <GlassTabs />\n * <DrillDetailView />\n * </>\n * );\n * }\n * ```\n */\nexport function GlassTabs() {\n const { drillPath, drillToRoot, drillToLevel } = useDrill();\n const { groups } = useActivity();\n\n if (drillPath.length === 0) return null;\n\n const tabs: { id: string; label: string; level: number }[] = [\n { id: \"root\", label: \"Chat\", level: -1 },\n ...drillPath.map((id, i) => ({\n id,\n label: groups[id]?.title || id,\n level: i,\n })),\n ];\n\n return (\n <nav className=\"kaboo-breadcrumb-bar\">\n {tabs.map((tab, i) => {\n const isLast = i === tabs.length - 1;\n return (\n <span key={tab.id} className=\"kaboo-breadcrumb-item\">\n {i > 0 && (\n <svg width={12} height={12} viewBox=\"0 0 16 16\" className=\"kaboo-breadcrumb-sep\">\n <path d=\"M6 4l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )}\n <button\n className={`kaboo-breadcrumb-link ${isLast ? \"kaboo-breadcrumb-current\" : \"\"}`}\n onClick={() => {\n if (isLast) return;\n if (tab.level === -1) drillToRoot();\n else drillToLevel(tab.level);\n }}\n disabled={isLast}\n >\n {i === 0 && (\n <svg width={14} height={14} viewBox=\"0 0 16 16\" className=\"kaboo-breadcrumb-icon\">\n <path d=\"M3 8.5L8 4l5 4.5M4.5 7.5V12h2.5V9.5h2V12h2.5V7.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n {tab.label}\n </button>\n </span>\n );\n })}\n </nav>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { useDrill } from \"../hooks/useDrill\";\nimport { useInterruptBridge } from \"../context/InterruptBridge\";\nimport {\n directChildren,\n partitionChildrenByToolCall,\n pendingToolAnchorExists,\n} from \"../utils/groups\";\nimport { AgentCard } from \"./AgentCard\";\nimport { Timeline } from \"./Timeline\";\nimport { InterruptRenderer } from \"./InterruptRenderer\";\n\n/**\n * Detail pane for the currently drilled-in group: its task, full timeline\n * (with delegated sub-agents interleaved at their tool-call position), any\n * unanchored interrupt prompts, and a \"Sub-agents\" section for swarm/graph\n * members. Renders a hidden placeholder at the root. Pair with {@link GlassTabs}.\n *\n * @example\n * ```tsx\n * import { GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n *\n * function DrillArea() {\n * return (\n * <>\n * <GlassTabs />\n * <DrillDetailView />\n * </>\n * );\n * }\n * ```\n */\nexport function DrillDetailView() {\n const { activeDrill } = useDrill();\n const { groups } = useActivity();\n const { active: activeInterrupts } = useInterruptBridge();\n const bodyRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (activeDrill && bodyRef.current) {\n bodyRef.current.scrollTop = 0;\n }\n }, [activeDrill]);\n\n if (!activeDrill) {\n return <div className=\"kaboo-drill-detail kaboo-hidden\" />;\n }\n\n const group = groups[activeDrill];\n const timeline = group?.timeline ?? [];\n // Prompts anchored to a pending tool call are rendered inline by the Timeline\n // at that tool's position (chronological); this block only handles interrupts\n // with no on-screen tool anchor — never a duplicate.\n const unanchoredInterrupts =\n group?.status === \"interrupted\"\n ? activeInterrupts.filter(\n (i) => !pendingToolAnchorExists(groups, i.toolCallId),\n )\n : [];\n\n const childEntries = directChildren(groups, activeDrill);\n // Interleave delegated children at their delegating tool-call position so a\n // sub-agent's card sits where it was delegated (before the parent's summary\n // text) rather than in a trailing block. Children with no tool-call anchor\n // (swarm/graph members) still render in the Sub-agents section below.\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]} />;\n };\n\n return (\n <div ref={bodyRef} className=\"kaboo-drill-detail\">\n <div className=\"kaboo-drill-detail-inner\">\n {group?.task && (\n <div className=\"kaboo-agent-card-task kaboo-drill-task\">\n <strong>Task:</strong> {group.task}\n </div>\n )}\n\n {group && timeline.length > 0 && (\n <div className=\"kaboo-drill-timeline\">\n <Timeline\n timeline={timeline}\n active={group.status === \"active\"}\n variant=\"drill\"\n renderToolCard={renderToolCard}\n />\n </div>\n )}\n\n {unanchoredInterrupts.length > 0 && (\n <div className=\"kaboo-drill-interrupt\">\n {unanchoredInterrupts.map((it) => (\n <InterruptRenderer\n key={it.id}\n reason={it.reason}\n toolCallId={it.toolCallId}\n onResolve={it.onResolve}\n onCancel={it.onCancel}\n />\n ))}\n </div>\n )}\n\n {leftoverChildren.length > 0 && (\n <div className=\"kaboo-drill-children\">\n <div className=\"kaboo-drill-section-label\">Sub-agents</div>\n {leftoverChildren.map(([id, childGroup]) => (\n <AgentCard key={id} groupId={id} group={childGroup} />\n ))}\n </div>\n )}\n\n {group && timeline.length === 0 && childEntries.length === 0 && (\n <div className=\"kaboo-agent-card-empty\">\n Working...\n </div>\n )}\n\n {!group && (\n <div className=\"kaboo-agent-card-empty\">\n No activity data for this group.\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_v2","import_react","import_jsx_runtime","import_v2","import_react","import_jsx_runtime","import_react","import_v2","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_v2","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_v2","import_jsx_runtime","import_jsx_runtime","ANY_PARAMETERS","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/context/ActivityProvider.tsx","../src/context/DrillContext.tsx","../src/context/KabooProvider.tsx","../src/context/InterruptBridge.tsx","../src/integrations/KabooInterruptHandler.tsx","../src/components/InterruptRenderer.tsx","../src/hooks/useActivity.ts","../src/utils/groups.ts","../src/integrations/KabooAskUser.tsx","../src/components/AskUserSummary.tsx","../src/formatters/askUser.ts","../src/integrations/KabooInlineCards.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/hooks/useDrill.ts","../src/integrations/KabooToolRender.tsx","../src/references/ReferencesProvider.tsx","../src/references/types.ts","../src/references/serialize.ts","../src/references/ReferenceInput.tsx","../src/references/uploadProvider.tsx","../src/components/ActivityPanel.tsx","../src/components/GlassTabs.tsx","../src/components/DrillDetailView.tsx"],"sourcesContent":["export type {\n ToolCall, TimelineEntry, StreamGroup, ActivityState, DrillState,\n FormQuestion, ApprovalReason, FormReason, InterruptReason,\n InterruptData, InterruptRendererProps,\n} from \"./types\";\n\nexport { KabooActivityProvider, StructuredRenderersContext } from \"./context/ActivityProvider\";\nexport type { KabooActivityProviderProps, StructuredRenderers } from \"./context/ActivityProvider\";\nexport { DrillProvider } from \"./context/DrillContext\";\nexport { KabooProvider } from \"./context/KabooProvider\";\nexport type { KabooProviderProps } from \"./context/KabooProvider\";\nexport {\n InterruptBridgeProvider,\n InterruptBridgePublisher,\n useInterruptBridge,\n useInterruptFor,\n} from \"./context/InterruptBridge\";\nexport type { ActiveInterrupt } from \"./context/InterruptBridge\";\n\nexport { useActivity } from \"./hooks/useActivity\";\nexport { useDrill } from \"./hooks/useDrill\";\n\nexport { ReferencesProvider, ReferenceStateSync, useReferences } from \"./references/ReferencesProvider\";\nexport type { ReferencesContextValue, ReferencesProviderProps } from \"./references/ReferencesProvider\";\nexport { KabooReferenceInput } from \"./references/ReferenceInput\";\nexport type { KabooReferenceInputProps } from \"./references/ReferenceInput\";\nexport {\n uploadProvider,\n isUploadProvider,\n buildAttachmentsConfig,\n uploadFileToReference,\n UPLOAD_MARKER,\n} from \"./references/uploadProvider\";\nexport type { UploadProviderConfig, UploadReferenceProvider } from \"./references/uploadProvider\";\nexport {\n mintReferenceId,\n referenceMarker,\n attachmentToInputContent,\n objectToStateEntry,\n serializeReferences,\n withReferenceState,\n buildUserContent,\n} from \"./references/serialize\";\nexport type { SerializedObjectReference, SerializedReferences } from \"./references/serialize\";\nexport {\n REFERENCE_METADATA_KEYS,\n REFERENCES_STATE_KEY,\n} from \"./references/types\";\nexport type {\n ReferenceProvider,\n ReferenceItem,\n PendingReference,\n ReferenceTransport,\n} from \"./references/types\";\nexport { topLevelGroups, directChildren } from \"./utils/groups\";\nexport type { GroupEntry } from \"./utils/groups\";\n\nexport { ActivityPanel } from \"./components/ActivityPanel\";\nexport { AgentCard } from \"./components/AgentCard\";\nexport type { AgentCardProps } from \"./components/AgentCard\";\nexport { ToolRow } from \"./components/ToolRow\";\nexport { MiniTable } from \"./components/MiniTable\";\nexport { GlassTabs } from \"./components/GlassTabs\";\nexport { DrillDetailView } from \"./components/DrillDetailView\";\nexport { MarkdownContent } from \"./components/MarkdownContent\";\nexport { InterruptRenderer } from \"./components/InterruptRenderer\";\nexport { Timeline } from \"./components/Timeline\";\nexport type { TimelineProps } from \"./components/Timeline\";\n\nexport { formatToolInput } from \"./formatters/input\";\nexport { formatToolResult, normalizeResult } from \"./formatters/output\";\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, 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 { ReactNode } from \"react\";\nimport { CopilotKit, type CopilotKitProps } from \"@copilotkit/react-core/v2\";\nimport { KabooActivityProvider, type StructuredRenderers } from \"./ActivityProvider\";\nimport { DrillProvider } from \"./DrillContext\";\nimport { InterruptBridgeProvider } from \"./InterruptBridge\";\nimport { KabooInterruptHandler, type KabooInterruptHandlerProps } from \"../integrations/KabooInterruptHandler\";\nimport { KabooInlineCards } from \"../integrations/KabooInlineCards\";\nimport { ReferencesProvider } from \"../references/ReferencesProvider\";\nimport type { ReferenceProvider } from \"../references/types\";\n\n/** Props for {@link KabooProvider}. */\nexport interface KabooProviderProps {\n /** URL of the CopilotKit runtime endpoint (e.g. `/api/copilotkit`). */\n runtimeUrl: string;\n /** CopilotKit agent id to run (the workflow entry agent). */\n agent: string;\n /** Conversation id. Scopes both the run and its activity. */\n threadId?: string;\n /** Renderers for structured agent outputs, keyed by output schema name. */\n structuredRenderers?: StructuredRenderers;\n /** Per-interrupt-type renderer overrides for the built-in HITL handler. */\n interruptRenderers?: KabooInterruptHandlerProps[\"renderers\"];\n /** Skip auto-mounting the built-in {@link KabooInterruptHandler}. */\n disableInterruptHandler?: boolean;\n /** Skip auto-mounting the built-in {@link KabooInlineCards}. */\n disableInlineCards?: boolean;\n /**\n * `@` reference providers made available to the composer / `useReferences`.\n * File upload is not implicit — include `uploadProvider()` to offer uploads.\n */\n references?: ReferenceProvider[];\n /** Extra props forwarded to the underlying `<CopilotKit>`. */\n copilotKitProps?: Partial<Omit<CopilotKitProps, \"children\" | \"runtimeUrl\" | \"agent\" | \"threadId\">>;\n /** Your app subtree, rendered inside all kaboo contexts. */\n children: ReactNode;\n}\n\n/**\n * Batteries-included CopilotKit plugin. Renders `<CopilotKit>` and nests every\n * kaboo context (activity -> drill -> interrupt bridge) plus the built-in HITL\n * and inline-card handlers, so integrators drop this once near the root and use\n * only kaboo-react. Activity rides the AG-UI run stream, so there is no separate\n * activity endpoint to configure.\n *\n * @example\n * ```tsx\n * import { CopilotChat } from \"@copilotkit/react-core/v2\";\n * import { KabooProvider, GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n * import { KabooMessageView } from \"@pgege/kaboo-react/copilotkit\";\n * import \"@pgege/kaboo-react/styles.css\";\n *\n * function App({ agent, threadId }: { agent: string; threadId: string }) {\n * return (\n * <KabooProvider runtimeUrl=\"/api/copilotkit\" agent={agent} threadId={threadId}>\n * <GlassTabs />\n * <CopilotChat messageView={KabooMessageView} />\n * <DrillDetailView />\n * </KabooProvider>\n * );\n * }\n * ```\n */\nexport function KabooProvider({\n runtimeUrl,\n agent,\n threadId,\n structuredRenderers,\n interruptRenderers,\n disableInterruptHandler = false,\n disableInlineCards = false,\n references,\n copilotKitProps,\n children,\n}: KabooProviderProps) {\n return (\n <CopilotKit\n runtimeUrl={runtimeUrl}\n agent={agent}\n threadId={threadId}\n useSingleEndpoint={false}\n {...copilotKitProps}\n >\n <KabooActivityProvider agentId={agent} structuredRenderers={structuredRenderers}>\n <DrillProvider>\n <InterruptBridgeProvider>\n <ReferencesProvider providers={references} syncObjectStateTo={agent}>\n {!disableInterruptHandler && (\n <KabooInterruptHandler agentId={agent} renderers={interruptRenderers} />\n )}\n {!disableInlineCards && <KabooInlineCards />}\n {children}\n </ReferencesProvider>\n </InterruptBridgeProvider>\n </DrillProvider>\n </KabooActivityProvider>\n </CopilotKit>\n );\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 { 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 { 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 { 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 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 { 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","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 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 { 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 { 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 { 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 { 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 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 { ReactNode } from \"react\";\n\n/**\n * Wire keys shared with kaboo-workflows. A file attachment carries its id/kind/\n * name in the CopilotKit `InputContent` part `metadata` under these keys; the\n * Python side reads the same keys back out. Kept snake_case so both stacks\n * agree without a translation layer.\n */\nexport const REFERENCE_METADATA_KEYS = {\n /** Metadata key carrying the reference id. */\n id: \"kaboo_id\",\n /** Metadata key carrying the reference kind. */\n kind: \"kaboo_kind\",\n /** Metadata key carrying the reference display name. */\n name: \"kaboo_name\",\n} as const;\n\n/** AG-UI `state` key under which object-transport references travel. */\nexport const REFERENCES_STATE_KEY = \"kaboo_references\";\n\n/**\n * How a reference reaches the agent.\n *\n * - `attachment` — a file/blob (pdf, image, csv, …). Serialized as a CopilotKit\n * `InputContent` part; its bytes are resolvable server-side. Files are the\n * only blob-capable transport.\n * - `object` — a pointer to a custom entity (table, dashboard, ticket, …).\n * Serialized into `state.kaboo_references`; resolved by the app's own MCP\n * tool. Never carries bytes.\n */\nexport type ReferenceTransport = \"attachment\" | \"object\";\n\n/**\n * One selectable item surfaced by a {@link ReferenceProvider} in the `@` menu.\n * `data` is provider-defined and threaded back to {@link ReferenceProvider.toReference}.\n */\nexport interface ReferenceItem<T = unknown> {\n /** Stable id for the underlying entity (provider scope). */\n id: string;\n /** Human label shown in the menu and used as the default mention chip text. */\n label: string;\n /** Optional secondary line (e.g. a path, table schema, owner). */\n description?: string;\n /** Provider-defined payload passed to {@link ReferenceProvider.toReference}. */\n data?: T;\n}\n\n/**\n * A reference that has been selected and is pending on the composer, before it\n * is serialized onto the outgoing message.\n */\nexport type PendingReference =\n | {\n /** Blob-capable transport discriminant. */\n transport: \"attachment\";\n /** Reference kind (e.g. `\"file\"`). */\n kind: string;\n /** Stable reference id, shared with the backend manifest. */\n id: string;\n /** File name shown on the chip. */\n name: string;\n /** MIME type of the file. */\n mimeType: string;\n /** Byte source: a fetchable URL, or inline base64. */\n source:\n | {\n /** A fetchable URL (preferred; keeps transport and log small). */\n url: string;\n }\n | {\n /** Inline base64 payload (fallback for small files). */\n data: string;\n };\n }\n | {\n /** Pointer-only transport discriminant. */\n transport: \"object\";\n /** Reference kind (e.g. `\"table\"`), resolved by your MCP tool. */\n kind: string;\n /** Stable reference id, shared with the backend manifest. */\n id: string;\n /** Label shown on the chip. */\n name: string;\n /** Arbitrary extra context threaded through to the resolver. */\n meta?: Record<string, unknown>;\n };\n\n/**\n * A pluggable entry in the `@` reference menu. File upload ships as a built-in\n * provider (see `uploadProvider`); apps register their own for entities/actions\n * (tables, dashboards, tickets, …).\n *\n * A provider is either *searchable* (supplies {@link search} so its items list\n * live in the menu) or *action-only* (omits {@link search}; selecting its group\n * row runs {@link onSelect}, e.g. opening a file picker).\n */\nexport interface ReferenceProvider<T = unknown> {\n /** Stable provider id, e.g. `\"upload\" | \"table\" | \"dashboard\"`. */\n id: string;\n /** Group heading shown in the `@` menu. */\n label: string;\n /** Optional icon rendered beside the group heading. */\n icon?: ReactNode;\n /**\n * Return the items to list for the current query. Omit for an action-only\n * provider (its group row triggers {@link onSelect} directly).\n */\n search?: (query: string) => ReferenceItem<T>[] | Promise<ReferenceItem<T>[]>;\n /** Custom row renderer; falls back to `label` + `description`. */\n renderItem?: (item: ReferenceItem<T>) => ReactNode;\n /**\n * Side effect when an item (or the action-only group row) is chosen, e.g.\n * opening a file dialog or running an action. Called before {@link toReference}.\n */\n onSelect?: (item: ReferenceItem<T>) => void | Promise<void>;\n /**\n * How a chosen item serializes onto the message. Omit for pure actions that\n * produce their reference asynchronously (e.g. upload, via its own callback).\n */\n toReference?: (item: ReferenceItem<T>) => PendingReference;\n}\n","import type { InputContent } from \"@copilotkit/shared\";\nimport {\n REFERENCE_METADATA_KEYS,\n REFERENCES_STATE_KEY,\n type PendingReference,\n} from \"./types\";\n\nexport type { PendingReference } from \"./types\";\n\n/**\n * Mint a stable reference id. Client-minted so the same id travels in the\n * message/state AND is what the agent later reads from the manifest and passes\n * to a tool. Prefixed by kind for readability in logs/manifests.\n */\nexport function mintReferenceId(kind: string): string {\n const rand =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : Math.random().toString(36).slice(2);\n return `${kind}_${rand}`;\n}\n\n/**\n * The textual marker kept at a reference's mention position in the message\n * text, so the model sees *where* each reference was cited (correlated to the\n * manifest by id). Chip UIs render `@name`; the serialized text keeps this\n * token.\n */\nexport function referenceMarker(ref: PendingReference): string {\n return `[${ref.kind}:${ref.id}]`;\n}\n\n/** AG-UI `AttachmentModality` for a mime type (best-effort; documents are the fallback). */\nfunction modalityFor(mimeType: string): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\n/**\n * Turn an `attachment`-transport reference into a CopilotKit `InputContent`\n * part, stamping the reference id/kind/name into `metadata` so kaboo-workflows\n * can key its registry off the same id the model reads from the manifest.\n */\nexport function attachmentToInputContent(\n ref: Extract<PendingReference, { transport: \"attachment\" }>,\n): InputContent {\n const source =\n \"url\" in ref.source\n ? { type: \"url\" as const, value: ref.source.url, mimeType: ref.mimeType }\n : { type: \"data\" as const, value: ref.source.data, mimeType: ref.mimeType };\n return {\n type: modalityFor(ref.mimeType),\n source,\n metadata: {\n [REFERENCE_METADATA_KEYS.id]: ref.id,\n [REFERENCE_METADATA_KEYS.kind]: ref.kind,\n [REFERENCE_METADATA_KEYS.name]: ref.name,\n filename: ref.name,\n },\n } as InputContent;\n}\n\n/** The serialized shape of an object reference inside `state.kaboo_references`. */\nexport interface SerializedObjectReference {\n /** Reference kind (e.g. `\"table\"`), resolved by the app's MCP tool. */\n kind: string;\n /** Stable reference id, shared with the backend manifest. */\n id: string;\n /** Human-readable label. */\n name: string;\n /** Arbitrary extra context threaded through to the resolver. */\n meta?: Record<string, unknown>;\n}\n\n/** Project an `object`-transport reference to its wire shape. */\nexport function objectToStateEntry(\n ref: Extract<PendingReference, { transport: \"object\" }>,\n): SerializedObjectReference {\n return { kind: ref.kind, id: ref.id, name: ref.name, meta: ref.meta };\n}\n\n/** The fully serialized outgoing payload derived from a set of pending references. */\nexport interface SerializedReferences {\n /** `InputContent` parts for attachment-transport references (append after text). */\n attachmentParts: InputContent[];\n /** Object-transport references destined for `state.kaboo_references`. */\n objectReferences: SerializedObjectReference[];\n}\n\n/** Split + serialize pending references into attachment parts and object-state entries. */\nexport function serializeReferences(refs: PendingReference[]): SerializedReferences {\n const attachmentParts: InputContent[] = [];\n const objectReferences: SerializedObjectReference[] = [];\n for (const ref of refs) {\n if (ref.transport === \"attachment\") {\n attachmentParts.push(attachmentToInputContent(ref));\n } else {\n objectReferences.push(objectToStateEntry(ref));\n }\n }\n return { attachmentParts, objectReferences };\n}\n\n/**\n * Merge object references into an existing AG-UI `state` under\n * {@link REFERENCES_STATE_KEY}. Returns a new object; empty input clears the key\n * so a prior turn's references never leak into the next run.\n */\nexport function withReferenceState(\n state: Record<string, unknown> | undefined,\n objectReferences: SerializedObjectReference[],\n): Record<string, unknown> {\n const next = { ...(state ?? {}) };\n if (objectReferences.length > 0) {\n next[REFERENCES_STATE_KEY] = objectReferences;\n } else {\n delete next[REFERENCES_STATE_KEY];\n }\n return next;\n}\n\n/**\n * Build the multimodal `content` array for a user message: the typed text\n * (already containing positional markers) followed by the attachment parts.\n * AG-UI content is an ordered array, so parts are appended after the text.\n */\nexport function buildUserContent(\n text: string,\n attachmentParts: InputContent[],\n): InputContent[] {\n const parts: InputContent[] = [];\n if (text.length > 0) parts.push({ type: \"text\", text } as InputContent);\n parts.push(...attachmentParts);\n return parts;\n}\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type ComponentProps,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { CopilotChatInput, useAgent, useCopilotChatConfiguration } from \"@copilotkit/react-core/v2\";\nimport { useReferences } from \"./ReferencesProvider\";\nimport { isUploadProvider, uploadFileToReference, UPLOAD_MARKER } from \"./uploadProvider\";\nimport { buildUserContent, serializeReferences } from \"./serialize\";\nimport type { PendingReference, ReferenceItem, ReferenceProvider } from \"./types\";\n\ntype CopilotInputProps = ComponentProps<typeof CopilotChatInput>;\ntype TextAreaSlotProps = ComponentProps<typeof CopilotChatInput.TextArea>;\n\n/**\n * Props for {@link KabooReferenceInput}. This is a drop-in value for\n * `<CopilotChat input={…}>`, so it receives every prop CopilotKit hands the\n * input slot (value, onChange, onSubmitMessage, …) plus a couple of\n * kaboo-specific knobs.\n */\nexport interface KabooReferenceInputProps extends CopilotInputProps {\n /** Character that opens the reference popover from the editor. Default `\"@\"`. */\n trigger?: string;\n}\n\n// One row in the shared popover.\ntype Row =\n | { kind: \"action\"; group: string; provider: ReferenceProvider }\n | { kind: \"item\"; group: string; provider: ReferenceProvider; item: ReferenceItem };\n\nconst CHIP_CLASS = \"kaboo-chip\";\nconst NBSP = \"\\u00A0\";\n\nconst AT_SVG =\n '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94\"/></svg>';\nconst FILE_SVG =\n '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><path d=\"M14 2v6h6\"/></svg>';\nconst X_SVG =\n '<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18M6 6l12 12\"/></svg>';\n\nconst AttachIcon = (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </svg>\n);\nconst AtIcon = (\n <svg width=\"16\" height=\"16\" 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 PlusIcon = (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M5 12h14M12 5v14\" />\n </svg>\n);\nconst SearchIcon = (\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n);\n\ninterface PopoverPosition {\n left: number;\n bottom: number;\n width: number;\n}\n\nconst POPOVER_WIDTH = 320;\nconst VIEWPORT_MARGIN = 8;\nconst ANCHOR_GAP = 6;\n\n/** Place the popover just above an anchor rect, left-aligned and clamped on-screen. */\nfunction computePosition(rect: DOMRect | null): PopoverPosition | null {\n if (!rect) return null;\n const width = Math.min(POPOVER_WIDTH, window.innerWidth - VIEWPORT_MARGIN * 2);\n const left = Math.max(\n VIEWPORT_MARGIN,\n Math.min(rect.left, window.innerWidth - width - VIEWPORT_MARGIN),\n );\n return { left, bottom: window.innerHeight - rect.top + ANCHOR_GAP, width };\n}\n\nfunction isImageMime(mime: string): boolean {\n return mime.startsWith(\"image/\");\n}\n\nfunction previewSrc(ref: Extract<PendingReference, { transport: \"attachment\" }>): string {\n return \"url\" in ref.source ? ref.source.url : `data:${ref.mimeType};base64,${ref.source.data}`;\n}\n\n/** Serialize the editor DOM to the plain string CopilotKit sends: text with\n * object chips as `@name` and file chips as their filename. */\nfunction serializeEditor(root: HTMLElement): string {\n let out = \"\";\n const walk = (node: ChildNode) => {\n if (node.nodeType === Node.TEXT_NODE) {\n out += node.textContent ?? \"\";\n return;\n }\n if (node instanceof HTMLElement) {\n if (node.classList.contains(CHIP_CLASS)) {\n const name = node.dataset.name ?? \"\";\n out += node.dataset.transport === \"object\" ? `@${name}` : name;\n return;\n }\n if (node.tagName === \"BR\") {\n out += \"\\n\";\n return;\n }\n if (node.tagName === \"DIV\" && out.length > 0 && !out.endsWith(\"\\n\")) out += \"\\n\";\n node.childNodes.forEach(walk);\n }\n };\n root.childNodes.forEach(walk);\n return out.replace(new RegExp(NBSP, \"g\"), \" \");\n}\n\n/**\n * A `<CopilotChat input={…}>` slot that keeps CopilotKit's native input chrome\n * (send button, disclaimer, theme, layout) but replaces the plain textarea with\n * a lightweight rich editor. References — your objects (via `@`) and files (via\n * the `+` button or the \"attach a file\" row) — render as interactive inline\n * chips: click a chip to swap it for another, or its `×` to remove it. The `+`\n * and `@` triggers open the *same* searchable popover. Object references ride\n * `state.kaboo_references` (agent sees them inline as `@name`); files ride the\n * message as attachment parts (agent is made aware via the manifest). On submit\n * the editor builds the multimodal message and runs the agent.\n *\n * @example\n * ```tsx\n * <KabooProvider references={[uploadProvider({ onUpload }), tableProvider]} …>\n * <CopilotChat input={KabooReferenceInput} />\n * </KabooProvider>\n * ```\n */\nexport function KabooReferenceInput({ trigger = \"@\", ...inputProps }: KabooReferenceInputProps) {\n const {\n providers,\n pending,\n addReference,\n removeReference,\n clearReferences,\n recordMessageReferences,\n } = useReferences();\n const config = useCopilotChatConfiguration();\n const configAgentId = (config as { agentId?: string } | null)?.agentId;\n const { agent } = useAgent(configAgentId ? { agentId: configAgentId } : undefined);\n const placeholder =\n (config as { labels?: { chatInputPlaceholder?: string } } | null)?.labels\n ?.chatInputPlaceholder ?? \"Type a message...\";\n\n const wrapRef = useRef<HTMLDivElement>(null);\n const trayRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const editorRef = useRef<HTMLDivElement | null>(null);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const addBtnRef = useRef<HTMLButtonElement | null>(null);\n const searchRef = useRef<HTMLInputElement | null>(null);\n const nativeChangeRef = useRef<((e: ChangeEvent<HTMLTextAreaElement>) => void) | undefined>(undefined);\n const anchorRef = useRef<() => DOMRect | null>(() => null);\n // The `@…` token being edited (contentEditable text node + start offset).\n const tokenRef = useRef<{ node: Text; start: number } | null>(null);\n // An inline chip currently being replaced (click-to-swap), if any.\n const replacingRef = useRef<HTMLElement | null>(null);\n // A tray reference id currently being replaced (click-to-swap), if any.\n const replacingTrayIdRef = useRef<string | null>(null);\n // Ids of references rendered inline (via `@`); everything else lives in the\n // tray. `+` never inserts inline — that's what distinguishes the two.\n const inlineIdsRef = useRef<Set<string>>(new Set());\n // Where the next selection lands: inline (from `@`) or the tray (from `+`).\n const commitTargetRef = useRef<\"inline\" | \"tray\">(\"inline\");\n\n const [open, setOpen] = useState(false);\n const [rows, setRows] = useState<Row[]>([]);\n const [active, setActive] = useState(0);\n const [query, setQuery] = useState(\"\");\n const [mode, setMode] = useState<\"token\" | \"menu\">(\"token\");\n const [pos, setPos] = useState<PopoverPosition | null>(null);\n\n const placeholderRef = useRef(placeholder);\n placeholderRef.current = placeholder;\n\n // Toggle the placeholder (contentEditable has no native one) via a DOM\n // attribute, so the editor node never has to re-render/remount.\n const markEmpty = useCallback(() => {\n const root = editorRef.current;\n if (!root) return;\n const isEmpty =\n root.querySelector(`.${CHIP_CLASS}`) === null && (root.textContent ?? \"\").trim().length === 0;\n root.dataset.empty = isEmpty ? \"true\" : \"false\";\n }, []);\n\n const uploadProviderDef = useMemo(() => providers.find(isUploadProvider), [providers]);\n const searchable = useMemo(() => providers.filter((p) => typeof p.search === \"function\"), [providers]);\n const actionProviders = useMemo(\n () => providers.filter((p) => typeof p.search !== \"function\"),\n [providers],\n );\n\n const buildRows = useCallback(\n async (q: string): Promise<Row[]> => {\n const next: Row[] = [];\n for (const provider of actionProviders) {\n const label = isUploadProvider(provider) ? \"Attach\" : provider.label;\n if (!q || label.toLowerCase().includes(q.toLowerCase())) {\n next.push({ kind: \"action\", group: label, provider });\n }\n }\n for (const provider of searchable) {\n try {\n const items = await provider.search!(q);\n for (const item of items) next.push({ kind: \"item\", group: provider.label, provider, item });\n } catch {\n /* a provider's search failure shouldn't break the menu */\n }\n }\n return next;\n },\n [actionProviders, searchable],\n );\n\n const refresh = useCallback(\n async (q: string) => {\n const next = await buildRows(q);\n setRows(next);\n setActive(0);\n },\n [buildRows],\n );\n\n const close = useCallback(() => {\n setOpen(false);\n setRows([]);\n setQuery(\"\");\n tokenRef.current = null;\n replacingRef.current = null;\n replacingTrayIdRef.current = null;\n }, []);\n\n // Push the serialized editor text into CopilotKit's controlled value.\n const emit = useCallback(() => {\n const root = editorRef.current;\n if (!root) return;\n const text = serializeEditor(root);\n markEmpty();\n nativeChangeRef.current?.({ target: { value: text } } as ChangeEvent<HTMLTextAreaElement>);\n }, [markEmpty]);\n\n // Drop any *inline* reference whose chip the user deleted by editing. Tray\n // references (added via `+`) are never in the editor DOM, so leave them be.\n const reconcile = useCallback(() => {\n const root = editorRef.current;\n if (!root) return;\n const live = new Set(\n Array.from(root.querySelectorAll<HTMLElement>(`.${CHIP_CLASS}`)).map((c) => c.dataset.refId),\n );\n for (const id of Array.from(inlineIdsRef.current)) {\n if (!live.has(id)) {\n inlineIdsRef.current.delete(id);\n removeReference(id);\n }\n }\n }, [removeReference]);\n\n const focusEditor = useCallback(() => editorRef.current?.focus(), []);\n\n // Build a chip DOM node with icon/preview, label, and a remove button.\n const createChip = useCallback((ref: PendingReference): HTMLElement => {\n const chip = document.createElement(\"span\");\n chip.className = `${CHIP_CLASS} ${CHIP_CLASS}-${ref.transport}`;\n chip.contentEditable = \"false\";\n chip.dataset.refId = ref.id;\n chip.dataset.kind = ref.kind;\n chip.dataset.name = ref.name;\n chip.dataset.transport = ref.transport;\n chip.title = ref.name;\n\n if (ref.transport === \"attachment\" && isImageMime(ref.mimeType)) {\n const img = document.createElement(\"img\");\n img.className = \"kaboo-chip-thumb\";\n img.src = previewSrc(ref);\n img.alt = ref.name;\n chip.appendChild(img);\n } else {\n const ic = document.createElement(\"span\");\n ic.className = \"kaboo-chip-ic\";\n ic.innerHTML = ref.transport === \"object\" ? AT_SVG : FILE_SVG;\n chip.appendChild(ic);\n }\n\n const label = document.createElement(\"span\");\n label.className = \"kaboo-chip-label\";\n label.textContent = ref.name;\n chip.appendChild(label);\n\n const x = document.createElement(\"button\");\n x.type = \"button\";\n x.className = \"kaboo-chip-x\";\n x.setAttribute(\"aria-label\", `Remove ${ref.name}`);\n x.innerHTML = X_SVG;\n x.addEventListener(\"mousedown\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n handlersRef.current.removeChip(chip);\n });\n chip.appendChild(x);\n\n chip.addEventListener(\"mousedown\", (e) => {\n if (e.target === x || x.contains(e.target as Node)) return;\n e.preventDefault();\n handlersRef.current.replaceChip(chip);\n });\n return chip;\n }, []);\n\n // Insert a node at the current selection (falls back to end of the editor).\n const insertAtCaret = useCallback((node: Node) => {\n const root = editorRef.current;\n if (!root) return;\n const sel = window.getSelection();\n let range: Range;\n if (sel && sel.rangeCount > 0 && root.contains(sel.focusNode)) {\n range = sel.getRangeAt(0);\n } else {\n range = document.createRange();\n range.selectNodeContents(root);\n range.collapse(false);\n }\n range.collapse(false);\n const space = document.createTextNode(NBSP);\n range.insertNode(space);\n range.insertNode(node);\n const after = document.createRange();\n after.setStartAfter(space);\n after.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(after);\n }, []);\n\n // Place a chip: replacing an existing one, dropping an `@` token, or at caret.\n const placeChip = useCallback(\n (ref: PendingReference) => {\n const chip = createChip(ref);\n const replacing = replacingRef.current;\n if (replacing) {\n const oldId = replacing.dataset.refId;\n if (oldId && oldId !== ref.id) removeReference(oldId);\n replacing.replaceWith(chip);\n replacingRef.current = null;\n } else if (tokenRef.current) {\n const { node, start } = tokenRef.current;\n const sel = window.getSelection();\n const range = document.createRange();\n range.setStart(node, Math.min(start, node.textContent?.length ?? 0));\n if (sel && sel.focusNode && editorRef.current?.contains(sel.focusNode)) {\n range.setEnd(sel.focusNode, sel.focusOffset);\n } else {\n range.setEnd(node, node.textContent?.length ?? 0);\n }\n range.deleteContents();\n const space = document.createTextNode(NBSP);\n range.insertNode(space);\n range.insertNode(chip);\n const after = document.createRange();\n after.setStartAfter(space);\n after.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(after);\n tokenRef.current = null;\n } else {\n insertAtCaret(chip);\n }\n emit();\n },\n [createChip, insertAtCaret, removeReference, emit],\n );\n\n // Stage a chosen reference either inline (in the editor) or in the tray.\n const commit = useCallback(\n (ref: PendingReference, target: \"inline\" | \"tray\") => {\n addReference(ref);\n if (target === \"inline\") {\n inlineIdsRef.current.add(ref.id);\n placeChip(ref);\n } else {\n const oldId = replacingTrayIdRef.current;\n if (oldId && oldId !== ref.id) removeReference(oldId);\n replacingTrayIdRef.current = null;\n inlineIdsRef.current.delete(ref.id);\n }\n },\n [addReference, placeChip, removeReference],\n );\n\n // Open the file picker; the chosen file is uploaded then staged.\n const openFilePicker = useCallback(\n (provider: ReferenceProvider, target: \"inline\" | \"tray\") => {\n const input = fileInputRef.current;\n if (!input) return;\n const cfg = isUploadProvider(provider) ? provider[UPLOAD_MARKER] : {};\n input.accept = (cfg as { accept?: string }).accept ?? \"\";\n input.onchange = async () => {\n const file = input.files?.[0];\n input.value = \"\";\n if (!file) return;\n try {\n const ref = await uploadFileToReference(file, cfg as Parameters<typeof uploadFileToReference>[1]);\n commit(ref, target);\n } catch (err) {\n console.error(\"[kaboo] upload failed\", err);\n }\n };\n input.click();\n },\n [commit],\n );\n\n // Remove the \"@…\" token that opened the menu (before an async upload).\n const stripToken = useCallback(() => {\n const t = tokenRef.current;\n if (!t) return;\n const sel = window.getSelection();\n const range = document.createRange();\n range.setStart(t.node, Math.min(t.start, t.node.textContent?.length ?? 0));\n if (sel?.focusNode && editorRef.current?.contains(sel.focusNode)) {\n range.setEnd(sel.focusNode, sel.focusOffset);\n } else {\n range.setEnd(t.node, t.node.textContent?.length ?? 0);\n }\n range.deleteContents();\n emit();\n }, [emit]);\n\n const select = useCallback(\n async (row: Row) => {\n // Capture target before close() resets it.\n const target = commitTargetRef.current;\n if (row.kind === \"action\") {\n const provider = row.provider;\n if (target === \"inline\") stripToken();\n close();\n if (isUploadProvider(provider)) openFilePicker(provider, target);\n else await provider.onSelect?.({ id: provider.id, label: provider.label });\n focusEditor();\n return;\n }\n // Commit (consumes token/replacing) *before* close() clears them.\n await row.provider.onSelect?.(row.item);\n const ref = row.provider.toReference?.(row.item);\n if (ref) commit(ref, target);\n close();\n focusEditor();\n },\n [stripToken, close, openFilePicker, focusEditor, commit],\n );\n\n // Open the popover anchored at the `@` caret.\n const openFromToken = useCallback(\n (q: string) => {\n commitTargetRef.current = \"inline\";\n replacingRef.current = null;\n replacingTrayIdRef.current = null;\n anchorRef.current = () => {\n const t = tokenRef.current;\n return t ? caretRectFor(t.node, t.start) : null;\n };\n setMode(\"token\");\n setQuery(q);\n setPos(computePosition(anchorRef.current()));\n setOpen(true);\n void refresh(q);\n },\n [refresh],\n );\n\n // Toggle the popover from the `+` button (menu mode: has its own search box).\n const toggleFromButton = useCallback(() => {\n setOpen((prev) => {\n if (prev) {\n close();\n return false;\n }\n commitTargetRef.current = \"tray\";\n tokenRef.current = null;\n replacingRef.current = null;\n replacingTrayIdRef.current = null;\n anchorRef.current = () => addBtnRef.current?.getBoundingClientRect() ?? null;\n setMode(\"menu\");\n setQuery(\"\");\n setPos(computePosition(anchorRef.current()));\n void refresh(\"\");\n return true;\n });\n }, [refresh, close]);\n\n const onSearch = useCallback(\n (value: string) => {\n setQuery(value);\n void refresh(value);\n },\n [refresh],\n );\n\n const handleNavKey = useCallback(\n (e: ReactKeyboardEvent): boolean => {\n if (!open || rows.length === 0) return false;\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActive((a) => (a + 1) % rows.length);\n return true;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActive((a) => (a - 1 + rows.length) % rows.length);\n return true;\n }\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n e.preventDefault();\n void select(rows[active]);\n return true;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n close();\n focusEditor();\n return true;\n }\n return false;\n },\n [open, rows, active, select, close, focusEditor],\n );\n\n // Click an inline chip to swap it: open the menu anchored to that chip.\n const replaceChip = useCallback(\n (chip: HTMLElement) => {\n commitTargetRef.current = \"inline\";\n replacingRef.current = chip;\n replacingTrayIdRef.current = null;\n tokenRef.current = null;\n anchorRef.current = () => chip.getBoundingClientRect();\n setMode(\"menu\");\n setQuery(\"\");\n setPos(computePosition(chip.getBoundingClientRect()));\n setOpen(true);\n void refresh(\"\");\n },\n [refresh],\n );\n\n // Click a tray chip to swap it: open the menu anchored to that chip.\n const replaceTrayChip = useCallback(\n (id: string, anchorEl: HTMLElement) => {\n commitTargetRef.current = \"tray\";\n replacingTrayIdRef.current = id;\n replacingRef.current = null;\n tokenRef.current = null;\n anchorRef.current = () => anchorEl.getBoundingClientRect();\n setMode(\"menu\");\n setQuery(\"\");\n setPos(computePosition(anchorEl.getBoundingClientRect()));\n setOpen(true);\n void refresh(\"\");\n },\n [refresh],\n );\n\n const removeChip = useCallback(\n (chip: HTMLElement) => {\n const id = chip.dataset.refId;\n const next = chip.nextSibling;\n chip.remove();\n if (next && next.nodeType === Node.TEXT_NODE && next.textContent === NBSP) next.remove();\n if (id) {\n inlineIdsRef.current.delete(id);\n removeReference(id);\n }\n emit();\n focusEditor();\n },\n [removeReference, emit, focusEditor],\n );\n\n const handlersRef = useRef({ removeChip, replaceChip });\n handlersRef.current = { removeChip, replaceChip };\n\n const ctl = { open, rows, active, trigger, openFromToken, toggleFromButton, close, handleNavKey };\n const ctlRef = useRef(ctl);\n ctlRef.current = ctl;\n\n // Read the `@…` token at the caret, if any.\n const readToken = useCallback((): { node: Text; start: number; query: string } | null => {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0 || !sel.isCollapsed) return null;\n const node = sel.focusNode;\n if (!node || node.nodeType !== Node.TEXT_NODE) return null;\n const text = node.textContent ?? \"\";\n const before = text.slice(0, sel.focusOffset);\n const at = before.lastIndexOf(ctlRef.current.trigger);\n if (at < 0) return null;\n const prev = at > 0 ? before[at - 1] : \"\";\n if (prev && !/\\s/.test(prev)) return null;\n const q = before.slice(at + 1);\n if (/\\s/.test(q)) return null;\n return { node: node as Text, start: at, query: q };\n }, []);\n\n const onEditorInput = useCallback(() => {\n reconcile();\n emit();\n const token = readToken();\n if (token) {\n tokenRef.current = { node: token.node, start: token.start };\n const c = ctlRef.current;\n if (!c.open || mode === \"token\") openFromToken(token.query);\n else {\n setQuery(token.query);\n void refresh(token.query);\n }\n } else if (ctlRef.current.open && mode === \"token\") {\n close();\n }\n }, [reconcile, emit, readToken, openFromToken, refresh, mode, close]);\n\n const TextAreaSlot = useMemo(\n () =>\n forwardRef<HTMLTextAreaElement, TextAreaSlotProps>(function KabooRefEditor(props, ref) {\n const { onChange, onKeyDown, className, autoFocus } = props as TextAreaSlotProps & {\n className?: string;\n autoFocus?: boolean;\n };\n nativeChangeRef.current = onChange as\n | ((e: ChangeEvent<HTMLTextAreaElement>) => void)\n | undefined;\n\n const setRefs = (node: HTMLDivElement | null) => {\n editorRef.current = node;\n if (typeof ref === \"function\") ref(node as unknown as HTMLTextAreaElement);\n else if (ref) (ref as RefObject<HTMLTextAreaElement | null>).current = node as unknown as HTMLTextAreaElement;\n };\n\n const handleKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>) => {\n if (ctlRef.current.handleNavKey(e)) return;\n onKeyDown?.(e as unknown as ReactKeyboardEvent<HTMLTextAreaElement>);\n };\n\n return (\n <div\n ref={setRefs}\n role=\"textbox\"\n aria-multiline=\"true\"\n tabIndex={0}\n contentEditable\n suppressContentEditableWarning\n data-placeholder={placeholderRef.current}\n className={`kaboo-ref-editor cpk:bg-transparent cpk:outline-none cpk:antialiased cpk:leading-relaxed cpk:text-[16px] ${className ?? \"\"}`}\n data-empty=\"true\"\n autoFocus={autoFocus}\n onInput={onEditorInput}\n onKeyDown={handleKeyDown}\n />\n );\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n const AddMenuButtonSlot = useMemo(\n () =>\n function KabooRefAddButton(props: { disabled?: boolean }) {\n return (\n <button\n ref={addBtnRef}\n type=\"button\"\n className=\"kaboo-ref-add\"\n aria-label=\"Add attachment or reference\"\n aria-haspopup=\"listbox\"\n aria-expanded={ctlRef.current.open}\n disabled={props.disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => ctlRef.current.toggleFromButton()}\n >\n {PlusIcon}\n </button>\n );\n },\n [],\n );\n\n // Dismiss on outside-click / Escape (menu is portaled outside the wrapper).\n useEffect(() => {\n if (!open) return;\n const onDocMouseDown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (wrapRef.current?.contains(target) || menuRef.current?.contains(target)) return;\n close();\n };\n const onDocKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") close();\n };\n document.addEventListener(\"mousedown\", onDocMouseDown);\n document.addEventListener(\"keydown\", onDocKey);\n return () => {\n document.removeEventListener(\"mousedown\", onDocMouseDown);\n document.removeEventListener(\"keydown\", onDocKey);\n };\n }, [open, close]);\n\n // Keep the portaled menu pinned to its anchor as layout shifts.\n useEffect(() => {\n if (!open) return;\n const reposition = () => setPos(computePosition(anchorRef.current()));\n window.addEventListener(\"resize\", reposition);\n window.addEventListener(\"scroll\", reposition, true);\n return () => {\n window.removeEventListener(\"resize\", reposition);\n window.removeEventListener(\"scroll\", reposition, true);\n };\n }, [open]);\n\n useLayoutEffect(() => {\n if (!open) return;\n setPos(computePosition(anchorRef.current()));\n if (mode === \"menu\") searchRef.current?.focus();\n }, [open, mode, rows.length]);\n\n // Clear staged references once a run has actually started (not on send), so\n // object refs on `state.kaboo_references` survive the in-flight run.\n useEffect(() => {\n const target = agent as unknown as {\n subscribe?: (s: Record<string, unknown>) => { unsubscribe?: () => void };\n } | null;\n if (!target || typeof target.subscribe !== \"function\") return;\n const sub = target.subscribe({ onRunStartedEvent: () => clearReferences() });\n return () => sub?.unsubscribe?.();\n }, [agent, clearReferences]);\n\n // Clear the editor DOM when CopilotKit resets the value (after a send).\n useEffect(() => {\n const root = editorRef.current;\n if (!root) return;\n if ((inputProps.value ?? \"\") === \"\" && root.childNodes.length > 0) {\n root.textContent = \"\";\n markEmpty();\n }\n }, [inputProps.value, markEmpty]);\n\n // Build the multimodal message and run the agent ourselves (files ride as\n // attachment parts; object refs travel on state.kaboo_references).\n const handleSubmit = useCallback(\n (message: string) => {\n const text = message.trim();\n const { attachmentParts } = serializeReferences(pending);\n const target = agent as unknown as {\n addMessage?: (m: unknown) => void;\n runAgent?: () => Promise<unknown> | void;\n } | null;\n if (text.length === 0 && attachmentParts.length === 0) return;\n if (!target?.addMessage || !target.runAgent) {\n // Fallback: let CopilotKit's own send handle plain text.\n (inputProps.onSubmitMessage as ((m: string) => void) | undefined)?.(message);\n close();\n return;\n }\n const content =\n attachmentParts.length > 0 ? buildUserContent(text, attachmentParts) : text;\n const id =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : Math.random().toString(36).slice(2);\n // Object references ride state, not the message content, so record them\n // against this message id for the bubble to render them as chips.\n recordMessageReferences(\n id,\n pending.filter((r) => r.transport === \"object\"),\n );\n target.addMessage({ id, role: \"user\", content });\n void Promise.resolve(target.runAgent()).catch((err) =>\n console.error(\"[kaboo] runAgent failed\", err),\n );\n const root = editorRef.current;\n if (root) root.textContent = \"\";\n markEmpty();\n close();\n },\n [pending, agent, inputProps, close, markEmpty, recordMessageReferences],\n );\n\n // Tray = staged references not rendered inline (added via `+`).\n const trayRefs = pending.filter((r) => !inlineIdsRef.current.has(r.id));\n\n // CopilotKit centers the input pill independently of our wrapper, so align\n // the tray's box to the pill (`.copilotKitInput`) rather than the wrapper.\n useLayoutEffect(() => {\n const tray = trayRef.current;\n const wrap = wrapRef.current;\n if (!tray || !wrap) return;\n const align = () => {\n const pill = wrap.querySelector<HTMLElement>(\".copilotKitInput\");\n if (!pill) return;\n const pr = pill.getBoundingClientRect();\n const wr = wrap.getBoundingClientRect();\n tray.style.marginLeft = `${Math.max(0, pr.left - wr.left)}px`;\n tray.style.width = `${pr.width}px`;\n };\n align();\n window.addEventListener(\"resize\", align);\n return () => window.removeEventListener(\"resize\", align);\n }, [trayRefs.length]);\n\n return (\n <div ref={wrapRef} className=\"kaboo-ref-input\">\n <input ref={fileInputRef} type=\"file\" className=\"kaboo-ref-file\" tabIndex={-1} aria-hidden=\"true\" />\n {trayRefs.length > 0 && (\n <div ref={trayRef} className=\"kaboo-ref-tray\">\n {trayRefs.map((r) => (\n <TrayChip\n key={r.id}\n reference={r}\n onRemove={() => removeReference(r.id)}\n onReplace={(el) => replaceTrayChip(r.id, el)}\n />\n ))}\n </div>\n )}\n <CopilotChatInput\n {...inputProps}\n onSubmitMessage={handleSubmit}\n textArea={TextAreaSlot}\n addMenuButton={AddMenuButtonSlot}\n />\n {open &&\n pos &&\n createPortal(\n <ReferencePopover\n ref={menuRef}\n pos={pos}\n rows={rows}\n active={active}\n query={query}\n mode={mode}\n searchRef={searchRef}\n hasUpload={!!uploadProviderDef}\n onSearch={onSearch}\n onSearchKeyDown={handleNavKey}\n onHover={setActive}\n onPick={select}\n />,\n document.body,\n )}\n </div>\n );\n}\n\n/** A staged reference shown in the tray (added via `+`, not inline). */\nfunction TrayChip({\n reference,\n onRemove,\n onReplace,\n}: {\n reference: PendingReference;\n onRemove: () => void;\n onReplace: (anchor: HTMLElement) => void;\n}) {\n const ref = useRef<HTMLSpanElement>(null);\n const isImage = reference.transport === \"attachment\" && isImageMime(reference.mimeType);\n return (\n <span\n ref={ref}\n className={`kaboo-chip ${CHIP_CLASS}-${reference.transport} kaboo-chip-tray`}\n title={reference.name}\n role=\"button\"\n tabIndex={0}\n onMouseDown={(e) => {\n e.preventDefault();\n if (ref.current) onReplace(ref.current);\n }}\n >\n {isImage ? (\n <img\n className=\"kaboo-chip-thumb\"\n src={previewSrc(reference as Extract<PendingReference, { transport: \"attachment\" }>)}\n alt={reference.name}\n />\n ) : (\n <span className=\"kaboo-chip-ic\">{reference.transport === \"object\" ? AtIcon : AttachIcon}</span>\n )}\n <span className=\"kaboo-chip-label\">{reference.name}</span>\n <button\n type=\"button\"\n className=\"kaboo-chip-x\"\n aria-label={`Remove ${reference.name}`}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onRemove();\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n </span>\n );\n}\n\n/** Caret rect for a text node offset (mirror-measured like getCaretRect). */\nfunction caretRectFor(node: Text, offset: number): DOMRect | null {\n try {\n const range = document.createRange();\n range.setStart(node, Math.min(offset, node.textContent?.length ?? 0));\n range.collapse(true);\n const rect = range.getBoundingClientRect();\n if (rect.top === 0 && rect.left === 0) {\n const parent = node.parentElement;\n return parent ? parent.getBoundingClientRect() : null;\n }\n return rect;\n } catch {\n return null;\n }\n}\n\nconst ReferencePopover = forwardRef<\n HTMLDivElement,\n {\n pos: PopoverPosition;\n rows: Row[];\n active: number;\n query: string;\n mode: \"token\" | \"menu\";\n searchRef: RefObject<HTMLInputElement | null>;\n hasUpload: boolean;\n onSearch: (value: string) => void;\n onSearchKeyDown: (e: ReactKeyboardEvent) => boolean;\n onHover: (i: number) => void;\n onPick: (row: Row) => void;\n }\n>(function ReferencePopover(\n { pos, rows, active, query, mode, searchRef, onSearch, onSearchKeyDown, onHover, onPick },\n ref,\n) {\n return (\n <div\n ref={ref}\n className=\"kaboo-refmenu\"\n role=\"listbox\"\n style={{ left: pos.left, bottom: pos.bottom, width: pos.width }}\n >\n {mode === \"menu\" && (\n <div className=\"kaboo-refmenu-search\">\n <span className=\"kaboo-refmenu-search-icon\">{SearchIcon}</span>\n <input\n ref={searchRef}\n type=\"text\"\n className=\"kaboo-refmenu-search-input\"\n placeholder=\"Search…\"\n value={query}\n onChange={(e) => onSearch(e.target.value)}\n onKeyDown={(e) => onSearchKeyDown(e)}\n />\n </div>\n )}\n {rows.length === 0 && <div className=\"kaboo-refmenu-empty\">No matches</div>}\n {rows.map((row, i) => {\n const key = row.kind === \"action\" ? `action:${row.provider.id}` : `${row.provider.id}:${row.item.id}`;\n const showHeader = i === 0 || rows[i - 1].group !== row.group;\n const isUpload = row.kind === \"action\" && isUploadProvider(row.provider);\n const icon: ReactNode = isUpload\n ? AttachIcon\n : row.kind === \"item\"\n ? (row.provider.icon ?? AtIcon)\n : (row.provider.icon ?? AtIcon);\n const title =\n row.kind === \"action\" ? (isUpload ? \"Attach a file\" : row.provider.label) : row.item.label;\n const subtitle =\n row.kind === \"action\"\n ? isUpload\n ? \"Upload from your device\"\n : undefined\n : row.item.description;\n const custom = row.kind === \"item\" ? row.provider.renderItem?.(row.item) : undefined;\n return (\n <div key={key}>\n {showHeader && <div className=\"kaboo-refmenu-group\">{row.group}</div>}\n <div\n role=\"option\"\n aria-selected={i === active}\n className={`kaboo-refmenu-item${i === active ? \" is-active\" : \"\"}`}\n onMouseEnter={() => onHover(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n onPick(row);\n }}\n >\n <span className=\"kaboo-refmenu-icon\">{icon}</span>\n {custom ?? (\n <span className=\"kaboo-refmenu-text\">\n <span className=\"kaboo-refmenu-title\">{title}</span>\n {subtitle && <span className=\"kaboo-refmenu-sub\">{subtitle}</span>}\n </span>\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n});\n","import type { AttachmentsConfig, AttachmentUploadResult } from \"@copilotkit/shared\";\nimport { REFERENCE_METADATA_KEYS } from \"./types\";\nimport { mintReferenceId, type PendingReference } from \"./serialize\";\nimport type { ReferenceProvider } from \"./types\";\n\n/** Configuration for the built-in file {@link uploadProvider}. */\nexport interface UploadProviderConfig {\n /** Provider id in the `@` menu. Default `\"upload\"`. */\n id?: string;\n /** Group label in the `@` menu. Default `\"Upload\"`. */\n label?: string;\n /** Reference kind stamped on emitted attachments. Default `\"file\"`. */\n kind?: string;\n /** `accept` filter for the file picker (e.g. `\"image/*,.pdf\"`). */\n accept?: string;\n /** Max file size in bytes. Files above this are rejected. Default 20MB. */\n maxSize?: number;\n /**\n * Store the file and return a fetchable source. Return a `url` (presigned or\n * public — the server fetches it with no auth) or inline `data` (base64).\n * When omitted, the file is inlined as base64 (fine for small files/tests,\n * bloats the event log for large ones).\n */\n onUpload?: (file: File) => AttachmentUploadResult | Promise<AttachmentUploadResult>;\n}\n\n/** Internal marker: identifies a {@link ReferenceProvider} produced by {@link uploadProvider}. */\nexport const UPLOAD_MARKER = \"__kabooUpload\" as const;\n\n/** A {@link ReferenceProvider} carrying its resolved upload config for the composer. */\nexport interface UploadReferenceProvider extends ReferenceProvider {\n /** Resolved upload config the composer reads to drive the file picker. */\n [UPLOAD_MARKER]: Required<Pick<UploadProviderConfig, \"kind\" | \"maxSize\">> &\n Pick<UploadProviderConfig, \"accept\" | \"onUpload\">;\n}\n\nconst DEFAULT_MAX_SIZE = 20 * 1024 * 1024;\n\nfunction readAsBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n const result = String(reader.result);\n const comma = result.indexOf(\",\");\n resolve(comma >= 0 ? result.slice(comma + 1) : result);\n };\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * Upload one file and return the pending attachment reference (id minted here).\n * Uses `config.onUpload` when provided, else inlines the bytes as base64.\n */\nexport async function uploadFileToReference(\n file: File,\n config: UploadProviderConfig,\n): Promise<PendingReference> {\n const kind = config.kind ?? \"file\";\n const id = mintReferenceId(kind);\n const maxSize = config.maxSize ?? DEFAULT_MAX_SIZE;\n if (file.size > maxSize) {\n throw new Error(`File \"${file.name}\" exceeds the ${maxSize}-byte limit.`);\n }\n\n if (config.onUpload) {\n const result = await config.onUpload(file);\n const mimeType = result.mimeType ?? file.type ?? \"application/octet-stream\";\n const source =\n result.type === \"url\" ? { url: result.value } : { data: result.value };\n return { transport: \"attachment\", kind, id, name: file.name, mimeType, source };\n }\n\n const data = await readAsBase64(file);\n return {\n transport: \"attachment\",\n kind,\n id,\n name: file.name,\n mimeType: file.type || \"application/octet-stream\",\n source: { data },\n };\n}\n\n/**\n * Built-in file-upload {@link ReferenceProvider}. Action-only: choosing it in\n * the `@` menu opens the file picker; the composer uploads the file (via\n * `onUpload` or base64) and adds an `attachment`-transport reference.\n *\n * @example\n * ```tsx\n * <KabooProvider references={[uploadProvider({ accept: \"image/*,.pdf\", onUpload })]} ...>\n * ```\n */\nexport function uploadProvider(config: UploadProviderConfig = {}): UploadReferenceProvider {\n return {\n id: config.id ?? \"upload\",\n label: config.label ?? \"Upload\",\n [UPLOAD_MARKER]: {\n kind: config.kind ?? \"file\",\n maxSize: config.maxSize ?? DEFAULT_MAX_SIZE,\n accept: config.accept,\n onUpload: config.onUpload,\n },\n };\n}\n\n/** Narrow a provider to an {@link UploadReferenceProvider}. */\nexport function isUploadProvider(\n provider: ReferenceProvider,\n): provider is UploadReferenceProvider {\n return UPLOAD_MARKER in provider;\n}\n\n/**\n * Build a CopilotKit `AttachmentsConfig` from an upload config, wrapping\n * `onUpload` so every uploaded file carries kaboo id/kind/name in its\n * `InputContent` metadata. Pass to `<CopilotChat attachments={...}>` to use\n * CopilotKit's native attachment UI instead of the `@` composer.\n */\nexport function buildAttachmentsConfig(config: UploadProviderConfig = {}): AttachmentsConfig {\n const kind = config.kind ?? \"file\";\n return {\n enabled: true,\n accept: config.accept,\n maxSize: config.maxSize,\n onUpload: async (file: File): Promise<AttachmentUploadResult> => {\n const id = mintReferenceId(kind);\n const kabooMeta = {\n [REFERENCE_METADATA_KEYS.id]: id,\n [REFERENCE_METADATA_KEYS.kind]: kind,\n [REFERENCE_METADATA_KEYS.name]: file.name,\n };\n if (config.onUpload) {\n const result = await config.onUpload(file);\n return { ...result, metadata: { ...(result.metadata ?? {}), ...kabooMeta } };\n }\n const value = await readAsBase64(file);\n return {\n type: \"data\",\n value,\n mimeType: file.type || \"application/octet-stream\",\n metadata: kabooMeta,\n };\n },\n };\n}\n","import { useActivity } from \"../hooks/useActivity\";\nimport { useDrill } from \"../hooks/useDrill\";\nimport { topLevelGroups, directChildren } from \"../utils/groups\";\nimport { AgentCard } from \"./AgentCard\";\n\n/**\n * Standalone panel that renders the current activity tree as a list of\n * {@link AgentCard}s — top-level groups at the root, or the drilled-in group's\n * children. Use it when you want the hierarchical activity view outside the chat\n * transcript (the in-chat view is handled by `KabooMessageView`). Renders\n * nothing when there is no activity.\n *\n * @example\n * ```tsx\n * import { ActivityPanel } from \"@pgege/kaboo-react\";\n *\n * function Sidebar() {\n * return (\n * <aside>\n * <ActivityPanel />\n * </aside>\n * );\n * }\n * ```\n */\nexport function ActivityPanel() {\n const { groups } = useActivity();\n const { activeDrill } = useDrill();\n\n if (Object.keys(groups).length === 0) return null;\n\n // A plain-agent entry group (`inlineChatOwner`) is rendered inline by the host\n // chat, so it must not also appear as a root card here — it only enriches\n // those inline tool rows. Nested/sub-agent drilling is unaffected.\n const filtered = activeDrill\n ? directChildren(groups, activeDrill)\n : topLevelGroups(groups).filter(([, g]) => !g.inlineChatOwner);\n\n if (filtered.length === 0 && activeDrill) {\n const exact = groups[activeDrill];\n if (exact) {\n return (\n <div className=\"kaboo-activity-panel\">\n <AgentCard groupId={activeDrill} group={exact} />\n </div>\n );\n }\n }\n\n return (\n <div className=\"kaboo-activity-panel\">\n {filtered.map(([id, group]) => (\n <AgentCard key={id} groupId={id} group={group} />\n ))}\n </div>\n );\n}\n","import { useActivity } from \"../hooks/useActivity\";\nimport { useDrill } from \"../hooks/useDrill\";\n\n/**\n * Breadcrumb navigation for the drill-down path: a \"Chat\" root followed by one\n * crumb per drilled-in group. Clicking a crumb jumps to that level; the current\n * (last) crumb is disabled. Renders nothing at the root. Pair with\n * {@link DrillDetailView}.\n *\n * @example\n * ```tsx\n * import { GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n *\n * function DrillArea() {\n * return (\n * <>\n * <GlassTabs />\n * <DrillDetailView />\n * </>\n * );\n * }\n * ```\n */\nexport function GlassTabs() {\n const { drillPath, drillToRoot, drillToLevel } = useDrill();\n const { groups } = useActivity();\n\n if (drillPath.length === 0) return null;\n\n const tabs: { id: string; label: string; level: number }[] = [\n { id: \"root\", label: \"Chat\", level: -1 },\n ...drillPath.map((id, i) => ({\n id,\n label: groups[id]?.title || id,\n level: i,\n })),\n ];\n\n return (\n <nav className=\"kaboo-breadcrumb-bar\">\n {tabs.map((tab, i) => {\n const isLast = i === tabs.length - 1;\n return (\n <span key={tab.id} className=\"kaboo-breadcrumb-item\">\n {i > 0 && (\n <svg width={12} height={12} viewBox=\"0 0 16 16\" className=\"kaboo-breadcrumb-sep\">\n <path d=\"M6 4l4 4-4 4\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )}\n <button\n className={`kaboo-breadcrumb-link ${isLast ? \"kaboo-breadcrumb-current\" : \"\"}`}\n onClick={() => {\n if (isLast) return;\n if (tab.level === -1) drillToRoot();\n else drillToLevel(tab.level);\n }}\n disabled={isLast}\n >\n {i === 0 && (\n <svg width={14} height={14} viewBox=\"0 0 16 16\" className=\"kaboo-breadcrumb-icon\">\n <path d=\"M3 8.5L8 4l5 4.5M4.5 7.5V12h2.5V9.5h2V12h2.5V7.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n {tab.label}\n </button>\n </span>\n );\n })}\n </nav>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { useDrill } from \"../hooks/useDrill\";\nimport { useInterruptBridge } from \"../context/InterruptBridge\";\nimport {\n directChildren,\n partitionChildrenByToolCall,\n pendingToolAnchorExists,\n} from \"../utils/groups\";\nimport { AgentCard } from \"./AgentCard\";\nimport { Timeline } from \"./Timeline\";\nimport { InterruptRenderer } from \"./InterruptRenderer\";\n\n/**\n * Detail pane for the currently drilled-in group: its task, full timeline\n * (with delegated sub-agents interleaved at their tool-call position), any\n * unanchored interrupt prompts, and a \"Sub-agents\" section for swarm/graph\n * members. Renders a hidden placeholder at the root. Pair with {@link GlassTabs}.\n *\n * @example\n * ```tsx\n * import { GlassTabs, DrillDetailView } from \"@pgege/kaboo-react\";\n *\n * function DrillArea() {\n * return (\n * <>\n * <GlassTabs />\n * <DrillDetailView />\n * </>\n * );\n * }\n * ```\n */\nexport function DrillDetailView() {\n const { activeDrill } = useDrill();\n const { groups } = useActivity();\n const { active: activeInterrupts } = useInterruptBridge();\n const bodyRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (activeDrill && bodyRef.current) {\n bodyRef.current.scrollTop = 0;\n }\n }, [activeDrill]);\n\n if (!activeDrill) {\n return <div className=\"kaboo-drill-detail kaboo-hidden\" />;\n }\n\n const group = groups[activeDrill];\n const timeline = group?.timeline ?? [];\n // Prompts anchored to a pending tool call are rendered inline by the Timeline\n // at that tool's position (chronological); this block only handles interrupts\n // with no on-screen tool anchor — never a duplicate.\n const unanchoredInterrupts =\n group?.status === \"interrupted\"\n ? activeInterrupts.filter(\n (i) => !pendingToolAnchorExists(groups, i.toolCallId),\n )\n : [];\n\n const childEntries = directChildren(groups, activeDrill);\n // Interleave delegated children at their delegating tool-call position so a\n // sub-agent's card sits where it was delegated (before the parent's summary\n // text) rather than in a trailing block. Children with no tool-call anchor\n // (swarm/graph members) still render in the Sub-agents section below.\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]} />;\n };\n\n return (\n <div ref={bodyRef} className=\"kaboo-drill-detail\">\n <div className=\"kaboo-drill-detail-inner\">\n {group?.task && (\n <div className=\"kaboo-agent-card-task kaboo-drill-task\">\n <strong>Task:</strong> {group.task}\n </div>\n )}\n\n {group && timeline.length > 0 && (\n <div className=\"kaboo-drill-timeline\">\n <Timeline\n timeline={timeline}\n active={group.status === \"active\"}\n variant=\"drill\"\n renderToolCard={renderToolCard}\n />\n </div>\n )}\n\n {unanchoredInterrupts.length > 0 && (\n <div className=\"kaboo-drill-interrupt\">\n {unanchoredInterrupts.map((it) => (\n <InterruptRenderer\n key={it.id}\n reason={it.reason}\n toolCallId={it.toolCallId}\n onResolve={it.onResolve}\n onCancel={it.onCancel}\n />\n ))}\n </div>\n )}\n\n {leftoverChildren.length > 0 && (\n <div className=\"kaboo-drill-children\">\n <div className=\"kaboo-drill-section-label\">Sub-agents</div>\n {leftoverChildren.map(([id, childGroup]) => (\n <AgentCard key={id} groupId={id} group={childGroup} />\n ))}\n </div>\n )}\n\n {group && timeline.length === 0 && childEntries.length === 0 && (\n <div className=\"kaboo-agent-card-empty\">\n Working...\n </div>\n )}\n\n {!group && (\n <div className=\"kaboo-agent-card-empty\">\n No activity data for this group.\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_v2","import_react","import_jsx_runtime","import_v2","import_react","import_jsx_runtime","import_react","import_v2","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_v2","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_v2","import_jsx_runtime","import_jsx_runtime","ANY_PARAMETERS","import_react","import_v2","import_jsx_runtime","import_jsx_runtime","import_react","import_v2","import_jsx_runtime","ReferencePopover","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}