@meshagent/meshagent-tailwind 0.38.2 → 0.38.4

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/Chat.d.ts +11 -3
  3. package/dist/cjs/Chat.js +376 -29
  4. package/dist/cjs/ChatBotView.d.ts +29 -0
  5. package/dist/cjs/ChatBotView.js +491 -0
  6. package/dist/cjs/ChatInput.d.ts +12 -3
  7. package/dist/cjs/ChatInput.js +143 -44
  8. package/dist/cjs/ChatThread.d.ts +17 -3
  9. package/dist/cjs/ChatThread.js +646 -90
  10. package/dist/cjs/ChatTypingIndicator.d.ts +12 -5
  11. package/dist/cjs/ChatTypingIndicator.js +104 -13
  12. package/dist/cjs/FileUploader.d.ts +3 -2
  13. package/dist/cjs/FileUploader.js +35 -11
  14. package/dist/cjs/UploadPill.d.ts +2 -2
  15. package/dist/cjs/UploadPill.js +70 -32
  16. package/dist/cjs/chat-hooks.d.ts +38 -0
  17. package/dist/cjs/chat-hooks.js +390 -0
  18. package/dist/cjs/chat-message.d.ts +11 -0
  19. package/dist/cjs/chat-message.js +33 -0
  20. package/dist/cjs/components/ui/button.d.ts +1 -1
  21. package/dist/cjs/conversation-descriptor.d.ts +59 -0
  22. package/dist/cjs/conversation-descriptor.js +300 -0
  23. package/dist/cjs/file-attachment.d.ts +45 -0
  24. package/dist/cjs/file-attachment.js +171 -0
  25. package/dist/cjs/index.d.ts +5 -0
  26. package/dist/cjs/index.js +5 -0
  27. package/dist/cjs/multi-thread-view.d.ts +18 -0
  28. package/dist/cjs/multi-thread-view.js +88 -0
  29. package/dist/cjs/tools/ui-toolkit.d.ts +1 -1
  30. package/dist/cjs/tools/ui-toolkit.js +2 -1
  31. package/dist/esm/Chat.d.ts +11 -3
  32. package/dist/esm/Chat.js +378 -31
  33. package/dist/esm/ChatBotView.d.ts +29 -0
  34. package/dist/esm/ChatBotView.js +486 -0
  35. package/dist/esm/ChatInput.d.ts +12 -3
  36. package/dist/esm/ChatInput.js +143 -34
  37. package/dist/esm/ChatThread.d.ts +17 -3
  38. package/dist/esm/ChatThread.js +648 -92
  39. package/dist/esm/ChatTypingIndicator.d.ts +12 -5
  40. package/dist/esm/ChatTypingIndicator.js +94 -13
  41. package/dist/esm/FileUploader.d.ts +3 -2
  42. package/dist/esm/FileUploader.js +26 -12
  43. package/dist/esm/UploadPill.d.ts +2 -2
  44. package/dist/esm/UploadPill.js +60 -32
  45. package/dist/esm/chat-hooks.d.ts +38 -0
  46. package/dist/esm/chat-hooks.js +372 -0
  47. package/dist/esm/chat-message.d.ts +11 -0
  48. package/dist/esm/chat-message.js +13 -0
  49. package/dist/esm/components/ui/button.d.ts +1 -1
  50. package/dist/esm/conversation-descriptor.d.ts +59 -0
  51. package/dist/esm/conversation-descriptor.js +280 -0
  52. package/dist/esm/file-attachment.d.ts +45 -0
  53. package/dist/esm/file-attachment.js +151 -0
  54. package/dist/esm/index.d.ts +5 -0
  55. package/dist/esm/index.js +5 -0
  56. package/dist/esm/multi-thread-view.d.ts +18 -0
  57. package/dist/esm/multi-thread-view.js +68 -0
  58. package/dist/esm/tools/ui-toolkit.d.ts +1 -1
  59. package/dist/esm/tools/ui-toolkit.js +2 -1
  60. package/dist/index.css +1 -1
  61. package/package.json +3 -3
@@ -0,0 +1,486 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { useDocumentChanged } from "@meshagent/meshagent-react";
4
+ import {
5
+ AlertTriangle,
6
+ Check,
7
+ MessageSquare,
8
+ MessageSquarePlus,
9
+ Pencil
10
+ } from "lucide-react";
11
+ import { useThreadStatus } from "./chat-hooks";
12
+ import { Chat } from "./Chat";
13
+ import { Button } from "./components/ui/button";
14
+ import { Spinner } from "./components/ui/spinner";
15
+ import {
16
+ ChatThreadDisplayMode,
17
+ chatDocumentPath,
18
+ defaultThreadDisplayNameFromPath,
19
+ resolvedThreadListPath
20
+ } from "./conversation-descriptor";
21
+ import { cn } from "./lib/utils";
22
+ import { MultiThreadView } from "./multi-thread-view";
23
+ const multiThreadLayoutBreakpointPx = 920;
24
+ import {
25
+ ChatThreadDisplayMode as ChatThreadDisplayMode2,
26
+ chatDocumentPath as chatDocumentPath2,
27
+ resolvedThreadListPath as resolvedThreadListPath2
28
+ } from "./conversation-descriptor";
29
+ function normalizePath(path) {
30
+ const normalized = path?.trim();
31
+ return normalized ? normalized : null;
32
+ }
33
+ function parseDate(value) {
34
+ const parsed = new Date(value);
35
+ return Number.isNaN(parsed.getTime()) ? /* @__PURE__ */ new Date(0) : parsed;
36
+ }
37
+ function compareThreadEntries(left, right) {
38
+ const leftSortDate = left.modifiedAt.trim() ? parseDate(left.modifiedAt) : parseDate(left.createdAt);
39
+ const rightSortDate = right.modifiedAt.trim() ? parseDate(right.modifiedAt) : parseDate(right.createdAt);
40
+ const dateComparison = rightSortDate.getTime() - leftSortDate.getTime();
41
+ if (dateComparison !== 0) {
42
+ return dateComparison;
43
+ }
44
+ const leftCreatedAt = parseDate(left.createdAt);
45
+ const rightCreatedAt = parseDate(right.createdAt);
46
+ const createdDateComparison = rightCreatedAt.getTime() - leftCreatedAt.getTime();
47
+ if (createdDateComparison !== 0) {
48
+ return createdDateComparison;
49
+ }
50
+ return left.path.localeCompare(right.path);
51
+ }
52
+ function parseThreadListEntries(document) {
53
+ const entries = [];
54
+ for (const child of document.root.getChildren()) {
55
+ if (child.tagName !== "thread") {
56
+ continue;
57
+ }
58
+ const rawPath = child.getAttribute("path");
59
+ if (typeof rawPath !== "string" || rawPath.trim() === "") {
60
+ continue;
61
+ }
62
+ const path = rawPath.trim();
63
+ const rawName = child.getAttribute("name");
64
+ const rawCreatedAt = child.getAttribute("created_at");
65
+ const rawModifiedAt = child.getAttribute("modified_at");
66
+ entries.push({
67
+ element: child,
68
+ path,
69
+ name: typeof rawName === "string" && rawName.trim() !== "" ? rawName.trim() : defaultThreadDisplayNameFromPath(path),
70
+ createdAt: typeof rawCreatedAt === "string" ? rawCreatedAt : "",
71
+ modifiedAt: typeof rawModifiedAt === "string" ? rawModifiedAt : ""
72
+ });
73
+ }
74
+ entries.sort(compareThreadEntries);
75
+ return entries;
76
+ }
77
+ function threadEntriesEqual(left, right) {
78
+ return left.length === right.length && left.every((entry, index) => {
79
+ const other = right[index];
80
+ return entry.path === other?.path && entry.name === other.name && entry.createdAt === other.createdAt && entry.modifiedAt === other.modifiedAt;
81
+ });
82
+ }
83
+ function describeError(error) {
84
+ if (error instanceof Error && error.message.trim() !== "") {
85
+ return error.message;
86
+ }
87
+ return `${error}`;
88
+ }
89
+ async function closeDocument(room, path) {
90
+ try {
91
+ await room.sync.close(path);
92
+ } catch {
93
+ }
94
+ }
95
+ function useIsWideLayout(minWidth) {
96
+ const [matches, setMatches] = useState(false);
97
+ useEffect(() => {
98
+ if (typeof window === "undefined") {
99
+ return;
100
+ }
101
+ const mediaQuery = window.matchMedia(`(min-width: ${minWidth}px)`);
102
+ const updateMatches = (event) => {
103
+ setMatches(event?.matches ?? mediaQuery.matches);
104
+ };
105
+ updateMatches();
106
+ mediaQuery.addEventListener("change", updateMatches);
107
+ return () => {
108
+ mediaQuery.removeEventListener("change", updateMatches);
109
+ };
110
+ }, [minWidth]);
111
+ return matches;
112
+ }
113
+ function useThreadListDocument({
114
+ room,
115
+ path
116
+ }) {
117
+ const [document, setDocument] = useState(null);
118
+ const [entries, setEntries] = useState([]);
119
+ const [loading, setLoading] = useState(path !== null);
120
+ const [error, setError] = useState(null);
121
+ const syncDocumentState = useCallback((nextDocument) => {
122
+ const nextEntries = parseThreadListEntries(nextDocument);
123
+ setEntries((currentEntries) => threadEntriesEqual(currentEntries, nextEntries) ? currentEntries : nextEntries);
124
+ }, []);
125
+ useEffect(() => {
126
+ let cancelled = false;
127
+ let opened = false;
128
+ if (path === null) {
129
+ setDocument(null);
130
+ setEntries([]);
131
+ setLoading(false);
132
+ setError(null);
133
+ return;
134
+ }
135
+ setDocument(null);
136
+ setEntries([]);
137
+ setLoading(true);
138
+ setError(null);
139
+ void room.sync.open(path).then((nextDocument) => {
140
+ if (cancelled) {
141
+ void closeDocument(room, path);
142
+ return;
143
+ }
144
+ opened = true;
145
+ setDocument(nextDocument);
146
+ syncDocumentState(nextDocument);
147
+ setLoading(false);
148
+ setError(null);
149
+ }).catch((nextError) => {
150
+ if (cancelled) {
151
+ return;
152
+ }
153
+ setDocument(null);
154
+ setEntries([]);
155
+ setLoading(false);
156
+ setError(nextError);
157
+ });
158
+ return () => {
159
+ cancelled = true;
160
+ if (opened) {
161
+ void closeDocument(room, path);
162
+ }
163
+ };
164
+ }, [path, room, syncDocumentState]);
165
+ useDocumentChanged({
166
+ document,
167
+ onChanged: syncDocumentState
168
+ });
169
+ return {
170
+ document,
171
+ entries,
172
+ loading,
173
+ error
174
+ };
175
+ }
176
+ function ThreadListRow({
177
+ title,
178
+ selected,
179
+ onClick,
180
+ icon,
181
+ trailing
182
+ }) {
183
+ return /* @__PURE__ */ jsx("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsxs(
184
+ "div",
185
+ {
186
+ className: cn(
187
+ "flex min-w-0 items-center rounded-lg border border-transparent transition-colors",
188
+ selected ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:bg-accent/50 hover:text-foreground"
189
+ ),
190
+ children: [
191
+ /* @__PURE__ */ jsxs(
192
+ "button",
193
+ {
194
+ type: "button",
195
+ className: "flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-left",
196
+ onClick,
197
+ children: [
198
+ /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: icon }),
199
+ /* @__PURE__ */ jsx(
200
+ "span",
201
+ {
202
+ className: cn(
203
+ "truncate text-sm font-medium",
204
+ selected ? "text-accent-foreground" : "text-foreground"
205
+ ),
206
+ children: title
207
+ }
208
+ )
209
+ ]
210
+ }
211
+ ),
212
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 pr-1", children: trailing ?? /* @__PURE__ */ jsx("div", { className: "h-8 w-8" }) })
213
+ ]
214
+ }
215
+ ) });
216
+ }
217
+ function ThreadListEntryRow({
218
+ room,
219
+ entry,
220
+ agentName,
221
+ selected,
222
+ onSelect,
223
+ onRename
224
+ }) {
225
+ const status = useThreadStatus({ room, path: entry.path, agentName });
226
+ const iconClassName = selected ? "text-accent-foreground" : "text-muted-foreground";
227
+ const hasStatus = status.text?.trim() !== "";
228
+ return /* @__PURE__ */ jsx(
229
+ ThreadListRow,
230
+ {
231
+ title: entry.name,
232
+ selected,
233
+ onClick: () => onSelect(entry),
234
+ icon: hasStatus ? /* @__PURE__ */ jsx(Spinner, { size: "sm", className: iconClassName }) : selected ? /* @__PURE__ */ jsx(Check, { className: cn("h-4 w-4", iconClassName) }) : /* @__PURE__ */ jsx(MessageSquare, { className: cn("h-4 w-4", iconClassName) }),
235
+ trailing: /* @__PURE__ */ jsx(
236
+ Button,
237
+ {
238
+ type: "button",
239
+ variant: "ghost",
240
+ size: "icon",
241
+ className: "h-8 w-8 rounded-md",
242
+ "aria-label": `Rename ${entry.name}`,
243
+ onClick: () => onRename(entry),
244
+ children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
245
+ }
246
+ )
247
+ }
248
+ );
249
+ }
250
+ function ThreadListPanel({
251
+ room,
252
+ threadList,
253
+ selectedThreadPath,
254
+ agentName,
255
+ onSelectThread,
256
+ onClearSelection,
257
+ onRenameThread
258
+ }) {
259
+ const { entries, error, loading } = threadList;
260
+ const hasSelectedEntry = selectedThreadPath !== null && entries.some((entry) => entry.path === selectedThreadPath);
261
+ const showPendingNewThreadSelection = selectedThreadPath === null || !hasSelectedEntry;
262
+ return /* @__PURE__ */ jsx("div", { className: "flex h-full min-h-0 flex-col overflow-hidden rounded-2xl border bg-background", children: loading ? /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsx(Spinner, { size: "lg", className: "text-muted-foreground" }) }) : error ? /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center p-6 text-center text-sm text-muted-foreground", children: `Unable to load threads: ${describeError(error)}` }) : /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto py-1", children: [
263
+ /* @__PURE__ */ jsx(
264
+ ThreadListRow,
265
+ {
266
+ title: "New thread",
267
+ selected: showPendingNewThreadSelection,
268
+ onClick: onClearSelection,
269
+ icon: showPendingNewThreadSelection ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-accent-foreground" }) : /* @__PURE__ */ jsx(MessageSquarePlus, { className: "h-4 w-4 text-muted-foreground" })
270
+ }
271
+ ),
272
+ entries.length === 0 && showPendingNewThreadSelection ? /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center px-4 py-6 text-center text-sm text-muted-foreground", children: "No threads yet" }) : null,
273
+ entries.map((entry) => /* @__PURE__ */ jsx(
274
+ ThreadListEntryRow,
275
+ {
276
+ room,
277
+ entry,
278
+ agentName,
279
+ selected: entry.path === selectedThreadPath,
280
+ onSelect: onSelectThread,
281
+ onRename: onRenameThread
282
+ },
283
+ entry.path
284
+ ))
285
+ ] }) });
286
+ }
287
+ function MultiThreadUnavailable() {
288
+ return /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center px-4 py-8", children: /* @__PURE__ */ jsx("div", { className: "w-full max-w-[912px] rounded-3xl border border-destructive/30 bg-destructive/5 p-6 text-destructive", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
289
+ /* @__PURE__ */ jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0" }),
290
+ /* @__PURE__ */ jsxs("div", { children: [
291
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Unable to start a new thread" }),
292
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-destructive/80", children: "No chat agent is selected." })
293
+ ] })
294
+ ] }) }) });
295
+ }
296
+ function ChatBotView({
297
+ room,
298
+ path,
299
+ documentPath,
300
+ participants,
301
+ agentName,
302
+ threadDisplayMode = ChatThreadDisplayMode.SingleThread,
303
+ threadDir,
304
+ threadListPath,
305
+ toolkit,
306
+ tool,
307
+ centerComposer = false,
308
+ emptyStateTitle = "No threads yet",
309
+ emptyStateDescription = "Start a new conversation to see it here.",
310
+ selectedThreadPath,
311
+ onSelectedThreadPathChanged,
312
+ onSelectedThreadResolved,
313
+ onThreadResolved,
314
+ newThreadResetVersion = 0,
315
+ showThreadList = true,
316
+ threadListWidth = 280,
317
+ threadListCollapsedHeight = 220
318
+ }) {
319
+ const isWideLayout = useIsWideLayout(multiThreadLayoutBreakpointPx);
320
+ const resolvedDocumentPath = useMemo(
321
+ () => normalizePath(documentPath ?? path),
322
+ [documentPath, path]
323
+ );
324
+ const resolvedSingleThreadPath = useMemo(
325
+ () => resolvedDocumentPath ?? chatDocumentPath(agentName, { threadDir }),
326
+ [agentName, resolvedDocumentPath, threadDir]
327
+ );
328
+ const explicitSelectedThreadPath = selectedThreadPath !== void 0 ? normalizePath(selectedThreadPath) : void 0;
329
+ const legacySelectedThreadPath = threadDisplayMode === ChatThreadDisplayMode.MultiThreadComposer ? resolvedDocumentPath : null;
330
+ const [internalSelectedThreadPath, setInternalSelectedThreadPath] = useState(() => explicitSelectedThreadPath ?? legacySelectedThreadPath ?? null);
331
+ const previousLegacySelectedThreadPathRef = useRef(legacySelectedThreadPath);
332
+ const previousNewThreadResetVersionRef = useRef(newThreadResetVersion);
333
+ const activeSelectedThreadPath = explicitSelectedThreadPath ?? internalSelectedThreadPath;
334
+ const resolvedThreadListDocumentPath = useMemo(
335
+ () => resolvedThreadListPath(threadListPath, { threadDir, agentName }),
336
+ [agentName, threadDir, threadListPath]
337
+ );
338
+ const threadList = useThreadListDocument({
339
+ room,
340
+ path: threadDisplayMode === ChatThreadDisplayMode.MultiThreadComposer && showThreadList && resolvedThreadListDocumentPath !== null ? resolvedThreadListDocumentPath : null
341
+ });
342
+ useEffect(() => {
343
+ if (explicitSelectedThreadPath === void 0) {
344
+ return;
345
+ }
346
+ setInternalSelectedThreadPath(explicitSelectedThreadPath);
347
+ }, [explicitSelectedThreadPath]);
348
+ useEffect(() => {
349
+ if (explicitSelectedThreadPath !== void 0) {
350
+ previousLegacySelectedThreadPathRef.current = legacySelectedThreadPath;
351
+ return;
352
+ }
353
+ if (legacySelectedThreadPath !== previousLegacySelectedThreadPathRef.current) {
354
+ setInternalSelectedThreadPath(legacySelectedThreadPath);
355
+ }
356
+ previousLegacySelectedThreadPathRef.current = legacySelectedThreadPath;
357
+ }, [explicitSelectedThreadPath, legacySelectedThreadPath]);
358
+ const emitResolvedThread = useCallback((nextPath, displayName) => {
359
+ onSelectedThreadResolved?.(nextPath, displayName);
360
+ onThreadResolved?.(nextPath, displayName);
361
+ }, [onSelectedThreadResolved, onThreadResolved]);
362
+ const handleSelectedThreadPathChanged = useCallback((nextPath) => {
363
+ const normalizedNextPath = normalizePath(nextPath);
364
+ if (explicitSelectedThreadPath === void 0) {
365
+ setInternalSelectedThreadPath(normalizedNextPath);
366
+ }
367
+ onSelectedThreadPathChanged?.(normalizedNextPath);
368
+ }, [explicitSelectedThreadPath, onSelectedThreadPathChanged]);
369
+ const setSelectedThread = useCallback((nextPath, displayName) => {
370
+ const normalizedNextPath = normalizePath(nextPath);
371
+ handleSelectedThreadPathChanged(normalizedNextPath);
372
+ emitResolvedThread(normalizedNextPath, displayName);
373
+ }, [emitResolvedThread, handleSelectedThreadPathChanged]);
374
+ useEffect(() => {
375
+ if (threadDisplayMode !== ChatThreadDisplayMode.MultiThreadComposer) {
376
+ previousNewThreadResetVersionRef.current = newThreadResetVersion;
377
+ return;
378
+ }
379
+ if (previousNewThreadResetVersionRef.current !== newThreadResetVersion && activeSelectedThreadPath !== null) {
380
+ setSelectedThread(null, null);
381
+ }
382
+ previousNewThreadResetVersionRef.current = newThreadResetVersion;
383
+ }, [activeSelectedThreadPath, newThreadResetVersion, setSelectedThread, threadDisplayMode]);
384
+ const handleRenameThread = useCallback((entry) => {
385
+ if (typeof window === "undefined") {
386
+ return;
387
+ }
388
+ const nextName = window.prompt("Rename thread", entry.name);
389
+ if (nextName === null) {
390
+ return;
391
+ }
392
+ const trimmedName = nextName.trim();
393
+ if (trimmedName === "" || trimmedName === entry.name) {
394
+ return;
395
+ }
396
+ entry.element.setAttribute("name", trimmedName);
397
+ if (entry.path === activeSelectedThreadPath) {
398
+ emitResolvedThread(entry.path, trimmedName);
399
+ }
400
+ }, [activeSelectedThreadPath, emitResolvedThread]);
401
+ if (threadDisplayMode !== ChatThreadDisplayMode.MultiThreadComposer) {
402
+ return /* @__PURE__ */ jsx(
403
+ Chat,
404
+ {
405
+ room,
406
+ path: resolvedSingleThreadPath,
407
+ participants,
408
+ agentName,
409
+ toolkit,
410
+ tool,
411
+ centerComposer,
412
+ emptyStateTitle,
413
+ emptyStateDescription,
414
+ onThreadResolved
415
+ }
416
+ );
417
+ }
418
+ if (!agentName?.trim()) {
419
+ return /* @__PURE__ */ jsx(MultiThreadUnavailable, {});
420
+ }
421
+ const content = /* @__PURE__ */ jsx(
422
+ MultiThreadView,
423
+ {
424
+ room,
425
+ agentName,
426
+ toolkit,
427
+ tool,
428
+ selectedThreadPath: activeSelectedThreadPath,
429
+ onSelectedThreadPathChanged: handleSelectedThreadPathChanged,
430
+ onSelectedThreadResolved: emitResolvedThread,
431
+ newThreadResetVersion,
432
+ centerComposer,
433
+ emptyStateTitle,
434
+ emptyStateDescription,
435
+ builder: (threadPath) => /* @__PURE__ */ jsx(
436
+ Chat,
437
+ {
438
+ room,
439
+ path: threadPath,
440
+ participants,
441
+ agentName,
442
+ toolkit,
443
+ tool,
444
+ centerComposer,
445
+ emptyStateTitle,
446
+ emptyStateDescription
447
+ }
448
+ )
449
+ }
450
+ );
451
+ if (!showThreadList || resolvedThreadListDocumentPath === null) {
452
+ return content;
453
+ }
454
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-1 h-full", isWideLayout ? "flex-row items-stretch" : "flex-col"), children: [
455
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col h-full min-h-0 min-w-0 flex-1", children: content }),
456
+ /* @__PURE__ */ jsx(
457
+ "div",
458
+ {
459
+ className: cn("shrink-0 mr-4", isWideLayout ? "ml-3" : "mt-3"),
460
+ style: isWideLayout ? { width: threadListWidth } : { height: threadListCollapsedHeight },
461
+ children: /* @__PURE__ */ jsx(
462
+ ThreadListPanel,
463
+ {
464
+ room,
465
+ threadList,
466
+ selectedThreadPath: activeSelectedThreadPath,
467
+ agentName,
468
+ onSelectThread: (entry) => {
469
+ setSelectedThread(entry.path, entry.name);
470
+ },
471
+ onClearSelection: () => {
472
+ setSelectedThread(null, null);
473
+ },
474
+ onRenameThread: handleRenameThread
475
+ }
476
+ )
477
+ }
478
+ )
479
+ ] });
480
+ }
481
+ export {
482
+ ChatBotView,
483
+ ChatThreadDisplayMode2 as ChatThreadDisplayMode,
484
+ chatDocumentPath2 as chatDocumentPath,
485
+ resolvedThreadListPath2 as resolvedThreadListPath
486
+ };
@@ -1,12 +1,21 @@
1
- import { ChatMessage, FileUpload } from "@meshagent/meshagent-react";
1
+ import type { ReactElement } from "react";
2
+ import { ChatMessage } from "./chat-message";
3
+ import { type FileUpload } from "./file-attachment";
2
4
  interface ChatInputProps {
3
- onSubmit: (message: ChatMessage) => void;
5
+ onSubmit: (message: ChatMessage) => void | Promise<void>;
4
6
  onFilesSelected: (files: File[]) => void;
5
7
  attachments: FileUpload[];
6
8
  setAttachments: (attachments: FileUpload[]) => void;
7
9
  onTextChange?: (text: string) => void;
8
10
  onCancelRequest?: () => void;
9
11
  showCancelButton?: boolean;
12
+ placeholder?: string;
13
+ disabled?: boolean;
14
+ clearOnSubmit?: boolean;
15
+ autoFocus?: boolean;
16
+ value?: string;
17
+ defaultValue?: string;
18
+ onValueChange?: (value: string) => void;
10
19
  }
11
- export declare function ChatInput({ onSubmit, onFilesSelected, attachments, setAttachments, onTextChange, onCancelRequest, showCancelButton }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
20
+ export declare function ChatInput({ onSubmit, onFilesSelected, attachments, setAttachments, onTextChange, onCancelRequest, showCancelButton, placeholder, disabled, clearOnSubmit, autoFocus, value: controlledValue, defaultValue, onValueChange, }: ChatInputProps): ReactElement;
12
21
  export {};