@timbal-ai/timbal-react 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +217 -10
- package/dist/index.cjs +49 -31
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.esm.js +50 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,9 +43,70 @@ import "katex/dist/katex.min.css";
|
|
|
43
43
|
|
|
44
44
|
## Usage
|
|
45
45
|
|
|
46
|
-
###
|
|
46
|
+
### One-liner
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
The simplest way to embed a chat UI. `TimbalChat` handles the runtime and the thread in one component:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { TimbalChat } from "@timbal-ai/timbal-react";
|
|
52
|
+
|
|
53
|
+
export default function App() {
|
|
54
|
+
return (
|
|
55
|
+
<div style={{ height: "100vh" }}>
|
|
56
|
+
<TimbalChat workforceId="your-workforce-id" />
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### With welcome screen and suggestions
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<TimbalChat
|
|
66
|
+
workforceId="your-workforce-id"
|
|
67
|
+
welcome={{
|
|
68
|
+
heading: "Hi, I'm your assistant",
|
|
69
|
+
subheading: "Ask me anything about your data.",
|
|
70
|
+
}}
|
|
71
|
+
suggestions={[
|
|
72
|
+
{ title: "Summarize this week", description: "Get a quick overview of recent activity" },
|
|
73
|
+
{ title: "What can you help with?" },
|
|
74
|
+
{ title: "Show me the latest report" },
|
|
75
|
+
]}
|
|
76
|
+
/>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### With a custom placeholder and width
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
<TimbalChat
|
|
83
|
+
workforceId="your-workforce-id"
|
|
84
|
+
composerPlaceholder="Type a question..."
|
|
85
|
+
maxWidth="60rem"
|
|
86
|
+
className="my-custom-class"
|
|
87
|
+
/>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Switching agents dynamically
|
|
91
|
+
|
|
92
|
+
Use `key` to reset the chat when the workforce changes:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
const [workforceId, setWorkforceId] = useState("agent-a");
|
|
96
|
+
|
|
97
|
+
<select onChange={(e) => setWorkforceId(e.target.value)}>
|
|
98
|
+
<option value="agent-a">Agent A</option>
|
|
99
|
+
<option value="agent-b">Agent B</option>
|
|
100
|
+
</select>
|
|
101
|
+
|
|
102
|
+
<TimbalChat workforceId={workforceId} key={workforceId} />
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### Compose manually
|
|
108
|
+
|
|
109
|
+
Use `TimbalRuntimeProvider` + `Thread` separately when you need to place the runtime above the chat UI — for example, to build a custom header that reads or controls chat state:
|
|
49
110
|
|
|
50
111
|
```tsx
|
|
51
112
|
import { TimbalRuntimeProvider, Thread } from "@timbal-ai/timbal-react";
|
|
@@ -53,14 +114,63 @@ import { TimbalRuntimeProvider, Thread } from "@timbal-ai/timbal-react";
|
|
|
53
114
|
export default function App() {
|
|
54
115
|
return (
|
|
55
116
|
<TimbalRuntimeProvider workforceId="your-workforce-id">
|
|
56
|
-
<div style={{ height: "100vh" }}>
|
|
57
|
-
<
|
|
117
|
+
<div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
|
|
118
|
+
<header>My App</header>
|
|
119
|
+
<Thread
|
|
120
|
+
composerPlaceholder="Ask anything..."
|
|
121
|
+
className="flex-1 min-h-0"
|
|
122
|
+
/>
|
|
58
123
|
</div>
|
|
59
124
|
</TimbalRuntimeProvider>
|
|
60
125
|
);
|
|
61
126
|
}
|
|
62
127
|
```
|
|
63
128
|
|
|
129
|
+
#### With a custom API base URL
|
|
130
|
+
|
|
131
|
+
Useful when your API is mounted at a subpath (e.g. behind a reverse proxy):
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<TimbalRuntimeProvider workforceId="your-workforce-id" baseUrl="/api">
|
|
135
|
+
<Thread />
|
|
136
|
+
</TimbalRuntimeProvider>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### With a custom fetch function
|
|
140
|
+
|
|
141
|
+
Pass your own `fetch` to add headers, inject tokens, or proxy requests:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { TimbalRuntimeProvider, Thread } from "@timbal-ai/timbal-react";
|
|
145
|
+
|
|
146
|
+
const myFetch: typeof fetch = (url, options) => {
|
|
147
|
+
return fetch(url, {
|
|
148
|
+
...options,
|
|
149
|
+
headers: {
|
|
150
|
+
...options?.headers,
|
|
151
|
+
"X-My-Header": "value",
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
<TimbalRuntimeProvider workforceId="your-workforce-id" fetch={myFetch}>
|
|
157
|
+
<Thread />
|
|
158
|
+
</TimbalRuntimeProvider>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### `TimbalChat` / `Thread` props
|
|
164
|
+
|
|
165
|
+
| Prop | Type | Default | Description |
|
|
166
|
+
|---|---|---|---|
|
|
167
|
+
| `welcome.heading` | `string` | `"How can I help you today?"` | Welcome screen heading |
|
|
168
|
+
| `welcome.subheading` | `string` | `"Send a message to start a conversation."` | Welcome screen subheading |
|
|
169
|
+
| `suggestions` | `{ title: string; description?: string }[]` | — | Suggestion chips on the welcome screen |
|
|
170
|
+
| `composerPlaceholder` | `string` | `"Send a message..."` | Composer input placeholder |
|
|
171
|
+
| `maxWidth` | `string` | `"44rem"` | Max width of the message column |
|
|
172
|
+
| `className` | `string` | — | Extra classes on the root element |
|
|
173
|
+
|
|
64
174
|
### `TimbalRuntimeProvider` props
|
|
65
175
|
|
|
66
176
|
| Prop | Type | Default | Description |
|
|
@@ -80,23 +190,33 @@ The package includes a session/auth system backed by localStorage tokens. The AP
|
|
|
80
190
|
Wrap your app with `SessionProvider` and protect routes with `AuthGuard`:
|
|
81
191
|
|
|
82
192
|
```tsx
|
|
193
|
+
// src/App.tsx
|
|
83
194
|
import { SessionProvider, AuthGuard, TooltipProvider } from "@timbal-ai/timbal-react";
|
|
195
|
+
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
|
196
|
+
import Home from "./pages/Home";
|
|
84
197
|
|
|
198
|
+
// Auth is opt-in — only active when VITE_TIMBAL_PROJECT_ID is set
|
|
85
199
|
const isAuthEnabled = !!import.meta.env.VITE_TIMBAL_PROJECT_ID;
|
|
86
200
|
|
|
87
|
-
function App() {
|
|
201
|
+
export default function App() {
|
|
88
202
|
return (
|
|
89
203
|
<SessionProvider enabled={isAuthEnabled}>
|
|
90
204
|
<TooltipProvider>
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
|
|
205
|
+
<BrowserRouter>
|
|
206
|
+
<AuthGuard requireAuth enabled={isAuthEnabled}>
|
|
207
|
+
<Routes>
|
|
208
|
+
<Route path="/" element={<Home />} />
|
|
209
|
+
</Routes>
|
|
210
|
+
</AuthGuard>
|
|
211
|
+
</BrowserRouter>
|
|
94
212
|
</TooltipProvider>
|
|
95
213
|
</SessionProvider>
|
|
96
214
|
);
|
|
97
215
|
}
|
|
98
216
|
```
|
|
99
217
|
|
|
218
|
+
When `enabled` is `false` (no project ID configured), both `SessionProvider` and `AuthGuard` are transparent — no redirects, no API calls.
|
|
219
|
+
|
|
100
220
|
### `SessionProvider` props
|
|
101
221
|
|
|
102
222
|
| Prop | Type | Default | Description |
|
|
@@ -112,25 +232,47 @@ function App() {
|
|
|
112
232
|
|
|
113
233
|
### `useSession` hook
|
|
114
234
|
|
|
235
|
+
Access the current session anywhere inside `SessionProvider`:
|
|
236
|
+
|
|
115
237
|
```tsx
|
|
116
238
|
import { useSession } from "@timbal-ai/timbal-react";
|
|
117
239
|
|
|
118
240
|
function Header() {
|
|
119
241
|
const { user, isAuthenticated, loading, logout } = useSession();
|
|
120
|
-
|
|
242
|
+
|
|
243
|
+
if (loading) return null;
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<header>
|
|
247
|
+
{isAuthenticated ? (
|
|
248
|
+
<>
|
|
249
|
+
<span>{user?.email}</span>
|
|
250
|
+
<button onClick={logout}>Log out</button>
|
|
251
|
+
</>
|
|
252
|
+
) : (
|
|
253
|
+
<a href="/login">Log in</a>
|
|
254
|
+
)}
|
|
255
|
+
</header>
|
|
256
|
+
);
|
|
121
257
|
}
|
|
122
258
|
```
|
|
123
259
|
|
|
124
260
|
### `authFetch`
|
|
125
261
|
|
|
126
|
-
A drop-in replacement for `fetch` that attaches the Bearer token and auto-refreshes on 401:
|
|
262
|
+
A drop-in replacement for `fetch` that attaches the Bearer token from localStorage and auto-refreshes on 401:
|
|
127
263
|
|
|
128
264
|
```tsx
|
|
129
265
|
import { authFetch } from "@timbal-ai/timbal-react";
|
|
130
266
|
|
|
267
|
+
// Fetch a list of workforce agents
|
|
131
268
|
const res = await authFetch("/api/workforce");
|
|
269
|
+
if (res.ok) {
|
|
270
|
+
const agents = await res.json();
|
|
271
|
+
}
|
|
132
272
|
```
|
|
133
273
|
|
|
274
|
+
It's also the default `fetch` used by `TimbalRuntimeProvider` — you only need to import it directly for your own API calls (e.g. loading workforce lists, metadata, etc.).
|
|
275
|
+
|
|
134
276
|
---
|
|
135
277
|
|
|
136
278
|
## Components
|
|
@@ -156,6 +298,71 @@ Re-exported Radix UI wrappers pre-styled to match the Timbal design system:
|
|
|
156
298
|
|
|
157
299
|
---
|
|
158
300
|
|
|
301
|
+
## Full example
|
|
302
|
+
|
|
303
|
+
A complete page with agent switching, auth, and a custom header:
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
// src/pages/Home.tsx
|
|
307
|
+
import { useEffect, useState } from "react";
|
|
308
|
+
import type { WorkforceItem } from "@timbal-ai/timbal-sdk";
|
|
309
|
+
import {
|
|
310
|
+
TimbalChat,
|
|
311
|
+
Button,
|
|
312
|
+
authFetch,
|
|
313
|
+
useSession,
|
|
314
|
+
} from "@timbal-ai/timbal-react";
|
|
315
|
+
import { LogOut } from "lucide-react";
|
|
316
|
+
|
|
317
|
+
const isAuthEnabled = !!import.meta.env.VITE_TIMBAL_PROJECT_ID;
|
|
318
|
+
|
|
319
|
+
export default function Home() {
|
|
320
|
+
const { logout } = useSession();
|
|
321
|
+
const [workforces, setWorkforces] = useState<WorkforceItem[]>([]);
|
|
322
|
+
const [selectedId, setSelectedId] = useState("");
|
|
323
|
+
|
|
324
|
+
useEffect(() => {
|
|
325
|
+
authFetch("/api/workforce")
|
|
326
|
+
.then((r) => r.json())
|
|
327
|
+
.then((data: WorkforceItem[]) => {
|
|
328
|
+
setWorkforces(data);
|
|
329
|
+
const agent = data.find((w) => w.type === "agent") ?? data[0];
|
|
330
|
+
if (agent) setSelectedId(agent.id ?? agent.name ?? "");
|
|
331
|
+
})
|
|
332
|
+
.catch(() => {});
|
|
333
|
+
}, []);
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
<div style={{ display: "flex", flexDirection: "column", height: "100vh" }}>
|
|
337
|
+
<header style={{ display: "flex", justifyContent: "space-between", padding: "0.5rem 1.25rem" }}>
|
|
338
|
+
<select value={selectedId} onChange={(e) => setSelectedId(e.target.value)}>
|
|
339
|
+
{workforces.map((w) => (
|
|
340
|
+
<option key={w.id ?? w.name} value={w.id ?? w.name ?? ""}>
|
|
341
|
+
{w.name}
|
|
342
|
+
</option>
|
|
343
|
+
))}
|
|
344
|
+
</select>
|
|
345
|
+
|
|
346
|
+
{isAuthEnabled && (
|
|
347
|
+
<Button variant="ghost" size="icon" onClick={logout}>
|
|
348
|
+
<LogOut />
|
|
349
|
+
</Button>
|
|
350
|
+
)}
|
|
351
|
+
</header>
|
|
352
|
+
|
|
353
|
+
<TimbalChat
|
|
354
|
+
workforceId={selectedId}
|
|
355
|
+
key={selectedId}
|
|
356
|
+
className="flex-1 min-h-0"
|
|
357
|
+
welcome={{ heading: "How can I help you today?" }}
|
|
358
|
+
/>
|
|
359
|
+
</div>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
159
366
|
## Local development
|
|
160
367
|
|
|
161
368
|
Install via a local path reference:
|
package/dist/index.cjs
CHANGED
|
@@ -49,6 +49,7 @@ __export(index_exports, {
|
|
|
49
49
|
Shimmer: () => Shimmer,
|
|
50
50
|
SyntaxHighlighter: () => syntax_highlighter_default,
|
|
51
51
|
Thread: () => Thread,
|
|
52
|
+
TimbalChat: () => TimbalChat,
|
|
52
53
|
TimbalRuntimeProvider: () => TimbalRuntimeProvider,
|
|
53
54
|
ToolFallback: () => ToolFallback,
|
|
54
55
|
Tooltip: () => Tooltip,
|
|
@@ -1267,21 +1268,28 @@ ToolFallback.displayName = "ToolFallback";
|
|
|
1267
1268
|
var import_react11 = require("@assistant-ui/react");
|
|
1268
1269
|
var import_lucide_react5 = require("lucide-react");
|
|
1269
1270
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1270
|
-
var Thread = (
|
|
1271
|
+
var Thread = ({
|
|
1272
|
+
className,
|
|
1273
|
+
maxWidth = "44rem",
|
|
1274
|
+
welcome,
|
|
1275
|
+
suggestions,
|
|
1276
|
+
composerPlaceholder = "Send a message..."
|
|
1277
|
+
}) => {
|
|
1271
1278
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1272
1279
|
import_react11.ThreadPrimitive.Root,
|
|
1273
1280
|
{
|
|
1274
|
-
className:
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1281
|
+
className: cn(
|
|
1282
|
+
"aui-root aui-thread-root @container flex h-full flex-col bg-background",
|
|
1283
|
+
className
|
|
1284
|
+
),
|
|
1285
|
+
style: { ["--thread-max-width"]: maxWidth },
|
|
1278
1286
|
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1279
1287
|
import_react11.ThreadPrimitive.Viewport,
|
|
1280
1288
|
{
|
|
1281
1289
|
turnAnchor: "bottom",
|
|
1282
1290
|
className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll px-4 pt-4",
|
|
1283
1291
|
children: [
|
|
1284
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react11.AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadWelcome, {}) }),
|
|
1292
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react11.AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadWelcome, { config: welcome, suggestions }) }),
|
|
1285
1293
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1286
1294
|
import_react11.ThreadPrimitive.Messages,
|
|
1287
1295
|
{
|
|
@@ -1294,7 +1302,7 @@ var Thread = () => {
|
|
|
1294
1302
|
),
|
|
1295
1303
|
/* @__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: [
|
|
1296
1304
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadScrollToBottom, {}),
|
|
1297
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Composer, {})
|
|
1305
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Composer, { placeholder: composerPlaceholder })
|
|
1298
1306
|
] })
|
|
1299
1307
|
]
|
|
1300
1308
|
}
|
|
@@ -1313,7 +1321,7 @@ var ThreadScrollToBottom = () => {
|
|
|
1313
1321
|
}
|
|
1314
1322
|
) });
|
|
1315
1323
|
};
|
|
1316
|
-
var ThreadWelcome = () => {
|
|
1324
|
+
var ThreadWelcome = ({ config, suggestions }) => {
|
|
1317
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: [
|
|
1318
1326
|
/* @__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: [
|
|
1319
1327
|
/* @__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: [
|
|
@@ -1334,42 +1342,40 @@ var ThreadWelcome = () => {
|
|
|
1334
1342
|
}
|
|
1335
1343
|
)
|
|
1336
1344
|
] }),
|
|
1337
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200", children: "How can I help you today?" }),
|
|
1338
|
-
/* @__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: "Send a message to start a conversation." })
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200", children: config?.heading ?? "How can I help you today?" }),
|
|
1346
|
+
/* @__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." })
|
|
1339
1347
|
] }) }),
|
|
1340
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadSuggestions, {})
|
|
1348
|
+
suggestions && suggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThreadSuggestions, { suggestions })
|
|
1341
1349
|
] });
|
|
1342
1350
|
};
|
|
1343
|
-
var ThreadSuggestions = () => {
|
|
1344
|
-
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: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1345
|
-
import_react11.ThreadPrimitive.Suggestions,
|
|
1346
|
-
{
|
|
1347
|
-
components: {
|
|
1348
|
-
Suggestion: ThreadSuggestionItem
|
|
1349
|
-
}
|
|
1350
|
-
}
|
|
1351
|
-
) });
|
|
1351
|
+
var ThreadSuggestions = ({ suggestions }) => {
|
|
1352
|
+
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)) });
|
|
1352
1353
|
};
|
|
1353
|
-
var ThreadSuggestionItem = () => {
|
|
1354
|
-
|
|
1354
|
+
var ThreadSuggestionItem = ({ title, description }) => {
|
|
1355
|
+
const runtime = (0, import_react11.useThreadRuntime)();
|
|
1356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-2 animate-in fill-mode-both duration-200", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1355
1357
|
Button,
|
|
1356
1358
|
{
|
|
1357
1359
|
variant: "ghost",
|
|
1358
1360
|
className: "aui-thread-welcome-suggestion h-auto w-full @md:flex-col flex-wrap items-start justify-start gap-1 rounded-2xl border px-4 py-3 text-left text-sm transition-colors hover:bg-muted",
|
|
1361
|
+
onClick: () => runtime.append({
|
|
1362
|
+
role: "user",
|
|
1363
|
+
content: [{ type: "text", text: title }]
|
|
1364
|
+
}),
|
|
1359
1365
|
children: [
|
|
1360
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "aui-thread-welcome-suggestion-text-1 font-medium", children:
|
|
1361
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground", children:
|
|
1366
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "aui-thread-welcome-suggestion-text-1 font-medium", children: title }),
|
|
1367
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground", children: description })
|
|
1362
1368
|
]
|
|
1363
1369
|
}
|
|
1364
|
-
) })
|
|
1370
|
+
) });
|
|
1365
1371
|
};
|
|
1366
|
-
var Composer = () => {
|
|
1372
|
+
var Composer = ({ placeholder }) => {
|
|
1367
1373
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react11.ComposerPrimitive.Root, { className: "aui-composer-root relative mt-3 flex w-full flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react11.ComposerPrimitive.AttachmentDropzone, { className: "aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:ring-2 has-[textarea:focus-visible]:ring-ring/20 data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50", children: [
|
|
1368
1374
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ComposerAttachments, {}),
|
|
1369
1375
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1370
1376
|
import_react11.ComposerPrimitive.Input,
|
|
1371
1377
|
{
|
|
1372
|
-
placeholder: "Send a message...",
|
|
1378
|
+
placeholder: placeholder ?? "Send a message...",
|
|
1373
1379
|
className: "aui-composer-input mb-1 max-h-32 min-h-14 w-full resize-none bg-transparent px-4 pt-2 pb-3 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-0",
|
|
1374
1380
|
rows: 1,
|
|
1375
1381
|
autoFocus: true,
|
|
@@ -1517,9 +1523,20 @@ var EditComposer = () => {
|
|
|
1517
1523
|
] }) });
|
|
1518
1524
|
};
|
|
1519
1525
|
|
|
1526
|
+
// src/components/chat.tsx
|
|
1527
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1528
|
+
function TimbalChat({
|
|
1529
|
+
workforceId,
|
|
1530
|
+
baseUrl,
|
|
1531
|
+
fetch: fetch2,
|
|
1532
|
+
...threadProps
|
|
1533
|
+
}) {
|
|
1534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TimbalRuntimeProvider, { workforceId, baseUrl, fetch: fetch2, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Thread, { ...threadProps }) });
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1520
1537
|
// src/auth/provider.tsx
|
|
1521
1538
|
var import_react12 = require("react");
|
|
1522
|
-
var
|
|
1539
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1523
1540
|
var SessionContext = (0, import_react12.createContext)(void 0);
|
|
1524
1541
|
var useSession = () => {
|
|
1525
1542
|
const context = (0, import_react12.useContext)(SessionContext);
|
|
@@ -1583,7 +1600,7 @@ var SessionProvider = ({
|
|
|
1583
1600
|
() => window.location.href = `/api/auth/login?return_to=${returnTo}`
|
|
1584
1601
|
);
|
|
1585
1602
|
}, []);
|
|
1586
|
-
return /* @__PURE__ */ (0,
|
|
1603
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1587
1604
|
SessionContext.Provider,
|
|
1588
1605
|
{
|
|
1589
1606
|
value: {
|
|
@@ -1599,7 +1616,7 @@ var SessionProvider = ({
|
|
|
1599
1616
|
|
|
1600
1617
|
// src/auth/guard.tsx
|
|
1601
1618
|
var import_lucide_react6 = require("lucide-react");
|
|
1602
|
-
var
|
|
1619
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1603
1620
|
var AuthGuard = ({
|
|
1604
1621
|
children,
|
|
1605
1622
|
requireAuth = false,
|
|
@@ -1610,7 +1627,7 @@ var AuthGuard = ({
|
|
|
1610
1627
|
return children;
|
|
1611
1628
|
}
|
|
1612
1629
|
if (loading) {
|
|
1613
|
-
return /* @__PURE__ */ (0,
|
|
1630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.Loader2, { className: "w-8 h-8 animate-spin" }) });
|
|
1614
1631
|
}
|
|
1615
1632
|
if (requireAuth && !isAuthenticated) {
|
|
1616
1633
|
const returnTo = encodeURIComponent(
|
|
@@ -1642,6 +1659,7 @@ var AuthGuard = ({
|
|
|
1642
1659
|
Shimmer,
|
|
1643
1660
|
SyntaxHighlighter,
|
|
1644
1661
|
Thread,
|
|
1662
|
+
TimbalChat,
|
|
1645
1663
|
TimbalRuntimeProvider,
|
|
1646
1664
|
ToolFallback,
|
|
1647
1665
|
Tooltip,
|
package/dist/index.d.cts
CHANGED
|
@@ -26,7 +26,30 @@ interface TimbalRuntimeProviderProps {
|
|
|
26
26
|
}
|
|
27
27
|
declare function TimbalRuntimeProvider({ workforceId, children, baseUrl, fetch: fetchFn, }: TimbalRuntimeProviderProps): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
interface ThreadSuggestion {
|
|
30
|
+
title: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
33
|
+
interface ThreadWelcomeConfig {
|
|
34
|
+
heading?: string;
|
|
35
|
+
subheading?: string;
|
|
36
|
+
}
|
|
37
|
+
interface ThreadProps {
|
|
38
|
+
className?: string;
|
|
39
|
+
/** Max width of the message column. Default: "44rem" */
|
|
40
|
+
maxWidth?: string;
|
|
41
|
+
/** Welcome screen text */
|
|
42
|
+
welcome?: ThreadWelcomeConfig;
|
|
43
|
+
/** Suggestion chips shown on the welcome screen */
|
|
44
|
+
suggestions?: ThreadSuggestion[];
|
|
45
|
+
/** Composer input placeholder. Default: "Send a message..." */
|
|
46
|
+
composerPlaceholder?: string;
|
|
47
|
+
}
|
|
48
|
+
declare const Thread: FC<ThreadProps>;
|
|
49
|
+
|
|
50
|
+
interface TimbalChatProps extends Omit<TimbalRuntimeProviderProps, "children">, ThreadProps {
|
|
51
|
+
}
|
|
52
|
+
declare function TimbalChat({ workforceId, baseUrl, fetch, ...threadProps }: TimbalChatProps): react_jsx_runtime.JSX.Element;
|
|
30
53
|
|
|
31
54
|
declare const MarkdownText: React.MemoExoticComponent<() => react_jsx_runtime.JSX.Element>;
|
|
32
55
|
|
|
@@ -113,4 +136,4 @@ declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, cla
|
|
|
113
136
|
|
|
114
137
|
declare function cn(...inputs: ClassValue[]): string;
|
|
115
138
|
|
|
116
|
-
export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,30 @@ interface TimbalRuntimeProviderProps {
|
|
|
26
26
|
}
|
|
27
27
|
declare function TimbalRuntimeProvider({ workforceId, children, baseUrl, fetch: fetchFn, }: TimbalRuntimeProviderProps): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
interface ThreadSuggestion {
|
|
30
|
+
title: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
33
|
+
interface ThreadWelcomeConfig {
|
|
34
|
+
heading?: string;
|
|
35
|
+
subheading?: string;
|
|
36
|
+
}
|
|
37
|
+
interface ThreadProps {
|
|
38
|
+
className?: string;
|
|
39
|
+
/** Max width of the message column. Default: "44rem" */
|
|
40
|
+
maxWidth?: string;
|
|
41
|
+
/** Welcome screen text */
|
|
42
|
+
welcome?: ThreadWelcomeConfig;
|
|
43
|
+
/** Suggestion chips shown on the welcome screen */
|
|
44
|
+
suggestions?: ThreadSuggestion[];
|
|
45
|
+
/** Composer input placeholder. Default: "Send a message..." */
|
|
46
|
+
composerPlaceholder?: string;
|
|
47
|
+
}
|
|
48
|
+
declare const Thread: FC<ThreadProps>;
|
|
49
|
+
|
|
50
|
+
interface TimbalChatProps extends Omit<TimbalRuntimeProviderProps, "children">, ThreadProps {
|
|
51
|
+
}
|
|
52
|
+
declare function TimbalChat({ workforceId, baseUrl, fetch, ...threadProps }: TimbalChatProps): react_jsx_runtime.JSX.Element;
|
|
30
53
|
|
|
31
54
|
declare const MarkdownText: React.MemoExoticComponent<() => react_jsx_runtime.JSX.Element>;
|
|
32
55
|
|
|
@@ -113,4 +136,4 @@ declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, cla
|
|
|
113
136
|
|
|
114
137
|
declare function cn(...inputs: ClassValue[]): string;
|
|
115
138
|
|
|
116
|
-
export { AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, ComposerAddAttachment, ComposerAttachments, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, MarkdownText, SessionProvider, Shimmer, ShikiSyntaxHighlighter as SyntaxHighlighter, type TextShimmerProps, Thread, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, UserMessageAttachments, authFetch, buttonVariants, clearTokens, cn, fetchCurrentUser, getAccessToken, getRefreshToken, refreshAccessToken, useSession };
|
|
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 };
|
package/dist/index.esm.js
CHANGED
|
@@ -1216,8 +1216,8 @@ import {
|
|
|
1216
1216
|
ComposerPrimitive as ComposerPrimitive2,
|
|
1217
1217
|
ErrorPrimitive,
|
|
1218
1218
|
MessagePrimitive as MessagePrimitive2,
|
|
1219
|
-
|
|
1220
|
-
|
|
1219
|
+
ThreadPrimitive,
|
|
1220
|
+
useThreadRuntime
|
|
1221
1221
|
} from "@assistant-ui/react";
|
|
1222
1222
|
import {
|
|
1223
1223
|
ArrowDownIcon,
|
|
@@ -1231,21 +1231,28 @@ import {
|
|
|
1231
1231
|
SquareIcon
|
|
1232
1232
|
} from "lucide-react";
|
|
1233
1233
|
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1234
|
-
var Thread = (
|
|
1234
|
+
var Thread = ({
|
|
1235
|
+
className,
|
|
1236
|
+
maxWidth = "44rem",
|
|
1237
|
+
welcome,
|
|
1238
|
+
suggestions,
|
|
1239
|
+
composerPlaceholder = "Send a message..."
|
|
1240
|
+
}) => {
|
|
1235
1241
|
return /* @__PURE__ */ jsx12(
|
|
1236
1242
|
ThreadPrimitive.Root,
|
|
1237
1243
|
{
|
|
1238
|
-
className:
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1244
|
+
className: cn(
|
|
1245
|
+
"aui-root aui-thread-root @container flex h-full flex-col bg-background",
|
|
1246
|
+
className
|
|
1247
|
+
),
|
|
1248
|
+
style: { ["--thread-max-width"]: maxWidth },
|
|
1242
1249
|
children: /* @__PURE__ */ jsxs7(
|
|
1243
1250
|
ThreadPrimitive.Viewport,
|
|
1244
1251
|
{
|
|
1245
1252
|
turnAnchor: "bottom",
|
|
1246
1253
|
className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll px-4 pt-4",
|
|
1247
1254
|
children: [
|
|
1248
|
-
/* @__PURE__ */ jsx12(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsx12(ThreadWelcome, {}) }),
|
|
1255
|
+
/* @__PURE__ */ jsx12(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsx12(ThreadWelcome, { config: welcome, suggestions }) }),
|
|
1249
1256
|
/* @__PURE__ */ jsx12(
|
|
1250
1257
|
ThreadPrimitive.Messages,
|
|
1251
1258
|
{
|
|
@@ -1258,7 +1265,7 @@ var Thread = () => {
|
|
|
1258
1265
|
),
|
|
1259
1266
|
/* @__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: [
|
|
1260
1267
|
/* @__PURE__ */ jsx12(ThreadScrollToBottom, {}),
|
|
1261
|
-
/* @__PURE__ */ jsx12(Composer, {})
|
|
1268
|
+
/* @__PURE__ */ jsx12(Composer, { placeholder: composerPlaceholder })
|
|
1262
1269
|
] })
|
|
1263
1270
|
]
|
|
1264
1271
|
}
|
|
@@ -1277,7 +1284,7 @@ var ThreadScrollToBottom = () => {
|
|
|
1277
1284
|
}
|
|
1278
1285
|
) });
|
|
1279
1286
|
};
|
|
1280
|
-
var ThreadWelcome = () => {
|
|
1287
|
+
var ThreadWelcome = ({ config, suggestions }) => {
|
|
1281
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: [
|
|
1282
1289
|
/* @__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: [
|
|
1283
1290
|
/* @__PURE__ */ jsxs7("div", { className: "fade-in animate-in fill-mode-both relative mb-6 flex size-14 items-center justify-center duration-300", children: [
|
|
@@ -1298,42 +1305,40 @@ var ThreadWelcome = () => {
|
|
|
1298
1305
|
}
|
|
1299
1306
|
)
|
|
1300
1307
|
] }),
|
|
1301
|
-
/* @__PURE__ */ jsx12("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200", children: "How can I help you today?" }),
|
|
1302
|
-
/* @__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: "Send a message to start a conversation." })
|
|
1308
|
+
/* @__PURE__ */ jsx12("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200", children: config?.heading ?? "How can I help you today?" }),
|
|
1309
|
+
/* @__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." })
|
|
1303
1310
|
] }) }),
|
|
1304
|
-
/* @__PURE__ */ jsx12(ThreadSuggestions, {})
|
|
1311
|
+
suggestions && suggestions.length > 0 && /* @__PURE__ */ jsx12(ThreadSuggestions, { suggestions })
|
|
1305
1312
|
] });
|
|
1306
1313
|
};
|
|
1307
|
-
var ThreadSuggestions = () => {
|
|
1308
|
-
return /* @__PURE__ */ jsx12("div", { className: "aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4", children: /* @__PURE__ */ jsx12(
|
|
1309
|
-
ThreadPrimitive.Suggestions,
|
|
1310
|
-
{
|
|
1311
|
-
components: {
|
|
1312
|
-
Suggestion: ThreadSuggestionItem
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
) });
|
|
1314
|
+
var ThreadSuggestions = ({ suggestions }) => {
|
|
1315
|
+
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)) });
|
|
1316
1316
|
};
|
|
1317
|
-
var ThreadSuggestionItem = () => {
|
|
1318
|
-
|
|
1317
|
+
var ThreadSuggestionItem = ({ title, description }) => {
|
|
1318
|
+
const runtime = useThreadRuntime();
|
|
1319
|
+
return /* @__PURE__ */ jsx12("div", { className: "aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-2 animate-in fill-mode-both duration-200", children: /* @__PURE__ */ jsxs7(
|
|
1319
1320
|
Button,
|
|
1320
1321
|
{
|
|
1321
1322
|
variant: "ghost",
|
|
1322
1323
|
className: "aui-thread-welcome-suggestion h-auto w-full @md:flex-col flex-wrap items-start justify-start gap-1 rounded-2xl border px-4 py-3 text-left text-sm transition-colors hover:bg-muted",
|
|
1324
|
+
onClick: () => runtime.append({
|
|
1325
|
+
role: "user",
|
|
1326
|
+
content: [{ type: "text", text: title }]
|
|
1327
|
+
}),
|
|
1323
1328
|
children: [
|
|
1324
|
-
/* @__PURE__ */ jsx12("span", { className: "aui-thread-welcome-suggestion-text-1 font-medium", children:
|
|
1325
|
-
/* @__PURE__ */ jsx12("span", { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground", children:
|
|
1329
|
+
/* @__PURE__ */ jsx12("span", { className: "aui-thread-welcome-suggestion-text-1 font-medium", children: title }),
|
|
1330
|
+
description && /* @__PURE__ */ jsx12("span", { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground", children: description })
|
|
1326
1331
|
]
|
|
1327
1332
|
}
|
|
1328
|
-
) })
|
|
1333
|
+
) });
|
|
1329
1334
|
};
|
|
1330
|
-
var Composer = () => {
|
|
1335
|
+
var Composer = ({ placeholder }) => {
|
|
1331
1336
|
return /* @__PURE__ */ jsx12(ComposerPrimitive2.Root, { className: "aui-composer-root relative mt-3 flex w-full flex-col", children: /* @__PURE__ */ jsxs7(ComposerPrimitive2.AttachmentDropzone, { className: "aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:ring-2 has-[textarea:focus-visible]:ring-ring/20 data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50", children: [
|
|
1332
1337
|
/* @__PURE__ */ jsx12(ComposerAttachments, {}),
|
|
1333
1338
|
/* @__PURE__ */ jsx12(
|
|
1334
1339
|
ComposerPrimitive2.Input,
|
|
1335
1340
|
{
|
|
1336
|
-
placeholder: "Send a message...",
|
|
1341
|
+
placeholder: placeholder ?? "Send a message...",
|
|
1337
1342
|
className: "aui-composer-input mb-1 max-h-32 min-h-14 w-full resize-none bg-transparent px-4 pt-2 pb-3 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-0",
|
|
1338
1343
|
rows: 1,
|
|
1339
1344
|
autoFocus: true,
|
|
@@ -1481,6 +1486,17 @@ var EditComposer = () => {
|
|
|
1481
1486
|
] }) });
|
|
1482
1487
|
};
|
|
1483
1488
|
|
|
1489
|
+
// src/components/chat.tsx
|
|
1490
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1491
|
+
function TimbalChat({
|
|
1492
|
+
workforceId,
|
|
1493
|
+
baseUrl,
|
|
1494
|
+
fetch: fetch2,
|
|
1495
|
+
...threadProps
|
|
1496
|
+
}) {
|
|
1497
|
+
return /* @__PURE__ */ jsx13(TimbalRuntimeProvider, { workforceId, baseUrl, fetch: fetch2, children: /* @__PURE__ */ jsx13(Thread, { ...threadProps }) });
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1484
1500
|
// src/auth/provider.tsx
|
|
1485
1501
|
import {
|
|
1486
1502
|
createContext,
|
|
@@ -1489,7 +1505,7 @@ import {
|
|
|
1489
1505
|
useEffect as useEffect4,
|
|
1490
1506
|
useState as useState5
|
|
1491
1507
|
} from "react";
|
|
1492
|
-
import { jsx as
|
|
1508
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1493
1509
|
var SessionContext = createContext(void 0);
|
|
1494
1510
|
var useSession = () => {
|
|
1495
1511
|
const context = useContext(SessionContext);
|
|
@@ -1553,7 +1569,7 @@ var SessionProvider = ({
|
|
|
1553
1569
|
() => window.location.href = `/api/auth/login?return_to=${returnTo}`
|
|
1554
1570
|
);
|
|
1555
1571
|
}, []);
|
|
1556
|
-
return /* @__PURE__ */
|
|
1572
|
+
return /* @__PURE__ */ jsx14(
|
|
1557
1573
|
SessionContext.Provider,
|
|
1558
1574
|
{
|
|
1559
1575
|
value: {
|
|
@@ -1569,7 +1585,7 @@ var SessionProvider = ({
|
|
|
1569
1585
|
|
|
1570
1586
|
// src/auth/guard.tsx
|
|
1571
1587
|
import { Loader2 } from "lucide-react";
|
|
1572
|
-
import { jsx as
|
|
1588
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1573
1589
|
var AuthGuard = ({
|
|
1574
1590
|
children,
|
|
1575
1591
|
requireAuth = false,
|
|
@@ -1580,7 +1596,7 @@ var AuthGuard = ({
|
|
|
1580
1596
|
return children;
|
|
1581
1597
|
}
|
|
1582
1598
|
if (loading) {
|
|
1583
|
-
return /* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ jsx15("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ jsx15(Loader2, { className: "w-8 h-8 animate-spin" }) });
|
|
1584
1600
|
}
|
|
1585
1601
|
if (requireAuth && !isAuthenticated) {
|
|
1586
1602
|
const returnTo = encodeURIComponent(
|
|
@@ -1611,6 +1627,7 @@ export {
|
|
|
1611
1627
|
Shimmer,
|
|
1612
1628
|
syntax_highlighter_default as SyntaxHighlighter,
|
|
1613
1629
|
Thread,
|
|
1630
|
+
TimbalChat,
|
|
1614
1631
|
TimbalRuntimeProvider,
|
|
1615
1632
|
ToolFallback,
|
|
1616
1633
|
Tooltip,
|