@agno-hq/chat-react 0.1.1 → 0.3.1

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,1335 @@
1
+ import { C as ChatMessage, l as RunEventData, e as ChatStatus, g as EntityType, q as ToolExecution, m as RunRequirement, S as SessionEntry, A as AgnoClient, E as Entity, j as ReferenceData, f as Citations$1, R as ReasoningStep, o as SubRun, r as WorkflowStep, I as ImageData, V as VideoData, c as AudioData } from '../client-DUyVqxU9.js';
2
+ import React$1 from 'react';
3
+ import { StreamdownProps } from 'streamdown';
4
+
5
+ /**
6
+ * useAgnoChat — a headless React hook for running any Agno agent, team or
7
+ * workflow against an AgentOS backend and consuming its streamed output.
8
+ *
9
+ * It owns the full chat lifecycle: sending a message, accumulating the streamed
10
+ * response (content, tool calls, reasoning, media), surfacing live status and
11
+ * the raw event feed, handling human-in-the-loop pauses, cancelling, and
12
+ * rehydrating prior sessions.
13
+ *
14
+ * The hook renders nothing — pair it with the components in this package or
15
+ * build your own UI from the values it returns.
16
+ */
17
+
18
+ interface UseAgnoChatOptions {
19
+ /** AgentOS base URL, e.g. "http://localhost:7777". Ignored if `client` given. */
20
+ baseUrl?: string;
21
+ /** A pre-built client (use this to share headers/auth across hooks). */
22
+ client?: AgnoClient;
23
+ /** Extra request headers (e.g. Authorization). Used only with `baseUrl`. */
24
+ headers?: Record<string, string>;
25
+ /** The agent/team/workflow to run. Can change between turns. */
26
+ entity?: Entity | null;
27
+ /** User id sent with every run. */
28
+ userId?: string;
29
+ /** Initial session id; updated automatically once the backend assigns one. */
30
+ sessionId?: string;
31
+ /** Pre-seed the transcript (e.g. when restoring a session). */
32
+ initialMessages?: ChatMessage[];
33
+ /** Called with every raw run event, for logging/telemetry. */
34
+ onEvent?: (event: RunEventData) => void;
35
+ /** Called when the session id changes (e.g. first run of a new session). */
36
+ onSessionId?: (sessionId: string) => void;
37
+ }
38
+ interface SendOptions {
39
+ files?: File[];
40
+ }
41
+ interface UseAgnoChat {
42
+ /** Full transcript, oldest first. */
43
+ messages: ChatMessage[];
44
+ /** The agent message currently streaming, or null when idle. */
45
+ streamingMessage: ChatMessage | null;
46
+ /** Every raw event from the current/most-recent run, in arrival order. */
47
+ events: RunEventData[];
48
+ /** The most recent raw event. */
49
+ currentEvent: RunEventData | null;
50
+ /** Lifecycle status of the active run. */
51
+ status: ChatStatus;
52
+ /** Live "what is it doing" label, e.g. "Calling get_weather". */
53
+ activity: string | null;
54
+ isStreaming: boolean;
55
+ isPaused: boolean;
56
+ error: string | null;
57
+ sessionId: string | undefined;
58
+ /** Type of the selected entity (agent / team / workflow). */
59
+ entityType: EntityType | undefined;
60
+ /** Tool calls of the active/most-recent agent message. */
61
+ tools: ToolExecution[];
62
+ /** Reasoning steps of the active/most-recent agent message. */
63
+ reasoning: ChatMessage['reasoning_steps'];
64
+ /** Outstanding human-in-the-loop requirements, if the run is paused. */
65
+ pendingRequirements: RunRequirement[];
66
+ /** Past sessions for the selected entity (populated by `refreshSessions`). */
67
+ sessions: SessionEntry[];
68
+ /**
69
+ * Sessions with a run in flight — the visible one plus any still streaming
70
+ * in the background after the user switched away.
71
+ */
72
+ streamingSessionIds: string[];
73
+ sessionsLoading: boolean;
74
+ /** Send a user message and stream the response. */
75
+ sendMessage: (message: string, options?: SendOptions) => Promise<void>;
76
+ /** Stop the active run. */
77
+ cancel: () => Promise<void>;
78
+ /** Continue a paused run with explicitly resolved requirements. */
79
+ continueRun: (resolution: {
80
+ tools?: ToolExecution[];
81
+ stepRequirements?: unknown[];
82
+ }) => Promise<void>;
83
+ /** Approve or reject all pending tool confirmations, then continue. */
84
+ respondToConfirmation: (approve: boolean) => Promise<void>;
85
+ /** Provide values for pending tool user-input fields, then continue. */
86
+ submitUserInput: (values: Record<string, unknown>) => Promise<void>;
87
+ /** Fetch the list of past sessions for the selected entity. */
88
+ refreshSessions: () => Promise<void>;
89
+ /** Load a past session's transcript into the chat. */
90
+ loadSession: (sessionId: string) => Promise<void>;
91
+ /** Delete a past session, removing it from the list. */
92
+ deleteSession: (sessionId: string) => Promise<void>;
93
+ /** Clear the transcript and start a new session. */
94
+ reset: () => void;
95
+ /** Replace the transcript (e.g. after loading a session from the backend). */
96
+ setMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>;
97
+ /** The underlying client, for ad-hoc calls (sessions, discovery, …). */
98
+ client: AgnoClient;
99
+ }
100
+ declare function useAgnoChat(options: UseAgnoChatOptions): UseAgnoChat;
101
+
102
+ /**
103
+ * Every visual slot in the chat components can be re-classed from the outside.
104
+ *
105
+ * Pass a `classNames` map to any chat component and it is threaded down to its
106
+ * children, so a single map at the top styles the whole surface:
107
+ *
108
+ * ```tsx
109
+ * <AgnoChat classNames={{ root: 'rounded-2xl', textarea: 'font-mono' }} />
110
+ * ```
111
+ *
112
+ * The built-in `agno-*` classes stay on the elements, so overrides compose with
113
+ * the shipped stylesheet rather than replacing it. Skip the stylesheet entirely
114
+ * (import only `tokens.css`, or nothing) to style purely with your own classes.
115
+ */
116
+ interface ChatClassNames {
117
+ /** Outer wrapper of `<AgnoChat>`. */
118
+ root?: string;
119
+ /** The `header` slot wrapper, when one is supplied. */
120
+ header?: string;
121
+ /** Row holding the sidebar(s) and the chat column. */
122
+ main?: string;
123
+ /** Either sidebar column (sessions, event log). */
124
+ sidebar?: string;
125
+ /** The "no entities found" banner. */
126
+ banner?: string;
127
+ /** `<ChatWindow>` column. */
128
+ chat?: string;
129
+ /** Error line under the transcript. */
130
+ error?: string;
131
+ /** `<MessageList>` scroll container. */
132
+ list?: string;
133
+ /** Empty-state placeholder inside the transcript. */
134
+ empty?: string;
135
+ /** Every `<Message>` row. */
136
+ message?: string;
137
+ /** User rows only (applied on top of `message`). */
138
+ userMessage?: string;
139
+ /** Agent rows only (applied on top of `message`). */
140
+ agentMessage?: string;
141
+ /** Message avatar. */
142
+ avatar?: string;
143
+ /** Message body column. */
144
+ messageBody?: string;
145
+ /** Rendered message content. */
146
+ messageContent?: string;
147
+ /** `<Markdown>` wrapper. */
148
+ markdown?: string;
149
+ /** "Working…" line shown while streaming with no content yet. */
150
+ activity?: string;
151
+ /** `<ChatInput>` wrapper. */
152
+ input?: string;
153
+ /** Row holding attach / textarea / send. */
154
+ inputRow?: string;
155
+ /** The textarea itself. */
156
+ textarea?: string;
157
+ /** Send button. */
158
+ sendButton?: string;
159
+ /** Stop button shown in place of send while streaming. */
160
+ stopButton?: string;
161
+ /** Attach-files button. */
162
+ attachButton?: string;
163
+ /** Pending attachment chips. */
164
+ files?: string;
165
+ /** The "why this file was refused" line under the chips. */
166
+ fileError?: string;
167
+ /** The overlay shown while files are dragged over the dock. */
168
+ dropOverlay?: string;
169
+ /** `<SessionList>` wrapper. */
170
+ sessions?: string;
171
+ /** Each session row. */
172
+ sessionItem?: string;
173
+ /** The active session row (applied on top of `sessionItem`). */
174
+ activeSessionItem?: string;
175
+ /** "New chat" button. */
176
+ newSessionButton?: string;
177
+ /** `<EntitySelector>` wrapper. */
178
+ select?: string;
179
+ /** Selector trigger button. */
180
+ selectTrigger?: string;
181
+ /** Selector popover. */
182
+ selectPanel?: string;
183
+ /** Each option in the popover. */
184
+ selectOption?: string;
185
+ /** Shared class for the collapsible panels below. */
186
+ panel?: string;
187
+ /** `<ToolCalls>`. */
188
+ toolCalls?: string;
189
+ /** `<Reasoning>`. */
190
+ reasoning?: string;
191
+ /** `<Citations>` — the sources block under an answer. */
192
+ citations?: string;
193
+ /** Each source card inside `<Citations>`. */
194
+ sourceCard?: string;
195
+ /** Inline `[1]` citation marker in the answer text. */
196
+ citationMarker?: string;
197
+ /** The hover card shown for a citation marker or a link. */
198
+ linkPreview?: string;
199
+ /** `<Followups>` — the "Related questions" block under the latest answer. */
200
+ followups?: string;
201
+ /** The heading above the follow-up list. */
202
+ followupsHead?: string;
203
+ /** Each follow-up button. */
204
+ followup?: string;
205
+ /** The copy button on a fenced code block. */
206
+ copyButton?: string;
207
+ /** `<WorkflowSteps>`. */
208
+ workflowSteps?: string;
209
+ /** `<MemberResponses>`. */
210
+ memberResponses?: string;
211
+ /** `<Multimedia>`. */
212
+ multimedia?: string;
213
+ /** `<EventLog>`. */
214
+ eventLog?: string;
215
+ /** `<HumanInput>` panel. */
216
+ humanInput?: string;
217
+ /** `<StatusIndicator>`. */
218
+ status?: string;
219
+ /** Floating launcher button of `<ChatLauncher>`. */
220
+ launcher?: string;
221
+ /** Floating panel of `<ChatLauncher>`. */
222
+ launcherPanel?: string;
223
+ }
224
+
225
+ /**
226
+ * Link metadata shown in a preview. Everything is optional — the URL-derived
227
+ * fields (host, favicon) are always available, the rest arrive only if the
228
+ * payload carried them or a `resolveLinkPreview` filled them in.
229
+ */
230
+ interface LinkPreview {
231
+ title?: string;
232
+ description?: string;
233
+ /** Absolute URL of a preview image (OpenGraph `og:image`). */
234
+ image?: string;
235
+ /** Absolute URL of the site icon. Defaults to `/favicon.ico` on the origin. */
236
+ favicon?: string;
237
+ /** Human name of the site, e.g. "Agno Docs". Falls back to the hostname. */
238
+ siteName?: string;
239
+ }
240
+ /**
241
+ * Resolve richer metadata for a link. Runs at most once per URL, lazily — on
242
+ * first hover, never on render — so a transcript full of citations costs
243
+ * nothing until someone actually points at one.
244
+ *
245
+ * Browsers can't read another origin's `<meta>` tags (CORS), so this has to be
246
+ * backed by something server-side of your own:
247
+ *
248
+ * ```tsx
249
+ * <ChatProvider
250
+ * resolveLinkPreview={async (url) => {
251
+ * const res = await fetch(`/api/og?url=${encodeURIComponent(url)}`)
252
+ * return res.ok ? res.json() : null
253
+ * }}
254
+ * />
255
+ * ```
256
+ *
257
+ * Return `null` when there's nothing to add; the card falls back to the
258
+ * hostname, favicon and whatever title the citation payload carried.
259
+ */
260
+ type ResolveLinkPreview = (url: string) => Promise<LinkPreview | null> | LinkPreview | null;
261
+ /** One numbered entry in a message's source list. */
262
+ /**
263
+ * Renders every link the components emit — in answers, on `[1]` chips and on
264
+ * source cards — in place of a plain `<a>`. Given `href`, `children` and the
265
+ * anchor attributes the component would have set (class, title, ARIA); it
266
+ * decides how to navigate, so nothing sets `target` for it. Hand it a router
267
+ * link to keep in-app URLs client-side.
268
+ */
269
+ type LinkComponent = React$1.ComponentType<React$1.AnchorHTMLAttributes<HTMLAnchorElement> & {
270
+ href: string;
271
+ children?: React$1.ReactNode;
272
+ }>;
273
+ interface Source {
274
+ /** 1-based position — what `[1]` in the answer text refers to. */
275
+ index: number;
276
+ /** DOM id of this source's card, so inline markers can link to it. */
277
+ anchorId: string;
278
+ /** A link the model browsed, or a chunk retrieved from a knowledge base. */
279
+ kind: 'url' | 'document';
280
+ /** Absolute URL, when there is one to open. */
281
+ url?: string;
282
+ /** Display name: the payload's title, the document name, or the hostname. */
283
+ title: string;
284
+ /** The passage that was actually retrieved, when the payload carries one. */
285
+ snippet?: string;
286
+ /** Retrieval query that surfaced this chunk (knowledge-base sources only). */
287
+ query?: string;
288
+ }
289
+ /** The hostname without `www.`, or undefined for anything unparseable. */
290
+ declare function sourceHost(url?: string): string | undefined;
291
+ /**
292
+ * The site's own icon. Same-origin to the site being cited, so no third-party
293
+ * favicon service is involved and nothing is requested until a card renders.
294
+ */
295
+ declare function faviconUrl(url?: string): string | undefined;
296
+ /** `docs.agno.com/introduction` — the host plus a trimmed path, for card chrome. */
297
+ declare function displayUrl(url?: string): string | undefined;
298
+ /**
299
+ * Flatten a message's `references` and `citations` into one numbered list.
300
+ *
301
+ * Retrieved documents come first (they are what grounded the answer), then any
302
+ * browsed links. Entries pointing at the same URL are merged, so a link that is
303
+ * both retrieved and cited is numbered once.
304
+ *
305
+ * `idBase` seeds the DOM ids used to link inline markers to cards — pass a
306
+ * value that is stable per message, e.g. React's `useId()`.
307
+ */
308
+ declare function collectSources(references: ReferenceData[] | undefined, citations: Citations$1 | undefined, idBase?: string): Source[];
309
+ /**
310
+ * The sources a model cited inline, for runs that carry no `references` or
311
+ * `citations` at all — a common shape, e.g.
312
+ *
313
+ * ```text
314
+ * Call `Agent.run()` in production. [1](https://docs.agno.com/agents/building-agents)
315
+ *
316
+ * Sources: [Building Agents](https://docs.agno.com/agents/building-agents)
317
+ * ```
318
+ *
319
+ * A link labelled with a bare number is the citation; a link labelled with text
320
+ * names the same URL, so the trailing "Sources:" line titles the cards. Numbers
321
+ * are kept exactly as the model wrote them, so the markers in the answer and
322
+ * the cards below it can't disagree. An answer with no numbered links has no
323
+ * sources — a plain link in prose is not a citation.
324
+ */
325
+ declare function sourcesFromMarkdown(content: string | undefined, idBase?: string): Source[];
326
+ /**
327
+ * The answer without its trailing "Sources:" line.
328
+ *
329
+ * When `sourcesFromMarkdown` has turned that line into cards, leaving it in
330
+ * the prose lists every source twice, back to back. The line is only dropped
331
+ * when it is the last thing in the answer and holds nothing but links — a
332
+ * paragraph that goes on to say something is prose, and stays. A half-written
333
+ * line mid-stream counts as links, so it never flashes up before the cards do.
334
+ */
335
+ declare function withoutSourcesLine(content: string): string;
336
+ /**
337
+ * Rewrite the bare citation markers in an answer as links to the source they
338
+ * name: `context [1].` becomes ``context [1](https://…).``
339
+ *
340
+ * A Markdown parser has no concept of a citation marker — `[1]` is prose — so
341
+ * this runs before parsing and leaves one shape for the renderer to handle. The
342
+ * preceding space is absorbed so the marker sits against the word it qualifies,
343
+ * the way a footnote does.
344
+ *
345
+ * Untouched: markers with no matching source, anything inside code, reference
346
+ * links (`[text][1]`), link definitions (`[1]: https://…`) and markers that are
347
+ * already links (`[1](…)`).
348
+ */
349
+ declare function linkCitations(content: string, sources: Source[]): string;
350
+ /**
351
+ * Publishes the sources of the message being rendered. `<Message>` wraps its
352
+ * body in one, which is how a `[1]` in the answer finds the card it points at —
353
+ * including inside a custom `renderMarkdown`.
354
+ */
355
+ declare const SourcesProvider: React$1.Provider<Source[]>;
356
+ /** The sources of the surrounding message; empty outside one. */
357
+ declare function useSources(): Source[];
358
+
359
+ /**
360
+ * Markdown for a chat transcript, rendered by [Streamdown](https://streamdown.ai).
361
+ *
362
+ * Answers arrive a token at a time, which is where a plain parser falls down:
363
+ * mid-stream the text is full of unterminated bold, half-written links and
364
+ * unclosed fences. Streamdown repairs that as it goes, and brings GFM (tables,
365
+ * task lists, strikethrough) and a sanitising pass with it.
366
+ *
367
+ * Streamdown styles itself with Tailwind utility classes, which do nothing in
368
+ * an app that doesn't use Tailwind. So every element is mapped back onto this
369
+ * package's own `agno-md-*` classes: the shipped stylesheet keeps working, no
370
+ * Tailwind is required, and `classNames`/tokens still govern the look.
371
+ *
372
+ * Prefer a different renderer? `renderMarkdown` on the chat components replaces
373
+ * this one entirely.
374
+ */
375
+
376
+ interface MarkdownProps {
377
+ content: string;
378
+ className?: string;
379
+ /**
380
+ * Sources the inline `[n]` markers refer to. Defaults to the sources of the
381
+ * surrounding `<Message>`; pass `[]` to render markers as plain text.
382
+ */
383
+ sources?: Source[];
384
+ /**
385
+ * The answer is still streaming, so repair half-written markdown rather than
386
+ * rendering a stray `**` or an unclosed fence.
387
+ */
388
+ streaming?: boolean;
389
+ /**
390
+ * Put a copy button on fenced code blocks. On by default; set `false` to drop
391
+ * it, or set `codeCopy` on `<ChatProvider>` to turn it off everywhere.
392
+ */
393
+ codeCopy?: boolean;
394
+ /**
395
+ * Render links with your own component instead of `<a>` — a router link
396
+ * keeps in-app URLs client-side. Defaults to the provider's `linkComponent`.
397
+ */
398
+ linkComponent?: LinkComponent;
399
+ /** Escape hatch onto Streamdown itself — anything not set here. */
400
+ options?: Omit<StreamdownProps, 'children' | 'className' | 'components'>;
401
+ }
402
+ /**
403
+ * Copy text, by whichever route the browser allows.
404
+ *
405
+ * The async Clipboard API is the right one, but it rejects on an insecure
406
+ * origin and whenever the document isn't focused — so a selection-based copy
407
+ * stands behind it. Returns whether anything was actually copied: the button
408
+ * should not claim success it didn't have.
409
+ *
410
+ * Exported because a host building its own copy affordance wants the same
411
+ * fallbacks, and because the failure paths are worth testing.
412
+ */
413
+ declare function writeClipboard(text: string): Promise<boolean>;
414
+ declare function Markdown({ content, className, sources, streaming, codeCopy, linkComponent, options, }: MarkdownProps): React$1.ReactElement;
415
+ type RenderMarkdown = (content: string) => React$1.ReactNode;
416
+
417
+ /**
418
+ * `<ChatProvider>` runs a chat and shares it with everything below it, so the
419
+ * layout is entirely yours:
420
+ *
421
+ * ```tsx
422
+ * <ChatProvider baseUrl="http://localhost:7777" entity={agent}>
423
+ * <MyOwnHeader />
424
+ * <ChatTranscript />
425
+ * <ChatComposer />
426
+ * </ChatProvider>
427
+ * ```
428
+ *
429
+ * Every chat component works standalone (pass it props directly) *or* inside a
430
+ * provider (props omitted, values read from context). Reach for the raw values
431
+ * with `useChatContext()`; use `useAgnoChat` directly if you'd rather own the
432
+ * state yourself and skip the provider.
433
+ */
434
+
435
+ interface ChatContextValue {
436
+ /** The live chat state and actions. */
437
+ chat: UseAgnoChat;
438
+ /** Slot class overrides, threaded to every descendant. */
439
+ classNames: ChatClassNames;
440
+ /** Markdown renderer override, threaded to every descendant. */
441
+ renderMarkdown?: RenderMarkdown;
442
+ /** Link-preview metadata lookup, threaded to every descendant. */
443
+ resolveLinkPreview?: ResolveLinkPreview;
444
+ /** Whether fenced code blocks carry a copy button. Defaults to true. */
445
+ codeCopy?: boolean;
446
+ /** Renders every link in place of `<a>`, threaded to every descendant. */
447
+ linkComponent?: LinkComponent;
448
+ }
449
+ interface ChatProviderProps extends UseAgnoChatOptions {
450
+ children: React$1.ReactNode;
451
+ /** Slot class overrides shared by every component in the tree. */
452
+ classNames?: ChatClassNames;
453
+ /** Markdown renderer shared by every component in the tree. */
454
+ renderMarkdown?: RenderMarkdown;
455
+ /**
456
+ * Fill out link previews with your own metadata (OpenGraph title,
457
+ * description, image). Called at most once per URL, on first hover — see
458
+ * `ResolveLinkPreview`. Without it previews still show the hostname, the site
459
+ * favicon and whatever title the citation payload carried.
460
+ */
461
+ resolveLinkPreview?: ResolveLinkPreview;
462
+ /**
463
+ * Put a copy button on fenced code blocks everywhere below this provider. On
464
+ * by default; pass `false` to drop it.
465
+ */
466
+ codeCopy?: boolean;
467
+ /**
468
+ * Render every link — in answers, on `[1]` chips, on source cards — with
469
+ * your own component instead of `<a>`. A router link keeps in-app URLs
470
+ * client-side; see `LinkComponent`.
471
+ */
472
+ linkComponent?: LinkComponent;
473
+ /**
474
+ * Use an existing `useAgnoChat` result instead of creating one. Lets a parent
475
+ * own the state (or share one chat across two providers).
476
+ */
477
+ chat?: UseAgnoChat;
478
+ /**
479
+ * Wrapper element rendered around the children. Defaults to a plain `div`
480
+ * carrying the theme classes; pass `false` to render children bare.
481
+ */
482
+ as?: React$1.ElementType | false;
483
+ className?: string;
484
+ /** Light theme instead of the default dark. */
485
+ light?: boolean;
486
+ style?: React$1.CSSProperties;
487
+ }
488
+ declare function ChatProvider({ children, classNames, renderMarkdown, resolveLinkPreview, codeCopy, linkComponent, chat: externalChat, as, className, light, style, ...options }: ChatProviderProps): React$1.ReactElement;
489
+ /**
490
+ * Read the chat, class overrides, markdown renderer and link-preview resolver
491
+ * provided by the nearest `<ChatProvider>`. Throws outside a provider — use the
492
+ * optional variant below if the component must also work standalone.
493
+ */
494
+ declare function useChatContext(): ChatContextValue;
495
+ /** Context lookup that returns null instead of throwing outside a provider. */
496
+ declare function useOptionalChatContext(): ChatContextValue | null;
497
+ /** The chat instance, from the prop if given, otherwise from context. */
498
+ declare function useResolvedChat(explicit?: UseAgnoChat): UseAgnoChat;
499
+ /** The provider's link component, if one was supplied. */
500
+ declare function useLinkComponent(): LinkComponent | undefined;
501
+ /** Merge the provider's class overrides with any passed directly. */
502
+ declare function useResolvedClassNames(explicit?: ChatClassNames): ChatClassNames;
503
+
504
+ /**
505
+ * The support-widget shell: a bubble pinned to a corner of the viewport that
506
+ * opens the chat in a popover — or over the whole screen — and closes it again.
507
+ *
508
+ * `<AgnoChat mode="launcher">` renders itself inside one of these. Use the
509
+ * component directly to give your own `<ChatWindow>` the same behaviour.
510
+ */
511
+
512
+ /** Corner the bubble (and the panel it opens) is pinned to. */
513
+ type LauncherPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
514
+ /** How far the panel opens: a corner popover, or the entire viewport. */
515
+ type LauncherPanel = 'popover' | 'fullscreen';
516
+ interface ChatLauncherProps {
517
+ /** The chat surface to reveal — usually `<AgnoChat>` or `<ChatWindow>`. */
518
+ children: React$1.ReactNode;
519
+ /** Corner to pin to. Default "bottom-right". */
520
+ position?: LauncherPosition;
521
+ /** Distance from both edges of that corner. Number means px. Default 24. */
522
+ offset?: number | string;
523
+ /** Popover (default) or full-screen when open. */
524
+ panel?: LauncherPanel;
525
+ /** Popover width. Number means px. Default 400. Ignored when full-screen. */
526
+ width?: number | string;
527
+ /** Popover height. Number means px. Default 620. Ignored when full-screen. */
528
+ height?: number | string;
529
+ /** Controlled open state. Pair with `onOpenChange`. */
530
+ open?: boolean;
531
+ /** Open state on first render when uncontrolled. Default false. */
532
+ defaultOpen?: boolean;
533
+ onOpenChange?: (open: boolean) => void;
534
+ /** Text beside the bubble glyph, e.g. "Chat with us". Icon-only without it. */
535
+ label?: string;
536
+ /** Replaces the default speech-bubble glyph. */
537
+ icon?: React$1.ReactNode;
538
+ /** Accessible name for the bubble. Default "Open chat" / "Close chat". */
539
+ ariaLabel?: string;
540
+ /** Close on Escape. Default true. */
541
+ closeOnEscape?: boolean;
542
+ /**
543
+ * Keep the bubble (as a close button) while the panel is open. Default true.
544
+ * Turn it off when the panel carries its own close control.
545
+ */
546
+ bubbleWhenOpen?: boolean;
547
+ /**
548
+ * Keep the chat mounted after the first open, so closing the panel does not
549
+ * discard the conversation or interrupt a run. Default true.
550
+ */
551
+ keepMounted?: boolean;
552
+ /** Render into `document.body`, escaping transformed ancestors. Default true. */
553
+ portal?: boolean;
554
+ className?: string;
555
+ }
556
+ declare function ChatLauncher({ children, position, offset, panel, width, height, open, defaultOpen, onOpenChange, label, icon, ariaLabel, closeOnEscape, bubbleWhenOpen, keepMounted, portal, className, }: ChatLauncherProps): React$1.ReactElement | null;
557
+
558
+ /**
559
+ * Suggested-prompt chips — the "what can I ask?" row a support chat shows on an
560
+ * empty transcript. `<ChatWindow>` renders these from its `quickPrompts` prop;
561
+ * render the component yourself to place them somewhere else.
562
+ */
563
+
564
+ /** A chip: plain text, or a short label that sends a longer prompt. */
565
+ type QuickPrompt = string | {
566
+ label: string;
567
+ prompt?: string;
568
+ };
569
+ declare const quickPromptLabel: (p: QuickPrompt) => string;
570
+ declare const quickPromptText: (p: QuickPrompt) => string;
571
+ interface QuickPromptsProps {
572
+ prompts: QuickPrompt[];
573
+ /** Called with the prompt text to send. */
574
+ onSelect: (prompt: string) => void;
575
+ disabled?: boolean;
576
+ className?: string;
577
+ }
578
+ declare function QuickPrompts({ prompts, onSelect, disabled, className, }: QuickPromptsProps): React$1.ReactElement | null;
579
+
580
+ /**
581
+ * Zero-wiring chat widget. Point it at an AgentOS URL and it discovers the
582
+ * available agents/teams/workflows, lets the user pick one, and runs a full
583
+ * streaming chat — transcript, tools, reasoning, media and human-in-the-loop.
584
+ *
585
+ * It renders inline by default. `mode="launcher"` turns it into a support
586
+ * widget instead: a bubble pinned to a corner that opens the chat in a popover
587
+ * (or over the whole screen with `panel="fullscreen"`).
588
+ *
589
+ * For finer control (custom layout, auth headers, session restore), call
590
+ * `useAgnoChat` directly and render `<ChatWindow>`.
591
+ */
592
+
593
+ interface AgnoChatProps {
594
+ /** AgentOS base URL, e.g. "http://localhost:7777". */
595
+ baseUrl?: string;
596
+ /** Pre-built client (overrides baseUrl); use for shared auth/headers. */
597
+ client?: AgnoClient;
598
+ headers?: Record<string, string>;
599
+ userId?: string;
600
+ /**
601
+ * The selected agent/team/workflow. Pass it to own the selection — the embed
602
+ * then only displays it, the way AgentOS drives the chat from its breadcrumb.
603
+ * Omit it and the embed discovers the entities and selects the first itself.
604
+ */
605
+ entity?: Entity;
606
+ /** Initial selection when `entity` is not supplied. */
607
+ defaultEntity?: Entity;
608
+ /** Fires whenever the selection changes, controlled or not. */
609
+ onEntityChange?: (entity: Entity) => void;
610
+ /** Provide entities explicitly instead of auto-discovering them. */
611
+ entities?: Entity[];
612
+ /**
613
+ * Put an interactive picker in the composer instead of the read-only badge.
614
+ * Off by default: AgentOS switches the entity from its own chrome, so the
615
+ * dock just reports what is answering. `<EntitySelector>` is exported for
616
+ * placing a picker in your `header` slot.
617
+ */
618
+ showEntityPicker?: boolean;
619
+ /** Hide the selection display in the composer entirely. */
620
+ hideEntityBadge?: boolean;
621
+ placeholder?: string;
622
+ /** Show the attach-files control. Default true, as the AgentOS dock does. */
623
+ allowFiles?: boolean;
624
+ /** The one-row composer instead of the dock. Suits a launcher or a sidebar. */
625
+ compactInput?: boolean;
626
+ /** Show the past-sessions sidebar. Default false. */
627
+ showSessions?: boolean;
628
+ /** Render the last run error above the input. Default false. */
629
+ showErrors?: boolean;
630
+ /** Suggested prompts offered while the transcript is empty. */
631
+ quickPrompts?: QuickPrompt[];
632
+ /**
633
+ * Hide the "Related questions" an agent built with `followups=True` suggests
634
+ * after its latest answer. Shown above the composer by default; clicking one
635
+ * sends it.
636
+ */
637
+ hideFollowups?: boolean;
638
+ /** Heading over the follow-ups. Default "Related questions"; `null` for none. */
639
+ followupsTitle?: React$1.ReactNode | null;
640
+ renderMarkdown?: RenderMarkdown;
641
+ /**
642
+ * Fill link previews with your own OpenGraph metadata. Called once per URL,
643
+ * on first hover — see `ResolveLinkPreview`.
644
+ */
645
+ resolveLinkPreview?: ResolveLinkPreview;
646
+ /** Put a copy button on fenced code blocks. Defaults to true. */
647
+ codeCopy?: boolean;
648
+ /** Render every link with your own component — a router link, say. */
649
+ linkComponent?: LinkComponent;
650
+ /**
651
+ * Your own header/toolbar, rendered above the chat. Nothing by default —
652
+ * the embed ships without chrome so it drops into yours.
653
+ */
654
+ header?: React$1.ReactNode;
655
+ /** Rendered below the chat, outside the composer. */
656
+ footer?: React$1.ReactNode;
657
+ /** Empty-state copy shown before the first message. */
658
+ emptyState?: React$1.ReactNode;
659
+ /** Light theme instead of the default dark. */
660
+ light?: boolean;
661
+ className?: string;
662
+ /** Per-slot class overrides — see `ChatClassNames`. */
663
+ classNames?: ChatClassNames;
664
+ style?: React$1.CSSProperties;
665
+ /**
666
+ * "inline" (default) renders the chat where you put it. "launcher" pins a
667
+ * support-style bubble to a corner of the viewport that opens the chat.
668
+ */
669
+ mode?: 'inline' | 'launcher';
670
+ /** Panel size — inline, or the launcher's popover. Number means px. */
671
+ width?: number | string;
672
+ height?: number | string;
673
+ /** Launcher only: corner to pin to. Default "bottom-right". */
674
+ position?: LauncherPosition;
675
+ /** Launcher only: distance from both edges of that corner. Default 24. */
676
+ offset?: number | string;
677
+ /** Launcher only: open as a corner popover (default) or over the whole screen. */
678
+ panel?: LauncherPanel;
679
+ /** Launcher only: text beside the bubble glyph, e.g. "Chat with us". */
680
+ launcherLabel?: string;
681
+ /** Launcher only: replaces the default speech-bubble glyph. */
682
+ launcherIcon?: React$1.ReactNode;
683
+ /** Launcher only: open on first render. Default false. */
684
+ defaultOpen?: boolean;
685
+ /** Launcher only: controlled open state. Pair with `onOpenChange`. */
686
+ open?: boolean;
687
+ onOpenChange?: (open: boolean) => void;
688
+ }
689
+ declare function AgnoChat(props: AgnoChatProps): React$1.ReactElement;
690
+
691
+ /** Scrollable transcript that auto-sticks to the bottom while streaming. */
692
+
693
+ interface MessageListProps {
694
+ /** Omit inside a `<ChatProvider>` to use the provider's transcript. */
695
+ messages?: ChatMessage[];
696
+ status?: ChatStatus;
697
+ activity?: string | null;
698
+ renderMarkdown?: RenderMarkdown;
699
+ emptyState?: React$1.ReactNode;
700
+ /** What is answering — picks the agent avatar. */
701
+ entityType?: EntityType;
702
+ /** Initials shown on the user avatar. Defaults to AgentOS's "ME". */
703
+ userInitials?: string;
704
+ /** Rendered after the last message (e.g. a human-in-the-loop panel). */
705
+ footer?: React$1.ReactNode;
706
+ /** Rendered above the first message, inside the scroll area. */
707
+ header?: React$1.ReactNode;
708
+ /** Replace how each message is rendered. */
709
+ renderMessage?: (message: ChatMessage, activity?: string | null) => React$1.ReactNode;
710
+ className?: string;
711
+ classNames?: ChatClassNames;
712
+ }
713
+ declare function MessageList({ messages, status, activity, renderMarkdown, emptyState, entityType, userInitials, footer, header, renderMessage, className, classNames, }: MessageListProps): React$1.ReactElement;
714
+
715
+ /**
716
+ * A complete chat surface built from a `useAgnoChat` result. Pass the hook's
717
+ * return value as `chat`; this renders the transcript, the live status, the
718
+ * human-in-the-loop panel, and the input box.
719
+ *
720
+ * Use this when you call `useAgnoChat` yourself (so you control the entity,
721
+ * session, headers, etc.). For a zero-wiring widget, use `<AgnoChat>`.
722
+ */
723
+
724
+ interface ChatWindowProps {
725
+ /** Omit inside a `<ChatProvider>`. */
726
+ chat?: UseAgnoChat;
727
+ placeholder?: string;
728
+ /** Initials shown on the user avatar. Defaults to AgentOS's "ME". */
729
+ userInitials?: string;
730
+ emptyState?: React$1.ReactNode;
731
+ allowFiles?: boolean;
732
+ /** The one-row composer instead of the dock — see `<ChatInput compact>`. */
733
+ compactInput?: boolean;
734
+ disabled?: boolean;
735
+ renderMarkdown?: RenderMarkdown;
736
+ /**
737
+ * Render the last run error above the input. Default false — it is raw
738
+ * backend text, too long for a narrow window. Read `chat.error` to show it
739
+ * your own way.
740
+ */
741
+ showErrors?: boolean;
742
+ /** Suggested prompts, offered while the transcript is empty. */
743
+ quickPrompts?: QuickPrompt[];
744
+ /** What a chip does. Defaults to sending it as the first message. */
745
+ onQuickPrompt?: (prompt: string) => void;
746
+ /** Hide the "Related questions" an agent suggests after its latest answer. */
747
+ hideFollowups?: boolean;
748
+ /** What a follow-up does. Defaults to sending it as the next message. */
749
+ onFollowup?: (prompt: string) => void;
750
+ /** Heading over the follow-ups. Default "Related questions"; `null` for none. */
751
+ followupsTitle?: React$1.ReactNode | null;
752
+ /** Replace how each message is rendered — see `<MessageList>`. */
753
+ renderMessage?: MessageListProps['renderMessage'];
754
+ /** Rendered above the transcript (your own toolbar, title, tabs…). */
755
+ header?: React$1.ReactNode;
756
+ /** Replace the composer entirely. Pass `false` for a read-only transcript. */
757
+ composer?: React$1.ReactNode | false;
758
+ className?: string;
759
+ classNames?: ChatClassNames;
760
+ }
761
+ declare function ChatWindow({ chat: chatProp, placeholder, userInitials, emptyState, allowFiles, compactInput, disabled, renderMarkdown, showErrors, quickPrompts, onQuickPrompt, hideFollowups, onFollowup, followupsTitle, renderMessage, header, composer, className, classNames, }: ChatWindowProps): React$1.ReactElement;
762
+
763
+ /** Renders a single chat message: content, tools, reasoning, media, citations, follow-ups. */
764
+
765
+ interface MessageProps {
766
+ message: ChatMessage;
767
+ /** Override the Markdown renderer (e.g. plug in react-markdown). */
768
+ renderMarkdown?: RenderMarkdown;
769
+ /** Live activity label, shown while streaming with no content yet. */
770
+ activity?: string | null;
771
+ /** What is answering — picks the avatar (Agno mark vs. the team glyph). */
772
+ entityType?: EntityType;
773
+ /** Initials shown on the user avatar. AgentOS falls back to "ME". */
774
+ userInitials?: string;
775
+ /** Hide the reasoning panel. */
776
+ hideReasoning?: boolean;
777
+ /** Hide tool calls. */
778
+ hideTools?: boolean;
779
+ /** Hide the sources block under the answer. */
780
+ hideSources?: boolean;
781
+ /**
782
+ * Render the "Related questions" the agent suggested under this message,
783
+ * sending the clicked one here. Off by default: `<ChatWindow>` pins them
784
+ * above the composer instead, so they stay in reach as the transcript grows.
785
+ */
786
+ onFollowup?: (prompt: string) => void;
787
+ /** Replace the avatar entirely. Pass `false` to drop it. */
788
+ avatar?: React$1.ReactNode | false;
789
+ /** Rendered after the message content, inside the body. */
790
+ children?: React$1.ReactNode;
791
+ className?: string;
792
+ classNames?: ChatClassNames;
793
+ }
794
+ declare function Message({ message, renderMarkdown, activity, avatar, children, className, classNames, entityType, userInitials, hideReasoning, hideTools, hideSources, onFollowup, }: MessageProps): React$1.ReactElement;
795
+
796
+ /**
797
+ * The AgentOS chat dock: a rounded card holding an auto-growing textarea and a
798
+ * bottom action row (attach on the left, send/stop on the right).
799
+ *
800
+ * It works as-is, and it also opens up for a host that needs more from the
801
+ * composer than a textarea — an @mention menu, context chips, a highlighted
802
+ * draft — without forking it:
803
+ *
804
+ * - `value` / `onValueChange` make the draft controlled.
805
+ * - `textareaProps` reach the textarea itself (key handlers, ARIA); a key
806
+ * handler that calls `preventDefault()` stops Enter from sending.
807
+ * - `renderTextarea` swaps the element for your own, given the props this one
808
+ * would have had — for a mirror-highlighted input, say.
809
+ * - `above` and `below` render inside the dock, around the field.
810
+ * - Dropped files land in the attachment tray, subject to `accept` and the
811
+ * size limits; the first reason a file was refused shows under the tray.
812
+ */
813
+
814
+ /** What the textarea receives — and what `renderTextarea` is handed. */
815
+ type ChatTextareaProps = React$1.TextareaHTMLAttributes<HTMLTextAreaElement> & {
816
+ ref: React$1.Ref<HTMLTextAreaElement>;
817
+ };
818
+ interface FileLimits {
819
+ /** Accepted extensions and/or MIME types, as the file picker takes them: `".md,.py,image/*"`. */
820
+ accept?: string;
821
+ /** Most files attached at once. */
822
+ maxFiles?: number;
823
+ /** Largest single file, in bytes. */
824
+ maxFileSize?: number;
825
+ /** Largest total across every attached file, in bytes. */
826
+ maxTotalSize?: number;
827
+ }
828
+ interface ChatInputProps extends FileLimits {
829
+ /**
830
+ * Omit inside a `<ChatProvider>` to send through the provider's chat. Return
831
+ * `false` (or a promise of it) to keep the draft — the send did not happen.
832
+ */
833
+ onSend?: (message: string, files?: File[]) => void | boolean | Promise<void | boolean>;
834
+ onStop?: () => void;
835
+ disabled?: boolean;
836
+ busy?: boolean;
837
+ placeholder?: string;
838
+ /** Allow attaching files. */
839
+ allowFiles?: boolean;
840
+ /**
841
+ * One row — the field with the buttons beside it — instead of the dock with
842
+ * its action row beneath. For a sidebar, a launcher, anywhere narrow.
843
+ */
844
+ compact?: boolean;
845
+ /** The draft, when you own it. Pair with `onValueChange`. */
846
+ value?: string;
847
+ onValueChange?: (value: string) => void;
848
+ /** Reach the textarea element. */
849
+ textareaRef?: React$1.Ref<HTMLTextAreaElement>;
850
+ /**
851
+ * Spread onto the textarea. Its `onKeyDown` runs before the Enter-to-send
852
+ * handling; call `preventDefault()` there to claim a key.
853
+ */
854
+ textareaProps?: React$1.TextareaHTMLAttributes<HTMLTextAreaElement>;
855
+ /**
856
+ * Replace the textarea with your own element, given the props this one would
857
+ * have rendered with. Your element sizes itself.
858
+ */
859
+ renderTextarea?: (props: ChatTextareaProps) => React$1.ReactNode;
860
+ /** Rendered inside the dock, above the attachment tray and the field. */
861
+ above?: React$1.ReactNode;
862
+ /** Rendered inside the dock, between the field and the action row. */
863
+ below?: React$1.ReactNode;
864
+ /** Text shown while files are dragged over the dock. */
865
+ dropLabel?: string;
866
+ /** Rendered in the left action group — where the entity picker sits. */
867
+ leading?: React$1.ReactNode;
868
+ /** Rendered in the right action group, before send. */
869
+ trailing?: React$1.ReactNode;
870
+ className?: string;
871
+ classNames?: ChatClassNames;
872
+ }
873
+ /** Does the file match an `accept` list, by extension or MIME type? */
874
+ declare function fileAccepted(file: File, accept?: string): boolean;
875
+ /**
876
+ * Apply the limits to files being added. Every limit is enforced; the message
877
+ * names the first reason something was left out.
878
+ */
879
+ declare function admitFiles(current: readonly File[], incoming: readonly File[], limits: FileLimits): {
880
+ files: File[];
881
+ error: string | null;
882
+ };
883
+ declare function ChatInput({ onSend, onStop, disabled, busy, placeholder, allowFiles, compact, accept, maxFiles, maxFileSize, maxTotalSize, value: controlled, onValueChange, textareaRef: externalRef, textareaProps, renderTextarea, above, below, dropLabel, leading, trailing, className, classNames, }: ChatInputProps): React$1.ReactElement;
884
+
885
+ /**
886
+ * Attachment previews, shown in a banner above the composer field — the
887
+ * AgentOS `FileUpload` banner: a count with a "clear all" control, then a
888
+ * horizontally scrolling row of items.
889
+ *
890
+ * Images render as a bordered thumbnail; everything else as a card with a
891
+ * file-type mark, the name, and a `TYPE • SIZE` label. Every item carries its
892
+ * remove control as a tab folded into the top-right corner.
893
+ */
894
+
895
+ interface FilePreviewProps {
896
+ files: File[];
897
+ onRemove: (index: number) => void;
898
+ onClear?: () => void;
899
+ className?: string;
900
+ }
901
+ declare function FilePreview({ files, onRemove, onClear, className }: FilePreviewProps): React$1.ReactElement | null;
902
+
903
+ /**
904
+ * The AgentOS "behind the scenes" panel: everything the run did on its way to
905
+ * the answer, folded under a single muted trigger above the message.
906
+ *
907
+ * The steps are derived from the run's own events, the way the AgentOS chat
908
+ * builds them — content deltas, model-request and reasoning-delta events are
909
+ * dropped, started/completed pairs collapse into one step that reports whether
910
+ * it has finished, and run lifecycle events read as "Run Started" / "Run
911
+ * Completed" with the run duration. Messages restored from session history
912
+ * carry their stored events, so the panel looks the same there.
913
+ *
914
+ * When a message has no events at all, the steps are synthesised from what it
915
+ * does carry (tools, reasoning, member turns, workflow steps).
916
+ */
917
+
918
+ interface BehindTheScenesProps {
919
+ message: ChatMessage;
920
+ /** True while this message is the one streaming. */
921
+ streaming?: boolean;
922
+ /** Live activity label, e.g. "Calling get_weather". */
923
+ activity?: string | null;
924
+ renderMarkdown?: RenderMarkdown;
925
+ defaultOpen?: boolean;
926
+ hideReasoning?: boolean;
927
+ hideTools?: boolean;
928
+ className?: string;
929
+ classNames?: ChatClassNames;
930
+ }
931
+ type BehindTheScenesStep = {
932
+ kind: 'status';
933
+ id: string;
934
+ label: string;
935
+ detail?: string;
936
+ icon: 'run' | 'continued';
937
+ } | {
938
+ kind: 'tool';
939
+ id: string;
940
+ tool: ToolExecution;
941
+ } | {
942
+ kind: 'reasoning';
943
+ id: string;
944
+ steps: ReasoningStep[];
945
+ completed: boolean;
946
+ } | {
947
+ kind: 'memory';
948
+ id: string;
949
+ completed: boolean;
950
+ } | {
951
+ kind: 'member';
952
+ id: string;
953
+ member: SubRun;
954
+ } | {
955
+ kind: 'step';
956
+ id: string;
957
+ step: WorkflowStep;
958
+ };
959
+ type Options = {
960
+ hideReasoning?: boolean;
961
+ hideTools?: boolean;
962
+ };
963
+ /** The steps shown for a message — from its events when it has them. */
964
+ declare function behindTheScenesItems(message: ChatMessage, opts?: Options): BehindTheScenesStep[];
965
+ /** Whether `<BehindTheScenes>` would render anything for this message. */
966
+ declare function hasBehindTheScenes(message: ChatMessage, opts?: Options): boolean;
967
+ /** The trigger label, mirroring AgentOS's `getBehindTheScenesLabel`. */
968
+ declare function behindTheScenesLabel(message: ChatMessage, streaming?: boolean, activity?: string | null): string;
969
+ declare function BehindTheScenes({ message, streaming, activity, renderMarkdown, defaultOpen, hideReasoning, hideTools, className, classNames, }: BehindTheScenesProps): React$1.ReactElement | null;
970
+
971
+ /**
972
+ * Tool calls, rendered the AgentOS way: a row of compact uppercase pills above
973
+ * the answer, with the selected one expanding into a detail panel showing its
974
+ * arguments and result.
975
+ */
976
+
977
+ declare function ToolCalls({ tools }: {
978
+ tools?: ToolExecution[];
979
+ }): React$1.ReactElement | null;
980
+
981
+ /** Renders a message's reasoning steps in a collapsible timeline. */
982
+
983
+ declare function Reasoning({ steps, defaultOpen, }: {
984
+ steps?: ReasoningStep[];
985
+ defaultOpen?: boolean;
986
+ }): React$1.ReactElement | null;
987
+
988
+ /**
989
+ * Renders the nested runs of a team or workflow turn — each team member's
990
+ * response (or each workflow step's executor) as a collapsible card with the
991
+ * member's name, streamed content and tool calls.
992
+ */
993
+
994
+ declare function MemberResponses({ members, renderMarkdown, title, }: {
995
+ members?: SubRun[];
996
+ renderMarkdown?: RenderMarkdown;
997
+ title?: string;
998
+ }): React$1.ReactElement | null;
999
+
1000
+ /**
1001
+ * Renders the steps of a workflow run as an ordered progress list, each with a
1002
+ * status indicator, the step name, and its collapsible output.
1003
+ */
1004
+
1005
+ declare function WorkflowSteps({ steps, renderMarkdown, title, }: {
1006
+ steps?: WorkflowStep[];
1007
+ renderMarkdown?: RenderMarkdown;
1008
+ title?: string;
1009
+ }): React$1.ReactElement | null;
1010
+
1011
+ /**
1012
+ * The sources behind an answer, as cards.
1013
+ *
1014
+ * Everything the message cited — retrieved knowledge-base chunks and links the
1015
+ * model browsed — is flattened into one numbered list by `collectSources`, so
1016
+ * the numbers here are the same ones the inline `[1]` markers in the answer
1017
+ * point at.
1018
+ */
1019
+
1020
+ interface CitationsProps {
1021
+ /** Retrieved knowledge-base chunks, as they arrive on the message. */
1022
+ references?: ReferenceData[];
1023
+ /** Links the model browsed, as they arrive on the message. */
1024
+ citations?: Citations$1;
1025
+ /**
1026
+ * A pre-built list, e.g. from `collectSources`. Wins over `references` and
1027
+ * `citations` — pass it when the inline markers were numbered elsewhere.
1028
+ */
1029
+ sources?: Source[];
1030
+ /** Heading above the cards. Defaults to "Sources used". */
1031
+ title?: string;
1032
+ /**
1033
+ * Pills shown in the row. The rest sit behind a "+N more" pill that opens a
1034
+ * list on hover. Defaults to 3; `0` puts every source in the row.
1035
+ */
1036
+ max?: number;
1037
+ className?: string;
1038
+ classNames?: ChatClassNames;
1039
+ }
1040
+ /**
1041
+ * One card: the site's favicon, the title and a link mark, linking to the
1042
+ * source. The number, URL and cited passage live on the hover card — a row of
1043
+ * cards under an answer only needs to say where it can take you.
1044
+ */
1045
+ declare function SourceCard({ source, className, }: {
1046
+ source: Source;
1047
+ className?: string;
1048
+ }): React$1.ReactElement;
1049
+ declare function Citations({ references, citations, sources: given, title, max, className, classNames, }: CitationsProps): React$1.ReactElement | null;
1050
+
1051
+ /**
1052
+ * "Related questions" — the follow-up prompts an agent suggests after its
1053
+ * answer, stacked as a list of one-line buttons. An agent built with
1054
+ * `followups=True` sends them as a `FollowupsCompleted` event and stores them
1055
+ * on the run; `<ChatWindow>` pins the latest answer's above the composer, and
1056
+ * `<Message onFollowup>` puts them under the answer instead. Render the
1057
+ * component yourself from `message.followups` to place them anywhere else.
1058
+ *
1059
+ * Prompts are trimmed, de-duplicated and clamped to one line each — a model
1060
+ * asked for "5–10 words" does not always comply, and a wrapped row reads like
1061
+ * an answer rather than a question to ask. The full text is on the `title`.
1062
+ */
1063
+
1064
+ interface FollowupsProps {
1065
+ /** The suggested prompts, as the run carried them. */
1066
+ items?: string[] | null;
1067
+ /** Called with the prompt text to send. */
1068
+ onSelect: (prompt: string) => void;
1069
+ /** Heading above the list. Pass `null` for none. Default "Related questions". */
1070
+ title?: React$1.ReactNode | null;
1071
+ /**
1072
+ * Lines each prompt may take before it is cut with an ellipsis. Default 1;
1073
+ * `false` lets them wrap.
1074
+ */
1075
+ lines?: number | false;
1076
+ /** Show at most this many. Default: all of them. */
1077
+ max?: number;
1078
+ /** Grey the list out (a run is in flight, the composer is disabled…). */
1079
+ disabled?: boolean;
1080
+ className?: string;
1081
+ classNames?: ChatClassNames;
1082
+ }
1083
+ /** Trim, drop empties, and keep the first of any duplicates (case-insensitively). */
1084
+ declare function normalizeFollowups(items?: readonly string[] | null): string[];
1085
+ declare function Followups({ items, onSelect, title, lines, max, disabled, className, classNames, }: FollowupsProps): React$1.ReactElement | null;
1086
+
1087
+ /**
1088
+ * Link previews: the little card that describes where a citation points.
1089
+ *
1090
+ * Two pieces of metadata feed it. The URL itself always yields a hostname and a
1091
+ * favicon, and the citation payload usually carries a title and the retrieved
1092
+ * passage — that much renders with no network beyond the site icon. Anything
1093
+ * richer (OpenGraph title, description, image) comes from the optional
1094
+ * `resolveLinkPreview` on `<ChatProvider>`, and only for links someone actually
1095
+ * points at: the fetch is triggered by the first hover, not by rendering.
1096
+ */
1097
+
1098
+ /**
1099
+ * Resolve metadata for `url`, at most once per URL per resolver.
1100
+ *
1101
+ * Nothing happens until `enabled` flips true, which is how hovering pays for
1102
+ * the lookup instead of rendering. Returns `null` while there is nothing to
1103
+ * add — the caller still has the hostname and favicon to fall back on.
1104
+ */
1105
+ declare function useLinkPreview(url: string | undefined, enabled: boolean): {
1106
+ preview: LinkPreview | null;
1107
+ loading: boolean;
1108
+ };
1109
+ /** The site's icon, falling back to a glyph when the origin serves none. */
1110
+ declare function Favicon({ url, kind, size, className, }: {
1111
+ url?: string;
1112
+ kind?: Source['kind'];
1113
+ size?: number;
1114
+ className?: string;
1115
+ }): React$1.ReactElement;
1116
+ interface LinkPreviewCardProps {
1117
+ source: Source;
1118
+ /** Resolved metadata, when a `resolveLinkPreview` returned some. */
1119
+ preview?: LinkPreview | null;
1120
+ loading?: boolean;
1121
+ className?: string;
1122
+ }
1123
+ /**
1124
+ * The preview body: site row, title, description. Shared by the hover card and
1125
+ * the source cards under a message, so the two always agree.
1126
+ */
1127
+ declare function LinkPreviewCard({ source, preview, loading, className, }: LinkPreviewCardProps): React$1.ReactElement;
1128
+ interface HoverPreviewProps {
1129
+ source: Source;
1130
+ /** The trigger — a citation marker or a link in the answer. */
1131
+ children: React$1.ReactElement;
1132
+ /** Turn the hover card off and render the trigger bare. */
1133
+ disabled?: boolean;
1134
+ className?: string;
1135
+ }
1136
+ /**
1137
+ * Wraps a citation marker or link so that pointing at it — or tabbing to it —
1138
+ * reveals the preview card. Escape dismisses it; the card is reachable with the
1139
+ * pointer, so links inside it stay clickable.
1140
+ */
1141
+ declare function HoverPreview({ source, children, disabled, className, }: HoverPreviewProps): React$1.ReactElement;
1142
+
1143
+ /** Renders images, videos and audio attached to a message. */
1144
+
1145
+ declare function Multimedia({ images, videos, audio, responseAudio, }: {
1146
+ images?: ImageData[];
1147
+ videos?: VideoData[];
1148
+ audio?: AudioData[];
1149
+ responseAudio?: AudioData;
1150
+ }): React$1.ReactElement | null;
1151
+
1152
+ /** A live status line showing what the run is currently doing. */
1153
+
1154
+ declare function StatusIndicator({ status, activity, }: {
1155
+ status: ChatStatus;
1156
+ activity?: string | null;
1157
+ }): React$1.ReactElement | null;
1158
+
1159
+ /**
1160
+ * A developer-facing live feed of run events. Consecutive repeats of the same
1161
+ * event (e.g. the stream of `RunContent` deltas) are folded into a single row
1162
+ * with a count, and each row is labelled with the agent/team/workflow it came
1163
+ * from — so a streaming run reads as one "RunContent ×N" line, not hundreds.
1164
+ */
1165
+
1166
+ declare function EventLog({ events, autoScroll, maxHeight, }: {
1167
+ events: RunEventData[];
1168
+ autoScroll?: boolean;
1169
+ maxHeight?: number;
1170
+ }): React$1.ReactElement;
1171
+
1172
+ /**
1173
+ * Human-in-the-loop panel, styled after the Agno OS chat HITL cards.
1174
+ *
1175
+ * When a run pauses, each pending tool / requirement renders as its own card:
1176
+ * the tool icon + UPPERCASE name, a collapsible Arguments accordion, per-card
1177
+ * Approve / Reject controls (with an optional rejection reason), and any
1178
+ * requested input fields. Submitting resolves every card and continues the run.
1179
+ */
1180
+
1181
+ interface HumanInputProps {
1182
+ message: ChatMessage;
1183
+ entityType?: EntityType;
1184
+ busy?: boolean;
1185
+ /** Continue the run with the resolved tools (agent/team) or step requirements (workflow). */
1186
+ onResolve: (resolution: {
1187
+ tools?: ToolExecution[];
1188
+ stepRequirements?: unknown[];
1189
+ }) => void;
1190
+ className?: string;
1191
+ }
1192
+ declare function HumanInput({ message, entityType, busy, onResolve, className, }: HumanInputProps): React$1.ReactElement | null;
1193
+
1194
+ /**
1195
+ * Entity picker styled after the Agno OS chat selector: a compact bordered
1196
+ * trigger showing the selection in mono-uppercase, opening a dark popover with
1197
+ * muted group labels (Agents / Teams / Workflows) and a check on the active
1198
+ * item. Custom popover (no native <select>, no extra deps).
1199
+ */
1200
+
1201
+ declare function EntitySelector({ entities, value, onChange, disabled, placeholder, className, classNames, }: {
1202
+ entities: Entity[];
1203
+ value?: Entity | null;
1204
+ onChange: (entity: Entity) => void;
1205
+ disabled?: boolean;
1206
+ placeholder?: string;
1207
+ className?: string;
1208
+ classNames?: ChatClassNames;
1209
+ }): React$1.ReactElement;
1210
+
1211
+ /**
1212
+ * The selected agent/team/workflow, shown read-only in the composer row — the
1213
+ * AgentOS `SelectComponentType` display: the name in mono uppercase, then the
1214
+ * model in a small bordered chip.
1215
+ *
1216
+ * This is deliberately not a control. AgentOS switches the entity from the
1217
+ * breadcrumb above the chat, not from the dock, so the selection is owned by
1218
+ * whatever renders the embed. Pass `entity` down and render `<EntitySelector>`
1219
+ * in your own chrome if you want users to change it.
1220
+ */
1221
+
1222
+ interface EntityBadgeProps {
1223
+ entity?: Entity | null;
1224
+ /** Shown when nothing is selected yet. */
1225
+ placeholder?: string;
1226
+ /** Hide the model mark. */
1227
+ hideModel?: boolean;
1228
+ className?: string;
1229
+ }
1230
+ declare function EntityBadge({ entity, placeholder, hideModel, className, }: EntityBadgeProps): React$1.ReactElement | null;
1231
+
1232
+ /**
1233
+ * Model-provider marks, shown on the selected-entity badge in the composer.
1234
+ *
1235
+ * The artwork is the AgentOS set (`agno-os/src/components/ui/icon/`), reduced to
1236
+ * plain geometry: the clip paths there wrap the full viewBox and their ids
1237
+ * would collide whenever an icon renders more than once on a page. Every mark
1238
+ * inherits `currentColor` so it follows the surrounding text.
1239
+ */
1240
+
1241
+ interface ProviderIconProps {
1242
+ size?: number;
1243
+ className?: string;
1244
+ }
1245
+ /**
1246
+ * Pick a mark from a provider or model string, the way AgentOS does — matching
1247
+ * on a substring so "anthropic", "claude-opus-5" and "us.anthropic.claude"
1248
+ * all land on the same logo. Returns null when nothing matches, and the badge
1249
+ * then falls back to the model name as text.
1250
+ */
1251
+ declare function getProviderIcon(value?: string): ((props: ProviderIconProps) => React$1.ReactElement) | null;
1252
+
1253
+ /**
1254
+ * A sidebar listing the past sessions of the selected entity. Clicking a
1255
+ * session loads its transcript; the trash icon deletes it.
1256
+ *
1257
+ * Pair with `useAgnoChat`: pass `chat.sessions`, `chat.loadSession`, etc.
1258
+ */
1259
+
1260
+ interface SessionListProps {
1261
+ /** Omit inside a `<ChatProvider>` to use the provider's session list. */
1262
+ sessions?: SessionEntry[];
1263
+ activeSessionId?: string;
1264
+ /** Sessions with a run in flight — each shows a spinner instead of the delete button. */
1265
+ streamingSessionIds?: string[];
1266
+ loading?: boolean;
1267
+ onSelect?: (sessionId: string) => void;
1268
+ onDelete?: (sessionId: string) => void;
1269
+ onNew?: () => void;
1270
+ title?: string;
1271
+ /** Hide the header row. */
1272
+ hideTitle?: boolean;
1273
+ className?: string;
1274
+ classNames?: ChatClassNames;
1275
+ }
1276
+ declare function SessionList({ sessions, activeSessionId, streamingSessionIds, loading, onSelect, onDelete, onNew, title, hideTitle, className, classNames, }: SessionListProps): React$1.ReactElement;
1277
+
1278
+ /**
1279
+ * The icon set.
1280
+ *
1281
+ * Standard icons come from lucide-react, which is what AgentOS itself renders.
1282
+ * They were hand-traced here to keep the install dependency-free, and the
1283
+ * approximations drifted — the paperclip read as a hook rather than a clip —
1284
+ * so the geometry is now maintained upstream instead. lucide is
1285
+ * `sideEffects: false` and tree-shakeable, so only the icons imported below
1286
+ * reach a consumer's bundle.
1287
+ *
1288
+ * Re-exported under our own names so call sites stay stable if a mapping
1289
+ * changes, and so the two pieces of Agno artwork lucide has no equivalent for
1290
+ * — the brand mark and the team glyph — sit alongside them. Model-provider
1291
+ * marks live in `providerIcons.tsx` for the same reason.
1292
+ */
1293
+
1294
+ type IconProps = {
1295
+ size?: number;
1296
+ className?: string;
1297
+ };
1298
+ declare const ChevronDown: ({ size, className }: IconProps) => React$1.ReactElement;
1299
+ declare const ArrowUp: ({ size, className }: IconProps) => React$1.ReactElement;
1300
+ declare const Paperclip: ({ size, className }: IconProps) => React$1.ReactElement;
1301
+ declare const FileIcon: ({ size, className }: IconProps) => React$1.ReactElement;
1302
+ declare const FileType: ({ size, className }: IconProps) => React$1.ReactElement;
1303
+ declare const FileAudio: ({ size, className }: IconProps) => React$1.ReactElement;
1304
+ declare const FileVideo: ({ size, className }: IconProps) => React$1.ReactElement;
1305
+ declare const Wrench: ({ size, className }: IconProps) => React$1.ReactElement;
1306
+ declare const BookOpen: ({ size, className }: IconProps) => React$1.ReactElement;
1307
+ declare const Globe: ({ size, className }: IconProps) => React$1.ReactElement;
1308
+ /** Trailing mark on a source pill. */
1309
+ declare const LinkIcon: ({ size, className }: IconProps) => React$1.ReactElement;
1310
+ declare const Brain: ({ size, className }: IconProps) => React$1.ReactElement;
1311
+ declare const Box: ({ size, className }: IconProps) => React$1.ReactElement;
1312
+ declare const Plus: ({ size, className }: IconProps) => React$1.ReactElement;
1313
+ declare const Check: ({ size, className }: IconProps) => React$1.ReactElement;
1314
+ declare const Copy: ({ size, className }: IconProps) => React$1.ReactElement;
1315
+ declare const Close: ({ size, className }: IconProps) => React$1.ReactElement;
1316
+ /** Memory-update steps. */
1317
+ declare const Memory: ({ size, className }: IconProps) => React$1.ReactElement;
1318
+ /** Run-continued marker. */
1319
+ declare const Rerun: ({ size, className }: IconProps) => React$1.ReactElement;
1320
+ declare const Pulse: ({ size, className }: IconProps) => React$1.ReactElement;
1321
+ declare const Trash: ({ size, className }: IconProps) => React$1.ReactElement;
1322
+ declare const ChatBubble: ({ size, className }: IconProps) => React$1.ReactElement;
1323
+ declare const Spinner: ({ size, className }: IconProps) => React$1.ReactElement;
1324
+ /** The stop control is a filled square, not an outline. */
1325
+ declare function Stop({ size, className }: IconProps): React$1.ReactElement;
1326
+ /** The Agno mark — used as the agent avatar, exactly as in AgentOS. */
1327
+ declare function AgnoMark({ size, className }: IconProps): React$1.ReactElement;
1328
+ /** The AgentOS `team` glyph, drawn in the current colour. */
1329
+ declare function TeamGlyph({ size, className }: IconProps): React$1.ReactElement;
1330
+ /** The grid loader AgentOS shows while a run is working. */
1331
+ declare function GridLoader({ className }: {
1332
+ className?: string;
1333
+ }): React$1.ReactElement;
1334
+
1335
+ export { AgnoChat, type AgnoChatProps, AgnoMark, ArrowUp, BehindTheScenes, type BehindTheScenesProps, BookOpen, Box, Brain, ChatBubble, type ChatClassNames, type ChatContextValue, ChatInput, type ChatInputProps, ChatLauncher, type ChatLauncherProps, ChatProvider, type ChatProviderProps, type ChatTextareaProps, ChatWindow, type ChatWindowProps, Check, ChevronDown, Citations, type CitationsProps, Close, Copy, EntityBadge, type EntityBadgeProps, EntitySelector, EventLog, Favicon, FileAudio, FileIcon, type FileLimits, FilePreview, type FilePreviewProps, FileType, FileVideo, Followups, type FollowupsProps, Globe, GridLoader, HoverPreview, type HoverPreviewProps, HumanInput, type HumanInputProps, type LauncherPanel, type LauncherPosition, type LinkComponent, LinkIcon, type LinkPreview, LinkPreviewCard, type LinkPreviewCardProps, Markdown, type MarkdownProps, MemberResponses, Memory, Message, MessageList, type MessageListProps, type MessageProps, Multimedia, Paperclip, Plus, Pulse, type QuickPrompt, QuickPrompts, type QuickPromptsProps, Reasoning, type RenderMarkdown, Rerun, type ResolveLinkPreview, type SendOptions, SessionList, type SessionListProps, type Source, SourceCard, SourcesProvider, Spinner, StatusIndicator, Stop, TeamGlyph, ToolCalls, Trash, type UseAgnoChat, type UseAgnoChatOptions, WorkflowSteps, Wrench, admitFiles, behindTheScenesItems, behindTheScenesLabel, collectSources, displayUrl, faviconUrl, fileAccepted, getProviderIcon, hasBehindTheScenes, linkCitations, normalizeFollowups, quickPromptLabel, quickPromptText, sourceHost, sourcesFromMarkdown, useAgnoChat, useChatContext, useLinkComponent, useLinkPreview, useOptionalChatContext, useResolvedChat, useResolvedClassNames, useSources, withoutSourcesLine, writeClipboard };