@meshagent/meshagent-tailwind 0.39.9 → 0.40.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.
Files changed (111) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/cjs/{ChatBotView.js → chat/chat-bot-view.js} +37 -22
  3. package/dist/cjs/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  4. package/dist/cjs/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  5. package/dist/cjs/{ChatInput.js → chat/chat-input.js} +9 -9
  6. package/dist/cjs/chat/chat-thread.d.ts +12 -0
  7. package/dist/cjs/{ChatThread.js → chat/chat-thread.js} +75 -28
  8. package/dist/cjs/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +4 -4
  9. package/dist/cjs/chat/dataset-chat-thread.d.ts +13 -0
  10. package/dist/cjs/chat/dataset-chat-thread.js +1840 -0
  11. package/dist/cjs/{FileUploader.js → chat/file-uploader.js} +4 -4
  12. package/dist/cjs/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  13. package/dist/cjs/chat/new-chat-thread.d.ts +17 -0
  14. package/dist/cjs/{Chat.js → chat/new-chat-thread.js} +43 -168
  15. package/dist/cjs/{UploadPill.js → chat/upload-pill.js} +5 -5
  16. package/dist/cjs/file-preview/file-preview.d.ts +34 -0
  17. package/dist/cjs/file-preview/file-preview.js +329 -0
  18. package/dist/cjs/forms/email-address.d.ts +10 -0
  19. package/dist/cjs/forms/email-address.js +105 -0
  20. package/dist/cjs/forms/form.d.ts +27 -0
  21. package/dist/cjs/forms/form.js +200 -0
  22. package/dist/cjs/forms/multi-select-autocomplete.d.ts +35 -0
  23. package/dist/cjs/forms/multi-select-autocomplete.js +294 -0
  24. package/dist/cjs/forms/select-users-dialog.d.ts +20 -0
  25. package/dist/cjs/forms/select-users-dialog.js +145 -0
  26. package/dist/cjs/forms/select-users.d.ts +16 -0
  27. package/dist/cjs/forms/select-users.js +117 -0
  28. package/dist/cjs/index.d.ts +19 -11
  29. package/dist/cjs/index.js +19 -11
  30. package/dist/cjs/meetings/audio-visualization.d.ts +7 -0
  31. package/dist/cjs/meetings/audio-visualization.js +74 -0
  32. package/dist/cjs/meetings/controls.d.ts +19 -0
  33. package/dist/cjs/meetings/controls.js +300 -0
  34. package/dist/cjs/meetings/meeting-scope.d.ts +83 -0
  35. package/dist/cjs/meetings/meeting-scope.js +309 -0
  36. package/dist/cjs/meetings/meetings.d.ts +5 -0
  37. package/dist/cjs/meetings/meetings.js +22 -0
  38. package/dist/cjs/meetings/participants.d.ts +13 -0
  39. package/dist/cjs/meetings/participants.js +154 -0
  40. package/dist/cjs/meetings/wake-lock.d.ts +4 -0
  41. package/dist/cjs/meetings/wake-lock.js +55 -0
  42. package/dist/esm/{ChatBotView.js → chat/chat-bot-view.js} +34 -19
  43. package/dist/esm/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  44. package/dist/esm/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  45. package/dist/esm/{ChatInput.js → chat/chat-input.js} +4 -4
  46. package/dist/esm/chat/chat-thread.d.ts +12 -0
  47. package/dist/esm/{ChatThread.js → chat/chat-thread.js} +70 -23
  48. package/dist/esm/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +1 -1
  49. package/dist/esm/chat/dataset-chat-thread.d.ts +13 -0
  50. package/dist/esm/chat/dataset-chat-thread.js +1815 -0
  51. package/dist/esm/{FileUploader.js → chat/file-uploader.js} +1 -1
  52. package/dist/esm/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  53. package/dist/esm/chat/new-chat-thread.d.ts +17 -0
  54. package/dist/esm/{Chat.js → chat/new-chat-thread.js} +40 -165
  55. package/dist/esm/{UploadPill.js → chat/upload-pill.js} +2 -2
  56. package/dist/esm/file-preview/file-preview.d.ts +34 -0
  57. package/dist/esm/file-preview/file-preview.js +316 -0
  58. package/dist/esm/forms/email-address.d.ts +10 -0
  59. package/dist/esm/forms/email-address.js +85 -0
  60. package/dist/esm/forms/form.d.ts +27 -0
  61. package/dist/esm/forms/form.js +193 -0
  62. package/dist/esm/forms/multi-select-autocomplete.d.ts +35 -0
  63. package/dist/esm/forms/multi-select-autocomplete.js +274 -0
  64. package/dist/esm/forms/select-users-dialog.d.ts +20 -0
  65. package/dist/esm/forms/select-users-dialog.js +132 -0
  66. package/dist/esm/forms/select-users.d.ts +16 -0
  67. package/dist/esm/forms/select-users.js +97 -0
  68. package/dist/esm/index.d.ts +19 -11
  69. package/dist/esm/index.js +19 -11
  70. package/dist/esm/meetings/audio-visualization.d.ts +7 -0
  71. package/dist/esm/meetings/audio-visualization.js +54 -0
  72. package/dist/esm/meetings/controls.d.ts +19 -0
  73. package/dist/esm/meetings/controls.js +294 -0
  74. package/dist/esm/meetings/meeting-scope.d.ts +83 -0
  75. package/dist/esm/meetings/meeting-scope.js +294 -0
  76. package/dist/esm/meetings/meetings.d.ts +5 -0
  77. package/dist/esm/meetings/meetings.js +5 -0
  78. package/dist/esm/meetings/participants.d.ts +13 -0
  79. package/dist/esm/meetings/participants.js +137 -0
  80. package/dist/esm/meetings/wake-lock.d.ts +4 -0
  81. package/dist/esm/meetings/wake-lock.js +35 -0
  82. package/dist/index.css +2 -2
  83. package/package.json +7 -4
  84. package/dist/cjs/Chat.d.ts +0 -15
  85. package/dist/cjs/ChatThread.d.ts +0 -21
  86. package/dist/esm/Chat.d.ts +0 -15
  87. package/dist/esm/ChatThread.d.ts +0 -21
  88. /package/dist/cjs/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  89. /package/dist/cjs/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  90. /package/dist/cjs/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  91. /package/dist/cjs/{chat-message.js → chat/chat-message.js} +0 -0
  92. /package/dist/cjs/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  93. /package/dist/cjs/{conversation-descriptor.d.ts → chat/conversation-descriptor.d.ts} +0 -0
  94. /package/dist/cjs/{conversation-descriptor.js → chat/conversation-descriptor.js} +0 -0
  95. /package/dist/cjs/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  96. /package/dist/cjs/{file-attachment.js → chat/file-attachment.js} +0 -0
  97. /package/dist/cjs/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  98. /package/dist/cjs/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  99. /package/dist/cjs/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
  100. /package/dist/esm/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  101. /package/dist/esm/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  102. /package/dist/esm/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  103. /package/dist/esm/{chat-message.js → chat/chat-message.js} +0 -0
  104. /package/dist/esm/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  105. /package/dist/esm/{conversation-descriptor.d.ts → chat/conversation-descriptor.d.ts} +0 -0
  106. /package/dist/esm/{conversation-descriptor.js → chat/conversation-descriptor.js} +0 -0
  107. /package/dist/esm/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  108. /package/dist/esm/{file-attachment.js → chat/file-attachment.js} +0 -0
  109. /package/dist/esm/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  110. /package/dist/esm/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  111. /package/dist/esm/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
@@ -32,15 +32,19 @@ export declare class PendingAgentMessage {
32
32
  readonly text: string;
33
33
  readonly attachments: string[];
34
34
  readonly senderName?: string;
35
+ readonly createdAt?: Date;
36
+ readonly matchByContentOnly: boolean;
35
37
  readonly awaitingAcceptance: boolean;
36
38
  readonly awaitingOnline: boolean;
37
- constructor({ messageId, messageType, threadPath, text, attachments, senderName, awaitingAcceptance, awaitingOnline, }: {
39
+ constructor({ messageId, messageType, threadPath, text, attachments, senderName, createdAt, matchByContentOnly, awaitingAcceptance, awaitingOnline, }: {
38
40
  messageId: string;
39
41
  messageType: string;
40
42
  threadPath: string;
41
43
  text: string;
42
44
  attachments: string[];
43
45
  senderName?: string;
46
+ createdAt?: Date;
47
+ matchByContentOnly?: boolean;
44
48
  awaitingAcceptance?: boolean;
45
49
  awaitingOnline?: boolean;
46
50
  });
@@ -20,6 +20,8 @@ class PendingAgentMessage {
20
20
  text;
21
21
  attachments;
22
22
  senderName;
23
+ createdAt;
24
+ matchByContentOnly;
23
25
  awaitingAcceptance;
24
26
  awaitingOnline;
25
27
  constructor({
@@ -29,6 +31,8 @@ class PendingAgentMessage {
29
31
  text,
30
32
  attachments,
31
33
  senderName,
34
+ createdAt,
35
+ matchByContentOnly = false,
32
36
  awaitingAcceptance = false,
33
37
  awaitingOnline = false
34
38
  }) {
@@ -38,6 +42,8 @@ class PendingAgentMessage {
38
42
  this.text = text;
39
43
  this.attachments = attachments;
40
44
  this.senderName = senderName;
45
+ this.createdAt = createdAt;
46
+ this.matchByContentOnly = matchByContentOnly;
41
47
  this.awaitingAcceptance = awaitingAcceptance;
42
48
  this.awaitingOnline = awaitingOnline;
43
49
  }
@@ -69,6 +75,8 @@ class PendingAgentMessage {
69
75
  const messageType = json["message_type"];
70
76
  const messageId = json["message_id"];
71
77
  const threadPath = json["thread_id"];
78
+ const createdAt = json["created_at"];
79
+ const parsedCreatedAt = typeof createdAt === "string" ? new Date(createdAt) : void 0;
72
80
  return new PendingAgentMessage({
73
81
  messageId: typeof messageId === "string" ? messageId : crypto.randomUUID(),
74
82
  messageType: typeof messageType === "string" ? messageType : agentTurnSteerType,
@@ -76,6 +84,8 @@ class PendingAgentMessage {
76
84
  text: textParts.join("\n\n"),
77
85
  attachments,
78
86
  senderName: typeof senderName === "string" && senderName.trim().length > 0 ? senderName.trim() : void 0,
87
+ createdAt: parsedCreatedAt instanceof Date && !Number.isNaN(parsedCreatedAt.getTime()) ? parsedCreatedAt : void 0,
88
+ matchByContentOnly: false,
79
89
  awaitingOnline: false
80
90
  });
81
91
  }
@@ -286,7 +296,7 @@ async function sendMessageToParticipant({
286
296
  await room.messaging.sendMessage({
287
297
  to: participant,
288
298
  type: agentRoomMessageType,
289
- message: { payload }
299
+ message: payload
290
300
  });
291
301
  return;
292
302
  }
@@ -510,7 +520,7 @@ function resolveThreadStatus({
510
520
  function pendingMessagesEqual(left, right) {
511
521
  return left.length === right.length && left.every((message, index) => {
512
522
  const other = right[index];
513
- return message.messageId === other.messageId && message.messageType === other.messageType && message.text === other.text && stringArraysEqual(message.attachments, other.attachments) && message.senderName === other.senderName;
523
+ return message.messageId === other.messageId && message.messageType === other.messageType && message.text === other.text && stringArraysEqual(message.attachments, other.attachments) && message.senderName === other.senderName && message.createdAt?.getTime() === other.createdAt?.getTime() && message.matchByContentOnly === other.matchByContentOnly && message.awaitingAcceptance === other.awaitingAcceptance && message.awaitingOnline === other.awaitingOnline;
514
524
  });
515
525
  }
516
526
  function threadStatusEquals(left, right) {
@@ -3,11 +3,11 @@ import { useRef, useState, useEffect, useMemo, useCallback } from "react";
3
3
  import { ArrowUp, LoaderCircle, X } from "lucide-react";
4
4
  import { v4 as uuidV4 } from "uuid";
5
5
  import { ChatMessage } from "./chat-message";
6
- import { Button } from "./components/ui/button";
7
- import { FileUploader } from "./FileUploader";
8
- import { UploadPill } from "./UploadPill";
6
+ import { Button } from "../components/ui/button";
7
+ import { FileUploader } from "./file-uploader";
8
+ import { UploadPill } from "./upload-pill";
9
9
  import { UploadStatus } from "./file-attachment";
10
- import { cn } from "./lib/utils";
10
+ import { cn } from "../lib/utils";
11
11
  const MIN_TEXTAREA_HEIGHT = 20;
12
12
  const MAX_TEXTAREA_HEIGHT = 160;
13
13
  function useAttachmentStatusVersion(attachments) {
@@ -0,0 +1,12 @@
1
+ import type { ReactElement } from "react";
2
+ import { Participant, RoomClient } from "@meshagent/meshagent";
3
+ export interface ChatThreadProps {
4
+ room: RoomClient;
5
+ path: string;
6
+ participants?: Participant[];
7
+ agentName?: string;
8
+ emptyStateTitle?: string;
9
+ emptyStateDescription?: string;
10
+ }
11
+ export declare function timeAgo(iso: string): string;
12
+ export declare function ChatThread({ room, path, participants, agentName, emptyStateTitle, emptyStateDescription, }: ChatThreadProps): ReactElement;
@@ -1,14 +1,17 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useMemo, useState, useEffect, useRef, useCallback } from "react";
3
- import { Download, FileText } from "lucide-react";
3
+ import { FileText } from "lucide-react";
4
4
  import ReactMarkdown from "react-markdown";
5
5
  import rehypeHighlight from "rehype-highlight";
6
6
  import rehypeSanitize from "rehype-sanitize";
7
7
  import remarkGfm from "remark-gfm";
8
- import { Button } from "./components/ui/button";
9
- import { Spinner } from "./components/ui/spinner";
10
- import { ChatTypingIndicator } from "./ChatTypingIndicator";
11
- import { cn } from "./lib/utils";
8
+ import { Button } from "../components/ui/button";
9
+ import { Spinner } from "../components/ui/spinner";
10
+ import { ChatTypingIndicator } from "./chat-typing-indicator";
11
+ import { ChatInput } from "./chat-input";
12
+ import { useChatThread, useThreadStatus } from "./chat-hooks";
13
+ import { FilePreviewDialog, isImagePath } from "../file-preview/file-preview";
14
+ import { cn } from "../lib/utils";
12
15
  const supportedEventKinds = /* @__PURE__ */ new Set([
13
16
  "exec",
14
17
  "tool",
@@ -74,9 +77,6 @@ function timeAgo(iso) {
74
77
  function displayParticipantName(name) {
75
78
  return name.split("@")[0]?.trim() ?? name.trim();
76
79
  }
77
- function isImagePath(path) {
78
- return /\.(avif|bmp|gif|jpe?g|png|svg|webp)$/i.test(path);
79
- }
80
80
  function isThreadAttachmentElement(element) {
81
81
  return element.tagName === "file" || element.tagName === "image";
82
82
  }
@@ -301,14 +301,11 @@ function ChatImage({
301
301
  if (!url) {
302
302
  return null;
303
303
  }
304
- return /* @__PURE__ */ jsx(
304
+ return /* @__PURE__ */ jsx(FilePreviewDialog, { room, path, children: /* @__PURE__ */ jsx(
305
305
  "button",
306
306
  {
307
307
  type: "button",
308
308
  className: "block overflow-hidden rounded-md bg-muted/20 shadow-xs transition-opacity hover:opacity-95",
309
- onClick: () => {
310
- window.open(url, "_blank", "noopener,noreferrer");
311
- },
312
309
  children: /* @__PURE__ */ jsx(
313
310
  "img",
314
311
  {
@@ -325,28 +322,21 @@ function ChatImage({
325
322
  }
326
323
  )
327
324
  }
328
- );
325
+ ) });
329
326
  }
330
327
  function FileAttachment({ room, path }) {
331
- const url = useDownloadUrl(room, path);
332
328
  const filename = path.split("/").pop() ?? path;
333
- return /* @__PURE__ */ jsxs(
329
+ return /* @__PURE__ */ jsx(FilePreviewDialog, { room, path, children: /* @__PURE__ */ jsxs(
334
330
  "button",
335
331
  {
336
332
  type: "button",
337
333
  className: "inline-flex max-w-full items-center gap-2 rounded-md bg-muted/60 px-3 py-2 text-left shadow-xs transition-colors hover:bg-muted/80",
338
- onClick: () => {
339
- if (url) {
340
- window.open(url, "_blank", "noopener,noreferrer");
341
- }
342
- },
343
334
  children: [
344
335
  /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
345
- /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium", children: filename }),
346
- /* @__PURE__ */ jsx(Download, { className: "h-4 w-4 shrink-0 text-muted-foreground" })
336
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium", children: filename })
347
337
  ]
348
338
  }
349
- );
339
+ ) });
350
340
  }
351
341
  function ThreadAttachment({ room, attachment, onImageSettled }) {
352
342
  const path = getTrimmedStringAttribute(attachment, "path");
@@ -551,6 +541,63 @@ function EmptyState({
551
541
  ] });
552
542
  }
553
543
  function ChatThread({
544
+ room,
545
+ path,
546
+ participants,
547
+ agentName,
548
+ emptyStateTitle,
549
+ emptyStateDescription
550
+ }) {
551
+ const status = useThreadStatus({ room, path, agentName });
552
+ const {
553
+ document,
554
+ messages,
555
+ sendMessage,
556
+ selectAttachments,
557
+ attachments,
558
+ setAttachments,
559
+ localParticipantName,
560
+ cancelRequest
561
+ } = useChatThread({
562
+ room,
563
+ path,
564
+ participants,
565
+ agentName,
566
+ useAgentMessages: agentName?.trim() !== "",
567
+ messageType: status.mode === "steerable" && status.turnId != null ? "steer" : "chat",
568
+ turnId: status.turnId
569
+ });
570
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
571
+ /* @__PURE__ */ jsx(
572
+ ChatThreadView,
573
+ {
574
+ room,
575
+ messages,
576
+ isLoading: document === null,
577
+ localParticipantName,
578
+ path,
579
+ threadStatusText: status.text,
580
+ threadStatusStartedAt: status.startedAt,
581
+ threadStatusMode: status.mode,
582
+ onCancelRequest: cancelRequest,
583
+ emptyStateTitle,
584
+ emptyStateDescription
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsx(
588
+ ChatInput,
589
+ {
590
+ onSubmit: sendMessage,
591
+ attachments,
592
+ onFilesSelected: selectAttachments,
593
+ setAttachments,
594
+ disabled: document === null,
595
+ placeholder: agentName?.trim() ? `Type a message or @${displayParticipantName(agentName)}` : "Type a message"
596
+ }
597
+ )
598
+ ] });
599
+ }
600
+ function ChatThreadView({
554
601
  room,
555
602
  messages,
556
603
  isLoading = false,
@@ -3,7 +3,7 @@ import * as React from "react";
3
3
  import { useRoomIndicators } from "@meshagent/meshagent-react";
4
4
  import { LoaderCircle, X } from "lucide-react";
5
5
  import { formatThreadStatusText } from "./chat-hooks";
6
- import { cn } from "./lib/utils";
6
+ import { cn } from "../lib/utils";
7
7
  function useStatusLabel(text, startedAt) {
8
8
  const normalizedText = text?.trim() ?? "";
9
9
  const [tick, setTick] = React.useState(0);
@@ -0,0 +1,13 @@
1
+ import type { ReactElement } from "react";
2
+ import type { RoomClient } from "@meshagent/meshagent";
3
+ export interface DatasetChatThreadProps {
4
+ room: RoomClient;
5
+ path: string;
6
+ agentName?: string;
7
+ emptyStateTitle?: string;
8
+ emptyStateDescription?: string;
9
+ inputPlaceholder?: string;
10
+ initialShowCompletedToolCalls?: boolean;
11
+ openFile?: (path: string) => void | Promise<void>;
12
+ }
13
+ export declare function DatasetChatThread({ room, path, agentName, emptyStateTitle, emptyStateDescription, inputPlaceholder, initialShowCompletedToolCalls, openFile, }: DatasetChatThreadProps): ReactElement;