@erdoai/ui 0.1.5
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/README.md +300 -0
- package/dist/index.d.ts +931 -0
- package/dist/index.js +4043 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# @erdoai/ui
|
|
2
|
+
|
|
3
|
+
React components for rendering Erdo AI agent results, including charts, tables, and content renderers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @erdoai/ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Peer Dependencies
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install react react-dom @tanstack/react-query
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### 1. Set up the Provider
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { ErdoProvider } from '@erdoai/ui';
|
|
23
|
+
import { ErdoClient } from '@erdoai/server';
|
|
24
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
25
|
+
|
|
26
|
+
const queryClient = new QueryClient();
|
|
27
|
+
const erdoClient = new ErdoClient({
|
|
28
|
+
endpoint: 'https://api.erdo.ai',
|
|
29
|
+
authToken: process.env.ERDO_API_KEY,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
function App() {
|
|
33
|
+
return (
|
|
34
|
+
<QueryClientProvider client={queryClient}>
|
|
35
|
+
<ErdoProvider
|
|
36
|
+
config={{
|
|
37
|
+
baseUrl: 'https://api.erdo.ai',
|
|
38
|
+
client: erdoClient,
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<YourApp />
|
|
42
|
+
</ErdoProvider>
|
|
43
|
+
</QueryClientProvider>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Invoke Agents and Render Results
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { useInvocation, Content } from '@erdoai/ui';
|
|
52
|
+
|
|
53
|
+
function ChatInterface() {
|
|
54
|
+
const { result, isStreaming, invoke } = useInvocation();
|
|
55
|
+
|
|
56
|
+
const handleSubmit = async (query: string) => {
|
|
57
|
+
await invoke('data-analyst', { query });
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
<form onSubmit={(e) => {
|
|
63
|
+
e.preventDefault();
|
|
64
|
+
handleSubmit(e.target.query.value);
|
|
65
|
+
}}>
|
|
66
|
+
<input name="query" placeholder="Ask a question..." />
|
|
67
|
+
<button type="submit" disabled={isStreaming}>
|
|
68
|
+
{isStreaming ? 'Analyzing...' : 'Send'}
|
|
69
|
+
</button>
|
|
70
|
+
</form>
|
|
71
|
+
|
|
72
|
+
{result?.contents.map((content) => (
|
|
73
|
+
<Content key={content.id} item={content} />
|
|
74
|
+
))}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Components
|
|
81
|
+
|
|
82
|
+
### Content Router
|
|
83
|
+
|
|
84
|
+
Automatically renders the appropriate component based on content type:
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { Content } from '@erdoai/ui';
|
|
88
|
+
|
|
89
|
+
<Content item={contentItem} />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Individual Renderers
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import {
|
|
96
|
+
TextContent,
|
|
97
|
+
JsonContent,
|
|
98
|
+
MarkdownContent,
|
|
99
|
+
TableContent,
|
|
100
|
+
ChartContent,
|
|
101
|
+
} from '@erdoai/ui';
|
|
102
|
+
|
|
103
|
+
<TextContent content="Plain text content" />
|
|
104
|
+
|
|
105
|
+
<JsonContent content={{ key: 'value', nested: { data: true } }} />
|
|
106
|
+
|
|
107
|
+
<MarkdownContent text="# Heading\n\nParagraph with **bold** text." />
|
|
108
|
+
|
|
109
|
+
<TableContent
|
|
110
|
+
columns={[
|
|
111
|
+
{ column_name: 'Name', key: 'name' },
|
|
112
|
+
{ column_name: 'Value', key: 'value', value_type: 'number' },
|
|
113
|
+
]}
|
|
114
|
+
data={[
|
|
115
|
+
{ name: 'Item 1', value: 100 },
|
|
116
|
+
{ name: 'Item 2', value: 200 },
|
|
117
|
+
]}
|
|
118
|
+
/>
|
|
119
|
+
|
|
120
|
+
<ChartContent
|
|
121
|
+
config={{
|
|
122
|
+
chart_type: 'bar',
|
|
123
|
+
chart_title: 'Sales by Region',
|
|
124
|
+
x_axis: { axis_label: 'Region', key: 'region' },
|
|
125
|
+
y_axes: [{ axis_label: 'Revenue', key: 'revenue' }],
|
|
126
|
+
series: [{ series_name: 'Revenue', key: 'revenue', color: '#3b82f6' }],
|
|
127
|
+
}}
|
|
128
|
+
data={chartData}
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Charts
|
|
133
|
+
|
|
134
|
+
Standalone chart components that accept data as props:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { BarChart, LineChart, PieChart, ScatterChart, HeatmapChart } from '@erdoai/ui';
|
|
138
|
+
|
|
139
|
+
<BarChart
|
|
140
|
+
title="Monthly Sales"
|
|
141
|
+
data={[
|
|
142
|
+
{ month: 'Jan', revenue: 1000 },
|
|
143
|
+
{ month: 'Feb', revenue: 1500 },
|
|
144
|
+
{ month: 'Mar', revenue: 1200 },
|
|
145
|
+
]}
|
|
146
|
+
displayConfig={{
|
|
147
|
+
month: { label: 'Month' },
|
|
148
|
+
revenue: { label: 'Revenue', color: '#3b82f6' },
|
|
149
|
+
}}
|
|
150
|
+
dataConfig={{
|
|
151
|
+
xAxis: { key: 'month', label: 'Month' },
|
|
152
|
+
yAxes: [{ key: 'revenue', label: 'Revenue' }],
|
|
153
|
+
series: [{ key: 'revenue', name: 'Revenue', color: '#3b82f6' }],
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### DatasetChart
|
|
159
|
+
|
|
160
|
+
Fetches data automatically using the provider:
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { DatasetChart } from '@erdoai/ui';
|
|
164
|
+
|
|
165
|
+
<DatasetChart
|
|
166
|
+
chartType="bar"
|
|
167
|
+
title="Sales by Region"
|
|
168
|
+
invocationId="inv-123"
|
|
169
|
+
datasetSlugs={['sales-data']}
|
|
170
|
+
xAxis={{ key: 'region', label: 'Region' }}
|
|
171
|
+
yAxes={[{ key: 'revenue', label: 'Revenue' }]}
|
|
172
|
+
series={[
|
|
173
|
+
{ key: 'revenue', name: 'Revenue', color: '#3b82f6', datasetSlug: 'sales-data' },
|
|
174
|
+
]}
|
|
175
|
+
dataReduction={{ strategy: 'sample', target_points: 1000 }}
|
|
176
|
+
stacked={false}
|
|
177
|
+
/>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Hooks
|
|
181
|
+
|
|
182
|
+
### useInvocation
|
|
183
|
+
|
|
184
|
+
Invoke agents with streaming support:
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
const {
|
|
188
|
+
result, // Current result state
|
|
189
|
+
isStreaming, // Whether streaming is in progress
|
|
190
|
+
error, // Any error that occurred
|
|
191
|
+
invoke, // Function to start invocation
|
|
192
|
+
} = useInvocation({
|
|
193
|
+
onEvent: (event) => console.log('Event:', event),
|
|
194
|
+
onFinish: (result) => console.log('Complete:', result),
|
|
195
|
+
onError: (error) => console.error('Error:', error),
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Invoke an agent
|
|
199
|
+
await invoke('data-analyst', {
|
|
200
|
+
query: 'Analyze our sales data',
|
|
201
|
+
threadId: 'thread-123',
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### useDatasetContents
|
|
206
|
+
|
|
207
|
+
Fetch dataset contents:
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
const { data, isLoading, error } = useDatasetContents('dataset-slug', 'invocation-id');
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### useMultipleDatasetContents
|
|
214
|
+
|
|
215
|
+
Fetch multiple datasets in parallel:
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
const results = useMultipleDatasetContents(
|
|
219
|
+
['dataset-1', 'dataset-2'],
|
|
220
|
+
'invocation-id'
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
const isLoading = results.some((r) => r.isLoading);
|
|
224
|
+
const allData = results.map((r) => r.data || []);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### useChartZoom
|
|
228
|
+
|
|
229
|
+
Manage chart zoom state:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
const { zoomDomain, setZoomDomain, resetZoom } = useChartZoom();
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Provider Configuration
|
|
236
|
+
|
|
237
|
+
### Standard Configuration (REST API)
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
<ErdoProvider
|
|
241
|
+
config={{
|
|
242
|
+
baseUrl: 'https://api.erdo.ai',
|
|
243
|
+
authToken: 'your-api-key',
|
|
244
|
+
}}
|
|
245
|
+
>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### With ErdoClient
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
import { ErdoClient } from '@erdoai/server';
|
|
252
|
+
|
|
253
|
+
const client = new ErdoClient({ authToken: 'your-api-key' });
|
|
254
|
+
|
|
255
|
+
<ErdoProvider
|
|
256
|
+
config={{
|
|
257
|
+
baseUrl: 'https://api.erdo.ai',
|
|
258
|
+
client,
|
|
259
|
+
}}
|
|
260
|
+
>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Custom Data Fetcher
|
|
264
|
+
|
|
265
|
+
For custom backends or authentication:
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
const customFetcher = {
|
|
269
|
+
fetchDatasetContents: async (slug, invocationId) => {
|
|
270
|
+
const response = await myCustomClient.getDataset(slug, invocationId);
|
|
271
|
+
return response.data;
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
<ErdoProvider
|
|
276
|
+
config={{
|
|
277
|
+
baseUrl: 'https://api.erdo.ai',
|
|
278
|
+
dataFetcher: customFetcher,
|
|
279
|
+
}}
|
|
280
|
+
>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Styling
|
|
284
|
+
|
|
285
|
+
Components use Tailwind CSS classes. Make sure Tailwind is configured in your project and includes the @erdoai/ui package in your content paths:
|
|
286
|
+
|
|
287
|
+
```js
|
|
288
|
+
// tailwind.config.js
|
|
289
|
+
module.exports = {
|
|
290
|
+
content: [
|
|
291
|
+
'./src/**/*.{js,ts,jsx,tsx}',
|
|
292
|
+
'./node_modules/@erdoai/ui/dist/**/*.js',
|
|
293
|
+
],
|
|
294
|
+
// ...
|
|
295
|
+
};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## License
|
|
299
|
+
|
|
300
|
+
MIT
|