@erdoai/ui 0.1.20 → 0.1.24

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.
package/dist/index.d.cts CHANGED
@@ -1,12 +1,19 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React$1 from 'react';
3
3
  import React__default from 'react';
4
- import { ErdoClient, ContentItem, InvokeResult, LogEntry, ToolGroup, InvocationStatus as InvocationStatus$1, SSEEvent, InvokeParams } from '@erdoai/types';
4
+ import { ErdoClient, ContentItem, InvokeResult, LogEntry, ToolGroup, InvocationStatus as InvocationStatus$1, SSEEvent, Thread } from '@erdoai/types';
5
5
  export { ContentItem } from '@erdoai/types';
6
6
  import * as RechartsPrimitive from 'recharts';
7
7
  import { UseQueryResult } from '@tanstack/react-query';
8
8
  import { ClassValue } from 'clsx';
9
9
 
10
+ /**
11
+ * Dataset details returned by getDatasetDetails
12
+ */
13
+ interface DatasetDetails {
14
+ id: string;
15
+ name: string;
16
+ }
10
17
  /**
11
18
  * Interface for custom data fetching implementations.
12
19
  * Use this when you need to override the default REST API behavior,
@@ -17,6 +24,16 @@ import { ClassValue } from 'clsx';
17
24
  */
18
25
  interface DataFetcher {
19
26
  fetchDatasetContents: (slug: string, invocationId: string) => Promise<any[]>;
27
+ /**
28
+ * Get dataset details (id and name) by slug.
29
+ * Used by DatasetDownload component to resolve slug to downloadable dataset.
30
+ */
31
+ getDatasetDetails?: (slug: string, threadId: string) => Promise<DatasetDetails | null>;
32
+ /**
33
+ * Download a dataset file by ID.
34
+ * Returns a Blob that can be saved as a file.
35
+ */
36
+ downloadDataset?: (datasetId: string) => Promise<Blob>;
20
37
  }
21
38
  /**
22
39
  * Configuration for the ErdoProvider.
@@ -27,6 +44,11 @@ interface ErdoProviderConfig {
27
44
  * Used by default REST implementation in hooks.
28
45
  */
29
46
  baseUrl: string;
47
+ /**
48
+ * Optional thread ID for dataset operations.
49
+ * Used by DatasetDownload to resolve dataset slugs.
50
+ */
51
+ threadId?: string;
30
52
  /**
31
53
  * Optional auth token for API calls.
32
54
  * Will be sent as Bearer token in Authorization header.
@@ -46,8 +68,8 @@ interface ErdoProviderConfig {
46
68
  */
47
69
  token?: string;
48
70
  /**
49
- * Optional ErdoClient for invoking bots.
50
- * Required if using useInvocation hook.
71
+ * Optional ErdoClient for thread operations.
72
+ * Required if using useThread hook.
51
73
  */
52
74
  client?: ErdoClient;
53
75
  /**
@@ -82,6 +104,21 @@ interface ErdoProviderConfig {
82
104
  content: any;
83
105
  className?: string;
84
106
  }>;
107
+ /**
108
+ * Optional callback when a suggestion is clicked.
109
+ * Use this to submit the suggestion as a new message.
110
+ *
111
+ * Example:
112
+ * ```tsx
113
+ * <ErdoProvider config={{
114
+ * baseUrl: '...',
115
+ * onSuggestionClick: (suggestion) => sendMessage(suggestion)
116
+ * }}>
117
+ * <App />
118
+ * </ErdoProvider>
119
+ * ```
120
+ */
121
+ onSuggestionClick?: (suggestion: string) => void;
85
122
  }
86
123
  interface ErdoProviderProps {
87
124
  children: React__default.ReactNode;
@@ -713,6 +750,14 @@ declare class ErrorBoundary extends React__default.Component<{
713
750
  render(): React__default.ReactNode;
714
751
  }
715
752
 
753
+ /**
754
+ * Spinning loader shown while content is being written/generated.
755
+ */
756
+ declare function WritingLoader(): react_jsx_runtime.JSX.Element;
757
+ /**
758
+ * Bouncing dots loader shown while streaming content is being parsed.
759
+ */
760
+ declare function StreamingLoader(): react_jsx_runtime.JSX.Element;
716
761
  /** Props passed to all content components */
717
762
  interface ContentComponentProps {
718
763
  content: ContentItem;
@@ -779,19 +824,29 @@ interface ErdoUIProps {
779
824
  /**
780
825
  * Main component for rendering Erdo agent results
781
826
  *
782
- * @example
827
+ * @example Server-side invocation result
828
+ * ```tsx
829
+ * import { ErdoUI } from '@erdoai/ui';
830
+ *
831
+ * // On your server
832
+ * const result = await client.invoke('my-bot', { messages: [...] });
833
+ *
834
+ * // On your client
835
+ * <ErdoUI result={result} />
836
+ * ```
837
+ *
838
+ * @example Client-side streaming with useThread
783
839
  * ```tsx
784
- * import { ErdoUI, useInvocation } from '@erdoai/ui';
840
+ * import { useThread, Content } from '@erdoai/ui';
785
841
  *
786
842
  * function MyComponent() {
787
- * const { result, isStreaming, invoke } = useInvocation();
843
+ * const { activeMessages, isStreaming, sendMessage } = useThread({ botKey: 'my-bot' });
788
844
  *
789
845
  * return (
790
846
  * <div>
791
- * <button onClick={() => invoke('my-bot', { messages: [...] })}>
792
- * Invoke
793
- * </button>
794
- * <ErdoUI result={result} isStreaming={isStreaming} />
847
+ * {activeMessages.flatMap(msg => msg.contents).map(content => (
848
+ * <Content key={content.id} content={content} />
849
+ * ))}
795
850
  * </div>
796
851
  * );
797
852
  * }
@@ -1118,6 +1173,29 @@ interface StatusSpinnerProps {
1118
1173
  */
1119
1174
  declare function StatusSpinner({ status, color, size, className }: StatusSpinnerProps): react_jsx_runtime.JSX.Element;
1120
1175
 
1176
+ interface DatasetDownloadProps {
1177
+ /** Dataset slug to download */
1178
+ slug: string;
1179
+ /** Invocation ID (used for context, may be needed by some backends) */
1180
+ invocationId?: string;
1181
+ /** Optional thread ID override (falls back to provider's threadId) */
1182
+ threadId?: string;
1183
+ /** Optional class name for styling */
1184
+ className?: string;
1185
+ }
1186
+ /**
1187
+ * A download button component for datasets.
1188
+ *
1189
+ * Uses the DataFetcher from ErdoProvider if available, otherwise falls back
1190
+ * to REST API calls using baseUrl and auth tokens.
1191
+ *
1192
+ * @example
1193
+ * ```tsx
1194
+ * <DatasetDownload slug="my-dataset" invocationId="abc123" />
1195
+ * ```
1196
+ */
1197
+ declare function DatasetDownload({ slug, invocationId: _invocationId, threadId: threadIdProp, className, }: DatasetDownloadProps): react_jsx_runtime.JSX.Element | null;
1198
+
1121
1199
  interface ZoomState {
1122
1200
  refAreaLeft: number | null;
1123
1201
  refAreaRight: number | null;
@@ -1181,58 +1259,118 @@ declare function useDatasetContents(datasetSlug: string, invocationId: string):
1181
1259
  */
1182
1260
  declare function useMultipleDatasetContents(datasetSlugs: string[], invocationId: string): UseQueryResult<any[], Error>[];
1183
1261
 
1184
- interface UseInvocationOptions {
1262
+ interface UseThreadOptions {
1263
+ /** Initial thread ID to use (if resuming an existing thread) */
1264
+ threadId?: string;
1265
+ /** Bot key to use for messages (optional - uses thread's default bot if not specified) */
1266
+ botKey?: string;
1185
1267
  /** Called for each SSE event received during streaming */
1186
1268
  onEvent?: (event: SSEEvent) => void;
1187
- /** Called when invocation completes successfully */
1188
- onFinish?: (result: InvokeResult) => void;
1269
+ /** Called when a message completes successfully */
1270
+ onFinish?: () => void;
1189
1271
  /** Called if an error occurs */
1190
1272
  onError?: (error: Error) => void;
1191
1273
  }
1192
- interface UseInvocationReturn {
1193
- /** Current invocation result (updates during streaming) */
1194
- result: InvokeResult | null;
1195
- /** Whether an invocation is currently in progress */
1274
+ interface UseThreadReturn {
1275
+ /** Current thread (null if not yet created) */
1276
+ thread: Thread | null;
1277
+ /** Whether a message is currently being sent/streamed */
1196
1278
  isStreaming: boolean;
1197
- /** Error if the last invocation failed */
1279
+ /** Error if the last operation failed */
1198
1280
  error: Error | null;
1199
- /** Function to start a new invocation */
1200
- invoke: (botKey: string, params: InvokeParams) => Promise<InvokeResult>;
1201
- /** Function to cancel the current invocation */
1281
+ /** Active messages being streamed (with parsedJson populated) */
1282
+ activeMessages: MessageWithContents[];
1283
+ /**
1284
+ * Flattened, filtered contents ready for rendering with the Content component.
1285
+ * Only includes visible content (user_visibility === 'visible').
1286
+ */
1287
+ streamingContents: ContentItem[];
1288
+ /** Function to send a message to the thread */
1289
+ sendMessage: (content: string) => Promise<void>;
1290
+ /** Function to cancel the current message */
1202
1291
  cancel: () => void;
1292
+ /** Function to create or set the thread */
1293
+ setThread: (thread: Thread) => void;
1203
1294
  }
1204
1295
  /**
1205
- * Hook for invoking Erdo bots and streaming results.
1296
+ * Hook for managing a thread and sending messages.
1297
+ *
1298
+ * Uses the thread/message API (`/threads/{id}/message`) which provides proper
1299
+ * message persistence and SSE event structure for UI rendering.
1300
+ *
1301
+ * ## Why threads instead of direct bot invoke?
1302
+ *
1303
+ * The direct bot invoke endpoint (`/bots/{key}/invoke`) returns raw SSE events
1304
+ * without message wrapping. The thread endpoint wraps all events with:
1305
+ * - `message created` events that establish message IDs
1306
+ * - Proper paths like `messages/{msgId}/contents/{idx}` for content
1307
+ * - `message updated` events for completion status
1308
+ *
1309
+ * This structure is required by `handleSSEEvent` to build the entity tree
1310
+ * that React components (like `Content`) use for rendering. Without it,
1311
+ * the UI components cannot properly track and display streaming content.
1312
+ *
1313
+ * For server-side processing where you don't need React rendering,
1314
+ * use `ErdoClient.invoke()` or `ErdoClient.invokeStream()` directly.
1315
+ *
1316
+ * ## Persisting message history
1317
+ *
1318
+ * This hook focuses on streaming new messages. For chat history, we recommend
1319
+ * storing messages in your own database as they complete:
1320
+ *
1321
+ * ```tsx
1322
+ * const { streamingContents, sendMessage } = useThread({
1323
+ * botKey: 'org.my-bot',
1324
+ * onFinish: () => {
1325
+ * // Save to your database when message completes
1326
+ * await saveMessageToDb(threadId, streamingContents);
1327
+ * },
1328
+ * });
1329
+ *
1330
+ * // Load history from your database
1331
+ * const { data: history } = useQuery({
1332
+ * queryKey: ['messages', threadId],
1333
+ * queryFn: () => fetchMessagesFromDb(threadId),
1334
+ * });
1335
+ * ```
1336
+ *
1337
+ * This gives you full control over your data and avoids extra API calls.
1338
+ *
1339
+ * Alternatively, you can fetch history from Erdo using `client.getThreadMessages()`:
1340
+ *
1341
+ * ```tsx
1342
+ * const { data: history } = useQuery({
1343
+ * queryKey: ['thread', 'messages', threadId],
1344
+ * queryFn: () => client.getThreadMessages(threadId),
1345
+ * });
1346
+ * ```
1206
1347
  *
1207
1348
  * Requires ErdoProvider with a client configured.
1208
1349
  *
1209
1350
  * @example
1210
1351
  * ```tsx
1211
- * function MyComponent() {
1212
- * const { result, isStreaming, invoke } = useInvocation({
1213
- * onEvent: (event) => console.log('Event:', event),
1214
- * onFinish: (result) => console.log('Done:', result),
1215
- * });
1352
+ * import { useThread, Content } from '@erdoai/ui';
1216
1353
  *
1217
- * const handleAnalyze = async () => {
1218
- * await invoke('org.my-bot', {
1219
- * messages: [{ role: 'user', content: 'Analyze sales data' }],
1220
- * datasets: ['sales-2024'],
1221
- * });
1222
- * };
1354
+ * function MyChat() {
1355
+ * const { isStreaming, streamingContents, sendMessage } = useThread({
1356
+ * botKey: 'org.my-bot',
1357
+ * onFinish: () => console.log('Message complete'),
1358
+ * });
1223
1359
  *
1224
1360
  * return (
1225
1361
  * <div>
1226
- * <button onClick={handleAnalyze} disabled={isStreaming}>
1227
- * {isStreaming ? 'Analyzing...' : 'Analyze'}
1362
+ * {streamingContents.map((content, idx) => (
1363
+ * <Content key={content.id || idx} content={content} />
1364
+ * ))}
1365
+ * <button onClick={() => sendMessage('Hello')} disabled={isStreaming}>
1366
+ * Send
1228
1367
  * </button>
1229
- * {result && <div>Result: {JSON.stringify(result)}</div>}
1230
1368
  * </div>
1231
1369
  * );
1232
1370
  * }
1233
1371
  * ```
1234
1372
  */
1235
- declare function useInvocation(options?: UseInvocationOptions): UseInvocationReturn;
1373
+ declare function useThread(options?: UseThreadOptions): UseThreadReturn;
1236
1374
 
1237
1375
  /**
1238
1376
  * Format a value based on its type and specified format pattern
@@ -1297,6 +1435,23 @@ declare function handleIncrementalMixedJsonParsing(outputContent: MessageContent
1297
1435
  * Returns the updated entity at the root level (typically a message or message_content),
1298
1436
  * or null if no update was performed (e.g., for message finished events).
1299
1437
  *
1438
+ * ## Important: Requires message-wrapped SSE events
1439
+ *
1440
+ * This function expects SSE events from the thread/message endpoint (`/threads/{id}/message`),
1441
+ * NOT from the direct bot invoke endpoint (`/bots/{key}/invoke`).
1442
+ *
1443
+ * The thread endpoint wraps events with message metadata:
1444
+ * - `message created` events establish message IDs in activeMessagesByID
1445
+ * - Event paths like `messages/{msgId}/contents/{idx}` locate content in the tree
1446
+ * - `message updated` events signal completion
1447
+ *
1448
+ * The direct invoke endpoint returns raw events without this wrapping, so content
1449
+ * cannot be properly associated with messages and the entity tree cannot be built.
1450
+ *
1451
+ * For React UI rendering, always use thread-based messaging via:
1452
+ * - `useThread` hook (client-side)
1453
+ * - `ErdoClient.sendMessage()` (server-side proxy)
1454
+ *
1300
1455
  * Note: Only message or message_content types can be returned as root objects.
1301
1456
  * Other entity types like invocation, step, output, etc. will be nested inside
1302
1457
  * a message_content entity.
@@ -1313,4 +1468,4 @@ declare function handleIncrementalMixedJsonParsing(outputContent: MessageContent
1313
1468
  */
1314
1469
  declare function handleSSEEvent(eventType: string, event: SSEEventData, path: string[], threadID: string, activeMessagesByID: Record<string, MessageWithContents>, currentEntity?: Entity | null, parents?: Entity[], entityIds?: Record<string, string>): Entity | null;
1315
1470
 
1316
- export { BarChart, type BaseChartProps, type BotInvocation, BotInvocationContent, type BotInvocationContentData, type BotInvocationContentProps, type BotInvocationData, type BotInvocationEventInfo, type BotInvocationStatusInfo, Chart, type ChartConfig, ChartContainer, ChartContent, type ChartContentProps, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, CodeexecContent, type CodeexecContentProps, CodegenContent, type CodegenContentProps, CollapsibleCodeBlock, type CollapsibleCodeBlockProps, Content, type ContentChartConfig, type ContentChunk, type ContentComponentProps, type ContentProps, type ContentType, type DataFetcher, DatasetChart, type DatasetChartProps, DatasetTable, type DatasetTableProps, type Entity, type EntityType, ErdoProvider, type ErdoProviderConfig, type ErdoProviderProps, ErdoUI, type ErdoUIProps, ErrorBoundary, ExecutionStatus, ExpandableOutputContent, type ExpandableOutputContentProps, HeatmapChart, InvocationEvent, type InvocationEventProps, InvocationEvents, type InvocationEventsProps, InvocationStatus, JSONStreamParser, type JSONValue, JsonContent, type JsonContentProps, LineChart, Log, LogContent, type LogContentProps, type LogProps, MarkdownContent, type MarkdownContentProps, type Message, type MessageContent, type MessageStreamingState, type MessageWithContents, Output, type OutputContent, type OutputProps, type OutputWithContents, PieChart, type ResolvedBotInvocation, type ResultHandler, type SSEEventData, ScatterChart, type SpinnerStatus, SqlContent, type SqlContentProps, type Status, type StatusEvent, StatusSpinner, type StatusSpinnerProps, StderrText, StdoutText, StdwarnText, type Step, StepInvocation, type StepInvocationProps, StepInvocationStatus, type StepInvocationStatusProps, TableContent, type TableContentProps, TextContent, type TextContentProps, ThinkingContent, type ThinkingContentProps, ToolGroupContent, type ToolGroupContentProps, type UseInvocationOptions, type UseInvocationReturn, WebParseContent, type WebParseContentProps, WebSearchContent, type WebSearchContentProps, type WrapperType, cn, extractContentItems, formatValue, handleIncrementalMixedJsonParsing, handleSSEEvent, isJsonLike, isParsingComplete, isParsingInProgress, isWhitespaceChar, parseCompleteJson, parseMixedJson, parseToDate, resolveKeyFromData, toSnakeCase, useChartZoom, useDatasetContents, useErdoConfig, useErdoConfigOptional, useInvocation, useMultipleDatasetContents };
1471
+ export { BarChart, type BaseChartProps, type BotInvocation, BotInvocationContent, type BotInvocationContentData, type BotInvocationContentProps, type BotInvocationData, type BotInvocationEventInfo, type BotInvocationStatusInfo, Chart, type ChartConfig, ChartContainer, ChartContent, type ChartContentProps, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, CodeexecContent, type CodeexecContentProps, CodegenContent, type CodegenContentProps, CollapsibleCodeBlock, type CollapsibleCodeBlockProps, Content, type ContentChartConfig, type ContentChunk, type ContentComponentProps, type ContentProps, type ContentType, type DataFetcher, DatasetChart, type DatasetChartProps, type DatasetDetails, DatasetDownload, type DatasetDownloadProps, DatasetTable, type DatasetTableProps, type Entity, type EntityType, ErdoProvider, type ErdoProviderConfig, type ErdoProviderProps, ErdoUI, type ErdoUIProps, ErrorBoundary, ExecutionStatus, ExpandableOutputContent, type ExpandableOutputContentProps, HeatmapChart, InvocationEvent, type InvocationEventProps, InvocationEvents, type InvocationEventsProps, InvocationStatus, JSONStreamParser, type JSONValue, JsonContent, type JsonContentProps, LineChart, Log, LogContent, type LogContentProps, type LogProps, MarkdownContent, type MarkdownContentProps, type Message, type MessageContent, type MessageStreamingState, type MessageWithContents, Output, type OutputContent, type OutputProps, type OutputWithContents, PieChart, type ResolvedBotInvocation, type ResultHandler, type SSEEventData, ScatterChart, type SpinnerStatus, SqlContent, type SqlContentProps, type Status, type StatusEvent, StatusSpinner, type StatusSpinnerProps, StderrText, StdoutText, StdwarnText, type Step, StepInvocation, type StepInvocationProps, StepInvocationStatus, type StepInvocationStatusProps, StreamingLoader, TableContent, type TableContentProps, TextContent, type TextContentProps, ThinkingContent, type ThinkingContentProps, ToolGroupContent, type ToolGroupContentProps, type UseThreadOptions, type UseThreadReturn, WebParseContent, type WebParseContentProps, WebSearchContent, type WebSearchContentProps, type WrapperType, WritingLoader, cn, extractContentItems, formatValue, handleIncrementalMixedJsonParsing, handleSSEEvent, isJsonLike, isParsingComplete, isParsingInProgress, isWhitespaceChar, parseCompleteJson, parseMixedJson, parseToDate, resolveKeyFromData, toSnakeCase, useChartZoom, useDatasetContents, useErdoConfig, useErdoConfigOptional, useMultipleDatasetContents, useThread };