@timbal-ai/timbal-react 0.2.0 → 0.2.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.
- package/README.md +175 -57
- package/dist/index.cjs +37 -11
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.esm.js +37 -10
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @timbal-ai/timbal-react
|
|
2
2
|
|
|
3
|
-
React components and runtime for building Timbal chat UIs.
|
|
3
|
+
React components and runtime for building Timbal chat UIs. Drop in a single component to get a fully-featured streaming chat interface connected to a Timbal workforce agent.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -10,15 +10,15 @@ npm install @timbal-ai/timbal-react
|
|
|
10
10
|
bun add @timbal-ai/timbal-react
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**Peer dependencies:**
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install react react-dom @assistant-ui/react @timbal-ai/timbal-sdk
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
###
|
|
19
|
+
### Tailwind setup
|
|
20
20
|
|
|
21
|
-
The package ships pre-built class names
|
|
21
|
+
The package ships pre-built Tailwind class names. Add this `@source` line to your CSS entry file — **without it the components will be unstyled**:
|
|
22
22
|
|
|
23
23
|
```css
|
|
24
24
|
/* src/index.css */
|
|
@@ -29,7 +29,7 @@ The package ships pre-built class names that Tailwind must scan. Add this `@sour
|
|
|
29
29
|
|
|
30
30
|
> Adjust the path if your CSS file lives at a different depth relative to `node_modules`.
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### CSS imports
|
|
33
33
|
|
|
34
34
|
Import these stylesheets once in your app entry:
|
|
35
35
|
|
|
@@ -41,11 +41,11 @@ import "katex/dist/katex.min.css";
|
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## Quick start
|
|
45
45
|
|
|
46
|
-
###
|
|
46
|
+
### Basic usage
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
`TimbalChat` is a single component that handles everything — runtime, streaming, messages, and the composer:
|
|
49
49
|
|
|
50
50
|
```tsx
|
|
51
51
|
import { TimbalChat } from "@timbal-ai/timbal-react";
|
|
@@ -59,7 +59,9 @@ export default function App() {
|
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
> `TimbalChat` requires a fixed height parent. Use `height: "100vh"` or `flex-1 min-h-0` depending on your layout.
|
|
63
|
+
|
|
64
|
+
### Welcome screen and suggestions
|
|
63
65
|
|
|
64
66
|
```tsx
|
|
65
67
|
<TimbalChat
|
|
@@ -76,7 +78,7 @@ export default function App() {
|
|
|
76
78
|
/>
|
|
77
79
|
```
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
### Placeholder and width
|
|
80
82
|
|
|
81
83
|
```tsx
|
|
82
84
|
<TimbalChat
|
|
@@ -87,9 +89,9 @@ export default function App() {
|
|
|
87
89
|
/>
|
|
88
90
|
```
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
### Switching agents dynamically
|
|
91
93
|
|
|
92
|
-
|
|
94
|
+
Pass `key` to fully reset the chat when the workforce changes:
|
|
93
95
|
|
|
94
96
|
```tsx
|
|
95
97
|
const [workforceId, setWorkforceId] = useState("agent-a");
|
|
@@ -104,9 +106,9 @@ const [workforceId, setWorkforceId] = useState("agent-a");
|
|
|
104
106
|
|
|
105
107
|
---
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
## Splitting the runtime and UI
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
`TimbalChat` is a convenience wrapper around `TimbalRuntimeProvider` + `Thread`. Use them separately when you need to place the runtime above the chat — for example, to build a custom header that reads or controls chat state:
|
|
110
112
|
|
|
111
113
|
```tsx
|
|
112
114
|
import { TimbalRuntimeProvider, Thread } from "@timbal-ai/timbal-react";
|
|
@@ -126,7 +128,7 @@ export default function App() {
|
|
|
126
128
|
}
|
|
127
129
|
```
|
|
128
130
|
|
|
129
|
-
|
|
131
|
+
### Custom API base URL
|
|
130
132
|
|
|
131
133
|
Useful when your API is mounted at a subpath (e.g. behind a reverse proxy):
|
|
132
134
|
|
|
@@ -136,20 +138,15 @@ Useful when your API is mounted at a subpath (e.g. behind a reverse proxy):
|
|
|
136
138
|
</TimbalRuntimeProvider>
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
|
|
141
|
+
### Custom fetch function
|
|
140
142
|
|
|
141
143
|
Pass your own `fetch` to add headers, inject tokens, or proxy requests:
|
|
142
144
|
|
|
143
145
|
```tsx
|
|
144
|
-
import { TimbalRuntimeProvider, Thread } from "@timbal-ai/timbal-react";
|
|
145
|
-
|
|
146
146
|
const myFetch: typeof fetch = (url, options) => {
|
|
147
147
|
return fetch(url, {
|
|
148
148
|
...options,
|
|
149
|
-
headers: {
|
|
150
|
-
...options?.headers,
|
|
151
|
-
"X-My-Header": "value",
|
|
152
|
-
},
|
|
149
|
+
headers: { ...options?.headers, "X-My-Header": "value" },
|
|
153
150
|
});
|
|
154
151
|
};
|
|
155
152
|
|
|
@@ -160,30 +157,168 @@ const myFetch: typeof fetch = (url, options) => {
|
|
|
160
157
|
|
|
161
158
|
---
|
|
162
159
|
|
|
163
|
-
|
|
160
|
+
## Customizing the UI
|
|
161
|
+
|
|
162
|
+
Use the `components` prop on `TimbalChat` or `Thread` to replace any part of the interface while keeping everything else as the default.
|
|
163
|
+
|
|
164
|
+
### Available slots
|
|
165
|
+
|
|
166
|
+
| Slot | Props forwarded | Default |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| `UserMessage` | none | built-in user bubble |
|
|
169
|
+
| `AssistantMessage` | none | built-in assistant bubble |
|
|
170
|
+
| `EditComposer` | none | built-in inline edit composer |
|
|
171
|
+
| `Composer` | `placeholder` | built-in composer bar |
|
|
172
|
+
| `Welcome` | `config`, `suggestions` | built-in welcome screen |
|
|
173
|
+
| `ScrollToBottom` | none | built-in scroll button |
|
|
174
|
+
|
|
175
|
+
Custom slot components read their data via hooks — no props are passed automatically except where noted above.
|
|
176
|
+
|
|
177
|
+
### Custom user message
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { TimbalChat, MessagePrimitive } from "@timbal-ai/timbal-react";
|
|
181
|
+
|
|
182
|
+
const CompactUserMessage = () => (
|
|
183
|
+
<MessagePrimitive.Root className="flex justify-end px-4 py-2">
|
|
184
|
+
<div className="bg-primary text-primary-foreground rounded-2xl px-4 py-2 text-sm max-w-[75%]">
|
|
185
|
+
<MessagePrimitive.Parts />
|
|
186
|
+
</div>
|
|
187
|
+
</MessagePrimitive.Root>
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
<TimbalChat workforceId="..." components={{ UserMessage: CompactUserMessage }} />
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Custom composer
|
|
194
|
+
|
|
195
|
+
The `Composer` slot receives `placeholder` from the `composerPlaceholder` prop:
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
import { TimbalChat, ComposerPrimitive } from "@timbal-ai/timbal-react";
|
|
199
|
+
|
|
200
|
+
const MinimalComposer = ({ placeholder }: { placeholder?: string }) => (
|
|
201
|
+
<ComposerPrimitive.Root className="flex items-center gap-2 border rounded-full px-4 py-2">
|
|
202
|
+
<ComposerPrimitive.Input
|
|
203
|
+
placeholder={placeholder ?? "Type here..."}
|
|
204
|
+
className="flex-1 bg-transparent text-sm outline-none"
|
|
205
|
+
rows={1}
|
|
206
|
+
/>
|
|
207
|
+
<ComposerPrimitive.Send className="text-primary font-medium text-sm">
|
|
208
|
+
Send
|
|
209
|
+
</ComposerPrimitive.Send>
|
|
210
|
+
</ComposerPrimitive.Root>
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
<TimbalChat workforceId="..." components={{ Composer: MinimalComposer }} />
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Custom welcome screen
|
|
217
|
+
|
|
218
|
+
The `Welcome` slot is always mounted and controls its own visibility. Use `useThread` to replicate the default "show only when the thread is empty" behaviour:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { TimbalChat, useThread, useThreadRuntime, type ThreadWelcomeProps } from "@timbal-ai/timbal-react";
|
|
222
|
+
|
|
223
|
+
const BrandedWelcome = ({ suggestions }: ThreadWelcomeProps) => {
|
|
224
|
+
const isEmpty = useThread((s) => s.isEmpty);
|
|
225
|
+
const runtime = useThreadRuntime();
|
|
226
|
+
if (!isEmpty) return null;
|
|
227
|
+
return (
|
|
228
|
+
<div className="flex flex-col items-center justify-center h-full gap-4">
|
|
229
|
+
<img src="/logo.svg" className="h-12" />
|
|
230
|
+
<h2 className="text-xl font-semibold">Welcome to Acme AI</h2>
|
|
231
|
+
<div className="flex gap-2 flex-wrap justify-center">
|
|
232
|
+
{suggestions?.map((s) => (
|
|
233
|
+
<button
|
|
234
|
+
key={s.title}
|
|
235
|
+
onClick={() => runtime.append({ role: "user", content: [{ type: "text", text: s.title }] })}
|
|
236
|
+
className="border rounded-full px-4 py-1.5 text-sm hover:bg-muted"
|
|
237
|
+
>
|
|
238
|
+
{s.title}
|
|
239
|
+
</button>
|
|
240
|
+
))}
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
<TimbalChat
|
|
247
|
+
workforceId="..."
|
|
248
|
+
suggestions={[{ title: "Get started" }, { title: "Show me an example" }]}
|
|
249
|
+
components={{ Welcome: BrandedWelcome }}
|
|
250
|
+
/>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Mixing slots
|
|
254
|
+
|
|
255
|
+
Override any combination — slots are independent of each other:
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
<TimbalChat
|
|
259
|
+
workforceId="..."
|
|
260
|
+
components={{
|
|
261
|
+
UserMessage: CompactUserMessage,
|
|
262
|
+
Composer: MinimalComposer,
|
|
263
|
+
}}
|
|
264
|
+
/>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Hooks and primitives
|
|
268
|
+
|
|
269
|
+
These are re-exported from `@assistant-ui/react` for use inside custom slot components:
|
|
270
|
+
|
|
271
|
+
| Export | Use inside |
|
|
272
|
+
|---|---|
|
|
273
|
+
| `ThreadPrimitive` | Any slot |
|
|
274
|
+
| `MessagePrimitive` | `UserMessage`, `AssistantMessage`, `EditComposer` |
|
|
275
|
+
| `ComposerPrimitive` | `Composer`, `EditComposer` |
|
|
276
|
+
| `ActionBarPrimitive` | `UserMessage`, `AssistantMessage` |
|
|
277
|
+
| `useThread` | Any slot — subscribe to thread state (e.g. `isRunning`, `isEmpty`) |
|
|
278
|
+
| `useThreadRuntime` | Any slot — call actions (e.g. `runtime.append(...)`) |
|
|
279
|
+
| `useMessageRuntime` | `UserMessage`, `AssistantMessage` — edit, reload, branch |
|
|
280
|
+
| `useComposerRuntime` | `Composer`, `EditComposer` — access composer state |
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## API reference
|
|
285
|
+
|
|
286
|
+
### `TimbalChat` props
|
|
287
|
+
|
|
288
|
+
`TimbalChat` accepts all `TimbalRuntimeProvider` props plus all `Thread` props.
|
|
164
289
|
|
|
165
290
|
| Prop | Type | Default | Description |
|
|
166
291
|
|---|---|---|---|
|
|
292
|
+
| `workforceId` | `string` | **required** | ID of the workforce to stream from |
|
|
293
|
+
| `baseUrl` | `string` | `"/api"` | Base URL for API calls. Posts to `{baseUrl}/workforce/{workforceId}/stream` |
|
|
294
|
+
| `fetch` | `(url, options?) => Promise<Response>` | `authFetch` | Custom fetch. Defaults to the built-in auth-aware fetch (Bearer token + auto-refresh) |
|
|
167
295
|
| `welcome.heading` | `string` | `"How can I help you today?"` | Welcome screen heading |
|
|
168
296
|
| `welcome.subheading` | `string` | `"Send a message to start a conversation."` | Welcome screen subheading |
|
|
169
297
|
| `suggestions` | `{ title: string; description?: string }[]` | — | Suggestion chips on the welcome screen |
|
|
170
298
|
| `composerPlaceholder` | `string` | `"Send a message..."` | Composer input placeholder |
|
|
299
|
+
| `components` | `ThreadComponents` | — | Override individual UI slots |
|
|
171
300
|
| `maxWidth` | `string` | `"44rem"` | Max width of the message column |
|
|
172
301
|
| `className` | `string` | — | Extra classes on the root element |
|
|
173
302
|
|
|
303
|
+
### `Thread` props
|
|
304
|
+
|
|
305
|
+
Same as `TimbalChat` minus `workforceId`, `baseUrl`, and `fetch` (those live on `TimbalRuntimeProvider`).
|
|
306
|
+
|
|
174
307
|
### `TimbalRuntimeProvider` props
|
|
175
308
|
|
|
176
309
|
| Prop | Type | Default | Description |
|
|
177
310
|
|---|---|---|---|
|
|
178
|
-
| `workforceId` | `string` |
|
|
179
|
-
| `baseUrl` | `string` | `"/api"` | Base URL for API calls
|
|
180
|
-
| `fetch` | `(url, options?) => Promise<Response>` | `authFetch` | Custom fetch function
|
|
311
|
+
| `workforceId` | `string` | **required** | ID of the workforce to stream from |
|
|
312
|
+
| `baseUrl` | `string` | `"/api"` | Base URL for API calls |
|
|
313
|
+
| `fetch` | `(url, options?) => Promise<Response>` | `authFetch` | Custom fetch function |
|
|
181
314
|
|
|
182
315
|
---
|
|
183
316
|
|
|
184
317
|
## Auth
|
|
185
318
|
|
|
186
|
-
The package includes
|
|
319
|
+
The package includes an optional session/auth system backed by localStorage tokens. The API is expected to expose `/api/auth/login`, `/api/auth/logout`, and `/api/auth/refresh`.
|
|
320
|
+
|
|
321
|
+
Auth is **opt-in** — it only activates when `VITE_TIMBAL_PROJECT_ID` is set in your environment.
|
|
187
322
|
|
|
188
323
|
### Setup
|
|
189
324
|
|
|
@@ -195,7 +330,6 @@ import { SessionProvider, AuthGuard, TooltipProvider } from "@timbal-ai/timbal-r
|
|
|
195
330
|
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
|
196
331
|
import Home from "./pages/Home";
|
|
197
332
|
|
|
198
|
-
// Auth is opt-in — only active when VITE_TIMBAL_PROJECT_ID is set
|
|
199
333
|
const isAuthEnabled = !!import.meta.env.VITE_TIMBAL_PROJECT_ID;
|
|
200
334
|
|
|
201
335
|
export default function App() {
|
|
@@ -215,20 +349,7 @@ export default function App() {
|
|
|
215
349
|
}
|
|
216
350
|
```
|
|
217
351
|
|
|
218
|
-
When `enabled` is `false
|
|
219
|
-
|
|
220
|
-
### `SessionProvider` props
|
|
221
|
-
|
|
222
|
-
| Prop | Type | Default | Description |
|
|
223
|
-
|---|---|---|---|
|
|
224
|
-
| `enabled` | `boolean` | `true` | When `false`, session is always `null` and no API calls are made |
|
|
225
|
-
|
|
226
|
-
### `AuthGuard` props
|
|
227
|
-
|
|
228
|
-
| Prop | Type | Default | Description |
|
|
229
|
-
|---|---|---|---|
|
|
230
|
-
| `requireAuth` | `boolean` | `false` | Redirect to login if not authenticated |
|
|
231
|
-
| `enabled` | `boolean` | `true` | When `false`, renders children unconditionally |
|
|
352
|
+
When `enabled` is `false`, both `SessionProvider` and `AuthGuard` are transparent — no redirects, no API calls.
|
|
232
353
|
|
|
233
354
|
### `useSession` hook
|
|
234
355
|
|
|
@@ -239,9 +360,7 @@ import { useSession } from "@timbal-ai/timbal-react";
|
|
|
239
360
|
|
|
240
361
|
function Header() {
|
|
241
362
|
const { user, isAuthenticated, loading, logout } = useSession();
|
|
242
|
-
|
|
243
363
|
if (loading) return null;
|
|
244
|
-
|
|
245
364
|
return (
|
|
246
365
|
<header>
|
|
247
366
|
{isAuthenticated ? (
|
|
@@ -259,25 +378,30 @@ function Header() {
|
|
|
259
378
|
|
|
260
379
|
### `authFetch`
|
|
261
380
|
|
|
262
|
-
A drop-in replacement for `fetch` that attaches the Bearer token from localStorage and auto-refreshes on 401:
|
|
381
|
+
A drop-in replacement for `fetch` that attaches the Bearer token from localStorage and auto-refreshes on 401. It's also the default `fetch` used by `TimbalRuntimeProvider`, so you only need to import it directly for your own API calls (e.g. loading workforce lists):
|
|
263
382
|
|
|
264
383
|
```tsx
|
|
265
384
|
import { authFetch } from "@timbal-ai/timbal-react";
|
|
266
385
|
|
|
267
|
-
// Fetch a list of workforce agents
|
|
268
386
|
const res = await authFetch("/api/workforce");
|
|
269
387
|
if (res.ok) {
|
|
270
388
|
const agents = await res.json();
|
|
271
389
|
}
|
|
272
390
|
```
|
|
273
391
|
|
|
274
|
-
|
|
392
|
+
### Auth prop reference
|
|
393
|
+
|
|
394
|
+
| Component | Prop | Type | Default | Description |
|
|
395
|
+
|---|---|---|---|---|
|
|
396
|
+
| `SessionProvider` | `enabled` | `boolean` | `true` | When `false`, session is always `null` and no API calls are made |
|
|
397
|
+
| `AuthGuard` | `requireAuth` | `boolean` | `false` | Redirect to login if not authenticated |
|
|
398
|
+
| `AuthGuard` | `enabled` | `boolean` | `true` | When `false`, renders children unconditionally |
|
|
275
399
|
|
|
276
400
|
---
|
|
277
401
|
|
|
278
|
-
##
|
|
402
|
+
## Other exports
|
|
279
403
|
|
|
280
|
-
|
|
404
|
+
### Components
|
|
281
405
|
|
|
282
406
|
| Export | Description |
|
|
283
407
|
|---|---|
|
|
@@ -306,12 +430,7 @@ A complete page with agent switching, auth, and a custom header:
|
|
|
306
430
|
// src/pages/Home.tsx
|
|
307
431
|
import { useEffect, useState } from "react";
|
|
308
432
|
import type { WorkforceItem } from "@timbal-ai/timbal-sdk";
|
|
309
|
-
import {
|
|
310
|
-
TimbalChat,
|
|
311
|
-
Button,
|
|
312
|
-
authFetch,
|
|
313
|
-
useSession,
|
|
314
|
-
} from "@timbal-ai/timbal-react";
|
|
433
|
+
import { TimbalChat, Button, authFetch, useSession } from "@timbal-ai/timbal-react";
|
|
315
434
|
import { LogOut } from "lucide-react";
|
|
316
435
|
|
|
317
436
|
const isAuthEnabled = !!import.meta.env.VITE_TIMBAL_PROJECT_ID;
|
|
@@ -368,7 +487,6 @@ export default function Home() {
|
|
|
368
487
|
Install via a local path reference:
|
|
369
488
|
|
|
370
489
|
```json
|
|
371
|
-
// package.json
|
|
372
490
|
{
|
|
373
491
|
"dependencies": {
|
|
374
492
|
"@timbal-ai/timbal-react": "file:../../timbal-react"
|
|
@@ -378,7 +496,7 @@ Install via a local path reference:
|
|
|
378
496
|
|
|
379
497
|
Adjust the relative path to where `timbal-react` lives on your machine.
|
|
380
498
|
|
|
381
|
-
After editing source files, rebuild
|
|
499
|
+
After editing source files, rebuild:
|
|
382
500
|
|
|
383
501
|
```bash
|
|
384
502
|
cd timbal-react
|
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ActionBarPrimitive: () => import_react13.ActionBarPrimitive,
|
|
33
34
|
AuthGuard: () => AuthGuard,
|
|
34
35
|
Avatar: () => Avatar,
|
|
35
36
|
AvatarFallback: () => AvatarFallback,
|
|
@@ -37,6 +38,7 @@ __export(index_exports, {
|
|
|
37
38
|
Button: () => Button,
|
|
38
39
|
ComposerAddAttachment: () => ComposerAddAttachment,
|
|
39
40
|
ComposerAttachments: () => ComposerAttachments,
|
|
41
|
+
ComposerPrimitive: () => import_react13.ComposerPrimitive,
|
|
40
42
|
Dialog: () => Dialog,
|
|
41
43
|
DialogClose: () => DialogClose,
|
|
42
44
|
DialogContent: () => DialogContent,
|
|
@@ -45,10 +47,12 @@ __export(index_exports, {
|
|
|
45
47
|
DialogTitle: () => DialogTitle,
|
|
46
48
|
DialogTrigger: () => DialogTrigger,
|
|
47
49
|
MarkdownText: () => MarkdownText,
|
|
50
|
+
MessagePrimitive: () => import_react13.MessagePrimitive,
|
|
48
51
|
SessionProvider: () => SessionProvider,
|
|
49
52
|
Shimmer: () => Shimmer,
|
|
50
53
|
SyntaxHighlighter: () => syntax_highlighter_default,
|
|
51
54
|
Thread: () => Thread,
|
|
55
|
+
ThreadPrimitive: () => import_react13.ThreadPrimitive,
|
|
52
56
|
TimbalChat: () => TimbalChat,
|
|
53
57
|
TimbalRuntimeProvider: () => TimbalRuntimeProvider,
|
|
54
58
|
ToolFallback: () => ToolFallback,
|
|
@@ -66,7 +70,11 @@ __export(index_exports, {
|
|
|
66
70
|
getAccessToken: () => getAccessToken,
|
|
67
71
|
getRefreshToken: () => getRefreshToken,
|
|
68
72
|
refreshAccessToken: () => refreshAccessToken,
|
|
69
|
-
|
|
73
|
+
useComposerRuntime: () => import_react13.useComposerRuntime,
|
|
74
|
+
useMessageRuntime: () => import_react13.useMessageRuntime,
|
|
75
|
+
useSession: () => useSession,
|
|
76
|
+
useThread: () => import_react13.useThread,
|
|
77
|
+
useThreadRuntime: () => import_react13.useThreadRuntime
|
|
70
78
|
});
|
|
71
79
|
module.exports = __toCommonJS(index_exports);
|
|
72
80
|
|
|
@@ -1273,8 +1281,15 @@ var Thread = ({
|
|
|
1273
1281
|
maxWidth = "44rem",
|
|
1274
1282
|
welcome,
|
|
1275
1283
|
suggestions,
|
|
1276
|
-
composerPlaceholder = "Send a message..."
|
|
1284
|
+
composerPlaceholder = "Send a message...",
|
|
1285
|
+
components
|
|
1277
1286
|
}) => {
|
|
1287
|
+
const WelcomeSlot = components?.Welcome ?? ThreadWelcome;
|
|
1288
|
+
const ComposerSlot = components?.Composer ?? Composer;
|
|
1289
|
+
const UserMessageSlot = components?.UserMessage ?? UserMessage;
|
|
1290
|
+
const AssistantMessageSlot = components?.AssistantMessage ?? AssistantMessage;
|
|
1291
|
+
const EditComposerSlot = components?.EditComposer ?? EditComposer;
|
|
1292
|
+
const ScrollToBottomSlot = components?.ScrollToBottom ?? ThreadScrollToBottom;
|
|
1278
1293
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1279
1294
|
import_react11.ThreadPrimitive.Root,
|
|
1280
1295
|
{
|
|
@@ -1289,20 +1304,20 @@ var Thread = ({
|
|
|
1289
1304
|
turnAnchor: "bottom",
|
|
1290
1305
|
className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll px-4 pt-4",
|
|
1291
1306
|
children: [
|
|
1292
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1307
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(WelcomeSlot, { config: welcome, suggestions }),
|
|
1293
1308
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1294
1309
|
import_react11.ThreadPrimitive.Messages,
|
|
1295
1310
|
{
|
|
1296
1311
|
components: {
|
|
1297
|
-
UserMessage,
|
|
1298
|
-
EditComposer,
|
|
1299
|
-
AssistantMessage
|
|
1312
|
+
UserMessage: UserMessageSlot,
|
|
1313
|
+
EditComposer: EditComposerSlot,
|
|
1314
|
+
AssistantMessage: AssistantMessageSlot
|
|
1300
1315
|
}
|
|
1301
1316
|
}
|
|
1302
1317
|
),
|
|
1303
1318
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react11.ThreadPrimitive.ViewportFooter, { className: "aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6", children: [
|
|
1304
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1305
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1319
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollToBottomSlot, {}),
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ComposerSlot, { placeholder: composerPlaceholder })
|
|
1306
1321
|
] })
|
|
1307
1322
|
]
|
|
1308
1323
|
}
|
|
@@ -1322,7 +1337,7 @@ var ThreadScrollToBottom = () => {
|
|
|
1322
1337
|
) });
|
|
1323
1338
|
};
|
|
1324
1339
|
var ThreadWelcome = ({ config, suggestions }) => {
|
|
1325
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
|
|
1340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react11.AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
|
|
1326
1341
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "aui-thread-welcome-message flex size-full flex-col items-center justify-center px-4 text-center", children: [
|
|
1327
1342
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "fade-in animate-in fill-mode-both relative mb-6 flex size-14 items-center justify-center duration-300", children: [
|
|
1328
1343
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "animate-ai-ring-glow absolute inset-0 rounded-2xl bg-gradient-to-br from-primary/15 to-primary/5 ring-1 ring-primary/15" }),
|
|
@@ -1346,7 +1361,7 @@ var ThreadWelcome = ({ config, suggestions }) => {
|
|
|
1346
1361
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground mt-2 delay-75 duration-200", children: config?.subheading ?? "Send a message to start a conversation." })
|
|
1347
1362
|
] }) }),
|
|
1348
1363
|
suggestions && suggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadSuggestions, { suggestions })
|
|
1349
|
-
] });
|
|
1364
|
+
] }) });
|
|
1350
1365
|
};
|
|
1351
1366
|
var ThreadSuggestions = ({ suggestions }) => {
|
|
1352
1367
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4", children: suggestions.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadSuggestionItem, { title: s.title, description: s.description }, i)) });
|
|
@@ -1534,6 +1549,9 @@ function TimbalChat({
|
|
|
1534
1549
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TimbalRuntimeProvider, { workforceId, baseUrl, fetch: fetch2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Thread, { ...threadProps }) });
|
|
1535
1550
|
}
|
|
1536
1551
|
|
|
1552
|
+
// src/index.ts
|
|
1553
|
+
var import_react13 = require("@assistant-ui/react");
|
|
1554
|
+
|
|
1537
1555
|
// src/auth/provider.tsx
|
|
1538
1556
|
var import_react12 = require("react");
|
|
1539
1557
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
@@ -1640,6 +1658,7 @@ var AuthGuard = ({
|
|
|
1640
1658
|
};
|
|
1641
1659
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1642
1660
|
0 && (module.exports = {
|
|
1661
|
+
ActionBarPrimitive,
|
|
1643
1662
|
AuthGuard,
|
|
1644
1663
|
Avatar,
|
|
1645
1664
|
AvatarFallback,
|
|
@@ -1647,6 +1666,7 @@ var AuthGuard = ({
|
|
|
1647
1666
|
Button,
|
|
1648
1667
|
ComposerAddAttachment,
|
|
1649
1668
|
ComposerAttachments,
|
|
1669
|
+
ComposerPrimitive,
|
|
1650
1670
|
Dialog,
|
|
1651
1671
|
DialogClose,
|
|
1652
1672
|
DialogContent,
|
|
@@ -1655,10 +1675,12 @@ var AuthGuard = ({
|
|
|
1655
1675
|
DialogTitle,
|
|
1656
1676
|
DialogTrigger,
|
|
1657
1677
|
MarkdownText,
|
|
1678
|
+
MessagePrimitive,
|
|
1658
1679
|
SessionProvider,
|
|
1659
1680
|
Shimmer,
|
|
1660
1681
|
SyntaxHighlighter,
|
|
1661
1682
|
Thread,
|
|
1683
|
+
ThreadPrimitive,
|
|
1662
1684
|
TimbalChat,
|
|
1663
1685
|
TimbalRuntimeProvider,
|
|
1664
1686
|
ToolFallback,
|
|
@@ -1676,5 +1698,9 @@ var AuthGuard = ({
|
|
|
1676
1698
|
getAccessToken,
|
|
1677
1699
|
getRefreshToken,
|
|
1678
1700
|
refreshAccessToken,
|
|
1679
|
-
|
|
1701
|
+
useComposerRuntime,
|
|
1702
|
+
useMessageRuntime,
|
|
1703
|
+
useSession,
|
|
1704
|
+
useThread,
|
|
1705
|
+
useThreadRuntime
|
|
1680
1706
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { ReactNode, FC, ComponentPropsWithRef, ElementType } from 'react';
|
|
3
|
+
import React__default, { ReactNode, FC, ComponentType, ComponentPropsWithRef, ElementType } from 'react';
|
|
4
4
|
import { ToolCallMessagePartComponent } from '@assistant-ui/react';
|
|
5
|
+
export { ActionBarPrimitive, ComposerPrimitive, MessagePrimitive, ThreadPrimitive, useComposerRuntime, useMessageRuntime, useThread, useThreadRuntime } from '@assistant-ui/react';
|
|
5
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
6
7
|
import { VariantProps } from 'class-variance-authority';
|
|
7
8
|
import { SyntaxHighlighterProps } from '@assistant-ui/react-markdown';
|
|
@@ -34,6 +35,26 @@ interface ThreadWelcomeConfig {
|
|
|
34
35
|
heading?: string;
|
|
35
36
|
subheading?: string;
|
|
36
37
|
}
|
|
38
|
+
interface ThreadWelcomeProps {
|
|
39
|
+
config?: ThreadWelcomeConfig;
|
|
40
|
+
suggestions?: ThreadSuggestion[];
|
|
41
|
+
}
|
|
42
|
+
interface ThreadComponents {
|
|
43
|
+
/** Replace the user message bubble. Access message content via `MessagePrimitive.Parts`. */
|
|
44
|
+
UserMessage?: ComponentType;
|
|
45
|
+
/** Replace the assistant message bubble. Access message content via `MessagePrimitive.Parts`. */
|
|
46
|
+
AssistantMessage?: ComponentType;
|
|
47
|
+
/** Replace the inline edit composer. */
|
|
48
|
+
EditComposer?: ComponentType;
|
|
49
|
+
/** Replace the composer (input bar). Receives `placeholder` from `composerPlaceholder`. */
|
|
50
|
+
Composer?: ComponentType<{
|
|
51
|
+
placeholder?: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** Replace the welcome / empty state. Receives `config` and `suggestions` props. Controls its own visibility — use `useThread(s => s.isEmpty)` to replicate the default behaviour. */
|
|
54
|
+
Welcome?: ComponentType<ThreadWelcomeProps>;
|
|
55
|
+
/** Replace the scroll-to-bottom button. */
|
|
56
|
+
ScrollToBottom?: ComponentType;
|
|
57
|
+
}
|
|
37
58
|
interface ThreadProps {
|
|
38
59
|
className?: string;
|
|
39
60
|
/** Max width of the message column. Default: "44rem" */
|
|
@@ -44,6 +65,8 @@ interface ThreadProps {
|
|
|
44
65
|
suggestions?: ThreadSuggestion[];
|
|
45
66
|
/** Composer input placeholder. Default: "Send a message..." */
|
|
46
67
|
composerPlaceholder?: string;
|
|
68
|
+
/** Override individual UI slots while keeping the rest as defaults. */
|
|
69
|
+
components?: ThreadComponents;
|
|
47
70
|
}
|
|
48
71
|
declare const Thread: FC<ThreadProps>;
|
|
49
72
|
|
|
@@ -136,4 +159,4 @@ declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, cla
|
|
|
136
159
|
|
|
137
160
|
declare function cn(...inputs: ClassValue[]): string;
|
|
138
161
|
|
|
139
|
-
export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
|
|
162
|
+
export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, type ThreadWelcomeProps, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { ReactNode, FC, ComponentPropsWithRef, ElementType } from 'react';
|
|
3
|
+
import React__default, { ReactNode, FC, ComponentType, ComponentPropsWithRef, ElementType } from 'react';
|
|
4
4
|
import { ToolCallMessagePartComponent } from '@assistant-ui/react';
|
|
5
|
+
export { ActionBarPrimitive, ComposerPrimitive, MessagePrimitive, ThreadPrimitive, useComposerRuntime, useMessageRuntime, useThread, useThreadRuntime } from '@assistant-ui/react';
|
|
5
6
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
6
7
|
import { VariantProps } from 'class-variance-authority';
|
|
7
8
|
import { SyntaxHighlighterProps } from '@assistant-ui/react-markdown';
|
|
@@ -34,6 +35,26 @@ interface ThreadWelcomeConfig {
|
|
|
34
35
|
heading?: string;
|
|
35
36
|
subheading?: string;
|
|
36
37
|
}
|
|
38
|
+
interface ThreadWelcomeProps {
|
|
39
|
+
config?: ThreadWelcomeConfig;
|
|
40
|
+
suggestions?: ThreadSuggestion[];
|
|
41
|
+
}
|
|
42
|
+
interface ThreadComponents {
|
|
43
|
+
/** Replace the user message bubble. Access message content via `MessagePrimitive.Parts`. */
|
|
44
|
+
UserMessage?: ComponentType;
|
|
45
|
+
/** Replace the assistant message bubble. Access message content via `MessagePrimitive.Parts`. */
|
|
46
|
+
AssistantMessage?: ComponentType;
|
|
47
|
+
/** Replace the inline edit composer. */
|
|
48
|
+
EditComposer?: ComponentType;
|
|
49
|
+
/** Replace the composer (input bar). Receives `placeholder` from `composerPlaceholder`. */
|
|
50
|
+
Composer?: ComponentType<{
|
|
51
|
+
placeholder?: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** Replace the welcome / empty state. Receives `config` and `suggestions` props. Controls its own visibility — use `useThread(s => s.isEmpty)` to replicate the default behaviour. */
|
|
54
|
+
Welcome?: ComponentType<ThreadWelcomeProps>;
|
|
55
|
+
/** Replace the scroll-to-bottom button. */
|
|
56
|
+
ScrollToBottom?: ComponentType;
|
|
57
|
+
}
|
|
37
58
|
interface ThreadProps {
|
|
38
59
|
className?: string;
|
|
39
60
|
/** Max width of the message column. Default: "44rem" */
|
|
@@ -44,6 +65,8 @@ interface ThreadProps {
|
|
|
44
65
|
suggestions?: ThreadSuggestion[];
|
|
45
66
|
/** Composer input placeholder. Default: "Send a message..." */
|
|
46
67
|
composerPlaceholder?: string;
|
|
68
|
+
/** Override individual UI slots while keeping the rest as defaults. */
|
|
69
|
+
components?: ThreadComponents;
|
|
47
70
|
}
|
|
48
71
|
declare const Thread: FC<ThreadProps>;
|
|
49
72
|
|
|
@@ -136,4 +159,4 @@ declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, cla
|
|
|
136
159
|
|
|
137
160
|
declare function cn(...inputs: ClassValue[]): string;
|
|
138
161
|
|
|
139
|
-
export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
|
|
162
|
+
export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadWelcomeConfig, type ThreadWelcomeProps, TimbalChat, type TimbalChatProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
|
package/dist/index.esm.js
CHANGED
|
@@ -1236,8 +1236,15 @@ var Thread = ({
|
|
|
1236
1236
|
maxWidth = "44rem",
|
|
1237
1237
|
welcome,
|
|
1238
1238
|
suggestions,
|
|
1239
|
-
composerPlaceholder = "Send a message..."
|
|
1239
|
+
composerPlaceholder = "Send a message...",
|
|
1240
|
+
components
|
|
1240
1241
|
}) => {
|
|
1242
|
+
const WelcomeSlot = components?.Welcome ?? ThreadWelcome;
|
|
1243
|
+
const ComposerSlot = components?.Composer ?? Composer;
|
|
1244
|
+
const UserMessageSlot = components?.UserMessage ?? UserMessage;
|
|
1245
|
+
const AssistantMessageSlot = components?.AssistantMessage ?? AssistantMessage;
|
|
1246
|
+
const EditComposerSlot = components?.EditComposer ?? EditComposer;
|
|
1247
|
+
const ScrollToBottomSlot = components?.ScrollToBottom ?? ThreadScrollToBottom;
|
|
1241
1248
|
return /* @__PURE__ */ jsx12(
|
|
1242
1249
|
ThreadPrimitive.Root,
|
|
1243
1250
|
{
|
|
@@ -1252,20 +1259,20 @@ var Thread = ({
|
|
|
1252
1259
|
turnAnchor: "bottom",
|
|
1253
1260
|
className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll px-4 pt-4",
|
|
1254
1261
|
children: [
|
|
1255
|
-
/* @__PURE__ */ jsx12(
|
|
1262
|
+
/* @__PURE__ */ jsx12(WelcomeSlot, { config: welcome, suggestions }),
|
|
1256
1263
|
/* @__PURE__ */ jsx12(
|
|
1257
1264
|
ThreadPrimitive.Messages,
|
|
1258
1265
|
{
|
|
1259
1266
|
components: {
|
|
1260
|
-
UserMessage,
|
|
1261
|
-
EditComposer,
|
|
1262
|
-
AssistantMessage
|
|
1267
|
+
UserMessage: UserMessageSlot,
|
|
1268
|
+
EditComposer: EditComposerSlot,
|
|
1269
|
+
AssistantMessage: AssistantMessageSlot
|
|
1263
1270
|
}
|
|
1264
1271
|
}
|
|
1265
1272
|
),
|
|
1266
1273
|
/* @__PURE__ */ jsxs7(ThreadPrimitive.ViewportFooter, { className: "aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6", children: [
|
|
1267
|
-
/* @__PURE__ */ jsx12(
|
|
1268
|
-
/* @__PURE__ */ jsx12(
|
|
1274
|
+
/* @__PURE__ */ jsx12(ScrollToBottomSlot, {}),
|
|
1275
|
+
/* @__PURE__ */ jsx12(ComposerSlot, { placeholder: composerPlaceholder })
|
|
1269
1276
|
] })
|
|
1270
1277
|
]
|
|
1271
1278
|
}
|
|
@@ -1285,7 +1292,7 @@ var ThreadScrollToBottom = () => {
|
|
|
1285
1292
|
) });
|
|
1286
1293
|
};
|
|
1287
1294
|
var ThreadWelcome = ({ config, suggestions }) => {
|
|
1288
|
-
return /* @__PURE__ */ jsxs7("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
|
|
1295
|
+
return /* @__PURE__ */ jsx12(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsxs7("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: [
|
|
1289
1296
|
/* @__PURE__ */ jsx12("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxs7("div", { className: "aui-thread-welcome-message flex size-full flex-col items-center justify-center px-4 text-center", children: [
|
|
1290
1297
|
/* @__PURE__ */ jsxs7("div", { className: "fade-in animate-in fill-mode-both relative mb-6 flex size-14 items-center justify-center duration-300", children: [
|
|
1291
1298
|
/* @__PURE__ */ jsx12("div", { className: "animate-ai-ring-glow absolute inset-0 rounded-2xl bg-gradient-to-br from-primary/15 to-primary/5 ring-1 ring-primary/15" }),
|
|
@@ -1309,7 +1316,7 @@ var ThreadWelcome = ({ config, suggestions }) => {
|
|
|
1309
1316
|
/* @__PURE__ */ jsx12("p", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground mt-2 delay-75 duration-200", children: config?.subheading ?? "Send a message to start a conversation." })
|
|
1310
1317
|
] }) }),
|
|
1311
1318
|
suggestions && suggestions.length > 0 && /* @__PURE__ */ jsx12(ThreadSuggestions, { suggestions })
|
|
1312
|
-
] });
|
|
1319
|
+
] }) });
|
|
1313
1320
|
};
|
|
1314
1321
|
var ThreadSuggestions = ({ suggestions }) => {
|
|
1315
1322
|
return /* @__PURE__ */ jsx12("div", { className: "aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4", children: suggestions.map((s, i) => /* @__PURE__ */ jsx12(ThreadSuggestionItem, { title: s.title, description: s.description }, i)) });
|
|
@@ -1497,6 +1504,18 @@ function TimbalChat({
|
|
|
1497
1504
|
return /* @__PURE__ */ jsx13(TimbalRuntimeProvider, { workforceId, baseUrl, fetch: fetch2, children: /* @__PURE__ */ jsx13(Thread, { ...threadProps }) });
|
|
1498
1505
|
}
|
|
1499
1506
|
|
|
1507
|
+
// src/index.ts
|
|
1508
|
+
import {
|
|
1509
|
+
ThreadPrimitive as ThreadPrimitive2,
|
|
1510
|
+
MessagePrimitive as MessagePrimitive3,
|
|
1511
|
+
ComposerPrimitive as ComposerPrimitive3,
|
|
1512
|
+
ActionBarPrimitive as ActionBarPrimitive2,
|
|
1513
|
+
useThread,
|
|
1514
|
+
useThreadRuntime as useThreadRuntime2,
|
|
1515
|
+
useMessageRuntime,
|
|
1516
|
+
useComposerRuntime
|
|
1517
|
+
} from "@assistant-ui/react";
|
|
1518
|
+
|
|
1500
1519
|
// src/auth/provider.tsx
|
|
1501
1520
|
import {
|
|
1502
1521
|
createContext,
|
|
@@ -1608,6 +1627,7 @@ var AuthGuard = ({
|
|
|
1608
1627
|
return children;
|
|
1609
1628
|
};
|
|
1610
1629
|
export {
|
|
1630
|
+
ActionBarPrimitive2 as ActionBarPrimitive,
|
|
1611
1631
|
AuthGuard,
|
|
1612
1632
|
Avatar,
|
|
1613
1633
|
AvatarFallback,
|
|
@@ -1615,6 +1635,7 @@ export {
|
|
|
1615
1635
|
Button,
|
|
1616
1636
|
ComposerAddAttachment,
|
|
1617
1637
|
ComposerAttachments,
|
|
1638
|
+
ComposerPrimitive3 as ComposerPrimitive,
|
|
1618
1639
|
Dialog,
|
|
1619
1640
|
DialogClose,
|
|
1620
1641
|
DialogContent,
|
|
@@ -1623,10 +1644,12 @@ export {
|
|
|
1623
1644
|
DialogTitle,
|
|
1624
1645
|
DialogTrigger,
|
|
1625
1646
|
MarkdownText,
|
|
1647
|
+
MessagePrimitive3 as MessagePrimitive,
|
|
1626
1648
|
SessionProvider,
|
|
1627
1649
|
Shimmer,
|
|
1628
1650
|
syntax_highlighter_default as SyntaxHighlighter,
|
|
1629
1651
|
Thread,
|
|
1652
|
+
ThreadPrimitive2 as ThreadPrimitive,
|
|
1630
1653
|
TimbalChat,
|
|
1631
1654
|
TimbalRuntimeProvider,
|
|
1632
1655
|
ToolFallback,
|
|
@@ -1644,5 +1667,9 @@ export {
|
|
|
1644
1667
|
getAccessToken,
|
|
1645
1668
|
getRefreshToken,
|
|
1646
1669
|
refreshAccessToken,
|
|
1647
|
-
|
|
1670
|
+
useComposerRuntime,
|
|
1671
|
+
useMessageRuntime,
|
|
1672
|
+
useSession,
|
|
1673
|
+
useThread,
|
|
1674
|
+
useThreadRuntime2 as useThreadRuntime
|
|
1648
1675
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timbal-ai/timbal-react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "React components and runtime for building Timbal chat UIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"build": "tsup",
|
|
23
23
|
"build:watch": "tsup --watch",
|
|
24
24
|
"clean": "rm -rf dist",
|
|
25
|
+
"test": "bun test",
|
|
26
|
+
"test:watch": "bun test --watch",
|
|
25
27
|
"typecheck": "tsc --noEmit",
|
|
26
28
|
"prepublishOnly": "bun run build && bun run typecheck"
|
|
27
29
|
},
|
|
@@ -52,9 +54,13 @@
|
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
56
|
"@assistant-ui/react": "^0.12.10",
|
|
57
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
58
|
+
"@testing-library/react": "^16.3.2",
|
|
59
|
+
"@testing-library/user-event": "^14.6.1",
|
|
55
60
|
"@timbal-ai/timbal-sdk": "0.4.9",
|
|
56
61
|
"@types/react": "^19.2.4",
|
|
57
62
|
"@types/react-dom": "^19.2.3",
|
|
63
|
+
"happy-dom": "^20.8.9",
|
|
58
64
|
"react": "^19.2.0",
|
|
59
65
|
"react-dom": "^19.2.0",
|
|
60
66
|
"tsup": "^8.5.0",
|