@meshagent/meshagent-tailwind 0.38.1 → 0.38.3

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
@@ -1,7 +1,14 @@
1
- import * as React from 'react';
2
- import { RoomClient } from '@meshagent/meshagent';
1
+ import * as React from "react";
2
+ import { RoomClient } from "@meshagent/meshagent";
3
3
  export interface ChatTypingIndicatorProps {
4
- room: RoomClient | null;
5
- path: string;
4
+ room?: RoomClient | null;
5
+ path?: string;
6
+ typing?: boolean;
7
+ thinking?: boolean;
8
+ statusText?: string | null;
9
+ startedAt?: Date | null;
10
+ onCancel?: () => void;
11
+ showCancelButton?: boolean;
12
+ cancelEnabled?: boolean;
6
13
  }
7
- export declare function ChatTypingIndicator({ room, path }: ChatTypingIndicatorProps): React.ReactElement | null;
14
+ export declare function ChatTypingIndicator({ room, path, typing, thinking, statusText, startedAt, onCancel, showCancelButton, cancelEnabled, }: ChatTypingIndicatorProps): React.ReactElement | null;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var ChatTypingIndicator_exports = {};
20
30
  __export(ChatTypingIndicator_exports, {
@@ -22,27 +32,108 @@ __export(ChatTypingIndicator_exports, {
22
32
  });
23
33
  module.exports = __toCommonJS(ChatTypingIndicator_exports);
24
34
  var import_jsx_runtime = require("react/jsx-runtime");
35
+ var React = __toESM(require("react"));
25
36
  var import_meshagent_react = require("@meshagent/meshagent-react");
26
- function ChatTypingIndicator({ room, path }) {
27
- const { typing, thinking } = (0, import_meshagent_react.useRoomIndicators)({ room, path });
28
- return typing || thinking ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-end space-x-1 h-6 p-6", children: [
29
- [0, 1, 2].map((index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
37
+ var import_lucide_react = require("lucide-react");
38
+ var import_chat_hooks = require("./chat-hooks");
39
+ var import_utils = require("./lib/utils");
40
+ function useStatusLabel(text, startedAt) {
41
+ const normalizedText = text?.trim() ?? "";
42
+ const [tick, setTick] = React.useState(0);
43
+ React.useEffect(() => {
44
+ if (normalizedText === "" || !(startedAt instanceof Date) || Number.isNaN(startedAt.getTime())) {
45
+ return;
46
+ }
47
+ const timer = window.setInterval(() => {
48
+ setTick((current) => current + 1);
49
+ }, 1e3);
50
+ return () => {
51
+ window.clearInterval(timer);
52
+ };
53
+ }, [normalizedText, startedAt]);
54
+ if (normalizedText === "") {
55
+ return null;
56
+ }
57
+ void tick;
58
+ return (0, import_chat_hooks.formatThreadStatusText)(normalizedText, startedAt);
59
+ }
60
+ function ProcessingStatusRow({
61
+ text,
62
+ onCancel,
63
+ showCancelButton = false,
64
+ cancelEnabled = true
65
+ }) {
66
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-3 rounded-full border border-border/70 bg-background/90 px-3 py-2 shadow-sm backdrop-blur", children: [
67
+ showCancelButton ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ onClick: cancelEnabled ? onCancel : void 0,
72
+ disabled: !cancelEnabled,
73
+ title: cancelEnabled ? "Stop" : "Cancelling",
74
+ className: (0, import_utils.cn)(
75
+ "relative inline-flex h-6 w-6 items-center justify-center rounded-full transition-opacity",
76
+ cancelEnabled ? "cursor-pointer" : "cursor-default opacity-55"
77
+ ),
78
+ children: [
79
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.LoaderCircle, { className: "absolute h-6 w-6 animate-spin text-muted-foreground" }),
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "relative inline-flex h-4 w-4 items-center justify-center rounded-full bg-foreground text-background", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { className: "h-3 w-3" }) })
81
+ ]
82
+ }
83
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.LoaderCircle, { className: "h-4 w-4 animate-spin text-muted-foreground" }),
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-muted-foreground", children: text })
85
+ ] });
86
+ }
87
+ function ChatTypingIndicator({
88
+ room = null,
89
+ path = "",
90
+ typing,
91
+ thinking,
92
+ statusText,
93
+ startedAt,
94
+ onCancel,
95
+ showCancelButton = false,
96
+ cancelEnabled = true
97
+ }) {
98
+ const roomIndicators = (0, import_meshagent_react.useRoomIndicators)({ room, path });
99
+ const resolvedTyping = typing ?? roomIndicators.typing;
100
+ const resolvedThinking = thinking ?? roomIndicators.thinking;
101
+ const resolvedStatusText = useStatusLabel(
102
+ statusText?.trim() ? statusText : resolvedThinking ? "Thinking" : null,
103
+ startedAt
104
+ );
105
+ if (resolvedStatusText) {
106
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
107
+ ProcessingStatusRow,
108
+ {
109
+ text: resolvedStatusText,
110
+ onCancel,
111
+ showCancelButton,
112
+ cancelEnabled
113
+ }
114
+ );
115
+ }
116
+ if (!resolvedTyping) {
117
+ return null;
118
+ }
119
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 rounded-full border border-border/70 bg-background/90 px-3 py-2 shadow-sm backdrop-blur", children: [
120
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-end gap-1", children: [0, 1, 2].map((index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
30
121
  "span",
31
122
  {
32
- className: `inline-block w-2 h-2 bg-current rounded-full`,
123
+ className: "inline-block h-2 w-2 rounded-full bg-muted-foreground",
33
124
  style: {
34
- animation: "typingBounce 0.6s ease-in-out infinite",
125
+ animation: "chatTypingBounce 0.6s ease-in-out infinite",
35
126
  animationDelay: `${index * 0.2}s`
36
127
  }
37
128
  },
38
129
  index
39
- )),
130
+ )) }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-muted-foreground", children: "Typing" }),
40
132
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
41
- @keyframes typingBounce {
42
- 0%, 100% { transform: translateY(0); }
43
- 50% { transform: translateY(-4px); }
133
+ @keyframes chatTypingBounce {
134
+ 0%, 100% { transform: translateY(0); opacity: 0.55; }
135
+ 50% { transform: translateY(-4px); opacity: 1; }
44
136
  }
45
- ` })
46
- ] }) : null;
137
+ ` })
138
+ ] });
47
139
  }
48
- ;
@@ -1,6 +1,7 @@
1
- import React from 'react';
1
+ import * as React from "react";
2
2
  export interface FileUploaderProps {
3
3
  onFilesSelected?: (files: File[]) => void;
4
4
  accept?: string;
5
+ disabled?: boolean;
5
6
  }
6
- export declare function FileUploader({ onFilesSelected, accept }: FileUploaderProps): React.ReactElement;
7
+ export declare function FileUploader({ onFilesSelected, accept, disabled, }: FileUploaderProps): React.ReactElement;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var FileUploader_exports = {};
20
30
  __export(FileUploader_exports, {
@@ -22,20 +32,30 @@ __export(FileUploader_exports, {
22
32
  });
23
33
  module.exports = __toCommonJS(FileUploader_exports);
24
34
  var import_jsx_runtime = require("react/jsx-runtime");
25
- var import_react = require("react");
35
+ var React = __toESM(require("react"));
26
36
  var import_lucide_react = require("lucide-react");
27
37
  var import_button = require("./components/ui/button");
28
- function FileUploader({ onFilesSelected, accept = "" }) {
29
- const inputRef = (0, import_react.useRef)(null);
30
- const handleButtonClick = () => inputRef.current?.click();
31
- const handleFileChange = (e) => {
32
- if (!e.target.files) {
38
+ function FileUploader({
39
+ onFilesSelected,
40
+ accept = "",
41
+ disabled = false
42
+ }) {
43
+ const inputRef = React.useRef(null);
44
+ const handleButtonClick = React.useCallback(() => {
45
+ if (disabled) {
33
46
  return;
34
47
  }
35
- const fileArray = Array.from(e.target.files);
36
- onFilesSelected?.(fileArray);
37
- };
38
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
48
+ inputRef.current?.click();
49
+ }, [disabled]);
50
+ const handleFileChange = React.useCallback((event) => {
51
+ if (!event.target.files) {
52
+ return;
53
+ }
54
+ const files = Array.from(event.target.files);
55
+ onFilesSelected?.(files);
56
+ event.target.value = "";
57
+ }, [onFilesSelected]);
58
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "shrink-0", children: [
39
59
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
40
60
  "input",
41
61
  {
@@ -43,6 +63,7 @@ function FileUploader({ onFilesSelected, accept = "" }) {
43
63
  type: "file",
44
64
  multiple: true,
45
65
  accept,
66
+ disabled,
46
67
  className: "hidden",
47
68
  onChange: handleFileChange
48
69
  }
@@ -50,11 +71,14 @@ function FileUploader({ onFilesSelected, accept = "" }) {
50
71
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51
72
  import_button.Button,
52
73
  {
74
+ type: "button",
53
75
  variant: "ghost",
54
76
  size: "icon",
55
77
  "aria-label": "Attach file",
78
+ className: "h-9 w-9 rounded-md",
79
+ disabled,
56
80
  onClick: handleButtonClick,
57
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Plus, { className: "w-10 h-10" })
81
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Paperclip, { className: "h-4 w-4" })
58
82
  }
59
83
  )
60
84
  ] });
@@ -1,5 +1,5 @@
1
- import React from "react";
2
- import { FileUpload } from "@meshagent/meshagent-react";
1
+ import * as React from "react";
2
+ import { type FileUpload } from "./file-attachment";
3
3
  export interface UploadPillProps {
4
4
  attachment: FileUpload;
5
5
  onCancel: (attachment: FileUpload) => void;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var UploadPill_exports = {};
20
30
  __export(UploadPill_exports, {
@@ -22,38 +32,66 @@ __export(UploadPill_exports, {
22
32
  });
23
33
  module.exports = __toCommonJS(UploadPill_exports);
24
34
  var import_jsx_runtime = require("react/jsx-runtime");
25
- var import_react = require("react");
26
- var import_progress = require("./components/ui/progress");
35
+ var React = __toESM(require("react"));
27
36
  var import_lucide_react = require("lucide-react");
28
- function UploadPill({ attachment, onCancel }) {
29
- const [progress, setProgress] = (0, import_react.useState)(0);
30
- const handleCancel = (0, import_react.useCallback)(() => onCancel(attachment), [attachment, onCancel]);
31
- (0, import_react.useEffect)(() => {
32
- const onChange = () => setProgress(
33
- Math.round(attachment.bytesUploaded * 100 / attachment.size)
34
- );
35
- attachment.on("status", onChange);
36
- return () => attachment.off("status", onChange);
37
+ var import_progress = require("./components/ui/progress");
38
+ var import_file_attachment = require("./file-attachment");
39
+ var import_utils = require("./lib/utils");
40
+ function measureUploadProgress(attachment) {
41
+ if (attachment.size <= 0) {
42
+ return attachment.status === import_file_attachment.UploadStatus.Completed ? 100 : 0;
43
+ }
44
+ return Math.max(0, Math.min(100, Math.round(attachment.bytesUploaded * 100 / attachment.size)));
45
+ }
46
+ function useUploadState(attachment) {
47
+ const [progress, setProgress] = React.useState(() => measureUploadProgress(attachment));
48
+ const [status, setStatus] = React.useState(attachment.status);
49
+ React.useEffect(() => {
50
+ const updateState = () => {
51
+ setStatus(attachment.status);
52
+ setProgress(measureUploadProgress(attachment));
53
+ };
54
+ updateState();
55
+ attachment.on("change", updateState);
56
+ return () => {
57
+ attachment.off("change", updateState);
58
+ };
37
59
  }, [attachment]);
38
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative inline-flex max-w-full items-center border bg-muted pl-3 pr-1 py-1 gap-2", children: [
39
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate text-sm font-medium leading-none", children: attachment.filename }),
40
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
41
- "button",
42
- {
43
- type: "button",
44
- onClick: handleCancel,
45
- "aria-label": "Cancel upload",
46
- className: "rounded-full p-1 transition-colors hover:bg-muted-foreground/20 focus:outline-none cursor-pointer focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
47
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { className: "h-4 w-4" })
48
- }
49
- ),
50
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51
- import_progress.Progress,
52
- {
53
- value: progress,
54
- className: "absolute left-0 bottom-0 h-0.5 w-full rounded-full bg-muted-foreground/20"
55
- }
56
- )
57
- ] });
60
+ return { progress, status };
61
+ }
62
+ function UploadPill({ attachment, onCancel }) {
63
+ const { progress, status } = useUploadState(attachment);
64
+ const handleCancel = React.useCallback(() => {
65
+ onCancel(attachment);
66
+ }, [attachment, onCancel]);
67
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
68
+ "div",
69
+ {
70
+ className: (0, import_utils.cn)(
71
+ "relative inline-flex max-w-full items-center gap-2 overflow-hidden rounded-md border bg-muted/60 pl-3 pr-2 py-2 text-sm",
72
+ status === import_file_attachment.UploadStatus.Failed && "border-destructive/40 bg-destructive/5 text-destructive"
73
+ ),
74
+ children: [
75
+ status === import_file_attachment.UploadStatus.Failed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.TriangleAlert, { className: "h-4 w-4 shrink-0" }) : status === import_file_attachment.UploadStatus.Completed ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.FileUp, { className: "h-4 w-4 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.LoaderCircle, { className: "h-4 w-4 shrink-0 animate-spin text-muted-foreground" }),
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate font-medium leading-none", children: attachment.filename }),
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
+ "button",
79
+ {
80
+ type: "button",
81
+ onClick: handleCancel,
82
+ "aria-label": "Remove attachment",
83
+ className: "rounded-md p-1 transition-colors hover:bg-foreground/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
84
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { className: "h-4 w-4" })
85
+ }
86
+ ),
87
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
88
+ import_progress.Progress,
89
+ {
90
+ value: status === import_file_attachment.UploadStatus.Completed ? 100 : progress,
91
+ className: "absolute inset-x-0 bottom-0 h-0.5 rounded-none bg-border/60"
92
+ }
93
+ )
94
+ ]
95
+ }
96
+ );
58
97
  }
59
- ;
@@ -0,0 +1,38 @@
1
+ import { Element, MeshDocument, Participant, RemoteParticipant, RoomClient } from "@meshagent/meshagent";
2
+ import { ChatMessage } from "./chat-message";
3
+ import { type FileUpload } from "./file-attachment";
4
+ export interface UseChatThreadProps {
5
+ room: RoomClient;
6
+ path: string;
7
+ participants?: Participant[];
8
+ participantNames?: string[];
9
+ includeLocalParticipant?: boolean;
10
+ initialMessage?: ChatMessage;
11
+ agentName?: string;
12
+ }
13
+ export interface UseChatThreadResult {
14
+ document: MeshDocument | null;
15
+ messages: Element[];
16
+ sendMessage: (message: ChatMessage) => void;
17
+ selectAttachments: (files: File[]) => void;
18
+ attachments: FileUpload[];
19
+ setAttachments: (attachments: FileUpload[]) => void;
20
+ schemaFileExists: boolean;
21
+ onlineParticipants: RemoteParticipant[];
22
+ localParticipantName: string;
23
+ cancelRequest?: () => void;
24
+ }
25
+ export interface ThreadStatus {
26
+ text: string | null;
27
+ mode: string | null;
28
+ startedAt: Date | null;
29
+ supportsAgentMessages: boolean;
30
+ }
31
+ export interface UseThreadStatusProps {
32
+ room: RoomClient;
33
+ path: string;
34
+ agentName?: string;
35
+ }
36
+ export declare function formatThreadStatusText(text: string, startedAt?: Date | null): string;
37
+ export declare function useChatThread({ room, path, participants, participantNames, initialMessage, includeLocalParticipant, agentName, }: UseChatThreadProps): UseChatThreadResult;
38
+ export declare function useThreadStatus({ room, path, agentName }: UseThreadStatusProps): ThreadStatus;