@athenaintel/react 0.15.0 → 0.15.1

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 (32) hide show
  1. package/dist/chat/super-grouping/toolkit-map.d.ts +8 -3
  2. package/dist/chat-ui/composer/tiptap-composer.d.ts +7 -0
  3. package/dist/chat-ui/header/chat-header.d.ts +19 -0
  4. package/dist/chat-ui/header/conversation-history-panel.d.ts +27 -0
  5. package/dist/chat-ui/index.d.ts +4 -0
  6. package/dist/chat-ui/messages/message-actions-config.d.ts +12 -0
  7. package/dist/chat-ui/messages/user-edit-composer.d.ts +8 -0
  8. package/dist/chat-ui/thread/chat-thread-shell.d.ts +13 -1
  9. package/dist/chat-ui.cjs +504 -144
  10. package/dist/chat-ui.cjs.map +1 -1
  11. package/dist/chat-ui.js +398 -38
  12. package/dist/chat-ui.js.map +1 -1
  13. package/dist/index.cjs +1182 -4284
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +750 -3831
  17. package/dist/index.js.map +1 -1
  18. package/dist/provider/AthenaProvider.d.ts +4 -1
  19. package/dist/runtime/statewire-run-config.d.ts +0 -2
  20. package/dist/runtime/useAthenaStatewireRuntime.d.ts +3 -1
  21. package/dist/styles.css +1 -1
  22. package/dist/threads/api.d.ts +7 -0
  23. package/dist/threads/conversation-list-fetcher.d.ts +5 -1
  24. package/dist/threads/use-rest-conversation-history.d.ts +43 -0
  25. package/dist/threads/use-statewire-conversation-history.d.ts +71 -0
  26. package/dist/{composer-send-or-stop-RPudYkWR.cjs → use-rest-conversation-history-CBPqoHoe.cjs} +4327 -271
  27. package/dist/use-rest-conversation-history-CBPqoHoe.cjs.map +1 -0
  28. package/dist/{composer-send-or-stop-C5AVmcwO.js → use-rest-conversation-history-DYvfgoBF.js} +4459 -424
  29. package/dist/use-rest-conversation-history-DYvfgoBF.js.map +1 -0
  30. package/package.json +1 -1
  31. package/dist/composer-send-or-stop-C5AVmcwO.js.map +0 -1
  32. package/dist/composer-send-or-stop-RPudYkWR.cjs.map +0 -1
package/dist/chat-ui.js CHANGED
@@ -1,10 +1,10 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { a4 as createLucideIcon, W as Node, z as mergeAttributes, a0 as Extension, av as Suggestion, at as useFloating, au as FloatingPortal, q as autoUpdate, o as offset, k as flip, s as shift, ar as getFilteredItems, aY as getFetchState, aZ as getEntry, a_ as updateFetchState, az as addItems, ay as registerSource, a$ as bindScopes, aq as useStore, ag as FileText, a6 as Workflow, aj as BookOpen, aM as Sheet, aK as Table, ah as Database, ai as Calendar, aa as Mail, aL as Image, a9 as Monitor, aI as Code, aN as Camera, ab as LayoutGrid, ac as HardDrive, a8 as Package, a5 as Wrench, a7 as Users, aJ as Search, ad as Globe, ae as FolderKanban, af as Folder, aU as File$1, t as cn, ax as Store, b0 as getSearchScope, b1 as assetTypeToThumb, b2 as fetchGraphQL, b3 as PAGINATED_ASSETS_QUERY, b4 as WORKSPACE_MEMBERS_QUERY, b5 as SIMPLE_SEARCH_QUERY, b6 as assetTypeToIcon, b7 as useMentionAuth, aB as createScopeRegistry, aA as createItemCache, an as useEditor, ap as StarterKit, aE as Placeholder, ao as EditorContent } from "./composer-send-or-stop-C5AVmcwO.js";
5
- import { b8, b9, ba, bb, bc, aQ, aP, bd, aR, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, bA } from "./composer-send-or-stop-C5AVmcwO.js";
4
+ import { au as createLucideIcon, O as cn, bJ as THREAD_HEADER_ACTIONS_CLASS, bK as THREAD_HEADER_PILL_CLASS, bL as THREAD_HEADER_CLASS, b4 as RefreshCw, bm as Plus, b9 as Search, be as LoaderCircle, bx as conversationDisplayTitle, b7 as Archive, bM as assetTypeToThumb, aA as MessageSquare, ak as Node, a2 as mergeAttributes, aq as Extension, aW as Suggestion, aU as useFloating, aV as FloatingPortal, N as autoUpdate, F as offset, I as flip, G as shift, aS as getFilteredItems, bN as getFetchState, bO as getEntry, bP as updateFetchState, a_ as addItems, aZ as registerSource, bQ as bindScopes, aR as useStore, aH as FileText, aw as Workflow, aK as BookOpen, bc as Sheet, ba as Table, aI as Database, aJ as Calendar, aB as Mail, bb as Image, az as Monitor, b8 as Code, bd as Camera, aC as LayoutGrid, aD as HardDrive, ay as Package, av as Wrench, ax as Users, aE as Globe, aF as FolderKanban, aG as Folder, bl as File$1, aY as Store, bR as getSearchScope, bS as fetchGraphQL, bT as PAGINATED_ASSETS_QUERY, bU as WORKSPACE_MEMBERS_QUERY, bV as SIMPLE_SEARCH_QUERY, bW as assetTypeToIcon, bX as useMentionAuth, b0 as createScopeRegistry, a$ as createItemCache, aO as useEditor, aQ as StarterKit, b3 as Placeholder, aP as EditorContent } from "./use-rest-conversation-history-DYvfgoBF.js";
5
+ import { bY, bZ, b_, b$, c0, bh, bg, c1, bi, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm, cn as cn2, co } from "./use-rest-conversation-history-DYvfgoBF.js";
6
6
  import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
7
- import { useEffect, useState, useRef, Fragment, useImperativeHandle, forwardRef, useCallback, useMemo, useId } from "react";
7
+ import { useMemo, useEffect, useState, useRef, Fragment, useImperativeHandle, forwardRef, useCallback, useId } from "react";
8
8
  import { useAui, unstable_useComposerInput } from "@assistant-ui/react";
9
9
  import "@assistant-ui/tap";
10
10
  import "statewire";
@@ -19,6 +19,21 @@ function registerChatAssetMentionHandler(threadId, handler) {
19
19
  }
20
20
  };
21
21
  }
22
+ /**
23
+ * @license lucide-react v0.575.0 - ISC
24
+ *
25
+ * This source code is licensed under the ISC license.
26
+ * See the LICENSE file in the root directory of this source tree.
27
+ */
28
+ const __iconNode$l = [
29
+ ["path", { d: "M12 8V4H8", key: "hb8ula" }],
30
+ ["rect", { width: "16", height: "12", x: "4", y: "8", rx: "2", key: "enze0r" }],
31
+ ["path", { d: "M2 14h2", key: "vft8re" }],
32
+ ["path", { d: "M20 14h2", key: "4cs60a" }],
33
+ ["path", { d: "M15 13v2", key: "1xurst" }],
34
+ ["path", { d: "M9 13v2", key: "rq6x2g" }]
35
+ ];
36
+ const Bot = createLucideIcon("bot", __iconNode$l);
22
37
  /**
23
38
  * @license lucide-react v0.575.0 - ISC
24
39
  *
@@ -346,6 +361,333 @@ const __iconNode = [
346
361
  ]
347
362
  ];
348
363
  const Zap = createLucideIcon("zap", __iconNode);
364
+ function ChatHeaderRoot({
365
+ children,
366
+ className
367
+ }) {
368
+ return /* @__PURE__ */ jsx("div", { className: cn(THREAD_HEADER_CLASS, className), children });
369
+ }
370
+ function ChatHeaderIdentity({
371
+ children,
372
+ className
373
+ }) {
374
+ return /* @__PURE__ */ jsx("div", { className: cn(THREAD_HEADER_PILL_CLASS, className), children });
375
+ }
376
+ function ChatHeaderActions({
377
+ children,
378
+ className
379
+ }) {
380
+ return /* @__PURE__ */ jsx("div", { className: cn(THREAD_HEADER_ACTIONS_CLASS, className), children });
381
+ }
382
+ const ChatHeader = {
383
+ Root: ChatHeaderRoot,
384
+ Identity: ChatHeaderIdentity,
385
+ Actions: ChatHeaderActions
386
+ };
387
+ const TIME_GROUPS = [
388
+ "Today",
389
+ "Yesterday",
390
+ "This Week",
391
+ "This Month",
392
+ "Older"
393
+ ];
394
+ const AUTOMATED_SOURCE_CHANNELS = /* @__PURE__ */ new Set([
395
+ "api",
396
+ "email",
397
+ "orchestration",
398
+ "slack",
399
+ "sms",
400
+ "task",
401
+ "teams"
402
+ ]);
403
+ function isAutomatedConversation(conversation) {
404
+ var _a, _b;
405
+ const sourceChannel = (_a = conversation.sourceChannel) == null ? void 0 : _a.trim().toLowerCase();
406
+ if (sourceChannel && AUTOMATED_SOURCE_CHANNELS.has(sourceChannel))
407
+ return true;
408
+ const triggerType = (_b = conversation.triggerType) == null ? void 0 : _b.trim().toLowerCase();
409
+ return Boolean(triggerType && triggerType !== "manual");
410
+ }
411
+ function conversationTimeGroup(value, now = /* @__PURE__ */ new Date()) {
412
+ const date = new Date(value);
413
+ if (Number.isNaN(date.getTime())) return "Older";
414
+ const startOfToday = new Date(
415
+ now.getFullYear(),
416
+ now.getMonth(),
417
+ now.getDate()
418
+ );
419
+ const startOfYesterday = new Date(startOfToday.getTime() - 864e5);
420
+ const startOfWeek = new Date(
421
+ startOfToday.getTime() - startOfToday.getDay() * 864e5
422
+ );
423
+ const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
424
+ if (date >= startOfToday) return "Today";
425
+ if (date >= startOfYesterday) return "Yesterday";
426
+ if (date >= startOfWeek) return "This Week";
427
+ if (date >= startOfMonth) return "This Month";
428
+ return "Older";
429
+ }
430
+ function originKey(conversation) {
431
+ return conversation.appId ?? conversation.sourceChannel ?? "unknown";
432
+ }
433
+ function originLabel(value) {
434
+ const normalized = value.toLowerCase();
435
+ if (normalized.includes("chrome")) return "Chrome";
436
+ if (normalized.includes("powerpoint")) return "PowerPoint";
437
+ if (normalized.includes("word")) return "Word";
438
+ if (normalized.includes("excel")) return "Excel";
439
+ if (normalized.includes("office")) return "Office";
440
+ if (normalized === "web" || normalized.includes("olympus")) return "Athena";
441
+ if (normalized.includes("mobile")) return "Mobile";
442
+ if (value === "unknown") return "Legacy";
443
+ return value.replace(/^athena[-_]/, "").replaceAll("_", " ");
444
+ }
445
+ function relativeTime(value) {
446
+ const timestamp = Date.parse(value);
447
+ if (!Number.isFinite(timestamp)) return "";
448
+ const elapsed = Math.max(0, Date.now() - timestamp);
449
+ const minutes = Math.floor(elapsed / 6e4);
450
+ if (minutes < 1) return "<1m ago";
451
+ if (minutes < 60) return `${minutes}m ago`;
452
+ const hours = Math.floor(minutes / 60);
453
+ if (hours < 24) return `${hours}h ${minutes % 60}m ago`;
454
+ const days = Math.floor(hours / 24);
455
+ return days < 7 ? `${days}d ago` : new Date(timestamp).toLocaleDateString();
456
+ }
457
+ function ConversationTypeIcon({
458
+ conversation,
459
+ automated
460
+ }) {
461
+ if (conversation.state === "running") {
462
+ return /* @__PURE__ */ jsx(
463
+ LoaderCircle,
464
+ {
465
+ "aria-label": "Conversation running",
466
+ className: "mt-0.5 size-4 shrink-0 animate-spin text-primary"
467
+ }
468
+ );
469
+ }
470
+ const thumbnail = assetTypeToThumb(conversation.assetType ?? "session");
471
+ if (thumbnail) {
472
+ return /* @__PURE__ */ jsx("img", { src: thumbnail, alt: "", className: "mt-0.5 size-4 shrink-0" });
473
+ }
474
+ return automated ? /* @__PURE__ */ jsx(Bot, { className: "mt-0.5 size-4 shrink-0 text-primary" }) : /* @__PURE__ */ jsx(MessageSquare, { className: "mt-0.5 size-4 shrink-0 text-emerald-500" });
475
+ }
476
+ function ConversationHistoryPanel({
477
+ conversations,
478
+ activeThreadId,
479
+ search,
480
+ onSearchChange,
481
+ activityFilter,
482
+ onActivityFilterChange,
483
+ originFilter,
484
+ onOriginFilterChange,
485
+ onSelect,
486
+ onNewChat,
487
+ onRefresh,
488
+ onArchive,
489
+ onSetReadState,
490
+ isLoading = false,
491
+ isRefreshing = false,
492
+ hasNextPage = false,
493
+ isFetchingNextPage = false,
494
+ onLoadMore
495
+ }) {
496
+ const origins = useMemo(
497
+ () => [...new Set(conversations.map(originKey))].sort(),
498
+ [conversations]
499
+ );
500
+ const grouped = useMemo(() => {
501
+ const visible = conversations.filter((conversation) => {
502
+ const automated = isAutomatedConversation(conversation);
503
+ if (activityFilter === "chat" && automated) return false;
504
+ if (activityFilter === "automated" && !automated) return false;
505
+ return originFilter === "all" || originKey(conversation) === originFilter;
506
+ });
507
+ const byGroup = /* @__PURE__ */ new Map();
508
+ for (const conversation of visible) {
509
+ const group = conversationTimeGroup(conversation.updatedAt);
510
+ const items = byGroup.get(group) ?? [];
511
+ items.push(conversation);
512
+ byGroup.set(group, items);
513
+ }
514
+ return TIME_GROUPS.flatMap((group) => {
515
+ const items = byGroup.get(group);
516
+ return items ? [{ group, items }] : [];
517
+ });
518
+ }, [activityFilter, conversations, originFilter]);
519
+ const visibleCount = grouped.reduce(
520
+ (count, group) => count + group.items.length,
521
+ 0
522
+ );
523
+ const handleSearch = (event) => onSearchChange(event.target.value);
524
+ return /* @__PURE__ */ jsxs(
525
+ "section",
526
+ {
527
+ "aria-label": "Conversation history",
528
+ className: "border-b border-border bg-background px-2 pb-2",
529
+ "data-testid": "conversation-history-panel",
530
+ children: [
531
+ /* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center gap-1.5 px-1", children: [
532
+ /* @__PURE__ */ jsx("h2", { className: "text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground", children: "Sessions" }),
533
+ /* @__PURE__ */ jsx(
534
+ "button",
535
+ {
536
+ type: "button",
537
+ "aria-label": "Refresh sessions",
538
+ title: "Refresh sessions",
539
+ disabled: isRefreshing,
540
+ onClick: onRefresh,
541
+ className: "ml-auto rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-50",
542
+ children: /* @__PURE__ */ jsx(
543
+ RefreshCw,
544
+ {
545
+ className: cn("size-3.5", isRefreshing && "animate-spin")
546
+ }
547
+ )
548
+ }
549
+ ),
550
+ /* @__PURE__ */ jsxs(
551
+ "button",
552
+ {
553
+ type: "button",
554
+ onClick: onNewChat,
555
+ className: "flex h-7 shrink-0 items-center gap-1 rounded-md bg-primary px-2 text-[11px] font-medium text-primary-foreground",
556
+ children: [
557
+ /* @__PURE__ */ jsx(Plus, { className: "size-3" }),
558
+ " New"
559
+ ]
560
+ }
561
+ )
562
+ ] }),
563
+ /* @__PURE__ */ jsxs("label", { className: "relative block min-w-0 px-1 pb-2", children: [
564
+ /* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 size-3.5 -translate-y-[calc(50%+0.25rem)] text-muted-foreground" }),
565
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Search sessions" }),
566
+ /* @__PURE__ */ jsx(
567
+ "input",
568
+ {
569
+ value: search,
570
+ onChange: handleSearch,
571
+ placeholder: "Search sessions...",
572
+ className: "h-8 w-full rounded-md border border-border bg-muted/40 pl-7 pr-2 text-xs outline-none focus:border-primary focus:bg-background"
573
+ }
574
+ )
575
+ ] }),
576
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1 overflow-x-auto px-1 pb-2 text-[11px]", children: [
577
+ ["all", "chat", "automated"].map((filter) => /* @__PURE__ */ jsx(
578
+ "button",
579
+ {
580
+ type: "button",
581
+ onClick: () => onActivityFilterChange(filter),
582
+ className: cn(
583
+ "rounded-full border px-2 py-1 capitalize",
584
+ activityFilter === filter ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground"
585
+ ),
586
+ children: filter === "chat" ? "Chats" : filter === "automated" ? "Automations" : "All"
587
+ },
588
+ filter
589
+ )),
590
+ /* @__PURE__ */ jsxs(
591
+ "select",
592
+ {
593
+ "aria-label": "Filter by origin",
594
+ value: originFilter,
595
+ onChange: (event) => onOriginFilterChange(event.target.value),
596
+ className: "ml-auto rounded-full border border-border bg-background px-2 text-[11px] text-muted-foreground",
597
+ children: [
598
+ /* @__PURE__ */ jsx("option", { value: "all", children: "All origins" }),
599
+ origins.map((origin) => /* @__PURE__ */ jsx("option", { value: origin, children: originLabel(origin) }, origin))
600
+ ]
601
+ }
602
+ )
603
+ ] }),
604
+ /* @__PURE__ */ jsxs("div", { className: "max-h-[min(60vh,28rem)] overflow-y-auto px-0.5", children: [
605
+ isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2 py-4 text-xs text-muted-foreground", children: [
606
+ /* @__PURE__ */ jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
607
+ " Loading sessions…"
608
+ ] }) : visibleCount === 0 ? /* @__PURE__ */ jsx("p", { className: "px-2 py-4 text-xs text-muted-foreground", children: "No matching sessions." }) : grouped.map(({ group, items }) => /* @__PURE__ */ jsxs("div", { children: [
609
+ /* @__PURE__ */ jsx("h3", { className: "px-2 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground/75", children: group }),
610
+ items.map((conversation) => {
611
+ const automated = isAutomatedConversation(conversation);
612
+ return /* @__PURE__ */ jsxs(
613
+ "div",
614
+ {
615
+ className: cn(
616
+ "group flex items-start gap-2 rounded-md px-2 py-2 hover:bg-accent",
617
+ conversation.threadId === activeThreadId && "bg-primary/10 text-primary"
618
+ ),
619
+ children: [
620
+ /* @__PURE__ */ jsxs(
621
+ "button",
622
+ {
623
+ type: "button",
624
+ onClick: () => {
625
+ onSelect(conversation.threadId);
626
+ if (conversation.isUnread) {
627
+ onSetReadState(conversation.threadId, false);
628
+ }
629
+ },
630
+ className: "flex min-w-0 flex-1 items-start gap-2 text-left",
631
+ children: [
632
+ /* @__PURE__ */ jsx(
633
+ ConversationTypeIcon,
634
+ {
635
+ conversation,
636
+ automated
637
+ }
638
+ ),
639
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
640
+ /* @__PURE__ */ jsxs("span", { className: "flex items-start gap-1", children: [
641
+ /* @__PURE__ */ jsx("span", { className: "line-clamp-2 flex-1 text-xs font-medium leading-snug", children: conversationDisplayTitle(conversation) }),
642
+ conversation.isUnread ? /* @__PURE__ */ jsx(
643
+ "span",
644
+ {
645
+ "aria-label": "Unread",
646
+ className: "mt-1 size-1.5 shrink-0 rounded-full bg-primary"
647
+ }
648
+ ) : null
649
+ ] }),
650
+ /* @__PURE__ */ jsxs("span", { className: "mt-0.5 flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
651
+ /* @__PURE__ */ jsx("span", { children: relativeTime(conversation.updatedAt) }),
652
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "·" }),
653
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: originLabel(originKey(conversation)) })
654
+ ] })
655
+ ] })
656
+ ]
657
+ }
658
+ ),
659
+ /* @__PURE__ */ jsx(
660
+ "button",
661
+ {
662
+ type: "button",
663
+ "aria-label": `Archive ${conversationDisplayTitle(conversation)}`,
664
+ title: "Archive conversation",
665
+ onClick: () => onArchive(conversation.threadId),
666
+ className: "invisible rounded p-1 text-muted-foreground hover:bg-background hover:text-foreground group-hover:visible focus:visible",
667
+ children: /* @__PURE__ */ jsx(Archive, { className: "size-3.5" })
668
+ }
669
+ )
670
+ ]
671
+ },
672
+ conversation.threadId
673
+ );
674
+ })
675
+ ] }, group)),
676
+ hasNextPage ? /* @__PURE__ */ jsx(
677
+ "button",
678
+ {
679
+ type: "button",
680
+ disabled: isFetchingNextPage,
681
+ onClick: onLoadMore,
682
+ className: "mt-1 w-full rounded-lg py-2 text-xs text-muted-foreground hover:bg-accent disabled:opacity-50",
683
+ children: isFetchingNextPage ? "Loading…" : "Load older sessions"
684
+ }
685
+ ) : visibleCount > 0 ? /* @__PURE__ */ jsx("p", { className: "py-2 text-center text-[10px] text-muted-foreground/70", children: "No more sessions" }) : null
686
+ ] })
687
+ ]
688
+ }
689
+ );
690
+ }
349
691
  function makeMentionUrl(attrs) {
350
692
  if (attrs.type === "tool") {
351
693
  return `mention://tool?name=${encodeURIComponent(attrs.id)}&description=${encodeURIComponent(attrs.description ?? "")}`;
@@ -1705,7 +2047,7 @@ function plainTextToTiptapContent(text) {
1705
2047
  };
1706
2048
  }
1707
2049
  const NO_WEBPAGES = [];
1708
- const TiptapComposer = forwardRef(({ placeholder = "Message Athena... (type @ to mention)", threadId, disabled = false, webpages = NO_WEBPAGES, rootCategories, onDraftStateChange }, outerRef) => {
2050
+ const TiptapComposer = forwardRef(({ placeholder = "Message Athena... (type @ to mention)", threadId, disabled = false, webpages = NO_WEBPAGES, rootCategories, onDraftStateChange, interceptSubmit }, outerRef) => {
1709
2051
  const aui = useAui();
1710
2052
  const composerInput = unstable_useComposerInput();
1711
2053
  const applyingRuntimeTextRef = useRef(false);
@@ -1737,6 +2079,7 @@ const TiptapComposer = forwardRef(({ placeholder = "Message Athena... (type @ to
1737
2079
  });
1738
2080
  const editorRef = useRef(null);
1739
2081
  const handleSubmit = useCallback(async () => {
2082
+ var _a;
1740
2083
  if (disabled) return;
1741
2084
  if (submitInFlightRef.current) return;
1742
2085
  submitInFlightRef.current = true;
@@ -1747,6 +2090,14 @@ const TiptapComposer = forwardRef(({ placeholder = "Message Athena... (type @ to
1747
2090
  const text = ed.getText({ blockSeparator: "\n" }).trim();
1748
2091
  if (!text) return;
1749
2092
  if (!composerInput.canSend) return;
2093
+ if (interceptSubmit) {
2094
+ const hasAttachments = (((_a = aui.composer.getState().attachments) == null ? void 0 : _a.length) ?? 0) > 0;
2095
+ if (!hasAttachments && await interceptSubmit(text)) {
2096
+ ed.commands.clearContent();
2097
+ onDraftStateChange == null ? void 0 : onDraftStateChange(false);
2098
+ return;
2099
+ }
2100
+ }
1750
2101
  composerInput.setText(text);
1751
2102
  composerInput.send({ steer: false });
1752
2103
  ed.commands.clearContent();
@@ -1754,7 +2105,7 @@ const TiptapComposer = forwardRef(({ placeholder = "Message Athena... (type @ to
1754
2105
  } finally {
1755
2106
  submitInFlightRef.current = false;
1756
2107
  }
1757
- }, [composerInput, disabled, onDraftStateChange]);
2108
+ }, [composerInput, disabled, interceptSubmit, onDraftStateChange]);
1758
2109
  const handleSubmitRef = useRef(handleSubmit);
1759
2110
  handleSubmitRef.current = handleSubmit;
1760
2111
  const addAttachment = useCallback(
@@ -1828,7 +2179,8 @@ const TiptapComposer = forwardRef(({ placeholder = "Message Athena... (type @ to
1828
2179
  ],
1829
2180
  editorProps: {
1830
2181
  attributes: {
1831
- class: "w-full resize-none bg-transparent px-1.5 py-2 text-sm leading-snug outline-none"
2182
+ class: "w-full resize-none bg-transparent px-1.5 py-2 text-sm leading-snug outline-none",
2183
+ "data-testid": "athena-chat-composer"
1832
2184
  },
1833
2185
  handlePaste,
1834
2186
  handleDrop
@@ -2022,28 +2374,34 @@ const SignInConsent = ({ checked, onChange, children }) => /* @__PURE__ */ jsxs(
2022
2374
  /* @__PURE__ */ jsx("span", { children })
2023
2375
  ] });
2024
2376
  export {
2025
- b8 as BranchPicker,
2026
- b9 as COMPOSER_DOCK_CLASS,
2027
- ba as COMPOSER_EDITOR_ROW_CLASS,
2028
- bb as COMPOSER_SURFACE_CLASS,
2029
- bc as COMPOSER_TOOLBAR_CLASS,
2030
- aQ as ChatComposerDock,
2031
- aP as ChatThreadShell,
2032
- bd as ComposerSendButton,
2033
- aR as ComposerSendOrStop,
2034
- be as ComposerStopButton,
2035
- bf as IconButton,
2036
- bg as MarkdownText,
2037
- bh as MentionAuthCtx,
2038
- bi as MentionChip,
2377
+ bY as BranchPicker,
2378
+ bZ as COMPOSER_DOCK_CLASS,
2379
+ b_ as COMPOSER_EDITOR_ROW_CLASS,
2380
+ b$ as COMPOSER_SURFACE_CLASS,
2381
+ c0 as COMPOSER_TOOLBAR_CLASS,
2382
+ bh as ChatComposerDock,
2383
+ ChatHeader,
2384
+ ChatHeaderActions,
2385
+ ChatHeaderIdentity,
2386
+ ChatHeaderRoot,
2387
+ bg as ChatThreadShell,
2388
+ c1 as ComposerSendButton,
2389
+ bi as ComposerSendOrStop,
2390
+ c2 as ComposerStopButton,
2391
+ ConversationHistoryPanel,
2392
+ c3 as IconButton,
2393
+ c4 as MarkdownText,
2394
+ c5 as MentionAuthCtx,
2395
+ c6 as MentionChip,
2039
2396
  MentionExtension,
2040
2397
  MentionIcon,
2041
- bj as MentionLink,
2398
+ c7 as MentionLink,
2042
2399
  MentionMenuSection,
2043
2400
  MentionSuggestionList,
2044
2401
  MentionSuggestionPopup,
2045
2402
  MentionSuggestionsExtension,
2046
2403
  MenuList,
2404
+ c8 as MessageActionsReadOnlyProvider,
2047
2405
  PendingAttachmentUploads,
2048
2406
  ROOT_MENTION_CATEGORIES,
2049
2407
  SIMPLE_SEARCH_QUERY,
@@ -2053,33 +2411,35 @@ export {
2053
2411
  SignInSecondaryButton,
2054
2412
  SignInSelect,
2055
2413
  SignInTextField,
2056
- bk as SmallIconButton,
2057
- bl as THREAD_HEADER_ACTIONS_CLASS,
2058
- bm as THREAD_HEADER_CLASS,
2059
- bn as THREAD_HEADER_ICON_CLASS,
2060
- bo as THREAD_HEADER_PILL_CLASS,
2061
- bp as THREAD_PANEL_CLASS,
2062
- bq as THREAD_SCROLL_TO_BOTTOM_CLASS,
2063
- br as TextShimmerLoader,
2064
- bs as ThreadRunningIndicator,
2414
+ c9 as SmallIconButton,
2415
+ THREAD_HEADER_ACTIONS_CLASS,
2416
+ THREAD_HEADER_CLASS,
2417
+ ca as THREAD_HEADER_ICON_CLASS,
2418
+ THREAD_HEADER_PILL_CLASS,
2419
+ cb as THREAD_PANEL_CLASS,
2420
+ cc as THREAD_SCROLL_TO_BOTTOM_CLASS,
2421
+ cd as TextShimmerLoader,
2422
+ ce as ThreadRunningIndicator,
2065
2423
  TiptapComposer,
2066
- bt as UserMessage,
2424
+ cf as UserEditComposer,
2425
+ cg as UserMessage,
2067
2426
  assetTypeToIcon,
2068
2427
  assetTypeToThumb,
2069
2428
  buildRootMenuItems,
2070
- bu as configureAssetIconBasePath,
2071
- bv as createAssistantMessage,
2072
- bw as createOlympusAssetUrl,
2429
+ ch as configureAssetIconBasePath,
2430
+ ci as createAssistantMessage,
2431
+ cj as createOlympusAssetUrl,
2073
2432
  fetchGraphQL,
2074
2433
  makeMentionUrl,
2075
- bx as normalizeAthenaMentionHtml,
2434
+ ck as normalizeAthenaMentionHtml,
2076
2435
  parseMentionAnchorAttributes,
2077
- by as parseMentionUrl,
2078
- bz as parseMentionsInText,
2436
+ cl as parseMentionUrl,
2437
+ cm as parseMentionsInText,
2079
2438
  plainTextToTiptapContent,
2080
- bA as resolveComposerAction,
2439
+ cn2 as resolveComposerAction,
2081
2440
  useMentionAuth,
2082
2441
  useMentionSuggestions,
2442
+ co as useMessageActionsReadOnly,
2083
2443
  webpageMentionFingerprint
2084
2444
  };
2085
2445
  //# sourceMappingURL=chat-ui.js.map