@meshagent/meshagent-tailwind 0.39.8 → 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 +8 -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/{esm → cjs/chat}/conversation-descriptor.d.ts +7 -1
  10. package/dist/cjs/{conversation-descriptor.js → chat/conversation-descriptor.js} +41 -7
  11. package/dist/cjs/chat/dataset-chat-thread.d.ts +13 -0
  12. package/dist/cjs/chat/dataset-chat-thread.js +1840 -0
  13. package/dist/cjs/{FileUploader.js → chat/file-uploader.js} +4 -4
  14. package/dist/cjs/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  15. package/dist/cjs/chat/new-chat-thread.d.ts +17 -0
  16. package/dist/cjs/{Chat.js → chat/new-chat-thread.js} +43 -168
  17. package/dist/cjs/{UploadPill.js → chat/upload-pill.js} +5 -5
  18. package/dist/cjs/file-preview/file-preview.d.ts +34 -0
  19. package/dist/cjs/file-preview/file-preview.js +329 -0
  20. package/dist/cjs/forms/email-address.d.ts +10 -0
  21. package/dist/cjs/forms/email-address.js +105 -0
  22. package/dist/cjs/forms/form.d.ts +27 -0
  23. package/dist/cjs/forms/form.js +200 -0
  24. package/dist/cjs/forms/multi-select-autocomplete.d.ts +35 -0
  25. package/dist/cjs/forms/multi-select-autocomplete.js +294 -0
  26. package/dist/cjs/forms/select-users-dialog.d.ts +20 -0
  27. package/dist/cjs/forms/select-users-dialog.js +145 -0
  28. package/dist/cjs/forms/select-users.d.ts +16 -0
  29. package/dist/cjs/forms/select-users.js +117 -0
  30. package/dist/cjs/index.d.ts +19 -11
  31. package/dist/cjs/index.js +19 -11
  32. package/dist/cjs/meetings/audio-visualization.d.ts +7 -0
  33. package/dist/cjs/meetings/audio-visualization.js +74 -0
  34. package/dist/cjs/meetings/controls.d.ts +19 -0
  35. package/dist/cjs/meetings/controls.js +300 -0
  36. package/dist/cjs/meetings/meeting-scope.d.ts +83 -0
  37. package/dist/cjs/meetings/meeting-scope.js +309 -0
  38. package/dist/cjs/meetings/meetings.d.ts +5 -0
  39. package/dist/cjs/meetings/meetings.js +22 -0
  40. package/dist/cjs/meetings/participants.d.ts +13 -0
  41. package/dist/cjs/meetings/participants.js +154 -0
  42. package/dist/cjs/meetings/wake-lock.d.ts +4 -0
  43. package/dist/cjs/meetings/wake-lock.js +55 -0
  44. package/dist/esm/{ChatBotView.js → chat/chat-bot-view.js} +34 -19
  45. package/dist/esm/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  46. package/dist/esm/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  47. package/dist/esm/{ChatInput.js → chat/chat-input.js} +4 -4
  48. package/dist/esm/chat/chat-thread.d.ts +12 -0
  49. package/dist/esm/{ChatThread.js → chat/chat-thread.js} +70 -23
  50. package/dist/esm/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +1 -1
  51. package/dist/{cjs → esm/chat}/conversation-descriptor.d.ts +7 -1
  52. package/dist/esm/{conversation-descriptor.js → chat/conversation-descriptor.js} +41 -7
  53. package/dist/esm/chat/dataset-chat-thread.d.ts +13 -0
  54. package/dist/esm/chat/dataset-chat-thread.js +1815 -0
  55. package/dist/esm/{FileUploader.js → chat/file-uploader.js} +1 -1
  56. package/dist/esm/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  57. package/dist/esm/chat/new-chat-thread.d.ts +17 -0
  58. package/dist/esm/{Chat.js → chat/new-chat-thread.js} +40 -165
  59. package/dist/esm/{UploadPill.js → chat/upload-pill.js} +2 -2
  60. package/dist/esm/file-preview/file-preview.d.ts +34 -0
  61. package/dist/esm/file-preview/file-preview.js +316 -0
  62. package/dist/esm/forms/email-address.d.ts +10 -0
  63. package/dist/esm/forms/email-address.js +85 -0
  64. package/dist/esm/forms/form.d.ts +27 -0
  65. package/dist/esm/forms/form.js +193 -0
  66. package/dist/esm/forms/multi-select-autocomplete.d.ts +35 -0
  67. package/dist/esm/forms/multi-select-autocomplete.js +274 -0
  68. package/dist/esm/forms/select-users-dialog.d.ts +20 -0
  69. package/dist/esm/forms/select-users-dialog.js +132 -0
  70. package/dist/esm/forms/select-users.d.ts +16 -0
  71. package/dist/esm/forms/select-users.js +97 -0
  72. package/dist/esm/index.d.ts +19 -11
  73. package/dist/esm/index.js +19 -11
  74. package/dist/esm/meetings/audio-visualization.d.ts +7 -0
  75. package/dist/esm/meetings/audio-visualization.js +54 -0
  76. package/dist/esm/meetings/controls.d.ts +19 -0
  77. package/dist/esm/meetings/controls.js +294 -0
  78. package/dist/esm/meetings/meeting-scope.d.ts +83 -0
  79. package/dist/esm/meetings/meeting-scope.js +294 -0
  80. package/dist/esm/meetings/meetings.d.ts +5 -0
  81. package/dist/esm/meetings/meetings.js +5 -0
  82. package/dist/esm/meetings/participants.d.ts +13 -0
  83. package/dist/esm/meetings/participants.js +137 -0
  84. package/dist/esm/meetings/wake-lock.d.ts +4 -0
  85. package/dist/esm/meetings/wake-lock.js +35 -0
  86. package/dist/index.css +2 -2
  87. package/package.json +7 -4
  88. package/dist/cjs/Chat.d.ts +0 -15
  89. package/dist/cjs/ChatThread.d.ts +0 -21
  90. package/dist/esm/Chat.d.ts +0 -15
  91. package/dist/esm/ChatThread.d.ts +0 -21
  92. /package/dist/cjs/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  93. /package/dist/cjs/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  94. /package/dist/cjs/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  95. /package/dist/cjs/{chat-message.js → chat/chat-message.js} +0 -0
  96. /package/dist/cjs/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  97. /package/dist/cjs/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  98. /package/dist/cjs/{file-attachment.js → chat/file-attachment.js} +0 -0
  99. /package/dist/cjs/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  100. /package/dist/cjs/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  101. /package/dist/cjs/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
  102. /package/dist/esm/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  103. /package/dist/esm/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  104. /package/dist/esm/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  105. /package/dist/esm/{chat-message.js → chat/chat-message.js} +0 -0
  106. /package/dist/esm/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +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
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.40.0]
2
+ - Enabled websocket compression for Node protocol connections while preserving the browser path.
3
+ - Aligned the JS and TS protocol surface with realtime model selection and output-modality negotiation.
4
+ - Refreshed the generated Node entrypoint to match the updated realtime protocol flow.
5
+
6
+ ## [0.39.9]
7
+ - Added streaming `watchTable` support to the TypeScript DatasetsClient to receive dataset table change events with versioning metadata.
8
+
1
9
  ## [0.39.8]
2
10
  - TypeScript API: `RoomContainer` now includes a required `ports: number[]` field (and validation) in container listings
3
11
  - TypeScript API: `ContainerSpec` now supports optional fields `private`, `on_demand`, and `writable_root_fs`
@@ -16,27 +16,28 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var ChatBotView_exports = {};
20
- __export(ChatBotView_exports, {
19
+ var chat_bot_view_exports = {};
20
+ __export(chat_bot_view_exports, {
21
21
  ChatBotView: () => ChatBotView,
22
22
  ChatThreadDisplayMode: () => import_conversation_descriptor2.ChatThreadDisplayMode,
23
23
  chatDocumentPath: () => import_conversation_descriptor2.chatDocumentPath,
24
24
  resolvedThreadListPath: () => import_conversation_descriptor2.resolvedThreadListPath
25
25
  });
26
- module.exports = __toCommonJS(ChatBotView_exports);
26
+ module.exports = __toCommonJS(chat_bot_view_exports);
27
27
  var import_jsx_runtime = require("react/jsx-runtime");
28
28
  var import_react = require("react");
29
29
  var import_meshagent_react = require("@meshagent/meshagent-react");
30
30
  var import_lucide_react = require("lucide-react");
31
31
  var import_chat_hooks = require("./chat-hooks");
32
- var import_Chat = require("./Chat");
33
- var import_button = require("./components/ui/button");
34
- var import_dialog = require("./components/ui/dialog");
35
- var import_input = require("./components/ui/input");
36
- var import_label = require("./components/ui/label");
37
- var import_spinner = require("./components/ui/spinner");
32
+ var import_chat_thread = require("./chat-thread");
33
+ var import_dataset_chat_thread = require("./dataset-chat-thread");
34
+ var import_button = require("../components/ui/button");
35
+ var import_dialog = require("../components/ui/dialog");
36
+ var import_input = require("../components/ui/input");
37
+ var import_label = require("../components/ui/label");
38
+ var import_spinner = require("../components/ui/spinner");
38
39
  var import_conversation_descriptor = require("./conversation-descriptor");
39
- var import_utils = require("./lib/utils");
40
+ var import_utils = require("../lib/utils");
40
41
  var import_multi_thread_view = require("./multi-thread-view");
41
42
  var import_conversation_descriptor2 = require("./conversation-descriptor");
42
43
  const multiThreadLayoutBreakpointPx = 920;
@@ -44,6 +45,9 @@ function normalizePath(path) {
44
45
  const normalized = path?.trim();
45
46
  return normalized ? normalized : null;
46
47
  }
48
+ function isDatasetBackedThreadPath(path) {
49
+ return path.startsWith("dataset://") || path.startsWith("tmp://");
50
+ }
47
51
  function parseDate(value) {
48
52
  const parsed = new Date(value);
49
53
  return Number.isNaN(parsed.getTime()) ? /* @__PURE__ */ new Date(0) : parsed;
@@ -482,19 +486,24 @@ function ChatBotView({
482
486
  closeRenameThreadDialog();
483
487
  }, [activeSelectedThreadPath, closeRenameThreadDialog, emitResolvedThread, renameThreadDialog]);
484
488
  if (threadDisplayMode !== import_conversation_descriptor.ChatThreadDisplayMode.MultiThreadComposer) {
485
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
486
- import_Chat.Chat,
489
+ return isDatasetBackedThreadPath(resolvedSingleThreadPath) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
490
+ import_dataset_chat_thread.DatasetChatThread,
491
+ {
492
+ room,
493
+ path: resolvedSingleThreadPath,
494
+ agentName,
495
+ emptyStateTitle,
496
+ emptyStateDescription
497
+ }
498
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
499
+ import_chat_thread.ChatThread,
487
500
  {
488
501
  room,
489
502
  path: resolvedSingleThreadPath,
490
503
  participants,
491
504
  agentName,
492
- toolkit,
493
- tool,
494
- centerComposer,
495
505
  emptyStateTitle,
496
- emptyStateDescription,
497
- onThreadResolved
506
+ emptyStateDescription
498
507
  }
499
508
  );
500
509
  }
@@ -513,16 +522,22 @@ function ChatBotView({
513
522
  onSelectedThreadResolved: emitResolvedThread,
514
523
  newThreadResetVersion,
515
524
  centerComposer,
516
- builder: (threadPath) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
517
- import_Chat.Chat,
525
+ builder: (threadPath) => isDatasetBackedThreadPath(threadPath) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
526
+ import_dataset_chat_thread.DatasetChatThread,
527
+ {
528
+ room,
529
+ path: threadPath,
530
+ agentName,
531
+ emptyStateTitle: startNewThreadTitle,
532
+ emptyStateDescription: startNewThreadDescription
533
+ }
534
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
535
+ import_chat_thread.ChatThread,
518
536
  {
519
537
  room,
520
538
  path: threadPath,
521
539
  participants,
522
540
  agentName,
523
- toolkit,
524
- tool,
525
- centerComposer,
526
541
  emptyStateTitle: startNewThreadTitle,
527
542
  emptyStateDescription: startNewThreadDescription
528
543
  }
@@ -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
  });
@@ -45,6 +45,8 @@ class PendingAgentMessage {
45
45
  text;
46
46
  attachments;
47
47
  senderName;
48
+ createdAt;
49
+ matchByContentOnly;
48
50
  awaitingAcceptance;
49
51
  awaitingOnline;
50
52
  constructor({
@@ -54,6 +56,8 @@ class PendingAgentMessage {
54
56
  text,
55
57
  attachments,
56
58
  senderName,
59
+ createdAt,
60
+ matchByContentOnly = false,
57
61
  awaitingAcceptance = false,
58
62
  awaitingOnline = false
59
63
  }) {
@@ -63,6 +67,8 @@ class PendingAgentMessage {
63
67
  this.text = text;
64
68
  this.attachments = attachments;
65
69
  this.senderName = senderName;
70
+ this.createdAt = createdAt;
71
+ this.matchByContentOnly = matchByContentOnly;
66
72
  this.awaitingAcceptance = awaitingAcceptance;
67
73
  this.awaitingOnline = awaitingOnline;
68
74
  }
@@ -94,6 +100,8 @@ class PendingAgentMessage {
94
100
  const messageType = json["message_type"];
95
101
  const messageId = json["message_id"];
96
102
  const threadPath = json["thread_id"];
103
+ const createdAt = json["created_at"];
104
+ const parsedCreatedAt = typeof createdAt === "string" ? new Date(createdAt) : void 0;
97
105
  return new PendingAgentMessage({
98
106
  messageId: typeof messageId === "string" ? messageId : crypto.randomUUID(),
99
107
  messageType: typeof messageType === "string" ? messageType : agentTurnSteerType,
@@ -101,6 +109,8 @@ class PendingAgentMessage {
101
109
  text: textParts.join("\n\n"),
102
110
  attachments,
103
111
  senderName: typeof senderName === "string" && senderName.trim().length > 0 ? senderName.trim() : void 0,
112
+ createdAt: parsedCreatedAt instanceof Date && !Number.isNaN(parsedCreatedAt.getTime()) ? parsedCreatedAt : void 0,
113
+ matchByContentOnly: false,
104
114
  awaitingOnline: false
105
115
  });
106
116
  }
@@ -311,7 +321,7 @@ async function sendMessageToParticipant({
311
321
  await room.messaging.sendMessage({
312
322
  to: participant,
313
323
  type: agentRoomMessageType,
314
- message: { payload }
324
+ message: payload
315
325
  });
316
326
  return;
317
327
  }
@@ -535,7 +545,7 @@ function resolveThreadStatus({
535
545
  function pendingMessagesEqual(left, right) {
536
546
  return left.length === right.length && left.every((message, index) => {
537
547
  const other = right[index];
538
- return message.messageId === other.messageId && message.messageType === other.messageType && message.text === other.text && stringArraysEqual(message.attachments, other.attachments) && message.senderName === other.senderName;
548
+ 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;
539
549
  });
540
550
  }
541
551
  function threadStatusEquals(left, right) {
@@ -16,21 +16,21 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var ChatInput_exports = {};
20
- __export(ChatInput_exports, {
19
+ var chat_input_exports = {};
20
+ __export(chat_input_exports, {
21
21
  ChatInput: () => ChatInput
22
22
  });
23
- module.exports = __toCommonJS(ChatInput_exports);
23
+ module.exports = __toCommonJS(chat_input_exports);
24
24
  var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_react = require("react");
26
26
  var import_lucide_react = require("lucide-react");
27
27
  var import_uuid = require("uuid");
28
28
  var import_chat_message = require("./chat-message");
29
- var import_button = require("./components/ui/button");
30
- var import_FileUploader = require("./FileUploader");
31
- var import_UploadPill = require("./UploadPill");
29
+ var import_button = require("../components/ui/button");
30
+ var import_file_uploader = require("./file-uploader");
31
+ var import_upload_pill = require("./upload-pill");
32
32
  var import_file_attachment = require("./file-attachment");
33
- var import_utils = require("./lib/utils");
33
+ var import_utils = require("../lib/utils");
34
34
  const MIN_TEXTAREA_HEIGHT = 20;
35
35
  const MAX_TEXTAREA_HEIGHT = 160;
36
36
  function useAttachmentStatusVersion(attachments) {
@@ -179,7 +179,7 @@ function ChatInput({
179
179
  const trailingButton = showCancelButton ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComposerActionButton, { onClick: onCancelRequest, showCancelButton: true }) : hasDraft ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComposerActionButton, { onClick: handleSend, disabled: !canSend }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-9 w-9 shrink-0" });
180
180
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-4 pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mx-auto flex w-full max-w-4xl flex-col gap-2 rounded-md border border-input/70 bg-background px-2 py-1 shadow-xs focus-within:border-primary focus-within:[outline:1px_solid_var(--color-primary)]", children: [
181
181
  attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex max-w-full flex-wrap gap-2 px-1 pt-1", children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
182
- import_UploadPill.UploadPill,
182
+ import_upload_pill.UploadPill,
183
183
  {
184
184
  attachment,
185
185
  onCancel: cancelAttachment
@@ -187,7 +187,7 @@ function ChatInput({
187
187
  `${attachment.path}-${index}`
188
188
  )) }) : null,
189
189
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
190
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FileUploader.FileUploader, { onFilesSelected, disabled }),
190
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_file_uploader.FileUploader, { onFilesSelected, disabled }),
191
191
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
192
192
  "textarea",
193
193
  {
@@ -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;
@@ -26,12 +26,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var ChatThread_exports = {};
30
- __export(ChatThread_exports, {
29
+ var chat_thread_exports = {};
30
+ __export(chat_thread_exports, {
31
31
  ChatThread: () => ChatThread,
32
32
  timeAgo: () => timeAgo
33
33
  });
34
- module.exports = __toCommonJS(ChatThread_exports);
34
+ module.exports = __toCommonJS(chat_thread_exports);
35
35
  var import_jsx_runtime = require("react/jsx-runtime");
36
36
  var import_react = require("react");
37
37
  var import_lucide_react = require("lucide-react");
@@ -39,10 +39,13 @@ var import_react_markdown = __toESM(require("react-markdown"));
39
39
  var import_rehype_highlight = __toESM(require("rehype-highlight"));
40
40
  var import_rehype_sanitize = __toESM(require("rehype-sanitize"));
41
41
  var import_remark_gfm = __toESM(require("remark-gfm"));
42
- var import_button = require("./components/ui/button");
43
- var import_spinner = require("./components/ui/spinner");
44
- var import_ChatTypingIndicator = require("./ChatTypingIndicator");
45
- var import_utils = require("./lib/utils");
42
+ var import_button = require("../components/ui/button");
43
+ var import_spinner = require("../components/ui/spinner");
44
+ var import_chat_typing_indicator = require("./chat-typing-indicator");
45
+ var import_chat_input = require("./chat-input");
46
+ var import_chat_hooks = require("./chat-hooks");
47
+ var import_file_preview = require("../file-preview/file-preview");
48
+ var import_utils = require("../lib/utils");
46
49
  const supportedEventKinds = /* @__PURE__ */ new Set([
47
50
  "exec",
48
51
  "tool",
@@ -108,9 +111,6 @@ function timeAgo(iso) {
108
111
  function displayParticipantName(name) {
109
112
  return name.split("@")[0]?.trim() ?? name.trim();
110
113
  }
111
- function isImagePath(path) {
112
- return /\.(avif|bmp|gif|jpe?g|png|svg|webp)$/i.test(path);
113
- }
114
114
  function isThreadAttachmentElement(element) {
115
115
  return element.tagName === "file" || element.tagName === "image";
116
116
  }
@@ -119,7 +119,7 @@ function isImageAttachmentElement(element) {
119
119
  return false;
120
120
  }
121
121
  const path = getTrimmedStringAttribute(element, "path");
122
- return element.tagName === "image" || path !== "" && isImagePath(path);
122
+ return element.tagName === "image" || path !== "" && (0, import_file_preview.isImagePath)(path);
123
123
  }
124
124
  function getAttachmentTrackingId(attachment) {
125
125
  const path = getTrimmedStringAttribute(attachment, "path");
@@ -335,14 +335,11 @@ function ChatImage({
335
335
  if (!url) {
336
336
  return null;
337
337
  }
338
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
338
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_file_preview.FilePreviewDialog, { room, path, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
339
339
  "button",
340
340
  {
341
341
  type: "button",
342
342
  className: "block overflow-hidden rounded-md bg-muted/20 shadow-xs transition-opacity hover:opacity-95",
343
- onClick: () => {
344
- window.open(url, "_blank", "noopener,noreferrer");
345
- },
346
343
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
347
344
  "img",
348
345
  {
@@ -359,28 +356,21 @@ function ChatImage({
359
356
  }
360
357
  )
361
358
  }
362
- );
359
+ ) });
363
360
  }
364
361
  function FileAttachment({ room, path }) {
365
- const url = useDownloadUrl(room, path);
366
362
  const filename = path.split("/").pop() ?? path;
367
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
363
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_file_preview.FilePreviewDialog, { room, path, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
368
364
  "button",
369
365
  {
370
366
  type: "button",
371
367
  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",
372
- onClick: () => {
373
- if (url) {
374
- window.open(url, "_blank", "noopener,noreferrer");
375
- }
376
- },
377
368
  children: [
378
369
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
379
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate text-sm font-medium", children: filename }),
380
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Download, { className: "h-4 w-4 shrink-0 text-muted-foreground" })
370
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate text-sm font-medium", children: filename })
381
371
  ]
382
372
  }
383
- );
373
+ ) });
384
374
  }
385
375
  function ThreadAttachment({ room, attachment, onImageSettled }) {
386
376
  const path = getTrimmedStringAttribute(attachment, "path");
@@ -388,7 +378,7 @@ function ThreadAttachment({ room, attachment, onImageSettled }) {
388
378
  return null;
389
379
  }
390
380
  const filename = path.split("/").pop() ?? "Attachment";
391
- if (attachment.tagName === "image" || isImagePath(path)) {
381
+ if (attachment.tagName === "image" || (0, import_file_preview.isImagePath)(path)) {
392
382
  const attachmentId = getAttachmentTrackingId(attachment);
393
383
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
394
384
  ChatImage,
@@ -585,6 +575,63 @@ function EmptyState({
585
575
  ] });
586
576
  }
587
577
  function ChatThread({
578
+ room,
579
+ path,
580
+ participants,
581
+ agentName,
582
+ emptyStateTitle,
583
+ emptyStateDescription
584
+ }) {
585
+ const status = (0, import_chat_hooks.useThreadStatus)({ room, path, agentName });
586
+ const {
587
+ document,
588
+ messages,
589
+ sendMessage,
590
+ selectAttachments,
591
+ attachments,
592
+ setAttachments,
593
+ localParticipantName,
594
+ cancelRequest
595
+ } = (0, import_chat_hooks.useChatThread)({
596
+ room,
597
+ path,
598
+ participants,
599
+ agentName,
600
+ useAgentMessages: agentName?.trim() !== "",
601
+ messageType: status.mode === "steerable" && status.turnId != null ? "steer" : "chat",
602
+ turnId: status.turnId
603
+ });
604
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col", children: [
605
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
606
+ ChatThreadView,
607
+ {
608
+ room,
609
+ messages,
610
+ isLoading: document === null,
611
+ localParticipantName,
612
+ path,
613
+ threadStatusText: status.text,
614
+ threadStatusStartedAt: status.startedAt,
615
+ threadStatusMode: status.mode,
616
+ onCancelRequest: cancelRequest,
617
+ emptyStateTitle,
618
+ emptyStateDescription
619
+ }
620
+ ),
621
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
622
+ import_chat_input.ChatInput,
623
+ {
624
+ onSubmit: sendMessage,
625
+ attachments,
626
+ onFilesSelected: selectAttachments,
627
+ setAttachments,
628
+ disabled: document === null,
629
+ placeholder: agentName?.trim() ? `Type a message or @${displayParticipantName(agentName)}` : "Type a message"
630
+ }
631
+ )
632
+ ] });
633
+ }
634
+ function ChatThreadView({
588
635
  room,
589
636
  messages,
590
637
  isLoading = false,
@@ -748,7 +795,7 @@ function ChatThread({
748
795
  }
749
796
  ),
750
797
  hasOverlay ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 flex justify-center px-4 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pointer-events-auto w-full max-w-[912px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
751
- import_ChatTypingIndicator.ChatTypingIndicator,
798
+ import_chat_typing_indicator.ChatTypingIndicator,
752
799
  {
753
800
  typing,
754
801
  thinking,
@@ -26,17 +26,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var ChatTypingIndicator_exports = {};
30
- __export(ChatTypingIndicator_exports, {
29
+ var chat_typing_indicator_exports = {};
30
+ __export(chat_typing_indicator_exports, {
31
31
  ChatTypingIndicator: () => ChatTypingIndicator
32
32
  });
33
- module.exports = __toCommonJS(ChatTypingIndicator_exports);
33
+ module.exports = __toCommonJS(chat_typing_indicator_exports);
34
34
  var import_jsx_runtime = require("react/jsx-runtime");
35
35
  var React = __toESM(require("react"));
36
36
  var import_meshagent_react = require("@meshagent/meshagent-react");
37
37
  var import_lucide_react = require("lucide-react");
38
38
  var import_chat_hooks = require("./chat-hooks");
39
- var import_utils = require("./lib/utils");
39
+ var import_utils = require("../lib/utils");
40
40
  function useStatusLabel(text, startedAt) {
41
41
  const normalizedText = text?.trim() ?? "";
42
42
  const [tick, setTick] = React.useState(0);
@@ -11,10 +11,11 @@ export declare enum ChatThreadDisplayMode {
11
11
  }
12
12
  export declare class ChatAgentConversationDescriptor {
13
13
  private constructor();
14
- static chat({ chatThreadDisplayMode, threadDir, threadListPath, }?: {
14
+ static chat({ chatThreadDisplayMode, threadDir, threadListPath, threadPath, }?: {
15
15
  chatThreadDisplayMode?: ChatThreadDisplayMode;
16
16
  threadDir?: string | null;
17
17
  threadListPath?: string | null;
18
+ threadPath?: string | null;
18
19
  }): ChatAgentConversationDescriptor;
19
20
  static voiceOnly(): ChatAgentConversationDescriptor;
20
21
  static meeting(): ChatAgentConversationDescriptor;
@@ -22,6 +23,7 @@ export declare class ChatAgentConversationDescriptor {
22
23
  readonly chatThreadDisplayMode: ChatThreadDisplayMode;
23
24
  readonly threadDir: string | null;
24
25
  readonly threadListPath: string | null;
26
+ readonly threadPath: string | null;
25
27
  get isChat(): boolean;
26
28
  get isVoiceOnly(): boolean;
27
29
  get isMeeting(): boolean;
@@ -36,11 +38,15 @@ export declare function chatThreadDisplayModeFromAnnotation(value: unknown): Cha
36
38
  export declare function normalizedThreadDir(threadDir?: string | null): string | null;
37
39
  export declare function participantThreadDir(participant: RemoteParticipant): string | null;
38
40
  export declare function participantThreadListPath(participant: RemoteParticipant): string | null;
41
+ export declare function participantThreadPath(participant: RemoteParticipant): string | null;
39
42
  export declare function participantConversationDescriptor(participant: RemoteParticipant): ChatAgentConversationDescriptor | null;
40
43
  export declare function serviceThreadDir(service: ServiceSpec): string | null;
41
44
  export declare function serviceThreadListPath(service: ServiceSpec, { remoteParticipants }?: {
42
45
  remoteParticipants?: Iterable<RemoteParticipant>;
43
46
  }): string | null;
47
+ export declare function serviceThreadPath(service: ServiceSpec, { remoteParticipants }?: {
48
+ remoteParticipants?: Iterable<RemoteParticipant>;
49
+ }): string | null;
44
50
  export declare function serviceConversationDescriptor(service: ServiceSpec, { remoteParticipants }?: {
45
51
  remoteParticipants?: Iterable<RemoteParticipant>;
46
52
  }): ChatAgentConversationDescriptor | null;
@@ -35,10 +35,12 @@ __export(conversation_descriptor_exports, {
35
35
  participantSupportsVoice: () => participantSupportsVoice,
36
36
  participantThreadDir: () => participantThreadDir,
37
37
  participantThreadListPath: () => participantThreadListPath,
38
+ participantThreadPath: () => participantThreadPath,
38
39
  resolvedThreadListPath: () => resolvedThreadListPath,
39
40
  serviceConversationDescriptor: () => serviceConversationDescriptor,
40
41
  serviceThreadDir: () => serviceThreadDir,
41
- serviceThreadListPath: () => serviceThreadListPath
42
+ serviceThreadListPath: () => serviceThreadListPath,
43
+ serviceThreadPath: () => serviceThreadPath
42
44
  });
43
45
  module.exports = __toCommonJS(conversation_descriptor_exports);
44
46
  var import_meshagent = require("@meshagent/meshagent");
@@ -60,23 +62,27 @@ class ChatAgentConversationDescriptor {
60
62
  kind,
61
63
  chatThreadDisplayMode = 0 /* SingleThread */,
62
64
  threadDir = null,
63
- threadListPath = null
65
+ threadListPath = null,
66
+ threadPath = null
64
67
  }) {
65
68
  this.kind = kind;
66
69
  this.chatThreadDisplayMode = chatThreadDisplayMode;
67
70
  this.threadDir = threadDir;
68
71
  this.threadListPath = threadListPath;
72
+ this.threadPath = threadPath;
69
73
  }
70
74
  static chat({
71
75
  chatThreadDisplayMode = 0 /* SingleThread */,
72
76
  threadDir = null,
73
- threadListPath = null
77
+ threadListPath = null,
78
+ threadPath = null
74
79
  } = {}) {
75
80
  return new ChatAgentConversationDescriptor({
76
81
  kind: 0 /* Chat */,
77
82
  chatThreadDisplayMode,
78
83
  threadDir,
79
- threadListPath
84
+ threadListPath,
85
+ threadPath
80
86
  });
81
87
  }
82
88
  static voiceOnly() {
@@ -93,6 +99,7 @@ class ChatAgentConversationDescriptor {
93
99
  chatThreadDisplayMode;
94
100
  threadDir;
95
101
  threadListPath;
102
+ threadPath;
96
103
  get isChat() {
97
104
  return this.kind === 0 /* Chat */;
98
105
  }
@@ -164,12 +171,16 @@ function participantThreadListPath(participant) {
164
171
  const threadListPath = normalizedAnnotationString(participant.getAttribute("meshagent.chatbot.thread-list"));
165
172
  return threadListPath ?? threadListPathFromThreadDir(participantThreadDir(participant));
166
173
  }
174
+ function participantThreadPath(participant) {
175
+ return normalizedAnnotationString(participant.getAttribute("meshagent.chatbot.thread-path"));
176
+ }
167
177
  function participantConversationDescriptor(participant) {
168
178
  const supportsVoice = participantSupportsVoice(participant);
169
179
  const supportsChat = participantSupportsChatOverride(participant);
170
180
  const threadDir = participantThreadDir(participant);
171
181
  const threadListPath = participantThreadListPath(participant);
172
- const hasThreadAnnotations = normalizedAnnotationString(participant.getAttribute("meshagent.chatbot.threading")) !== null || threadDir !== null || threadListPath !== null;
182
+ const threadPath = participantThreadPath(participant);
183
+ const hasThreadAnnotations = normalizedAnnotationString(participant.getAttribute("meshagent.chatbot.threading")) !== null || threadDir !== null || threadListPath !== null || threadPath !== null;
173
184
  if (supportsChat === false) {
174
185
  return supportsVoice ? ChatAgentConversationDescriptor.voiceOnly() : null;
175
186
  }
@@ -182,7 +193,8 @@ function participantConversationDescriptor(participant) {
182
193
  participant.getAttribute("meshagent.chatbot.threading")
183
194
  ),
184
195
  threadDir,
185
- threadListPath
196
+ threadListPath,
197
+ threadPath
186
198
  });
187
199
  }
188
200
  if (supportsVoice) {
@@ -216,6 +228,24 @@ function serviceThreadListPath(service, { remoteParticipants = [] } = {}) {
216
228
  }
217
229
  return null;
218
230
  }
231
+ function serviceThreadPath(service, { remoteParticipants = [] } = {}) {
232
+ const annotationPath = normalizedAnnotationString(
233
+ firstAgent(service)?.annotations?.["meshagent.chatbot.thread-path"]
234
+ );
235
+ if (annotationPath !== null) {
236
+ return annotationPath;
237
+ }
238
+ const agentName = firstAgent(service)?.name;
239
+ if (!agentName || agentName.trim() === "") {
240
+ return null;
241
+ }
242
+ for (const participant of remoteParticipants) {
243
+ if (participant.getAttribute("name") === agentName) {
244
+ return participantThreadPath(participant);
245
+ }
246
+ }
247
+ return null;
248
+ }
219
249
  function serviceConversationDescriptor(service, { remoteParticipants = [] } = {}) {
220
250
  const type = firstAgent(service)?.annotations?.["meshagent.agent.type"];
221
251
  if (type === "VoiceBot") {
@@ -232,7 +262,8 @@ function serviceConversationDescriptor(service, { remoteParticipants = [] } = {}
232
262
  firstAgent(service)?.annotations?.["meshagent.chatbot.threading"]
233
263
  ),
234
264
  threadDir: serviceThreadDir(service),
235
- threadListPath: serviceThreadListPath(service, { remoteParticipants })
265
+ threadListPath: serviceThreadListPath(service, { remoteParticipants }),
266
+ threadPath: serviceThreadPath(service, { remoteParticipants })
236
267
  });
237
268
  }
238
269
  function conversationDescriptorForParticipant(participant, {
@@ -277,6 +308,9 @@ function chatDocumentPath(agentName, {
277
308
  } = {}) {
278
309
  const normalizedDir = normalizedThreadDir(threadDir);
279
310
  if (normalizedDir !== null) {
311
+ if (normalizedDir.startsWith("dataset://") || normalizedDir.startsWith("tmp://")) {
312
+ return `${normalizedDir}/main`;
313
+ }
280
314
  return `${normalizedDir}/main.thread`;
281
315
  }
282
316
  const defaultThreadDir = defaultThreadDocumentDir(agentName);
@@ -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;