@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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context/ActivityProvider.tsx","../src/context/DrillContext.tsx","../src/context/InterruptBridge.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/KabooInterruptHandler.tsx","../src/formatters/output.ts","../src/components/MarkdownContent.tsx","../src/formatters/input.ts","../src/components/MiniTable.tsx","../src/components/ToolRow.tsx","../src/components/Timeline.tsx","../src/hooks/useDrill.ts","../src/components/AgentCard.tsx","../src/integrations/KabooToolRender.tsx","../src/integrations/KabooInlineCards.tsx","../src/references/types.ts","../src/references/serialize.ts","../src/references/ReferencesProvider.tsx"],"sourcesContent":["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 {\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 { 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 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","/**\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","/**\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 { 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","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 { useContext } from \"react\";\nimport { DrillContext } from \"../context/DrillContext\";\nimport type { DrillState } from \"../types\";\n\n/**\n * Reads the drill-down navigation state ({@link DrillState}) from the nearest\n * {@link DrillProvider}: the current path plus `drillIn`/`drillUp`/`drillToRoot`/\n * `drillToLevel`.\n *\n * @example\n * ```tsx\n * import { useDrill } from \"@pgege/kaboo-react\";\n *\n * function BackButton() {\n * const { drillUp, activeDrill } = useDrill();\n * if (!activeDrill) return null;\n * return <button onClick={drillUp}>Back</button>;\n * }\n * ```\n */\nexport function useDrill(): DrillState {\n return useContext(DrillContext);\n}\n","import { useState, 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","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 { 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 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 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"],"mappings":"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","names":["useState","createContext","jsx","createContext","useState","useCallback","useEffect","jsx","useState","jsx","useContext","useContext","jsx","jsxs","Fragment","jsx","Fragment","jsx","jsxs","Fragment","jsx","jsx","jsxs","useState","jsx","jsxs","useState","text","Fragment","Fragment","jsx","jsxs","useContext","useContext","useState","useEffect","useRef","useContext","jsx","jsxs","useContext","useState","useRef","useEffect","Fragment","jsx","useRenderTool","Fragment","jsx","jsxs","ANY_PARAMETERS","useRenderTool","createContext","useCallback","useContext","useEffect","useState","useAgent","jsx","jsxs","createContext","useState","useCallback","useAgent","useEffect","useContext"]}
@@ -25,7 +25,8 @@ __export(copilotkit_exports, {
25
25
  KabooInlineCards: () => KabooInlineCards,
26
26
  KabooInterruptHandler: () => KabooInterruptHandler,
27
27
  KabooMessageView: () => KabooMessageView,
28
- KabooToolRender: () => KabooToolRender
28
+ KabooToolRender: () => KabooToolRender,
29
+ KabooUserMessage: () => KabooUserMessage
29
30
  });
30
31
  module.exports = __toCommonJS(copilotkit_exports);
31
32
 
@@ -1079,19 +1080,149 @@ function KabooAssistantMessage(props) {
1079
1080
  }
1080
1081
 
1081
1082
  // src/integrations/KabooMessageView.tsx
1083
+ var import_v27 = require("@copilotkit/react-core/v2");
1084
+
1085
+ // src/integrations/KabooUserMessage.tsx
1086
+ var import_v26 = require("@copilotkit/react-core/v2");
1087
+
1088
+ // src/references/ReferencesProvider.tsx
1089
+ var import_react11 = require("react");
1082
1090
  var import_v25 = require("@copilotkit/react-core/v2");
1083
1091
  var import_jsx_runtime15 = require("react/jsx-runtime");
1092
+ var ReferencesContext = (0, import_react11.createContext)({
1093
+ providers: [],
1094
+ pending: [],
1095
+ addReference: () => {
1096
+ },
1097
+ removeReference: () => {
1098
+ },
1099
+ clearReferences: () => {
1100
+ },
1101
+ messageReferences: {},
1102
+ recordMessageReferences: () => {
1103
+ }
1104
+ });
1105
+ function useReferences() {
1106
+ return (0, import_react11.useContext)(ReferencesContext);
1107
+ }
1108
+
1109
+ // src/integrations/KabooUserMessage.tsx
1110
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1111
+ var WRAP_CLASS = "copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10";
1112
+ var BUBBLE_CLASS = "cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:inline-block cpk:whitespace-pre-wrap";
1113
+ var AtIcon = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1114
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
1115
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94" })
1116
+ ] });
1117
+ var FileIcon = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1118
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1119
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14 2v6h6" })
1120
+ ] });
1121
+ function messageText(content) {
1122
+ if (typeof content === "string") return content;
1123
+ if (!Array.isArray(content)) return "";
1124
+ return content.map(
1125
+ (p) => p && typeof p === "object" && p.type === "text" ? String(p.text ?? "") : ""
1126
+ ).filter(Boolean).join("\n");
1127
+ }
1128
+ function fileParts(content) {
1129
+ if (!Array.isArray(content)) return [];
1130
+ const out = [];
1131
+ for (const part of content) {
1132
+ const type = part?.type;
1133
+ if (type !== "image" && type !== "audio" && type !== "video" && type !== "document") continue;
1134
+ const source = part.source;
1135
+ if (!source?.value) continue;
1136
+ const src = source.type === "url" ? source.value : `data:${source.mimeType ?? ""};base64,${source.value}`;
1137
+ const meta = part.metadata;
1138
+ out.push({ kind: type, src, filename: meta?.filename ?? source.mimeType ?? "file" });
1139
+ }
1140
+ return out;
1141
+ }
1142
+ function ObjectChip({ reference, inline }) {
1143
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1144
+ "span",
1145
+ {
1146
+ className: `kaboo-chip kaboo-chip-object kaboo-msg-chip${inline ? " kaboo-msg-chip-inline" : ""}`,
1147
+ title: reference.name,
1148
+ children: [
1149
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "kaboo-chip-ic", children: AtIcon }),
1150
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "kaboo-chip-label", children: reference.name })
1151
+ ]
1152
+ }
1153
+ );
1154
+ }
1155
+ function FileChip({ file }) {
1156
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "kaboo-chip kaboo-chip-attachment kaboo-msg-chip", title: file.filename, children: [
1157
+ file.kind === "image" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("img", { className: "kaboo-chip-thumb", src: file.src, alt: file.filename }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "kaboo-chip-ic", children: FileIcon }),
1158
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "kaboo-chip-label", children: file.filename })
1159
+ ] });
1160
+ }
1161
+ function renderInline2(text, refs) {
1162
+ if (refs.length === 0) return [text];
1163
+ const tokens = refs.map((ref) => ({ ref, token: `@${ref.name}` })).sort((a, b) => b.token.length - a.token.length);
1164
+ const out = [];
1165
+ let i = 0;
1166
+ let key = 0;
1167
+ while (i < text.length) {
1168
+ const hit = tokens.find((t) => text.startsWith(t.token, i));
1169
+ if (hit) {
1170
+ out.push(/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ObjectChip, { reference: hit.ref, inline: true }, key++));
1171
+ i += hit.token.length;
1172
+ continue;
1173
+ }
1174
+ let next = text.length;
1175
+ for (const t of tokens) {
1176
+ const idx = text.indexOf(t.token, i + 1);
1177
+ if (idx !== -1 && idx < next) next = idx;
1178
+ }
1179
+ out.push(text.slice(i, next));
1180
+ i = next;
1181
+ }
1182
+ return out;
1183
+ }
1184
+ function KabooUserMessage(props) {
1185
+ const { messageReferences } = useReferences();
1186
+ const message = props.message;
1187
+ const id = message?.id;
1188
+ const objectRefs = (id ? messageReferences[id] : void 0) ?? [];
1189
+ const text = messageText(message?.content);
1190
+ const files = fileParts(message?.content);
1191
+ const inlineRefs = objectRefs.filter((r) => text.includes(`@${r.name}`));
1192
+ const trayRefs = objectRefs.filter((r) => !text.includes(`@${r.name}`));
1193
+ const hasChipRow = files.length > 0 || trayRefs.length > 0;
1194
+ const MessageRenderer = ({ content, className }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: className ? `${BUBBLE_CLASS} ${className}` : BUBBLE_CLASS, children: renderInline2(content, inlineRefs) });
1195
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1196
+ import_v26.CopilotChatUserMessage,
1197
+ {
1198
+ ...props,
1199
+ messageRenderer: MessageRenderer,
1200
+ children: ({ messageRenderer, toolbar }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { "data-copilotkit": true, "data-message-id": id, className: `${WRAP_CLASS} kaboo-user-message`, children: [
1201
+ hasChipRow && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "kaboo-msg-refs", children: [
1202
+ files.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FileChip, { file: f }, `f${i}`)),
1203
+ trayRefs.map((r) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ObjectChip, { reference: r }, r.id))
1204
+ ] }),
1205
+ messageRenderer,
1206
+ toolbar
1207
+ ] })
1208
+ }
1209
+ );
1210
+ }
1211
+
1212
+ // src/integrations/KabooMessageView.tsx
1213
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1084
1214
  function KabooMessageViewImpl(props) {
1085
1215
  const { groups } = useActivity();
1086
- const { copilotkit } = (0, import_v25.useCopilotKit)();
1087
- const config = (0, import_v25.useCopilotChatConfiguration)();
1216
+ const { copilotkit } = (0, import_v27.useCopilotKit)();
1217
+ const config = (0, import_v27.useCopilotChatConfiguration)();
1088
1218
  const agentId = config?.agentId;
1089
1219
  const threadId = config?.threadId;
1090
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1091
- import_v25.CopilotChatMessageView,
1220
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1221
+ import_v27.CopilotChatMessageView,
1092
1222
  {
1093
1223
  ...props,
1094
1224
  assistantMessage: KabooAssistantMessage,
1225
+ userMessage: KabooUserMessage,
1095
1226
  children: ({ messages, messageElements, interruptElement, isRunning }) => {
1096
1227
  const roots = chatRootGroups(groups);
1097
1228
  const rootsByTurn = /* @__PURE__ */ new Map();
@@ -1126,11 +1257,11 @@ function KabooMessageViewImpl(props) {
1126
1257
  return !key || !boundTurns.has(key);
1127
1258
  });
1128
1259
  const showStartCursor = isRunning && pending.length === 0;
1129
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(TurnBindingProvider, { value: { rootsByMessageId }, children: [
1260
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(TurnBindingProvider, { value: { rootsByMessageId }, children: [
1130
1261
  messageElements,
1131
- pending.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "kaboo-inline-cards", children: pending.map(([groupId, group]) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentCard, { groupId, group, showChildren: true }, groupId)) }),
1262
+ pending.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "kaboo-inline-cards", children: pending.map(([groupId, group]) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AgentCard, { groupId, group, showChildren: true }, groupId)) }),
1132
1263
  interruptElement,
1133
- showStartCursor && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_v25.CopilotChatMessageView.Cursor, {})
1264
+ showStartCursor && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_v27.CopilotChatMessageView.Cursor, {})
1134
1265
  ] });
1135
1266
  }
1136
1267
  }
@@ -1141,15 +1272,15 @@ var KabooMessageView = Object.assign(KabooMessageViewImpl, {
1141
1272
  * The streaming cursor slot, re-exported from CopilotKit so `KabooMessageView`
1142
1273
  * is a drop-in `messageView` (the slot expects a component carrying `Cursor`).
1143
1274
  */
1144
- Cursor: import_v25.CopilotChatMessageView.Cursor
1275
+ Cursor: import_v27.CopilotChatMessageView.Cursor
1145
1276
  });
1146
1277
 
1147
1278
  // src/integrations/KabooInterruptHandler.tsx
1148
- var import_v27 = require("@copilotkit/react-core/v2");
1279
+ var import_v29 = require("@copilotkit/react-core/v2");
1149
1280
 
1150
1281
  // src/integrations/KabooAskUser.tsx
1151
- var import_v26 = require("@copilotkit/react-core/v2");
1152
- var import_jsx_runtime16 = require("react/jsx-runtime");
1282
+ var import_v28 = require("@copilotkit/react-core/v2");
1283
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1153
1284
  var ANY_PARAMETERS2 = {
1154
1285
  "~standard": {
1155
1286
  version: 1,
@@ -1158,14 +1289,14 @@ var ANY_PARAMETERS2 = {
1158
1289
  }
1159
1290
  };
1160
1291
  function KabooAskUser({ agentId }) {
1161
- (0, import_v26.useRenderTool)({
1292
+ (0, import_v28.useRenderTool)({
1162
1293
  name: "ask_user",
1163
1294
  ...agentId ? { agentId } : {},
1164
1295
  parameters: ANY_PARAMETERS2,
1165
1296
  render: ({ parameters, result }) => {
1166
1297
  const questions = normalizeQuestions(parameters);
1167
- if (questions.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, {});
1168
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AskUserCard, { questions, result });
1298
+ if (questions.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, {});
1299
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AskUserCard, { questions, result });
1169
1300
  }
1170
1301
  });
1171
1302
  return null;
@@ -1175,12 +1306,12 @@ function AskUserCard({
1175
1306
  result
1176
1307
  }) {
1177
1308
  const answers = parseAnswers(result);
1178
- if (!answers) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, {});
1179
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AskUserSummary, { questions, answers });
1309
+ if (!answers) return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, {});
1310
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AskUserSummary, { questions, answers });
1180
1311
  }
1181
1312
 
1182
1313
  // src/integrations/KabooInterruptHandler.tsx
1183
- var import_jsx_runtime17 = require("react/jsx-runtime");
1314
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1184
1315
  function ChatInterruptSlot({
1185
1316
  interrupt,
1186
1317
  Renderer
@@ -1189,7 +1320,7 @@ function ChatInterruptSlot({
1189
1320
  if (pendingToolAnchorExists(groups, interrupt.toolCallId)) {
1190
1321
  return null;
1191
1322
  }
1192
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1323
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1193
1324
  Renderer,
1194
1325
  {
1195
1326
  reason: interrupt.reason,
@@ -1204,7 +1335,7 @@ function KabooInterruptHandler({
1204
1335
  renderers,
1205
1336
  bridge = true
1206
1337
  }) {
1207
- (0, import_v27.useInterrupt)({
1338
+ (0, import_v29.useInterrupt)({
1208
1339
  ...agentId ? { agentId } : {},
1209
1340
  render: ({ interrupts, resolve, cancel }) => {
1210
1341
  const active = (interrupts ?? []).map((intr) => {
@@ -1219,11 +1350,11 @@ function KabooInterruptHandler({
1219
1350
  };
1220
1351
  }).filter((x) => x !== null);
1221
1352
  if (active.length === 0) {
1222
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, {});
1353
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, {});
1223
1354
  }
1224
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1225
- bridge && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(InterruptBridgePublisher, { interrupts: active }),
1226
- active.map((a) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1355
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1356
+ bridge && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InterruptBridgePublisher, { interrupts: active }),
1357
+ active.map((a) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1227
1358
  ChatInterruptSlot,
1228
1359
  {
1229
1360
  interrupt: a,
@@ -1234,7 +1365,7 @@ function KabooInterruptHandler({
1234
1365
  ] });
1235
1366
  }
1236
1367
  });
1237
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(KabooAskUser, { agentId });
1368
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(KabooAskUser, { agentId });
1238
1369
  }
1239
1370
  // Annotate the CommonJS export names for ESM import in node:
1240
1371
  0 && (module.exports = {
@@ -1243,6 +1374,7 @@ function KabooInterruptHandler({
1243
1374
  KabooInlineCards,
1244
1375
  KabooInterruptHandler,
1245
1376
  KabooMessageView,
1246
- KabooToolRender
1377
+ KabooToolRender,
1378
+ KabooUserMessage
1247
1379
  });
1248
1380
  //# sourceMappingURL=copilotkit.cjs.map