local-operator-ui 0.12.6 → 0.12.7

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 (46) hide show
  1. package/out/main/index.jsc +0 -0
  2. package/out/preload/index.jsc +0 -0
  3. package/out/renderer/assets/{_basePickBy-CV2bZNyc.js → _basePickBy-Xni00Dlk.js} +2 -2
  4. package/out/renderer/assets/{_baseUniq-CT1VRxf8.js → _baseUniq-JxZZknyU.js} +1 -1
  5. package/out/renderer/assets/{arc-BRfzIVaB.js → arc-BPRFPuHz.js} +1 -1
  6. package/out/renderer/assets/{architectureDiagram-IEHRJDOE-BE1k5yn0.js → architectureDiagram-IEHRJDOE-iKnn0iSS.js} +7 -7
  7. package/out/renderer/assets/{blockDiagram-JOT3LUYC-CKjlYfeC.js → blockDiagram-JOT3LUYC-BW-Yo0Fe.js} +5 -5
  8. package/out/renderer/assets/{c4Diagram-VJAJSXHY-DnUBXdyl.js → c4Diagram-VJAJSXHY-cTGz3ymz.js} +2 -2
  9. package/out/renderer/assets/{channel-D5pw1lrZ.js → channel-CsQk5gsI.js} +1 -1
  10. package/out/renderer/assets/{chunk-4BMEZGHF-C1IeWpO1.js → chunk-4BMEZGHF-DjpLWrPj.js} +1 -1
  11. package/out/renderer/assets/{chunk-A2AXSNBT-DItzEHfB.js → chunk-A2AXSNBT-Blza621e.js} +2 -2
  12. package/out/renderer/assets/{chunk-AEK57VVT-CPn79hs1.js → chunk-AEK57VVT-ZmlsDCZe.js} +2 -2
  13. package/out/renderer/assets/{chunk-D6G4REZN-xxtdtOvH.js → chunk-D6G4REZN-C7msyVje.js} +1 -1
  14. package/out/renderer/assets/{chunk-RZ5BOZE2-DZzd7XF-.js → chunk-RZ5BOZE2-CWvJQJJl.js} +1 -1
  15. package/out/renderer/assets/{chunk-XZIHB7SX-D47Ag_yH.js → chunk-XZIHB7SX-C-gdVJBt.js} +1 -1
  16. package/out/renderer/assets/{classDiagram-GIVACNV2-BTb1dsm_.js → classDiagram-GIVACNV2-BcRnaMRd.js} +3 -3
  17. package/out/renderer/assets/{classDiagram-v2-COTLJTTW-BTb1dsm_.js → classDiagram-v2-COTLJTTW-BcRnaMRd.js} +3 -3
  18. package/out/renderer/assets/{clone-tf2h75F9.js → clone-3XFGex6Y.js} +1 -1
  19. package/out/renderer/assets/{dagre-OKDRZEBW-uJDV0tEB.js → dagre-OKDRZEBW-BMuSMCUF.js} +6 -6
  20. package/out/renderer/assets/{diagram-SSKATNLV-BxlaHBtJ.js → diagram-SSKATNLV-BCxxN7T6.js} +6 -6
  21. package/out/renderer/assets/{diagram-VNBRO52H-CCeijHj7.js → diagram-VNBRO52H-q41sVUvc.js} +6 -6
  22. package/out/renderer/assets/{erDiagram-Q7BY3M3F-D66PtkGh.js → erDiagram-Q7BY3M3F-BFd2rLsa.js} +3 -3
  23. package/out/renderer/assets/{flowDiagram-4HSFHLVR-CjBlaiPH.js → flowDiagram-4HSFHLVR-_Arrrk_3.js} +3 -3
  24. package/out/renderer/assets/{ganttDiagram-APWFNJXF-CifvAN8h.js → ganttDiagram-APWFNJXF-Dzw68AV_.js} +1 -1
  25. package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-BC17Lxhk.js → gitGraphDiagram-7IBYFJ6S-BlkO8Bzg.js} +7 -7
  26. package/out/renderer/assets/{graph-_Hab34Nn.js → graph-DL-34vhw.js} +2 -2
  27. package/out/renderer/assets/{index-BOEHLAOZ.js → index-BDLsFoJv.js} +1 -1
  28. package/out/renderer/assets/{index-Bq43-Afm.js → index-MaDq9HTX.js} +1888 -1408
  29. package/out/renderer/assets/{index-CIm5Gpeu.js → index-vAasWWpO.js} +1 -1
  30. package/out/renderer/assets/{infoDiagram-PH2N3AL5-Dsj1auFt.js → infoDiagram-PH2N3AL5-DO4pqvW_.js} +5 -5
  31. package/out/renderer/assets/{journeyDiagram-U35MCT3I-CBWci7yb.js → journeyDiagram-U35MCT3I-BJQ-FRal.js} +3 -3
  32. package/out/renderer/assets/{kanban-definition-NDS4AKOZ-BrBwgyJQ.js → kanban-definition-NDS4AKOZ-B1zGbozL.js} +1 -1
  33. package/out/renderer/assets/{layout-BlsQazV2.js → layout-BrQGvDtH.js} +4 -4
  34. package/out/renderer/assets/{mindmap-definition-ALO5MXBD-e-VrUTAA.js → mindmap-definition-ALO5MXBD-B5SNv6RZ.js} +1 -1
  35. package/out/renderer/assets/{pieDiagram-IB7DONF6-CZvzTYvc.js → pieDiagram-IB7DONF6-DKT0Bk2S.js} +7 -7
  36. package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-CJSNfyeY.js → quadrantDiagram-7GDLP6J5-CFMDiFFE.js} +1 -1
  37. package/out/renderer/assets/{radar-MK3ICKWK-hFlyH6N6.js → radar-MK3ICKWK-DwsnroMG.js} +4 -4
  38. package/out/renderer/assets/{requirementDiagram-KVF5MWMF-BzJ8TKJn.js → requirementDiagram-KVF5MWMF-DPTaldQZ.js} +2 -2
  39. package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-C1MZHoLs.js → sankeyDiagram-QLVOVGJD-DIFNjSQ_.js} +1 -1
  40. package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-QlZcg6un.js → sequenceDiagram-X6HHIX6F-Chi1Y6mU.js} +3 -3
  41. package/out/renderer/assets/{stateDiagram-DGXRK772-lkNrTERo.js → stateDiagram-DGXRK772-DcmhTUVK.js} +7 -7
  42. package/out/renderer/assets/{stateDiagram-v2-YXO3MK2T-Cnlxf-OJ.js → stateDiagram-v2-YXO3MK2T-Dy-oRm-T.js} +3 -3
  43. package/out/renderer/assets/{timeline-definition-BDJGKUSR-ClHwwcwA.js → timeline-definition-BDJGKUSR-0y2wZWef.js} +2 -2
  44. package/out/renderer/assets/{xychartDiagram-VJFVF3MP-Jn_L_tBu.js → xychartDiagram-VJFVF3MP-Bbr5uqsp.js} +1 -1
  45. package/out/renderer/index.html +1 -1
  46. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-BOEHLAOZ.js","./fonts-DqkQ6BY5.js","./fonts-CM-VN_uu.css","./index-CIm5Gpeu.js","./pug-By0kVCfm.js","./javascript-C3MnDRiU.js","./dagre-OKDRZEBW-uJDV0tEB.js","./graph-_Hab34Nn.js","./_baseUniq-CT1VRxf8.js","./layout-BlsQazV2.js","./_basePickBy-CV2bZNyc.js","./clone-tf2h75F9.js","./c4Diagram-VJAJSXHY-DnUBXdyl.js","./chunk-D6G4REZN-xxtdtOvH.js","./flowDiagram-4HSFHLVR-CjBlaiPH.js","./chunk-RZ5BOZE2-DZzd7XF-.js","./channel-D5pw1lrZ.js","./erDiagram-Q7BY3M3F-D66PtkGh.js","./gitGraphDiagram-7IBYFJ6S-BC17Lxhk.js","./chunk-4BMEZGHF-C1IeWpO1.js","./chunk-XZIHB7SX-D47Ag_yH.js","./radar-MK3ICKWK-hFlyH6N6.js","./ganttDiagram-APWFNJXF-CifvAN8h.js","./infoDiagram-PH2N3AL5-Dsj1auFt.js","./pieDiagram-IB7DONF6-CZvzTYvc.js","./arc-BRfzIVaB.js","./quadrantDiagram-7GDLP6J5-CJSNfyeY.js","./xychartDiagram-VJFVF3MP-Jn_L_tBu.js","./requirementDiagram-KVF5MWMF-BzJ8TKJn.js","./sequenceDiagram-X6HHIX6F-QlZcg6un.js","./classDiagram-GIVACNV2-BTb1dsm_.js","./chunk-A2AXSNBT-DItzEHfB.js","./classDiagram-v2-COTLJTTW-BTb1dsm_.js","./stateDiagram-DGXRK772-lkNrTERo.js","./chunk-AEK57VVT-CPn79hs1.js","./stateDiagram-v2-YXO3MK2T-Cnlxf-OJ.js","./journeyDiagram-U35MCT3I-CBWci7yb.js","./timeline-definition-BDJGKUSR-ClHwwcwA.js","./mindmap-definition-ALO5MXBD-e-VrUTAA.js","./cytoscape.esm-C0AOj4uS.js","./kanban-definition-NDS4AKOZ-BrBwgyJQ.js","./sankeyDiagram-QLVOVGJD-C1MZHoLs.js","./diagram-VNBRO52H-CCeijHj7.js","./diagram-SSKATNLV-BxlaHBtJ.js","./blockDiagram-JOT3LUYC-CKjlYfeC.js","./architectureDiagram-IEHRJDOE-BE1k5yn0.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-BDLsFoJv.js","./fonts-DqkQ6BY5.js","./fonts-CM-VN_uu.css","./index-vAasWWpO.js","./pug-By0kVCfm.js","./javascript-C3MnDRiU.js","./dagre-OKDRZEBW-BMuSMCUF.js","./graph-DL-34vhw.js","./_baseUniq-JxZZknyU.js","./layout-BrQGvDtH.js","./_basePickBy-Xni00Dlk.js","./clone-3XFGex6Y.js","./c4Diagram-VJAJSXHY-cTGz3ymz.js","./chunk-D6G4REZN-C7msyVje.js","./flowDiagram-4HSFHLVR-_Arrrk_3.js","./chunk-RZ5BOZE2-CWvJQJJl.js","./channel-CsQk5gsI.js","./erDiagram-Q7BY3M3F-BFd2rLsa.js","./gitGraphDiagram-7IBYFJ6S-BlkO8Bzg.js","./chunk-4BMEZGHF-DjpLWrPj.js","./chunk-XZIHB7SX-C-gdVJBt.js","./radar-MK3ICKWK-DwsnroMG.js","./ganttDiagram-APWFNJXF-Dzw68AV_.js","./infoDiagram-PH2N3AL5-DO4pqvW_.js","./pieDiagram-IB7DONF6-DKT0Bk2S.js","./arc-BPRFPuHz.js","./quadrantDiagram-7GDLP6J5-CFMDiFFE.js","./xychartDiagram-VJFVF3MP-Bbr5uqsp.js","./requirementDiagram-KVF5MWMF-DPTaldQZ.js","./sequenceDiagram-X6HHIX6F-Chi1Y6mU.js","./classDiagram-GIVACNV2-BcRnaMRd.js","./chunk-A2AXSNBT-Blza621e.js","./classDiagram-v2-COTLJTTW-BcRnaMRd.js","./stateDiagram-DGXRK772-DcmhTUVK.js","./chunk-AEK57VVT-ZmlsDCZe.js","./stateDiagram-v2-YXO3MK2T-Dy-oRm-T.js","./journeyDiagram-U35MCT3I-BJQ-FRal.js","./timeline-definition-BDJGKUSR-0y2wZWef.js","./mindmap-definition-ALO5MXBD-B5SNv6RZ.js","./cytoscape.esm-C0AOj4uS.js","./kanban-definition-NDS4AKOZ-B1zGbozL.js","./sankeyDiagram-QLVOVGJD-DIFNjSQ_.js","./diagram-VNBRO52H-q41sVUvc.js","./diagram-SSKATNLV-BCxxN7T6.js","./blockDiagram-JOT3LUYC-BW-Yo0Fe.js","./architectureDiagram-IEHRJDOE-iKnn0iSS.js"])))=>i.map(i=>d[i]);
2
2
  import { i as createStyled, l as resolveProps, m as useTheme, n as useTheme$1, r as reactExports, o as React, p as useEnhancedEffect$1, q as clsx, t as useForkRef$1, v as extendSxProp, j as jsxRuntimeExports, w as handleBreakpoints, x as resolveBreakpointValues, y as createUnarySpacing, z as deepmerge, A as mergeBreakpointsInOrder, F as composeClasses$1, G as generateUtilityClass$1, I as createTheme$1, J as getValue$1, h as React$1, K as requireReactDom, g as getDefaultExportFromCjs, L as defaultTheme$2, M as THEME_ID, N as generateUtilityClasses$1, O as useDefaultProps, s as styled$1, P as capitalize$1, Q as memoTheme, _ as _inheritsLoose, S as _objectWithoutPropertiesLoose$k, U as TransitionGroupContext, V as _extends$w, W as duration, u as useTheme$2, X as useTimeout$1, Y as useId$1, Z as ButtonBase, b as alpha$1, $ as createSimplePaletteValueFilter, a0 as CircularProgress, a1 as Paper, a2 as darken$1, a3 as lighten$1, a4 as useEventCallback$1, a5 as useRtl, a6 as globalCss, a7 as formatMuiErrorMessage$1, a8 as rootShouldForwardProp, T as Typography, a9 as css$1, k as keyframes, aa as getPath$2, ab as isFocusVisible, ac as typographyClasses, ad as slotShouldForwardProp, ae as clamp$1, af as emphasize, ag as Timeout$1, c as createLucideIcon, a as Button, B as Box, ah as FontAwesomeIcon, ai as faExclamationTriangle, D as DEFAULT_THEME, aj as faChevronLeft, ak as faChevronRight, al as faRobot, am as faCheck, an as faTimes, ao as faEraser, ap as faPen, aq as faFileImport, ar as faUpload, as as GlobalStyles, at as requireReact, au as faComment, av as faSave, aw as faEdit, ax as faTrashAlt, ay as faInfoCircle, az as faGear, aA as faPlus, aB as faServer, aC as faStar, aD as faTag, aE as faIdCard, aF as faCalendarAlt, aG as faCodeBranch, aH as faShieldAlt, aI as faArrowLeft, aJ as faClock, C as Code, aK as faHome, aL as faDownload, aM as faFileAlt, aN as faDesktop, aO as faImage, aP as faMusic, aQ as faVideo, aR as faLaptop, aS as faUsers, aT as faDatabase, aU as faBoxOpen, aV as faBook, aW as faHdd, aX as faBox, aY as faArchive, aZ as faNetworkWired, a_ as faFolder, a$ as faFolderOpen, b0 as faFolderTree, b1 as faFile, b2 as faCode, b3 as faSliders, b4 as faTrash, b5 as faArrowDown, b6 as faPaperclip, b7 as faPaperPlane, b8 as faExclamationCircle, b9 as faChevronDown, ba as isDevelopmentMode, bb as faCommentSlash, bc as faArrowRight, bd as faBrain, be as faWandMagicSparkles, bf as faExternalLinkAlt, bg as faKey, bh as radientTheme, bi as faGlobe, bj as faSearch, bk as PropTypes, bl as shouldForwardProp, bm as TransitionGroup, bn as commonjsGlobal, bo as faLock, bp as faPuzzlePiece, H as HardDrive, bq as faSignOut, br as themes$1, bs as faMoon, bt as faSun, bu as faHexagonNodes, bv as faSkull, bw as faLeaf, bx as faMountain, by as faFire, bz as faIcicles, bA as faBolt, bB as faAdjust, bC as faWaveSquare, bD as faUser, bE as faEnvelope, bF as faHistory, bG as faListAlt, bH as faCreditCard, bI as faPlusCircle, bJ as faChartLine, bK as faShield, bL as library$1, bM as icons$1, f as CssBaseline, e as ThemeProvider$1, d as getTheme, R as ReactDOM$1, E as ErrorBoundary } from "./fonts-DqkQ6BY5.js";
3
3
  const styled = createStyled();
4
4
  function getThemeProps(params) {
@@ -35738,12 +35738,13 @@ const useAgents = (page = 1, perPage = 50, refetchInterval = 0, name2, sort, dir
35738
35738
  throw error;
35739
35739
  }
35740
35740
  },
35741
- // Prevent automatic refetches on window focus
35742
- refetchOnWindowFocus: true,
35741
+ // Avoid eager focus-based refetches to reduce sidebar churn.
35742
+ refetchOnWindowFocus: false,
35743
+ refetchOnMount: false,
35743
35744
  // Set refetch interval if provided
35744
35745
  refetchInterval,
35745
- // Prevent stale time to avoid unnecessary refetches
35746
- staleTime: 5e3
35746
+ placeholderData: (previousData) => previousData,
35747
+ staleTime: 30 * 1e3
35747
35748
  });
35748
35749
  };
35749
35750
  const useAgent = (agentId) => {
@@ -35777,7 +35778,10 @@ const useAgent = (agentId) => {
35777
35778
  }
35778
35779
  throw error;
35779
35780
  }
35780
- }
35781
+ },
35782
+ refetchOnWindowFocus: false,
35783
+ refetchOnMount: false,
35784
+ staleTime: 30 * 1e3
35781
35785
  });
35782
35786
  };
35783
35787
  const useCreateAgent = () => {
@@ -39220,6 +39224,28 @@ const useCheckFirstTimeUser = () => {
39220
39224
  resetOnboarding
39221
39225
  };
39222
39226
  };
39227
+ const areStringArraysEqual = (a2, b2) => {
39228
+ if (a2 === b2) return true;
39229
+ if (!a2 || !b2) return !a2 && !b2;
39230
+ if (a2.length !== b2.length) return false;
39231
+ return a2.every((value, index2) => value === b2[index2]);
39232
+ };
39233
+ const areMessagesEqual = (current, next2) => {
39234
+ const currentTimestamp = current.timestamp instanceof Date ? current.timestamp.getTime() : new Date(current.timestamp).getTime();
39235
+ const nextTimestamp = next2.timestamp instanceof Date ? next2.timestamp.getTime() : new Date(next2.timestamp).getTime();
39236
+ return current.id === next2.id && current.role === next2.role && currentTimestamp === nextTimestamp && current.message === next2.message && current.code === next2.code && current.stdout === next2.stdout && current.stderr === next2.stderr && current.logging === next2.logging && current.formatted_print === next2.formatted_print && current.status === next2.status && current.task_classification === next2.task_classification && current.action === next2.action && current.execution_type === next2.execution_type && current.is_streamable === next2.is_streamable && current.is_complete === next2.is_complete && current.conversation_id === next2.conversation_id && current.content === next2.content && current.file_path === next2.file_path && current.replacements === next2.replacements && current.agent === next2.agent && current.learnings === next2.learnings && current.thinking === next2.thinking && areStringArraysEqual(current.files, next2.files);
39237
+ };
39238
+ const getMessageTimestamp = (message2) => {
39239
+ return message2.timestamp instanceof Date ? message2.timestamp.getTime() : new Date(message2.timestamp).getTime();
39240
+ };
39241
+ const isSortedByTimestamp = (messages) => {
39242
+ for (let index2 = 1; index2 < messages.length; index2 += 1) {
39243
+ if (getMessageTimestamp(messages[index2 - 1]) > getMessageTimestamp(messages[index2])) {
39244
+ return false;
39245
+ }
39246
+ }
39247
+ return true;
39248
+ };
39223
39249
  const useChatStore = create$6((set2, get2) => ({
39224
39250
  messagesByConversation: {},
39225
39251
  paginationByConversation: {},
@@ -39234,16 +39260,22 @@ const useChatStore = create$6((set2, get2) => ({
39234
39260
  if (uniqueNewMessages.length === 0) {
39235
39261
  return state2;
39236
39262
  }
39237
- const allMessages = prepend ? [...uniqueNewMessages, ...existingMessages] : [...existingMessages, ...uniqueNewMessages];
39238
- const sortedMessages = [...allMessages].sort((a2, b2) => {
39239
- const timeA = a2.timestamp instanceof Date ? a2.timestamp.getTime() : new Date(a2.timestamp).getTime();
39240
- const timeB = b2.timestamp instanceof Date ? b2.timestamp.getTime() : new Date(b2.timestamp).getTime();
39241
- return timeA - timeB;
39242
- });
39263
+ const sortedNewMessages = isSortedByTimestamp(uniqueNewMessages) ? uniqueNewMessages : [...uniqueNewMessages].sort(
39264
+ (a2, b2) => getMessageTimestamp(a2) - getMessageTimestamp(b2)
39265
+ );
39266
+ let mergedMessages = prepend ? [...sortedNewMessages, ...existingMessages] : [...existingMessages, ...sortedNewMessages];
39267
+ const canSkipGlobalSort = existingMessages.length === 0 || (prepend ? getMessageTimestamp(
39268
+ sortedNewMessages[sortedNewMessages.length - 1]
39269
+ ) <= getMessageTimestamp(existingMessages[0]) : getMessageTimestamp(sortedNewMessages[0]) >= getMessageTimestamp(existingMessages[existingMessages.length - 1]));
39270
+ if (!canSkipGlobalSort) {
39271
+ mergedMessages = [...mergedMessages].sort(
39272
+ (a2, b2) => getMessageTimestamp(a2) - getMessageTimestamp(b2)
39273
+ );
39274
+ }
39243
39275
  return {
39244
39276
  messagesByConversation: {
39245
39277
  ...state2.messagesByConversation,
39246
- [conversationId]: sortedMessages
39278
+ [conversationId]: mergedMessages
39247
39279
  },
39248
39280
  lastUpdated: Date.now()
39249
39281
  };
@@ -39251,11 +39283,25 @@ const useChatStore = create$6((set2, get2) => ({
39251
39283
  },
39252
39284
  setMessages: (conversationId, messages) => {
39253
39285
  set2((state2) => {
39254
- const sortedMessages = [...messages].sort((a2, b2) => {
39255
- const timeA = a2.timestamp instanceof Date ? a2.timestamp.getTime() : new Date(a2.timestamp).getTime();
39256
- const timeB = b2.timestamp instanceof Date ? b2.timestamp.getTime() : new Date(b2.timestamp).getTime();
39257
- return timeA - timeB;
39258
- });
39286
+ const sortedMessages = isSortedByTimestamp(messages) ? messages : [...messages].sort(
39287
+ (a2, b2) => getMessageTimestamp(a2) - getMessageTimestamp(b2)
39288
+ );
39289
+ const existingMessages = state2.messagesByConversation[conversationId] || [];
39290
+ if (existingMessages.length === sortedMessages.length) {
39291
+ let hasChanges = false;
39292
+ for (let messageIndex = 0; messageIndex < existingMessages.length; messageIndex += 1) {
39293
+ if (!areMessagesEqual(
39294
+ existingMessages[messageIndex],
39295
+ sortedMessages[messageIndex]
39296
+ )) {
39297
+ hasChanges = true;
39298
+ break;
39299
+ }
39300
+ }
39301
+ if (!hasChanges) {
39302
+ return state2;
39303
+ }
39304
+ }
39259
39305
  return {
39260
39306
  messagesByConversation: {
39261
39307
  ...state2.messagesByConversation,
@@ -39286,6 +39332,9 @@ const useChatStore = create$6((set2, get2) => ({
39286
39332
  const existingMessages = state2.messagesByConversation[conversationId] || [];
39287
39333
  const updatedMessages = existingMessages.map((msg) => {
39288
39334
  if (msg.id === message2.id) {
39335
+ if (areMessagesEqual(msg, message2)) {
39336
+ return msg;
39337
+ }
39289
39338
  updated = true;
39290
39339
  return message2;
39291
39340
  }
@@ -39325,6 +39374,9 @@ const useChatStore = create$6((set2, get2) => ({
39325
39374
  totalPages: 1,
39326
39375
  hasMore: false
39327
39376
  };
39377
+ if (existingPagination.currentPage === page && existingPagination.totalPages === totalPages && existingPagination.hasMore === hasMore) {
39378
+ return state2;
39379
+ }
39328
39380
  return {
39329
39381
  paginationByConversation: {
39330
39382
  ...state2.paginationByConversation,
@@ -39353,6 +39405,9 @@ const useChatStore = create$6((set2, get2) => ({
39353
39405
  totalPages: 1,
39354
39406
  hasMore: false
39355
39407
  };
39408
+ if (existingPagination.scrollPosition === scrollPosition) {
39409
+ return state2;
39410
+ }
39356
39411
  return {
39357
39412
  paginationByConversation: {
39358
39413
  ...state2.paginationByConversation,
@@ -39467,6 +39522,12 @@ const useClearAgentConversation = () => {
39467
39522
  });
39468
39523
  };
39469
39524
  const conversationMessagesQueryKey = ["conversation-messages"];
39525
+ const EMPTY_MESSAGES = [];
39526
+ const DEFAULT_PAGINATION = {
39527
+ currentPage: 1,
39528
+ totalPages: 1,
39529
+ hasMore: false
39530
+ };
39470
39531
  const convertToMessage = (record, conversationId) => {
39471
39532
  const role = record.role === "user" || record.role === "human" ? "user" : "assistant";
39472
39533
  return {
@@ -39502,17 +39563,28 @@ const useConversationMessages = (conversationId, pageSize2 = 20) => {
39502
39563
  const scrollPositionBeforeLoadRef = reactExports.useRef(0);
39503
39564
  const scrollTimeoutRef = reactExports.useRef(null);
39504
39565
  const lastScrollPositionRef = reactExports.useRef(0);
39505
- const {
39506
- getMessages,
39507
- addMessages,
39508
- setMessages,
39509
- lastUpdated,
39510
- updatePagination,
39511
- getPagination,
39512
- updateScrollPosition,
39513
- getScrollPosition
39514
- } = useChatStore();
39566
+ const processedPagesRef = reactExports.useRef(/* @__PURE__ */ new Map());
39567
+ const processedConversationIdRef = reactExports.useRef(conversationId);
39568
+ const addMessages = useChatStore((state2) => state2.addMessages);
39569
+ const setMessages = useChatStore((state2) => state2.setMessages);
39570
+ const updatePagination = useChatStore((state2) => state2.updatePagination);
39571
+ const getPagination = useChatStore((state2) => state2.getPagination);
39572
+ const updateScrollPosition = useChatStore(
39573
+ (state2) => state2.updateScrollPosition
39574
+ );
39575
+ const getScrollPosition = useChatStore((state2) => state2.getScrollPosition);
39576
+ const getMessages = useChatStore((state2) => state2.getMessages);
39577
+ const messages = useChatStore(
39578
+ (state2) => conversationId ? state2.messagesByConversation[conversationId] || EMPTY_MESSAGES : EMPTY_MESSAGES
39579
+ );
39580
+ const pagination = useChatStore(
39581
+ (state2) => conversationId ? state2.paginationByConversation[conversationId] || DEFAULT_PAGINATION : DEFAULT_PAGINATION
39582
+ );
39515
39583
  const { shouldEnableQuery, getConnectivityError } = useConnectivityGate();
39584
+ const client2 = reactExports.useMemo(
39585
+ () => createLocalOperatorClient(apiConfig.baseUrl),
39586
+ []
39587
+ );
39516
39588
  const connectivityError = getConnectivityError();
39517
39589
  reactExports.useEffect(() => {
39518
39590
  if (connectivityError) {
@@ -39535,8 +39607,9 @@ const useConversationMessages = (conversationId, pageSize2 = 20) => {
39535
39607
  // Only enable the query if server is online (bypass internet check)
39536
39608
  enabled: shouldEnableQuery({ bypassInternetCheck: true }) && !!conversationId,
39537
39609
  queryKey: [...conversationMessagesQueryKey, conversationId],
39538
- // Set stale time to 0 to ensure refetch always gets fresh data
39539
- staleTime: 0,
39610
+ staleTime: 15 * 1e3,
39611
+ refetchOnWindowFocus: false,
39612
+ refetchOnMount: false,
39540
39613
  queryFn: async ({ pageParam }) => {
39541
39614
  try {
39542
39615
  if (!conversationId) {
@@ -39548,7 +39621,6 @@ const useConversationMessages = (conversationId, pageSize2 = 20) => {
39548
39621
  };
39549
39622
  }
39550
39623
  const page = pageParam;
39551
- const client2 = createLocalOperatorClient(apiConfig.baseUrl);
39552
39624
  const response = await client2.agents.getAgentExecutionHistory(
39553
39625
  conversationId,
39554
39626
  page,
@@ -39682,7 +39754,21 @@ const useConversationMessages = (conversationId, pageSize2 = 20) => {
39682
39754
  }, [conversationId]);
39683
39755
  reactExports.useEffect(() => {
39684
39756
  if (!conversationId || !data2?.pages) return;
39757
+ if (processedConversationIdRef.current !== conversationId) {
39758
+ processedPagesRef.current.clear();
39759
+ processedConversationIdRef.current = conversationId;
39760
+ }
39761
+ const processedPages = processedPagesRef.current;
39685
39762
  for (const page of data2.pages) {
39763
+ const firstMessageId = page.messages[0]?.id ?? "";
39764
+ const lastMessage = page.messages[page.messages.length - 1];
39765
+ const lastMessageId = lastMessage?.id ?? "";
39766
+ const lastMessageCompletionState = lastMessage?.is_complete ?? false;
39767
+ const signature = `${page.messages.length}:${firstMessageId}:${lastMessageId}:${lastMessageCompletionState}:${lastMessage?.message?.length ?? 0}:${lastMessage?.code?.length ?? 0}:${lastMessage?.stdout?.length ?? 0}:${lastMessage?.stderr?.length ?? 0}`;
39768
+ if (processedPages.get(page.page) === signature) {
39769
+ continue;
39770
+ }
39771
+ processedPages.set(page.page, signature);
39686
39772
  if (page.page > 1) {
39687
39773
  addMessages(conversationId, page.messages, true);
39688
39774
  } else {
@@ -39695,12 +39781,6 @@ const useConversationMessages = (conversationId, pageSize2 = 20) => {
39695
39781
  }
39696
39782
  }
39697
39783
  }, [data2, conversationId, addMessages, setMessages, getMessages]);
39698
- const messages = reactExports.useMemo(() => {
39699
- return conversationId ? getMessages(conversationId) : [];
39700
- }, [conversationId, getMessages, lastUpdated]);
39701
- const pagination = reactExports.useMemo(() => {
39702
- return conversationId ? getPagination(conversationId) : { currentPage: 1, totalPages: 1, hasMore: false };
39703
- }, [conversationId, getPagination]);
39704
39784
  return {
39705
39785
  messages,
39706
39786
  isLoading,
@@ -39908,6 +39988,13 @@ const useInitializeModels = () => {
39908
39988
  refreshModels
39909
39989
  };
39910
39990
  };
39991
+ const HISTORY_SYNC_INTERVAL_MS = 3e3;
39992
+ const hasMeaningfulMessageChanges = (existing, next2) => {
39993
+ if (!existing) return true;
39994
+ const existingTimestamp = existing.timestamp instanceof Date ? existing.timestamp.getTime() : new Date(existing.timestamp).getTime();
39995
+ const nextTimestamp = next2.timestamp instanceof Date ? next2.timestamp.getTime() : new Date(next2.timestamp).getTime();
39996
+ return existingTimestamp !== nextTimestamp || existing.message !== next2.message || existing.code !== next2.code || existing.stdout !== next2.stdout || existing.stderr !== next2.stderr || existing.logging !== next2.logging || existing.status !== next2.status || existing.action !== next2.action || existing.execution_type !== next2.execution_type || existing.task_classification !== next2.task_classification || existing.is_complete !== next2.is_complete || existing.is_streamable !== next2.is_streamable || existing.content !== next2.content || existing.file_path !== next2.file_path || existing.replacements !== next2.replacements || existing.agent !== next2.agent || existing.learnings !== next2.learnings || existing.thinking !== next2.thinking;
39997
+ };
39911
39998
  const useJobPolling = ({
39912
39999
  conversationId,
39913
40000
  addMessage
@@ -39922,10 +40009,15 @@ const useJobPolling = ({
39922
40009
  }
39923
40010
  }, []);
39924
40011
  const queryClient2 = useQueryClient();
39925
- const { getMessages, setMessages } = useChatStore();
40012
+ const getMessages = useChatStore((state2) => state2.getMessages);
40013
+ const setMessages = useChatStore((state2) => state2.setMessages);
39926
40014
  const lastProcessedJobDataRef = reactExports.useRef(null);
39927
- const client2 = createLocalOperatorClient(apiConfig.baseUrl);
39928
- const previousConversationIdRef = reactExports.useRef(conversationId);
40015
+ const client2 = reactExports.useMemo(
40016
+ () => createLocalOperatorClient(apiConfig.baseUrl),
40017
+ []
40018
+ );
40019
+ const previousConversationIdRef = reactExports.useRef(void 0);
40020
+ const lastHistorySyncAtRef = reactExports.useRef(0);
39929
40021
  const { shouldEnableQuery, getConnectivityError } = useConnectivityGate();
39930
40022
  const checkForActiveJobs = reactExports.useCallback(
39931
40023
  async (agentId) => {
@@ -39941,11 +40033,10 @@ const useJobPolling = ({
39941
40033
  return false;
39942
40034
  }
39943
40035
  try {
39944
- const pendingResponse = await client2.jobs.listJobs(agentId, "pending");
39945
- const processingResponse = await client2.jobs.listJobs(
39946
- agentId,
39947
- "processing"
39948
- );
40036
+ const [pendingResponse, processingResponse] = await Promise.all([
40037
+ client2.jobs.listJobs(agentId, "pending"),
40038
+ client2.jobs.listJobs(agentId, "processing")
40039
+ ]);
39949
40040
  const pendingJobs = pendingResponse.result?.jobs || [];
39950
40041
  const processingJobs = processingResponse.result?.jobs || [];
39951
40042
  const activeJobs = [...pendingJobs, ...processingJobs];
@@ -39957,10 +40048,11 @@ const useJobPolling = ({
39957
40048
  })[0];
39958
40049
  if (mostRecentJob.id !== currentJobId) {
39959
40050
  setCurrentJobId(mostRecentJob.id);
39960
- setIsLoading(true);
39961
40051
  }
40052
+ setIsLoading(true);
39962
40053
  return true;
39963
40054
  }
40055
+ setIsLoading(false);
39964
40056
  return false;
39965
40057
  } catch (error2) {
39966
40058
  console.error("Error checking for active jobs:", error2);
@@ -39976,57 +40068,18 @@ const useJobPolling = ({
39976
40068
  ]
39977
40069
  );
39978
40070
  reactExports.useEffect(() => {
39979
- if (conversationId !== previousConversationIdRef.current) {
39980
- setIsLoading(false);
39981
- setCurrentJobId(null);
39982
- if (conversationId) {
39983
- const checkNewAgentJobs = async () => {
39984
- if (!shouldEnableQuery({ bypassInternetCheck: true })) {
39985
- const error2 = getConnectivityError();
39986
- if (error2) {
39987
- console.error(
39988
- "Cannot check for active jobs due to connectivity issue:",
39989
- error2.message
39990
- );
39991
- }
39992
- return;
39993
- }
39994
- try {
39995
- const pendingResponse = await client2.jobs.listJobs(
39996
- conversationId,
39997
- "pending"
39998
- );
39999
- const processingResponse = await client2.jobs.listJobs(
40000
- conversationId,
40001
- "processing"
40002
- );
40003
- const pendingJobs = pendingResponse.result?.jobs || [];
40004
- const processingJobs = processingResponse.result?.jobs || [];
40005
- const activeJobs = [...pendingJobs, ...processingJobs];
40006
- if (activeJobs.length > 0) {
40007
- const mostRecentJob = activeJobs.sort((a2, b2) => {
40008
- const dateA = new Date(a2.created_at || 0);
40009
- const dateB = new Date(b2.created_at || 0);
40010
- return dateB.getTime() - dateA.getTime();
40011
- })[0];
40012
- setCurrentJobId(mostRecentJob.id);
40013
- setIsLoading(true);
40014
- }
40015
- } catch (error2) {
40016
- console.error("Error checking for active jobs:", error2);
40017
- }
40018
- };
40019
- checkNewAgentJobs();
40020
- }
40071
+ if (conversationId === previousConversationIdRef.current) {
40072
+ return;
40021
40073
  }
40022
40074
  previousConversationIdRef.current = conversationId;
40023
- }, [
40024
- conversationId,
40025
- client2.jobs,
40026
- shouldEnableQuery,
40027
- getConnectivityError,
40028
- setCurrentJobId
40029
- ]);
40075
+ lastProcessedJobDataRef.current = null;
40076
+ lastHistorySyncAtRef.current = 0;
40077
+ setIsLoading(false);
40078
+ setCurrentJobId(null);
40079
+ if (conversationId) {
40080
+ void checkForActiveJobs(conversationId);
40081
+ }
40082
+ }, [conversationId, checkForActiveJobs, setCurrentJobId]);
40030
40083
  const updateConversationMessages = reactExports.useCallback(
40031
40084
  async (agentId) => {
40032
40085
  if (!agentId) return;
@@ -40041,8 +40094,7 @@ const useJobPolling = ({
40041
40094
  return false;
40042
40095
  }
40043
40096
  try {
40044
- const client22 = createLocalOperatorClient(apiConfig.baseUrl);
40045
- const response = await client22.agents.getAgentExecutionHistory(
40097
+ const response = await client2.agents.getAgentExecutionHistory(
40046
40098
  agentId,
40047
40099
  1,
40048
40100
  // First page
@@ -40056,20 +40108,20 @@ const useJobPolling = ({
40056
40108
  }
40057
40109
  const executionRecords = response.result.history || [];
40058
40110
  const existingMessages = getMessages(agentId);
40059
- const apiMessages = executionRecords.map((record) => {
40060
- return convertToMessage(record, agentId);
40061
- });
40062
- const existingIds = new Set(existingMessages.map((m2) => m2.id));
40063
- const newMessages = apiMessages.filter((m2) => !existingIds.has(m2.id));
40064
- if (newMessages.length > 0) {
40065
- const updatedMessages = [...existingMessages, ...newMessages];
40066
- setMessages(agentId, updatedMessages);
40067
- queryClient2.invalidateQueries({
40068
- queryKey: [...conversationMessagesQueryKey, agentId]
40069
- });
40070
- queryClient2.invalidateQueries({
40071
- queryKey: agentsQueryKey
40072
- });
40111
+ const apiMessages = executionRecords.map(
40112
+ (record) => convertToMessage(record, agentId)
40113
+ );
40114
+ const existingById = new Map(existingMessages.map((m2) => [m2.id, m2]));
40115
+ let hasChanges = false;
40116
+ for (const apiMessage of apiMessages) {
40117
+ const existingMessage = existingById.get(apiMessage.id);
40118
+ if (hasMeaningfulMessageChanges(existingMessage, apiMessage)) {
40119
+ existingById.set(apiMessage.id, apiMessage);
40120
+ hasChanges = true;
40121
+ }
40122
+ }
40123
+ if (hasChanges) {
40124
+ setMessages(agentId, Array.from(existingById.values()));
40073
40125
  }
40074
40126
  return true;
40075
40127
  } catch (error2) {
@@ -40077,13 +40129,7 @@ const useJobPolling = ({
40077
40129
  return false;
40078
40130
  }
40079
40131
  },
40080
- [
40081
- getMessages,
40082
- setMessages,
40083
- queryClient2,
40084
- shouldEnableQuery,
40085
- getConnectivityError
40086
- ]
40132
+ [getMessages, setMessages, shouldEnableQuery, getConnectivityError, client2]
40087
40133
  );
40088
40134
  const handleJobCompletion = reactExports.useCallback(
40089
40135
  async (job) => {
@@ -40117,7 +40163,13 @@ const useJobPolling = ({
40117
40163
  setCurrentJobId(null);
40118
40164
  setIsLoading(false);
40119
40165
  },
40120
- [conversationId, addMessage, updateConversationMessages, setCurrentJobId]
40166
+ [
40167
+ conversationId,
40168
+ addMessage,
40169
+ updateConversationMessages,
40170
+ setCurrentJobId,
40171
+ queryClient2
40172
+ ]
40121
40173
  );
40122
40174
  const {
40123
40175
  data: jobData,
@@ -40142,10 +40194,10 @@ const useJobPolling = ({
40142
40194
  enabled: shouldEnableQuery({ bypassInternetCheck: true }) && !!currentJobId,
40143
40195
  refetchInterval: currentJobId ? 1e3 : false,
40144
40196
  refetchIntervalInBackground: false,
40145
- refetchOnWindowFocus: true,
40146
- gcTime: 0,
40147
- staleTime: 0,
40148
- retry: true,
40197
+ refetchOnWindowFocus: false,
40198
+ gcTime: 60 * 1e3,
40199
+ staleTime: 500,
40200
+ retry: 1,
40149
40201
  retryDelay: 1e3
40150
40202
  });
40151
40203
  function isJobDetails(data2) {
@@ -40171,13 +40223,15 @@ const useJobPolling = ({
40171
40223
  setCurrentExecution(jobData.current_execution);
40172
40224
  }
40173
40225
  if (jobData.status === "processing") {
40174
- const debounceTimeout = setTimeout(() => {
40175
- updateConversationMessages(conversationId);
40176
- }, 500);
40177
- return () => clearTimeout(debounceTimeout);
40226
+ const now2 = Date.now();
40227
+ if (now2 - lastHistorySyncAtRef.current >= HISTORY_SYNC_INTERVAL_MS) {
40228
+ lastHistorySyncAtRef.current = now2;
40229
+ void updateConversationMessages(conversationId);
40230
+ }
40178
40231
  }
40179
40232
  if (jobData.status === "completed" || jobData.status === "failed") {
40180
- handleJobCompletion(jobData);
40233
+ lastHistorySyncAtRef.current = 0;
40234
+ void handleJobCompletion(jobData);
40181
40235
  setCurrentExecution(null);
40182
40236
  }
40183
40237
  }
@@ -40194,11 +40248,8 @@ const useJobPolling = ({
40194
40248
  reactExports.useEffect(() => {
40195
40249
  if (error) {
40196
40250
  console.error("Error polling job status:", error);
40197
- if (currentJobId) {
40198
- queryClient2.invalidateQueries({ queryKey: ["job", currentJobId] });
40199
- }
40200
40251
  }
40201
- }, [error, currentJobId, queryClient2]);
40252
+ }, [error]);
40202
40253
  const validJobStatuses = [
40203
40254
  "pending",
40204
40255
  "processing",
@@ -42279,40 +42330,94 @@ const useScrollToBottom = (buttonThreshold = 50, externalContainerRef, contentKe
42279
42330
  scrollToBottom
42280
42331
  };
42281
42332
  };
42333
+ const STREAMING_MESSAGE_MAX_AGE_MS = 15 * 60 * 1e3;
42334
+ const STREAMING_MESSAGE_MAX_ENTRIES = 250;
42335
+ const hasMeaningfulStreamingChange = (previous2, next2) => {
42336
+ if (!previous2) return true;
42337
+ return previous2.is_complete !== next2.is_complete || previous2.is_streamable !== next2.is_streamable || previous2.message !== next2.message || previous2.code !== next2.code || previous2.stdout !== next2.stdout || previous2.stderr !== next2.stderr || previous2.logging !== next2.logging || previous2.content !== next2.content || previous2.replacements !== next2.replacements || previous2.action !== next2.action || previous2.execution_type !== next2.execution_type;
42338
+ };
42339
+ const pruneMessages = (streamingMessages, now2) => {
42340
+ const entries2 = Object.entries(streamingMessages);
42341
+ const activeEntries = entries2.filter(
42342
+ ([_2, value]) => !value.isComplete || now2 - value.lastUpdated < STREAMING_MESSAGE_MAX_AGE_MS
42343
+ );
42344
+ if (activeEntries.length <= STREAMING_MESSAGE_MAX_ENTRIES) {
42345
+ return Object.fromEntries(activeEntries);
42346
+ }
42347
+ const sorted = [...activeEntries].sort(
42348
+ (a2, b2) => b2[1].lastUpdated - a2[1].lastUpdated
42349
+ );
42350
+ return Object.fromEntries(sorted.slice(0, STREAMING_MESSAGE_MAX_ENTRIES));
42351
+ };
42282
42352
  const useStreamingMessagesStore = create$6(
42283
42353
  (set2, get2) => ({
42284
42354
  streamingMessages: {},
42285
42355
  updateStreamingMessage: (messageId, content2) => {
42286
42356
  set2((state2) => {
42357
+ const now2 = Date.now();
42287
42358
  const existingState = state2.streamingMessages[messageId] || {
42288
42359
  content: null,
42289
42360
  isComplete: false,
42290
- lastUpdated: Date.now()
42361
+ lastUpdated: now2
42291
42362
  };
42292
- return {
42293
- streamingMessages: {
42294
- ...state2.streamingMessages,
42295
- [messageId]: {
42296
- ...existingState,
42297
- content: content2,
42298
- lastUpdated: Date.now()
42299
- }
42363
+ if (!existingState.isComplete && !hasMeaningfulStreamingChange(existingState.content, content2)) {
42364
+ return state2;
42365
+ }
42366
+ const nextMessages = {
42367
+ ...state2.streamingMessages,
42368
+ [messageId]: {
42369
+ ...existingState,
42370
+ content: content2,
42371
+ lastUpdated: now2
42300
42372
  }
42301
42373
  };
42374
+ return {
42375
+ streamingMessages: pruneMessages(nextMessages, now2)
42376
+ };
42302
42377
  });
42303
42378
  },
42304
42379
  completeStreamingMessage: (messageId, content2) => {
42305
42380
  set2((state2) => {
42306
- return {
42307
- streamingMessages: {
42308
- ...state2.streamingMessages,
42309
- [messageId]: {
42310
- content: content2,
42311
- isComplete: true,
42312
- lastUpdated: Date.now()
42313
- }
42381
+ const now2 = Date.now();
42382
+ const existingState = state2.streamingMessages[messageId];
42383
+ if (existingState?.isComplete && !hasMeaningfulStreamingChange(existingState.content, content2)) {
42384
+ return state2;
42385
+ }
42386
+ const nextMessages = {
42387
+ ...state2.streamingMessages,
42388
+ [messageId]: {
42389
+ content: content2,
42390
+ isComplete: true,
42391
+ lastUpdated: now2
42314
42392
  }
42315
42393
  };
42394
+ return {
42395
+ streamingMessages: pruneMessages(nextMessages, now2)
42396
+ };
42397
+ });
42398
+ },
42399
+ removeStreamingMessage: (messageId) => {
42400
+ set2((state2) => {
42401
+ if (!state2.streamingMessages[messageId]) {
42402
+ return state2;
42403
+ }
42404
+ const remainingMessages = { ...state2.streamingMessages };
42405
+ delete remainingMessages[messageId];
42406
+ return {
42407
+ streamingMessages: remainingMessages
42408
+ };
42409
+ });
42410
+ },
42411
+ pruneStreamingMessages: () => {
42412
+ set2((state2) => {
42413
+ const now2 = Date.now();
42414
+ const prunedMessages = pruneMessages(state2.streamingMessages, now2);
42415
+ if (Object.keys(prunedMessages).length === Object.keys(state2.streamingMessages).length) {
42416
+ return state2;
42417
+ }
42418
+ return {
42419
+ streamingMessages: prunedMessages
42420
+ };
42316
42421
  });
42317
42422
  },
42318
42423
  getStreamingMessage: (messageId) => {
@@ -42328,6 +42433,7 @@ const useStreamingMessagesStore = create$6(
42328
42433
  }
42329
42434
  })
42330
42435
  );
42436
+ const autoConnectLocks = /* @__PURE__ */ new Set();
42331
42437
  const useWebSocketMessage = (options) => {
42332
42438
  const {
42333
42439
  baseUrl,
@@ -42348,147 +42454,134 @@ const useWebSocketMessage = (options) => {
42348
42454
  const [error, setError] = reactExports.useState(null);
42349
42455
  const [isLoading, setIsLoading] = reactExports.useState(false);
42350
42456
  const clientRef = reactExports.useRef(null);
42351
- const cleanupRef = reactExports.useRef(null);
42352
- const connectRef = reactExports.useRef(null);
42353
- const messageRef = reactExports.useRef(null);
42457
+ const callbackRefs = reactExports.useRef({
42458
+ onUpdate,
42459
+ onStatusChange,
42460
+ onError
42461
+ });
42354
42462
  reactExports.useEffect(() => {
42355
- messageRef.current = message2;
42356
- }, [message2]);
42357
- const connect = reactExports.useCallback(async () => {
42358
- if (!messageId || !baseUrl) {
42359
- return Promise.reject(new Error("Missing messageId or baseUrl"));
42463
+ callbackRefs.current = {
42464
+ onUpdate,
42465
+ onStatusChange,
42466
+ onError
42467
+ };
42468
+ }, [onUpdate, onStatusChange, onError]);
42469
+ const detachClient = reactExports.useCallback(() => {
42470
+ if (!clientRef.current) {
42471
+ return;
42360
42472
  }
42361
- try {
42362
- setIsLoading(true);
42363
- setError(null);
42364
- if (!clientRef.current) {
42365
- clientRef.current = new WebSocketClient(
42366
- baseUrl,
42367
- messageId,
42368
- {
42369
- autoReconnect,
42370
- reconnectInterval,
42371
- maxReconnectAttempts,
42372
- pingInterval,
42373
- messageDelay: 350
42374
- },
42375
- WebsocketConnectionType.MESSAGE
42376
- );
42377
- clientRef.current.on("status", (newStatus) => {
42378
- const typedStatus = newStatus;
42379
- setStatus(typedStatus);
42380
- onStatusChange?.(typedStatus);
42381
- });
42382
- clientRef.current.on(`update:${messageId}`, (update) => {
42383
- const typedUpdate = update;
42384
- setMessage((prevMessage) => {
42385
- const updatedMessage = !prevMessage ? typedUpdate : {
42386
- ...prevMessage,
42387
- ...typedUpdate
42388
- };
42389
- return updatedMessage;
42390
- });
42391
- const isMessageComplete = typedUpdate.is_complete || false;
42392
- const isMessageStreamable = typedUpdate.is_streamable || false;
42393
- if (isMessageComplete) {
42394
- setIsComplete(true);
42395
- }
42396
- if (isMessageStreamable) {
42397
- setIsStreamable(true);
42398
- }
42399
- onUpdate?.(typedUpdate);
42400
- });
42401
- clientRef.current.on("error", (wsError) => {
42402
- let typedError;
42403
- if (wsError instanceof Error) {
42404
- typedError = wsError;
42405
- } else if (typeof wsError === "string") {
42406
- typedError = new Error(wsError);
42407
- } else {
42408
- typedError = new Error(`WebSocket error for ${messageId}`);
42409
- }
42410
- console.error(`WebSocket error for ${messageId}:`, typedError);
42411
- setError(typedError);
42412
- onError?.(typedError);
42413
- });
42414
- cleanupRef.current = () => {
42415
- if (clientRef.current) {
42416
- clientRef.current.disconnect();
42417
- clientRef.current = null;
42418
- }
42473
+ clientRef.current.removeAllListeners();
42474
+ clientRef.current.disconnect();
42475
+ clientRef.current = null;
42476
+ }, []);
42477
+ const createClient = reactExports.useCallback(() => {
42478
+ if (clientRef.current) {
42479
+ return clientRef.current;
42480
+ }
42481
+ const client2 = new WebSocketClient(
42482
+ baseUrl,
42483
+ messageId,
42484
+ {
42485
+ autoReconnect,
42486
+ reconnectInterval,
42487
+ maxReconnectAttempts,
42488
+ pingInterval,
42489
+ messageDelay: 250
42490
+ },
42491
+ WebsocketConnectionType.MESSAGE
42492
+ );
42493
+ client2.on("status", (newStatus) => {
42494
+ const typedStatus = newStatus;
42495
+ setStatus(typedStatus);
42496
+ callbackRefs.current.onStatusChange?.(typedStatus);
42497
+ });
42498
+ client2.on(`update:${messageId}`, (update) => {
42499
+ const typedUpdate = update;
42500
+ setMessage((previous2) => {
42501
+ if (!previous2) {
42502
+ return typedUpdate;
42503
+ }
42504
+ return {
42505
+ ...previous2,
42506
+ ...typedUpdate
42419
42507
  };
42508
+ });
42509
+ if (typeof typedUpdate.is_complete === "boolean") {
42510
+ setIsComplete(typedUpdate.is_complete);
42420
42511
  }
42421
- await clientRef.current.connect();
42422
- setIsLoading(false);
42423
- return Promise.resolve();
42424
- } catch (err) {
42425
- const formattedError = err instanceof Error ? err : new Error(String(err));
42426
- console.error(
42427
- `Error connecting to WebSocket for ${messageId}:`,
42428
- formattedError
42512
+ if (typeof typedUpdate.is_streamable === "boolean") {
42513
+ setIsStreamable(typedUpdate.is_streamable);
42514
+ }
42515
+ callbackRefs.current.onUpdate?.(typedUpdate);
42516
+ });
42517
+ client2.on("error", (wsError) => {
42518
+ const typedError = wsError instanceof Error ? wsError : new Error(
42519
+ typeof wsError === "string" ? wsError : `WebSocket error for ${messageId}`
42429
42520
  );
42430
- setError(formattedError);
42431
- setIsLoading(false);
42432
- onError?.(formattedError);
42433
- return Promise.reject(formattedError);
42434
- }
42521
+ setError(typedError);
42522
+ callbackRefs.current.onError?.(typedError);
42523
+ });
42524
+ clientRef.current = client2;
42525
+ return client2;
42435
42526
  }, [
42436
- messageId,
42437
42527
  baseUrl,
42528
+ messageId,
42438
42529
  autoReconnect,
42439
42530
  reconnectInterval,
42440
42531
  maxReconnectAttempts,
42441
- pingInterval,
42442
- onUpdate,
42443
- onStatusChange,
42444
- onError
42532
+ pingInterval
42445
42533
  ]);
42446
- reactExports.useEffect(() => {
42447
- connectRef.current = connect;
42448
- }, [connect]);
42449
- const globalClientsRef = reactExports.useRef({});
42450
- reactExports.useEffect(() => {
42451
- if (autoConnect && messageId && baseUrl && connectRef.current && !clientRef.current && !globalClientsRef.current[messageId]) {
42452
- const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
42453
- globalClientsRef.current[messageId] = true;
42454
- setTimeout(() => {
42455
- if (connectRef.current) {
42456
- connectRef.current().catch((err) => {
42457
- console.warn(
42458
- `[${timestamp2}] Error auto-connecting WebSocket for ${messageId}:`,
42459
- err
42460
- );
42461
- globalClientsRef.current[messageId] = false;
42462
- });
42463
- }
42464
- }, 500);
42534
+ const connect = reactExports.useCallback(async () => {
42535
+ if (!messageId || !baseUrl) {
42536
+ throw new Error("Missing messageId or baseUrl");
42465
42537
  }
42466
- }, [autoConnect, messageId, baseUrl]);
42467
- const disconnect = reactExports.useCallback(() => {
42468
- if (clientRef.current) {
42469
- clientRef.current.disconnect();
42470
- clientRef.current = null;
42538
+ setError(null);
42539
+ setIsLoading(true);
42540
+ const client2 = createClient();
42541
+ const currentStatus = client2.getStatus();
42542
+ if (currentStatus === "connected" || currentStatus === "connecting" || currentStatus === "reconnecting") {
42543
+ setIsLoading(false);
42544
+ return;
42471
42545
  }
42546
+ try {
42547
+ await client2.connect();
42548
+ } catch (connectError) {
42549
+ const formattedError = connectError instanceof Error ? connectError : new Error(String(connectError));
42550
+ setError(formattedError);
42551
+ callbackRefs.current.onError?.(formattedError);
42552
+ throw formattedError;
42553
+ } finally {
42554
+ setIsLoading(false);
42555
+ }
42556
+ }, [messageId, baseUrl, createClient]);
42557
+ const disconnect = reactExports.useCallback(() => {
42558
+ detachClient();
42472
42559
  setStatus("disconnected");
42473
- }, []);
42560
+ setIsLoading(false);
42561
+ }, [detachClient]);
42562
+ reactExports.useEffect(() => {
42563
+ if (!autoConnect || !messageId || !baseUrl) {
42564
+ return;
42565
+ }
42566
+ if (autoConnectLocks.has(messageId)) {
42567
+ return;
42568
+ }
42569
+ autoConnectLocks.add(messageId);
42570
+ void connect().catch((connectError) => {
42571
+ console.warn(
42572
+ `Error auto-connecting WebSocket for ${messageId}:`,
42573
+ connectError
42574
+ );
42575
+ }).finally(() => {
42576
+ autoConnectLocks.delete(messageId);
42577
+ });
42578
+ }, [autoConnect, messageId, baseUrl, connect]);
42474
42579
  reactExports.useEffect(() => {
42475
- const currentCleanup = cleanupRef.current;
42476
- const currentMessageId = messageId;
42477
42580
  return () => {
42478
- setTimeout(() => {
42479
- if (currentCleanup) {
42480
- const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
42481
- console.log(
42482
- `[${timestamp2}] Running delayed cleanup for WebSocket ${currentMessageId}`
42483
- );
42484
- if (globalClientsRef.current[currentMessageId]) {
42485
- globalClientsRef.current[currentMessageId] = false;
42486
- }
42487
- currentCleanup();
42488
- }
42489
- }, 200);
42581
+ autoConnectLocks.delete(messageId);
42582
+ disconnect();
42490
42583
  };
42491
- }, [messageId]);
42584
+ }, [messageId, disconnect]);
42492
42585
  reactExports.useEffect(() => {
42493
42586
  setIsLoading(status === "connecting" || status === "reconnecting");
42494
42587
  }, [status]);
@@ -42503,7 +42596,33 @@ const useWebSocketMessage = (options) => {
42503
42596
  error
42504
42597
  };
42505
42598
  };
42599
+ const CONNECTION_THROTTLE_MS = 1500;
42600
+ const CHAT_STORE_FLUSH_MS = 80;
42601
+ const COMPLETE_REFETCH_DELAY_MS = 180;
42506
42602
  const globalConnectionRegistry = /* @__PURE__ */ new Map();
42603
+ const ensureRegistryEntry = (messageId, keepAlive, conversationId) => {
42604
+ const existing = globalConnectionRegistry.get(messageId);
42605
+ if (existing) {
42606
+ existing.keepAlive = keepAlive;
42607
+ if (conversationId) {
42608
+ existing.conversationId = conversationId;
42609
+ }
42610
+ return existing;
42611
+ }
42612
+ const created = {
42613
+ connected: false,
42614
+ connecting: false,
42615
+ connectionPromise: null,
42616
+ keepAlive,
42617
+ instanceCount: 0,
42618
+ messageData: null,
42619
+ isComplete: false,
42620
+ isStreamable: false,
42621
+ conversationId
42622
+ };
42623
+ globalConnectionRegistry.set(messageId, created);
42624
+ return created;
42625
+ };
42507
42626
  const useStreamingMessage = ({
42508
42627
  messageId,
42509
42628
  autoConnect = true,
@@ -42515,16 +42634,61 @@ const useStreamingMessage = ({
42515
42634
  refetchOnComplete = true
42516
42635
  }) => {
42517
42636
  const mountedRef = reactExports.useRef(false);
42637
+ const isRegisteredInstanceRef = reactExports.useRef(false);
42518
42638
  const lastConnectionAttemptRef = reactExports.useRef(0);
42519
- const CONNECTION_THROTTLE_MS = 2e3;
42639
+ const completionNotifiedRef = reactExports.useRef(null);
42640
+ const wsCompletionHandledRef = reactExports.useRef(false);
42641
+ const refetchTimeoutRef = reactExports.useRef(null);
42642
+ const chatStoreFlushTimeoutRef = reactExports.useRef(null);
42643
+ const pendingChatUpdateRef = reactExports.useRef(null);
42520
42644
  const [isRefetching, setIsRefetching] = reactExports.useState(false);
42521
- const {
42522
- updateStreamingMessage,
42523
- completeStreamingMessage,
42524
- isMessageStreamingComplete
42525
- } = useStreamingMessagesStore();
42526
- const isStoreMessageComplete = isMessageStreamingComplete(messageId);
42527
- const { addMessage, updateMessage } = useChatStore();
42645
+ const updateStreamingMessage = useStreamingMessagesStore(
42646
+ (state2) => state2.updateStreamingMessage
42647
+ );
42648
+ const completeStreamingMessage = useStreamingMessagesStore(
42649
+ (state2) => state2.completeStreamingMessage
42650
+ );
42651
+ const pruneStreamingMessages = useStreamingMessagesStore(
42652
+ (state2) => state2.pruneStreamingMessages
42653
+ );
42654
+ const isStoreMessageComplete = useStreamingMessagesStore(
42655
+ (state2) => state2.streamingMessages[messageId]?.isComplete ?? false
42656
+ );
42657
+ const addMessage = useChatStore((state2) => state2.addMessage);
42658
+ const updateMessage = useChatStore((state2) => state2.updateMessage);
42659
+ const pushMessageToChatStore = reactExports.useCallback(
42660
+ (messageData) => {
42661
+ if (!conversationId || !messageData.id) {
42662
+ return;
42663
+ }
42664
+ const messageForStore = convertToMessage(messageData, conversationId);
42665
+ const updated = updateMessage(conversationId, messageForStore);
42666
+ if (!updated) {
42667
+ addMessage(conversationId, messageForStore);
42668
+ }
42669
+ },
42670
+ [conversationId, updateMessage, addMessage]
42671
+ );
42672
+ const flushPendingChatUpdate = reactExports.useCallback(() => {
42673
+ if (!pendingChatUpdateRef.current) {
42674
+ return;
42675
+ }
42676
+ pushMessageToChatStore(pendingChatUpdateRef.current);
42677
+ pendingChatUpdateRef.current = null;
42678
+ }, [pushMessageToChatStore]);
42679
+ const notifyCompleteOnce = reactExports.useCallback(
42680
+ (messageData) => {
42681
+ if (!onComplete || !mountedRef.current) {
42682
+ return;
42683
+ }
42684
+ if (completionNotifiedRef.current === messageId) {
42685
+ return;
42686
+ }
42687
+ completionNotifiedRef.current = messageId;
42688
+ onComplete(messageData);
42689
+ },
42690
+ [onComplete, messageId]
42691
+ );
42528
42692
  const refetchMessage = reactExports.useCallback(async () => {
42529
42693
  if (!messageId) {
42530
42694
  return;
@@ -42540,7 +42704,7 @@ const useStreamingMessage = ({
42540
42704
  const response = await client2.agents.getAgentExecutionHistory(
42541
42705
  agentId,
42542
42706
  1,
42543
- 20
42707
+ 30
42544
42708
  );
42545
42709
  if (response.status >= 400 || !response.result) {
42546
42710
  throw new Error(response.message || "Failed to fetch message data");
@@ -42548,40 +42712,20 @@ const useStreamingMessage = ({
42548
42712
  const messageData = response.result.history.find(
42549
42713
  (record) => record.id === messageId
42550
42714
  );
42551
- if (!messageData) {
42552
- if (registryEntry?.messageData && registryEntry.isComplete) {
42553
- completeStreamingMessage(messageId, registryEntry.messageData);
42554
- if (conversationId) {
42555
- const messageForStore = convertToMessage(
42556
- registryEntry.messageData,
42557
- conversationId
42558
- );
42559
- const updated = updateMessage(conversationId, messageForStore);
42560
- if (!updated) {
42561
- addMessage(conversationId, messageForStore);
42562
- }
42563
- }
42564
- if (onComplete && mountedRef.current) {
42565
- onComplete(registryEntry.messageData);
42566
- }
42567
- }
42715
+ if (messageData) {
42716
+ completeStreamingMessage(messageId, messageData);
42717
+ const entry = ensureRegistryEntry(messageId, keepAlive, conversationId);
42718
+ entry.messageData = messageData;
42719
+ entry.isComplete = true;
42720
+ entry.isStreamable = !!messageData.is_streamable;
42721
+ pushMessageToChatStore(messageData);
42722
+ notifyCompleteOnce(messageData);
42568
42723
  return;
42569
42724
  }
42570
- completeStreamingMessage(messageId, messageData);
42571
- if (registryEntry) {
42572
- registryEntry.messageData = messageData;
42573
- registryEntry.isComplete = true;
42574
- registryEntry.isStreamable = !!messageData.is_streamable;
42575
- }
42576
- if (conversationId) {
42577
- const messageForStore = convertToMessage(messageData, conversationId);
42578
- const updated = updateMessage(conversationId, messageForStore);
42579
- if (!updated) {
42580
- addMessage(conversationId, messageForStore);
42581
- }
42582
- }
42583
- if (onComplete && mountedRef.current) {
42584
- onComplete(messageData);
42725
+ if (registryEntry?.messageData && registryEntry.isComplete) {
42726
+ completeStreamingMessage(messageId, registryEntry.messageData);
42727
+ pushMessageToChatStore(registryEntry.messageData);
42728
+ notifyCompleteOnce(registryEntry.messageData);
42585
42729
  }
42586
42730
  } catch (error2) {
42587
42731
  const errorMessage = error2 instanceof Error ? error2.message : String(error2);
@@ -42592,95 +42736,23 @@ const useStreamingMessage = ({
42592
42736
  }, [
42593
42737
  messageId,
42594
42738
  baseUrl,
42595
- completeStreamingMessage,
42596
42739
  conversationId,
42597
- addMessage,
42598
- updateMessage,
42599
- onComplete
42740
+ completeStreamingMessage,
42741
+ pushMessageToChatStore,
42742
+ keepAlive,
42743
+ notifyCompleteOnce
42600
42744
  ]);
42601
- const handleUpdate = reactExports.useCallback(
42602
- (update) => {
42603
- if (onUpdate && mountedRef.current) {
42604
- onUpdate(update);
42605
- }
42606
- const registryEntry = globalConnectionRegistry.get(messageId);
42607
- if (registryEntry) {
42608
- registryEntry.messageData = {
42609
- ...registryEntry.messageData,
42610
- ...update
42611
- };
42612
- if (update.is_complete) {
42613
- registryEntry.isComplete = true;
42614
- }
42615
- if (update.is_streamable) {
42616
- registryEntry.isStreamable = true;
42617
- }
42618
- }
42619
- const messageData = {
42620
- ...registryEntry?.messageData,
42621
- ...update
42622
- };
42623
- const currentRegistryEntry = globalConnectionRegistry.get(messageId);
42624
- const alreadyCompleted = currentRegistryEntry?.isComplete;
42625
- if (update.is_complete && !alreadyCompleted) {
42626
- completeStreamingMessage(messageId, messageData);
42627
- if (currentRegistryEntry) {
42628
- currentRegistryEntry.isComplete = true;
42629
- }
42630
- if (conversationId && messageData.id) {
42631
- const messageForStore = convertToMessage(messageData, conversationId);
42632
- const updated = updateMessage(conversationId, messageForStore);
42633
- if (!updated) {
42634
- addMessage(conversationId, messageForStore);
42635
- }
42636
- }
42637
- if (refetchOnComplete && !isRefetching) {
42638
- setTimeout(() => {
42639
- if (mountedRef.current) {
42640
- refetchMessage().catch((error2) => {
42641
- console.error("Error during refetch after completion:", error2);
42642
- });
42643
- }
42644
- }, 150);
42645
- }
42646
- } else if (!update.is_complete) {
42647
- updateStreamingMessage(messageId, messageData);
42648
- if (conversationId && messageData.id) {
42649
- const messageForStore = convertToMessage(messageData, conversationId);
42650
- if (!updateChatStoreTimeoutRef.current) {
42651
- updateChatStoreTimeoutRef.current = setTimeout(() => {
42652
- const updated = updateMessage(conversationId, messageForStore);
42653
- if (!updated) {
42654
- addMessage(conversationId, messageForStore);
42655
- }
42656
- updateChatStoreTimeoutRef.current = null;
42657
- }, 50);
42658
- }
42659
- }
42660
- }
42661
- },
42662
- [
42663
- messageId,
42664
- conversationId,
42665
- onUpdate,
42666
- refetchOnComplete,
42667
- updateStreamingMessage,
42668
- completeStreamingMessage,
42669
- updateMessage,
42670
- addMessage,
42671
- isRefetching,
42672
- refetchMessage
42673
- ]
42674
- );
42675
- const updateChatStoreTimeoutRef = reactExports.useRef(null);
42676
- reactExports.useEffect(() => {
42677
- return () => {
42678
- if (updateChatStoreTimeoutRef.current) {
42679
- clearTimeout(updateChatStoreTimeoutRef.current);
42680
- updateChatStoreTimeoutRef.current = null;
42745
+ const scheduleCompletionRefetch = reactExports.useCallback(() => {
42746
+ if (!refetchOnComplete || refetchTimeoutRef.current) {
42747
+ return;
42748
+ }
42749
+ refetchTimeoutRef.current = setTimeout(() => {
42750
+ refetchTimeoutRef.current = null;
42751
+ if (mountedRef.current) {
42752
+ void refetchMessage();
42681
42753
  }
42682
- };
42683
- }, []);
42754
+ }, COMPLETE_REFETCH_DELAY_MS);
42755
+ }, [refetchOnComplete, refetchMessage]);
42684
42756
  const {
42685
42757
  message: message2,
42686
42758
  isComplete,
@@ -42694,8 +42766,37 @@ const useStreamingMessage = ({
42694
42766
  baseUrl,
42695
42767
  messageId,
42696
42768
  autoConnect: false,
42697
- // We'll handle connection manually
42698
- onUpdate: handleUpdate
42769
+ onUpdate: (update) => {
42770
+ if (onUpdate && mountedRef.current) {
42771
+ onUpdate(update);
42772
+ }
42773
+ const entry = ensureRegistryEntry(messageId, keepAlive, conversationId);
42774
+ const messageData = {
42775
+ ...entry.messageData,
42776
+ ...update
42777
+ };
42778
+ entry.messageData = messageData;
42779
+ entry.isStreamable = Boolean(update.is_streamable || entry.isStreamable);
42780
+ if (update.is_complete) {
42781
+ entry.isComplete = true;
42782
+ completeStreamingMessage(messageId, messageData);
42783
+ pendingChatUpdateRef.current = messageData;
42784
+ flushPendingChatUpdate();
42785
+ notifyCompleteOnce(messageData);
42786
+ scheduleCompletionRefetch();
42787
+ return;
42788
+ }
42789
+ updateStreamingMessage(messageId, messageData);
42790
+ if (conversationId && messageData.id) {
42791
+ pendingChatUpdateRef.current = messageData;
42792
+ if (!chatStoreFlushTimeoutRef.current) {
42793
+ chatStoreFlushTimeoutRef.current = setTimeout(() => {
42794
+ chatStoreFlushTimeoutRef.current = null;
42795
+ flushPendingChatUpdate();
42796
+ }, CHAT_STORE_FLUSH_MS);
42797
+ }
42798
+ }
42799
+ }
42699
42800
  });
42700
42801
  const attemptConnection = reactExports.useCallback(async () => {
42701
42802
  if (isComplete || isStoreMessageComplete) {
@@ -42706,139 +42807,113 @@ const useStreamingMessage = ({
42706
42807
  return;
42707
42808
  }
42708
42809
  lastConnectionAttemptRef.current = now2;
42709
- if (!globalConnectionRegistry.has(messageId)) {
42710
- globalConnectionRegistry.set(messageId, {
42711
- connected: false,
42712
- connecting: false,
42713
- timestamp: Date.now(),
42714
- instanceCount: 0,
42715
- connectionPromise: null,
42716
- keepAlive,
42717
- // Set the keepAlive flag
42718
- wsClient: null,
42719
- messageData: null,
42720
- isComplete: false,
42721
- isStreamable: false,
42722
- conversationId
42723
- // Store the conversation ID
42724
- });
42725
- } else {
42726
- const entry = globalConnectionRegistry.get(messageId);
42727
- if (entry) {
42728
- entry.keepAlive = keepAlive;
42729
- if (conversationId) {
42730
- entry.conversationId = conversationId;
42731
- }
42732
- }
42733
- }
42734
- const registryEntry = globalConnectionRegistry.get(messageId);
42735
- if (!registryEntry) {
42736
- console.error(
42737
- "Failed to get registry entry, aborting connection attempt"
42738
- );
42739
- return;
42740
- }
42741
- registryEntry.instanceCount++;
42742
- if (registryEntry.connected) {
42810
+ const entry = ensureRegistryEntry(messageId, keepAlive, conversationId);
42811
+ if (entry.connected) {
42743
42812
  return;
42744
42813
  }
42745
- if (registryEntry.connecting && registryEntry.connectionPromise) {
42814
+ if (entry.connectionPromise) {
42746
42815
  try {
42747
- await registryEntry.connectionPromise;
42748
- } catch (_error2) {
42749
- console.warn(
42750
- "Existing connection failed, will attempt a new connection"
42751
- );
42816
+ await entry.connectionPromise;
42817
+ } catch {
42752
42818
  }
42753
42819
  return;
42754
42820
  }
42755
- registryEntry.connecting = true;
42756
- const connectionPromise = (async () => {
42757
- try {
42758
- await wsConnect();
42759
- if (globalConnectionRegistry.has(messageId)) {
42760
- const entry = globalConnectionRegistry.get(messageId);
42761
- if (entry) {
42762
- entry.connected = true;
42763
- entry.connecting = false;
42764
- entry.timestamp = Date.now();
42765
- entry.wsClient = { connect: wsConnect, disconnect: wsDisconnect };
42766
- }
42767
- }
42768
- return Promise.resolve();
42769
- } catch (error2) {
42770
- const errorMessage = error2 instanceof Error ? error2.message : "Unknown error connecting to WebSocket";
42771
- console.error(`WebSocket connection failed: ${errorMessage}`);
42772
- if (globalConnectionRegistry.has(messageId)) {
42773
- const entry = globalConnectionRegistry.get(messageId);
42774
- if (entry) {
42775
- entry.connected = false;
42776
- entry.connecting = false;
42777
- entry.timestamp = Date.now();
42778
- }
42779
- }
42780
- return Promise.reject(error2);
42821
+ entry.connecting = true;
42822
+ entry.connectionPromise = wsConnect().then(() => {
42823
+ const current = globalConnectionRegistry.get(messageId);
42824
+ if (current) {
42825
+ current.connected = true;
42826
+ current.connecting = false;
42781
42827
  }
42782
- })();
42783
- registryEntry.connectionPromise = connectionPromise;
42784
- try {
42785
- await connectionPromise;
42786
- } catch (_error2) {
42787
- } finally {
42788
- if (globalConnectionRegistry.has(messageId)) {
42789
- const entry = globalConnectionRegistry.get(messageId);
42790
- if (entry) {
42791
- entry.connectionPromise = null;
42792
- }
42828
+ }).catch((connectionError) => {
42829
+ const current = globalConnectionRegistry.get(messageId);
42830
+ if (current) {
42831
+ current.connected = false;
42832
+ current.connecting = false;
42833
+ }
42834
+ throw connectionError;
42835
+ }).finally(() => {
42836
+ const current = globalConnectionRegistry.get(messageId);
42837
+ if (current) {
42838
+ current.connectionPromise = null;
42793
42839
  }
42840
+ });
42841
+ try {
42842
+ await entry.connectionPromise;
42843
+ } catch (connectionError) {
42844
+ console.error("WebSocket connection failed:", connectionError);
42794
42845
  }
42795
42846
  }, [
42796
- wsConnect,
42797
- wsDisconnect,
42798
42847
  isComplete,
42799
42848
  isStoreMessageComplete,
42800
42849
  messageId,
42801
42850
  keepAlive,
42802
- conversationId
42851
+ conversationId,
42852
+ wsConnect
42803
42853
  ]);
42804
42854
  const safeDisconnect = reactExports.useCallback(() => {
42805
- if (!globalConnectionRegistry.has(messageId)) {
42806
- return;
42807
- }
42808
- const registryEntry = globalConnectionRegistry.get(messageId);
42809
- if (!registryEntry) {
42810
- return;
42811
- }
42812
- registryEntry.instanceCount = Math.max(0, registryEntry.instanceCount - 1);
42813
- if (registryEntry.instanceCount === 0 && !registryEntry.keepAlive) {
42814
- try {
42815
- wsDisconnect();
42816
- registryEntry.connected = false;
42817
- registryEntry.connecting = false;
42818
- registryEntry.connectionPromise = null;
42819
- registryEntry.wsClient = null;
42820
- } catch (error2) {
42821
- const errorMessage = error2 instanceof Error ? error2.message : String(error2);
42822
- console.error(`Error disconnecting WebSocket: ${errorMessage}`);
42855
+ const entry = globalConnectionRegistry.get(messageId);
42856
+ if (entry) {
42857
+ entry.keepAlive = false;
42858
+ entry.connected = false;
42859
+ entry.connecting = false;
42860
+ entry.connectionPromise = null;
42861
+ if (entry.instanceCount <= 1) {
42862
+ globalConnectionRegistry.delete(messageId);
42823
42863
  }
42824
42864
  }
42825
- }, [wsDisconnect, messageId]);
42865
+ wsDisconnect();
42866
+ }, [messageId, wsDisconnect]);
42826
42867
  reactExports.useEffect(() => {
42827
42868
  mountedRef.current = true;
42869
+ wsCompletionHandledRef.current = false;
42870
+ completionNotifiedRef.current = null;
42871
+ const entry = ensureRegistryEntry(messageId, keepAlive, conversationId);
42872
+ if (!isRegisteredInstanceRef.current) {
42873
+ entry.instanceCount += 1;
42874
+ isRegisteredInstanceRef.current = true;
42875
+ }
42876
+ let connectTimer = null;
42828
42877
  if (autoConnect && !isComplete && !isStoreMessageComplete) {
42829
- const timer2 = setTimeout(() => {
42878
+ connectTimer = setTimeout(() => {
42830
42879
  if (mountedRef.current) {
42831
- attemptConnection().catch((error2) => {
42832
- console.error(`Initial connection attempt failed: ${error2}`);
42833
- });
42880
+ void attemptConnection();
42834
42881
  }
42835
- }, 100);
42836
- return () => clearTimeout(timer2);
42882
+ }, 120);
42837
42883
  }
42838
42884
  return () => {
42839
42885
  mountedRef.current = false;
42840
- if (!keepAlive) {
42841
- safeDisconnect();
42886
+ if (connectTimer) {
42887
+ clearTimeout(connectTimer);
42888
+ }
42889
+ if (refetchTimeoutRef.current) {
42890
+ clearTimeout(refetchTimeoutRef.current);
42891
+ refetchTimeoutRef.current = null;
42892
+ }
42893
+ if (chatStoreFlushTimeoutRef.current) {
42894
+ clearTimeout(chatStoreFlushTimeoutRef.current);
42895
+ chatStoreFlushTimeoutRef.current = null;
42896
+ }
42897
+ flushPendingChatUpdate();
42898
+ pruneStreamingMessages();
42899
+ if (isRegisteredInstanceRef.current) {
42900
+ const currentEntry = globalConnectionRegistry.get(messageId);
42901
+ if (currentEntry) {
42902
+ currentEntry.instanceCount = Math.max(
42903
+ 0,
42904
+ currentEntry.instanceCount - 1
42905
+ );
42906
+ if (currentEntry.instanceCount === 0) {
42907
+ currentEntry.connected = false;
42908
+ currentEntry.connecting = false;
42909
+ currentEntry.connectionPromise = null;
42910
+ if (!currentEntry.keepAlive) {
42911
+ globalConnectionRegistry.delete(messageId);
42912
+ wsDisconnect();
42913
+ }
42914
+ }
42915
+ }
42916
+ isRegisteredInstanceRef.current = false;
42842
42917
  }
42843
42918
  };
42844
42919
  }, [
@@ -42846,70 +42921,75 @@ const useStreamingMessage = ({
42846
42921
  isComplete,
42847
42922
  isStoreMessageComplete,
42848
42923
  attemptConnection,
42849
- safeDisconnect,
42850
- keepAlive
42924
+ messageId,
42925
+ keepAlive,
42926
+ conversationId,
42927
+ flushPendingChatUpdate,
42928
+ pruneStreamingMessages,
42929
+ wsDisconnect
42851
42930
  ]);
42852
42931
  reactExports.useEffect(() => {
42853
- if (status === "disconnected" && !isComplete && !isStoreMessageComplete && mountedRef.current) {
42854
- const reconnectTimer = setTimeout(() => {
42855
- if (mountedRef.current) {
42856
- attemptConnection().catch((error2) => {
42857
- console.error(`Auto-reconnection attempt failed: ${error2}`);
42858
- });
42859
- }
42860
- }, 2e3);
42861
- return () => clearTimeout(reconnectTimer);
42932
+ const entry = ensureRegistryEntry(messageId, keepAlive, conversationId);
42933
+ entry.keepAlive = keepAlive;
42934
+ if (conversationId) {
42935
+ entry.conversationId = conversationId;
42862
42936
  }
42863
- return void 0;
42864
- }, [status, isComplete, isStoreMessageComplete, attemptConnection]);
42865
- const isCompletePrevRef = reactExports.useRef(false);
42937
+ }, [messageId, keepAlive, conversationId]);
42866
42938
  reactExports.useEffect(() => {
42867
- if (isComplete && !isCompletePrevRef.current && message2 && mountedRef.current) {
42868
- isCompletePrevRef.current = true;
42869
- completeStreamingMessage(messageId, message2);
42870
- if (onComplete) {
42871
- setTimeout(() => {
42872
- if (mountedRef.current) {
42873
- onComplete(message2);
42874
- }
42875
- }, 50);
42876
- }
42877
- if (!keepAlive) {
42878
- safeDisconnect();
42939
+ const entry = globalConnectionRegistry.get(messageId);
42940
+ if (!entry) {
42941
+ return;
42942
+ }
42943
+ entry.connected = status === "connected";
42944
+ entry.connecting = status === "connecting" || status === "reconnecting";
42945
+ if (!entry.connecting) {
42946
+ entry.connectionPromise = null;
42947
+ }
42948
+ }, [messageId, status]);
42949
+ reactExports.useEffect(() => {
42950
+ if (status !== "disconnected" || isComplete || isStoreMessageComplete || !mountedRef.current) {
42951
+ return;
42952
+ }
42953
+ const reconnectTimer = setTimeout(() => {
42954
+ if (mountedRef.current) {
42955
+ void attemptConnection();
42879
42956
  }
42880
- } else if (!isComplete) {
42881
- isCompletePrevRef.current = false;
42957
+ }, 1600);
42958
+ return () => clearTimeout(reconnectTimer);
42959
+ }, [status, isComplete, isStoreMessageComplete, attemptConnection]);
42960
+ reactExports.useEffect(() => {
42961
+ if (!isComplete || !message2) {
42962
+ wsCompletionHandledRef.current = false;
42963
+ return;
42964
+ }
42965
+ if (wsCompletionHandledRef.current) {
42966
+ return;
42967
+ }
42968
+ wsCompletionHandledRef.current = true;
42969
+ const entry = ensureRegistryEntry(messageId, keepAlive, conversationId);
42970
+ entry.isComplete = true;
42971
+ entry.messageData = message2;
42972
+ entry.isStreamable = !!message2.is_streamable;
42973
+ completeStreamingMessage(messageId, message2);
42974
+ pendingChatUpdateRef.current = message2;
42975
+ flushPendingChatUpdate();
42976
+ notifyCompleteOnce(message2);
42977
+ scheduleCompletionRefetch();
42978
+ if (!keepAlive && entry.instanceCount <= 1) {
42979
+ safeDisconnect();
42882
42980
  }
42883
42981
  }, [
42884
42982
  isComplete,
42885
42983
  message2,
42886
- onComplete,
42887
- keepAlive,
42888
- safeDisconnect,
42889
42984
  messageId,
42890
- completeStreamingMessage
42985
+ keepAlive,
42986
+ conversationId,
42987
+ completeStreamingMessage,
42988
+ flushPendingChatUpdate,
42989
+ notifyCompleteOnce,
42990
+ scheduleCompletionRefetch,
42991
+ safeDisconnect
42891
42992
  ]);
42892
- reactExports.useEffect(() => {
42893
- return () => {
42894
- if (globalConnectionRegistry.has(messageId)) {
42895
- const entry = globalConnectionRegistry.get(messageId);
42896
- if (entry && entry.instanceCount > 0) {
42897
- entry.instanceCount = Math.max(0, entry.instanceCount - 1);
42898
- if (entry.instanceCount === 0 && !entry.keepAlive) {
42899
- try {
42900
- wsDisconnect();
42901
- entry.connected = false;
42902
- entry.connecting = false;
42903
- entry.connectionPromise = null;
42904
- entry.wsClient = null;
42905
- } catch (error2) {
42906
- console.warn("Error during cleanup:", error2);
42907
- }
42908
- }
42909
- }
42910
- }
42911
- };
42912
- }, [messageId, wsDisconnect]);
42913
42993
  return {
42914
42994
  message: message2,
42915
42995
  isComplete,
@@ -68138,6 +68218,18 @@ const AgentSettings = ({
68138
68218
  ] })
68139
68219
  ] }) });
68140
68220
  };
68221
+ function useDebouncedValue(value, delay) {
68222
+ const [debouncedValue, setDebouncedValue] = reactExports.useState(value);
68223
+ reactExports.useEffect(() => {
68224
+ const handler = setTimeout(() => {
68225
+ setDebouncedValue(value);
68226
+ }, delay);
68227
+ return () => {
68228
+ clearTimeout(handler);
68229
+ };
68230
+ }, [value, delay]);
68231
+ return debouncedValue;
68232
+ }
68141
68233
  const SignInButton = styled$1(Button)(({ theme: theme2 }) => ({
68142
68234
  display: "flex",
68143
68235
  alignItems: "center",
@@ -68603,7 +68695,13 @@ const AgentsSidebarItem = ({
68603
68695
  }
68604
68696
  ) }, agent.id);
68605
68697
  };
68606
- const MemoizedAgentsSidebarItem = reactExports.memo(AgentsSidebarItem);
68698
+ const areAgentsSidebarItemsEqual = (prev2, next2) => {
68699
+ return prev2.isSelected === next2.isSelected && prev2.agent.id === next2.agent.id && prev2.agent.name === next2.agent.name && prev2.agent.description === next2.agent.description && prev2.agent.created_date === next2.agent.created_date && prev2.onSelectAgent === next2.onSelectAgent && prev2.formatDate === next2.formatDate && prev2.onChatWithAgent === next2.onChatWithAgent && prev2.onExportAgent === next2.onExportAgent && prev2.onAgentDeleted === next2.onAgentDeleted && prev2.onUploadAgentToHub === next2.onUploadAgentToHub;
68700
+ };
68701
+ const MemoizedAgentsSidebarItem = reactExports.memo(
68702
+ AgentsSidebarItem,
68703
+ areAgentsSidebarItemsEqual
68704
+ );
68607
68705
  const formatDate$1 = (dateString) => {
68608
68706
  if (!dateString) return "Unknown date";
68609
68707
  const date2 = new Date(dateString);
@@ -68613,19 +68711,26 @@ const formatDate$1 = (dateString) => {
68613
68711
  day: "numeric"
68614
68712
  });
68615
68713
  };
68616
- const AgentsSidebar = ({
68714
+ const AgentsSidebarComponent = ({
68617
68715
  selectedAgentId,
68618
68716
  onSelectAgent
68619
68717
  }) => {
68620
68718
  const navigate = useNavigate();
68621
68719
  const [searchQuery, setSearchQuery2] = reactExports.useState("");
68622
- const { openCreateAgentDialog } = useUiPreferencesStore();
68720
+ const openCreateAgentDialog = useUiPreferencesStore(
68721
+ (state2) => state2.openCreateAgentDialog
68722
+ );
68723
+ const debouncedSearchQuery = useDebouncedValue(searchQuery.trim(), 250);
68623
68724
  const [isImportDialogOpen, setIsImportDialogOpen] = reactExports.useState(false);
68624
68725
  const perPage = 50;
68625
68726
  const [isUploadDialogOpen, setIsUploadDialogOpen] = reactExports.useState(false);
68626
68727
  const [uploadAgent, setUploadAgent] = reactExports.useState(null);
68627
68728
  const [uploadValidationIssues, setUploadValidationIssues] = reactExports.useState([]);
68628
68729
  const { isAuthenticated } = useRadientAuth();
68730
+ const agentClient = reactExports.useMemo(
68731
+ () => createLocalOperatorClient(apiConfig.baseUrl),
68732
+ []
68733
+ );
68629
68734
  const exportAgentMutation = useExportAgent();
68630
68735
  const { page, setPage } = usePaginationParams();
68631
68736
  const {
@@ -68633,7 +68738,14 @@ const AgentsSidebar = ({
68633
68738
  isLoading,
68634
68739
  isError,
68635
68740
  refetch
68636
- } = useAgents(page, perPage, 0, searchQuery, "created_date", "desc");
68741
+ } = useAgents(
68742
+ page,
68743
+ perPage,
68744
+ 0,
68745
+ debouncedSearchQuery || void 0,
68746
+ "created_date",
68747
+ "desc"
68748
+ );
68637
68749
  const agents = agentListResult?.agents || [];
68638
68750
  const totalAgents = agentListResult?.total || 0;
68639
68751
  const { data: selectedAgentDetails } = useAgent(
@@ -68711,53 +68823,34 @@ const AgentsSidebar = ({
68711
68823
  },
68712
68824
  [getAgentUploadValidationIssues]
68713
68825
  );
68714
- const handleCloseUploadDialog = () => {
68826
+ const handleCloseUploadDialog = reactExports.useCallback(() => {
68715
68827
  setIsUploadDialogOpen(false);
68716
68828
  setUploadAgent(null);
68717
68829
  setUploadValidationIssues([]);
68718
- };
68719
- const handleConfirmUpload = () => {
68830
+ }, []);
68831
+ const handleConfirmUpload = reactExports.useCallback(() => {
68720
68832
  handleCloseUploadDialog();
68721
- };
68833
+ }, [handleCloseUploadDialog]);
68722
68834
  const handleAgentCreated = reactExports.useCallback(
68723
- (agentId) => {
68724
- const fetchAndSelectAgent = async () => {
68725
- try {
68726
- const result = await refetch();
68727
- const updatedAgentList = result.data?.agents || [];
68728
- const createdAgent = updatedAgentList.find(
68729
- (agent) => agent.id === agentId
68730
- );
68731
- if (createdAgent) {
68732
- onSelectAgent(createdAgent);
68733
- } else {
68734
- try {
68735
- const { data: newAgentDetails } = await refetch();
68736
- const foundAgent = (newAgentDetails?.agents || []).find(
68737
- (a2) => a2.id === agentId
68738
- );
68739
- if (foundAgent) {
68740
- onSelectAgent(foundAgent);
68741
- } else {
68742
- console.warn(
68743
- "Newly created agent not found immediately after refetch."
68744
- );
68745
- }
68746
- } catch (fetchError) {
68747
- console.error(
68748
- "Error fetching newly created agent details:",
68749
- fetchError
68750
- );
68751
- }
68752
- }
68753
- } catch (error) {
68754
- console.error("Error refetching agents list:", error);
68835
+ async (agentId) => {
68836
+ try {
68837
+ const result = await refetch();
68838
+ const createdAgent = (result.data?.agents || []).find(
68839
+ (agent) => agent.id === agentId
68840
+ );
68841
+ if (createdAgent) {
68842
+ onSelectAgent(createdAgent);
68843
+ return;
68755
68844
  }
68756
- };
68757
- fetchAndSelectAgent();
68845
+ const detailsResponse = await agentClient.agents.getAgent(agentId);
68846
+ if (detailsResponse.status < 400 && detailsResponse.result) {
68847
+ onSelectAgent(detailsResponse.result);
68848
+ }
68849
+ } catch (error) {
68850
+ console.error("Error selecting newly created agent:", error);
68851
+ }
68758
68852
  },
68759
- [onSelectAgent, refetch]
68760
- // Keep dependencies
68853
+ [onSelectAgent, refetch, agentClient]
68761
68854
  );
68762
68855
  const handleChatWithAgent = reactExports.useCallback(
68763
68856
  (agentId) => {
@@ -68852,6 +68945,7 @@ const AgentsSidebar = ({
68852
68945
  )
68853
68946
  ] });
68854
68947
  };
68948
+ const AgentsSidebar = reactExports.memo(AgentsSidebarComponent);
68855
68949
  const Container = styled$1(Box)({
68856
68950
  display: "flex",
68857
68951
  height: "100%",
@@ -89895,7 +89989,7 @@ const languages = [
89895
89989
  name: "Go",
89896
89990
  extensions: ["go"],
89897
89991
  load() {
89898
- return __vitePreload(() => import("./index-BOEHLAOZ.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m2) => m2.go());
89992
+ return __vitePreload(() => import("./index-BDLsFoJv.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m2) => m2.go());
89899
89993
  }
89900
89994
  }),
89901
89995
  /* @__PURE__ */ LanguageDescription.of({
@@ -90072,7 +90166,7 @@ const languages = [
90072
90166
  alias: ["yml"],
90073
90167
  extensions: ["yaml", "yml"],
90074
90168
  load() {
90075
- return __vitePreload(() => import("./index-CIm5Gpeu.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m2) => m2.yaml());
90169
+ return __vitePreload(() => import("./index-vAasWWpO.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m2) => m2.yaml());
90076
90170
  }
90077
90171
  }),
90078
90172
  // Legacy modes ported from CodeMirror 5
@@ -127954,18 +128048,6 @@ var ReactCodeMirror = /* @__PURE__ */ reactExports.forwardRef((props2, ref) => {
127954
128048
  }, other2));
127955
128049
  });
127956
128050
  ReactCodeMirror.displayName = "CodeMirror";
127957
- function useDebouncedValue(value, delay) {
127958
- const [debouncedValue, setDebouncedValue] = reactExports.useState(value);
127959
- reactExports.useEffect(() => {
127960
- const handler = setTimeout(() => {
127961
- setDebouncedValue(value);
127962
- }, delay);
127963
- return () => {
127964
- clearTimeout(handler);
127965
- };
127966
- }, [value, delay]);
127967
- return debouncedValue;
127968
- }
127969
128051
  const getCodeMirrorTheme = (theme2) => {
127970
128052
  const colors = {
127971
128053
  background: theme2.palette.background.paper,
@@ -233200,6 +233282,8 @@ const ScrollToBottomButton = ({
233200
233282
  }
233201
233283
  ) }) });
233202
233284
  };
233285
+ const EMPTY_REPLIES = [];
233286
+ const EMPTY_ATTACHMENTS = [];
233203
233287
  const InputOuterContainer = styled$1(Box, {
233204
233288
  shouldForwardProp: (prop) => prop !== "isSmallView"
233205
233289
  })(({ theme: theme2, isSmallView }) => ({
@@ -233426,21 +233510,30 @@ const MessageInput = reactExports.forwardRef(
233426
233510
  agentData,
233427
233511
  isSmallView = false
233428
233512
  }, ref) => {
233429
- const {
233430
- inputByConversation,
233431
- removeReply,
233432
- clearReplies,
233433
- addAttachment,
233434
- removeAttachment,
233435
- clearAttachments
233436
- } = useConversationInputStore();
233437
- const replies = reactExports.useMemo(
233438
- () => conversationId && inputByConversation[conversationId]?.replies || [],
233439
- [inputByConversation, conversationId]
233513
+ const removeReply = useConversationInputStore((state2) => state2.removeReply);
233514
+ const clearReplies = useConversationInputStore(
233515
+ (state2) => state2.clearReplies
233516
+ );
233517
+ const addAttachment = useConversationInputStore(
233518
+ (state2) => state2.addAttachment
233519
+ );
233520
+ const removeAttachment = useConversationInputStore(
233521
+ (state2) => state2.removeAttachment
233522
+ );
233523
+ const clearAttachments = useConversationInputStore(
233524
+ (state2) => state2.clearAttachments
233525
+ );
233526
+ const replies = useConversationInputStore(
233527
+ reactExports.useCallback(
233528
+ (state2) => conversationId ? state2.inputByConversation[conversationId]?.replies ?? EMPTY_REPLIES : EMPTY_REPLIES,
233529
+ [conversationId]
233530
+ )
233440
233531
  );
233441
- const attachments = reactExports.useMemo(
233442
- () => conversationId && inputByConversation[conversationId]?.attachments || [],
233443
- [inputByConversation, conversationId]
233532
+ const attachments = useConversationInputStore(
233533
+ reactExports.useCallback(
233534
+ (state2) => conversationId ? state2.inputByConversation[conversationId]?.attachments ?? EMPTY_ATTACHMENTS : EMPTY_ATTACHMENTS,
233535
+ [conversationId]
233536
+ )
233444
233537
  );
233445
233538
  const [isRecording, setIsRecording] = reactExports.useState(false);
233446
233539
  const [audioBlob, setAudioBlob] = reactExports.useState(null);
@@ -234146,8 +234239,10 @@ const getDetailedStatusText = (status, execution) => {
234146
234239
  return status ? getStatusText(status) : "thinking";
234147
234240
  };
234148
234241
  const LoadingIndicator = reactExports.memo(({ status, currentExecution, isSmallView }) => {
234149
- const { getStreamingMessage } = useStreamingMessagesStore();
234150
- const streamingMessage = getStreamingMessage(currentExecution?.id || "");
234242
+ const currentExecutionId = currentExecution?.id ?? "";
234243
+ const streamingMessage = useStreamingMessagesStore(
234244
+ (state2) => state2.streamingMessages[currentExecutionId] ?? null
234245
+ );
234151
234246
  const isStreaming = !!streamingMessage && !streamingMessage.isComplete;
234152
234247
  if (isStreaming) {
234153
234248
  return null;
@@ -273867,7 +273962,7 @@ var registerDefaultLayoutLoaders = /* @__PURE__ */ __name(() => {
273867
273962
  registerLayoutLoaders([
273868
273963
  {
273869
273964
  name: "dagre",
273870
- loader: /* @__PURE__ */ __name(async () => await __vitePreload(() => import("./dagre-OKDRZEBW-uJDV0tEB.js"), true ? __vite__mapDeps([6,7,8,9,10,11,1,2]) : void 0, import.meta.url), "loader")
273965
+ loader: /* @__PURE__ */ __name(async () => await __vitePreload(() => import("./dagre-OKDRZEBW-BMuSMCUF.js"), true ? __vite__mapDeps([6,7,8,9,10,11,1,2]) : void 0, import.meta.url), "loader")
273871
273966
  }
273872
273967
  ]);
273873
273968
  }, "registerDefaultLayoutLoaders");
@@ -274457,7 +274552,7 @@ var detector = /* @__PURE__ */ __name((txt) => {
274457
274552
  }, "detector");
274458
274553
  var loader = /* @__PURE__ */ __name(async () => {
274459
274554
  const { diagram: diagram2 } = await __vitePreload(async () => {
274460
- const { diagram: diagram22 } = await import("./c4Diagram-VJAJSXHY-DnUBXdyl.js");
274555
+ const { diagram: diagram22 } = await import("./c4Diagram-VJAJSXHY-cTGz3ymz.js");
274461
274556
  return { diagram: diagram22 };
274462
274557
  }, true ? __vite__mapDeps([12,13,1,2]) : void 0, import.meta.url);
274463
274558
  return { id, diagram: diagram2 };
@@ -274477,7 +274572,7 @@ var detector2 = /* @__PURE__ */ __name((txt, config2) => {
274477
274572
  }, "detector");
274478
274573
  var loader2 = /* @__PURE__ */ __name(async () => {
274479
274574
  const { diagram: diagram2 } = await __vitePreload(async () => {
274480
- const { diagram: diagram22 } = await import("./flowDiagram-4HSFHLVR-CjBlaiPH.js");
274575
+ const { diagram: diagram22 } = await import("./flowDiagram-4HSFHLVR-_Arrrk_3.js");
274481
274576
  return { diagram: diagram22 };
274482
274577
  }, true ? __vite__mapDeps([14,15,16,1,2]) : void 0, import.meta.url);
274483
274578
  return { id: id2, diagram: diagram2 };
@@ -274503,7 +274598,7 @@ var detector3 = /* @__PURE__ */ __name((txt, config2) => {
274503
274598
  }, "detector");
274504
274599
  var loader3 = /* @__PURE__ */ __name(async () => {
274505
274600
  const { diagram: diagram2 } = await __vitePreload(async () => {
274506
- const { diagram: diagram22 } = await import("./flowDiagram-4HSFHLVR-CjBlaiPH.js");
274601
+ const { diagram: diagram22 } = await import("./flowDiagram-4HSFHLVR-_Arrrk_3.js");
274507
274602
  return { diagram: diagram22 };
274508
274603
  }, true ? __vite__mapDeps([14,15,16,1,2]) : void 0, import.meta.url);
274509
274604
  return { id: id3, diagram: diagram2 };
@@ -274520,7 +274615,7 @@ var detector4 = /* @__PURE__ */ __name((txt) => {
274520
274615
  }, "detector");
274521
274616
  var loader4 = /* @__PURE__ */ __name(async () => {
274522
274617
  const { diagram: diagram2 } = await __vitePreload(async () => {
274523
- const { diagram: diagram22 } = await import("./erDiagram-Q7BY3M3F-D66PtkGh.js");
274618
+ const { diagram: diagram22 } = await import("./erDiagram-Q7BY3M3F-BFd2rLsa.js");
274524
274619
  return { diagram: diagram22 };
274525
274620
  }, true ? __vite__mapDeps([17,15,16,1,2]) : void 0, import.meta.url);
274526
274621
  return { id: id4, diagram: diagram2 };
@@ -274537,7 +274632,7 @@ var detector5 = /* @__PURE__ */ __name((txt) => {
274537
274632
  }, "detector");
274538
274633
  var loader5 = /* @__PURE__ */ __name(async () => {
274539
274634
  const { diagram: diagram2 } = await __vitePreload(async () => {
274540
- const { diagram: diagram22 } = await import("./gitGraphDiagram-7IBYFJ6S-BC17Lxhk.js");
274635
+ const { diagram: diagram22 } = await import("./gitGraphDiagram-7IBYFJ6S-BlkO8Bzg.js");
274541
274636
  return { diagram: diagram22 };
274542
274637
  }, true ? __vite__mapDeps([18,19,20,21,8,10,11,1,2]) : void 0, import.meta.url);
274543
274638
  return { id: id5, diagram: diagram2 };
@@ -274554,7 +274649,7 @@ var detector6 = /* @__PURE__ */ __name((txt) => {
274554
274649
  }, "detector");
274555
274650
  var loader6 = /* @__PURE__ */ __name(async () => {
274556
274651
  const { diagram: diagram2 } = await __vitePreload(async () => {
274557
- const { diagram: diagram22 } = await import("./ganttDiagram-APWFNJXF-CifvAN8h.js");
274652
+ const { diagram: diagram22 } = await import("./ganttDiagram-APWFNJXF-Dzw68AV_.js");
274558
274653
  return { diagram: diagram22 };
274559
274654
  }, true ? __vite__mapDeps([22,1,2]) : void 0, import.meta.url);
274560
274655
  return { id: id6, diagram: diagram2 };
@@ -274571,7 +274666,7 @@ var detector7 = /* @__PURE__ */ __name((txt) => {
274571
274666
  }, "detector");
274572
274667
  var loader7 = /* @__PURE__ */ __name(async () => {
274573
274668
  const { diagram: diagram2 } = await __vitePreload(async () => {
274574
- const { diagram: diagram22 } = await import("./infoDiagram-PH2N3AL5-Dsj1auFt.js");
274669
+ const { diagram: diagram22 } = await import("./infoDiagram-PH2N3AL5-DO4pqvW_.js");
274575
274670
  return { diagram: diagram22 };
274576
274671
  }, true ? __vite__mapDeps([23,21,8,10,11,1,2]) : void 0, import.meta.url);
274577
274672
  return { id: id7, diagram: diagram2 };
@@ -274587,7 +274682,7 @@ var detector8 = /* @__PURE__ */ __name((txt) => {
274587
274682
  }, "detector");
274588
274683
  var loader8 = /* @__PURE__ */ __name(async () => {
274589
274684
  const { diagram: diagram2 } = await __vitePreload(async () => {
274590
- const { diagram: diagram22 } = await import("./pieDiagram-IB7DONF6-CZvzTYvc.js");
274685
+ const { diagram: diagram22 } = await import("./pieDiagram-IB7DONF6-DKT0Bk2S.js");
274591
274686
  return { diagram: diagram22 };
274592
274687
  }, true ? __vite__mapDeps([24,19,21,8,10,11,25,1,2]) : void 0, import.meta.url);
274593
274688
  return { id: id8, diagram: diagram2 };
@@ -274603,7 +274698,7 @@ var detector9 = /* @__PURE__ */ __name((txt) => {
274603
274698
  }, "detector");
274604
274699
  var loader9 = /* @__PURE__ */ __name(async () => {
274605
274700
  const { diagram: diagram2 } = await __vitePreload(async () => {
274606
- const { diagram: diagram22 } = await import("./quadrantDiagram-7GDLP6J5-CJSNfyeY.js");
274701
+ const { diagram: diagram22 } = await import("./quadrantDiagram-7GDLP6J5-CFMDiFFE.js");
274607
274702
  return { diagram: diagram22 };
274608
274703
  }, true ? __vite__mapDeps([26,1,2]) : void 0, import.meta.url);
274609
274704
  return { id: id9, diagram: diagram2 };
@@ -274620,7 +274715,7 @@ var detector10 = /* @__PURE__ */ __name((txt) => {
274620
274715
  }, "detector");
274621
274716
  var loader10 = /* @__PURE__ */ __name(async () => {
274622
274717
  const { diagram: diagram2 } = await __vitePreload(async () => {
274623
- const { diagram: diagram22 } = await import("./xychartDiagram-VJFVF3MP-Jn_L_tBu.js");
274718
+ const { diagram: diagram22 } = await import("./xychartDiagram-VJFVF3MP-Bbr5uqsp.js");
274624
274719
  return { diagram: diagram22 };
274625
274720
  }, true ? __vite__mapDeps([27,1,2]) : void 0, import.meta.url);
274626
274721
  return { id: id10, diagram: diagram2 };
@@ -274637,7 +274732,7 @@ var detector11 = /* @__PURE__ */ __name((txt) => {
274637
274732
  }, "detector");
274638
274733
  var loader11 = /* @__PURE__ */ __name(async () => {
274639
274734
  const { diagram: diagram2 } = await __vitePreload(async () => {
274640
- const { diagram: diagram22 } = await import("./requirementDiagram-KVF5MWMF-BzJ8TKJn.js");
274735
+ const { diagram: diagram22 } = await import("./requirementDiagram-KVF5MWMF-DPTaldQZ.js");
274641
274736
  return { diagram: diagram22 };
274642
274737
  }, true ? __vite__mapDeps([28,15,1,2]) : void 0, import.meta.url);
274643
274738
  return { id: id11, diagram: diagram2 };
@@ -274654,7 +274749,7 @@ var detector12 = /* @__PURE__ */ __name((txt) => {
274654
274749
  }, "detector");
274655
274750
  var loader12 = /* @__PURE__ */ __name(async () => {
274656
274751
  const { diagram: diagram2 } = await __vitePreload(async () => {
274657
- const { diagram: diagram22 } = await import("./sequenceDiagram-X6HHIX6F-QlZcg6un.js");
274752
+ const { diagram: diagram22 } = await import("./sequenceDiagram-X6HHIX6F-Chi1Y6mU.js");
274658
274753
  return { diagram: diagram22 };
274659
274754
  }, true ? __vite__mapDeps([29,13,20,1,2]) : void 0, import.meta.url);
274660
274755
  return { id: id12, diagram: diagram2 };
@@ -274674,7 +274769,7 @@ var detector13 = /* @__PURE__ */ __name((txt, config2) => {
274674
274769
  }, "detector");
274675
274770
  var loader13 = /* @__PURE__ */ __name(async () => {
274676
274771
  const { diagram: diagram2 } = await __vitePreload(async () => {
274677
- const { diagram: diagram22 } = await import("./classDiagram-GIVACNV2-BTb1dsm_.js");
274772
+ const { diagram: diagram22 } = await import("./classDiagram-GIVACNV2-BcRnaMRd.js");
274678
274773
  return { diagram: diagram22 };
274679
274774
  }, true ? __vite__mapDeps([30,31,15,1,2]) : void 0, import.meta.url);
274680
274775
  return { id: id13, diagram: diagram2 };
@@ -274694,7 +274789,7 @@ var detector14 = /* @__PURE__ */ __name((txt, config2) => {
274694
274789
  }, "detector");
274695
274790
  var loader14 = /* @__PURE__ */ __name(async () => {
274696
274791
  const { diagram: diagram2 } = await __vitePreload(async () => {
274697
- const { diagram: diagram22 } = await import("./classDiagram-v2-COTLJTTW-BTb1dsm_.js");
274792
+ const { diagram: diagram22 } = await import("./classDiagram-v2-COTLJTTW-BcRnaMRd.js");
274698
274793
  return { diagram: diagram22 };
274699
274794
  }, true ? __vite__mapDeps([32,31,15,1,2]) : void 0, import.meta.url);
274700
274795
  return { id: id14, diagram: diagram2 };
@@ -274714,7 +274809,7 @@ var detector15 = /* @__PURE__ */ __name((txt, config2) => {
274714
274809
  }, "detector");
274715
274810
  var loader15 = /* @__PURE__ */ __name(async () => {
274716
274811
  const { diagram: diagram2 } = await __vitePreload(async () => {
274717
- const { diagram: diagram22 } = await import("./stateDiagram-DGXRK772-lkNrTERo.js");
274812
+ const { diagram: diagram22 } = await import("./stateDiagram-DGXRK772-DcmhTUVK.js");
274718
274813
  return { diagram: diagram22 };
274719
274814
  }, true ? __vite__mapDeps([33,34,15,7,8,9,10,1,2]) : void 0, import.meta.url);
274720
274815
  return { id: id15, diagram: diagram2 };
@@ -274737,7 +274832,7 @@ var detector16 = /* @__PURE__ */ __name((txt, config2) => {
274737
274832
  }, "detector");
274738
274833
  var loader16 = /* @__PURE__ */ __name(async () => {
274739
274834
  const { diagram: diagram2 } = await __vitePreload(async () => {
274740
- const { diagram: diagram22 } = await import("./stateDiagram-v2-YXO3MK2T-Cnlxf-OJ.js");
274835
+ const { diagram: diagram22 } = await import("./stateDiagram-v2-YXO3MK2T-Dy-oRm-T.js");
274741
274836
  return { diagram: diagram22 };
274742
274837
  }, true ? __vite__mapDeps([35,34,15,1,2]) : void 0, import.meta.url);
274743
274838
  return { id: id16, diagram: diagram2 };
@@ -274754,7 +274849,7 @@ var detector17 = /* @__PURE__ */ __name((txt) => {
274754
274849
  }, "detector");
274755
274850
  var loader17 = /* @__PURE__ */ __name(async () => {
274756
274851
  const { diagram: diagram2 } = await __vitePreload(async () => {
274757
- const { diagram: diagram22 } = await import("./journeyDiagram-U35MCT3I-CBWci7yb.js");
274852
+ const { diagram: diagram22 } = await import("./journeyDiagram-U35MCT3I-BJQ-FRal.js");
274758
274853
  return { diagram: diagram22 };
274759
274854
  }, true ? __vite__mapDeps([36,13,25,1,2]) : void 0, import.meta.url);
274760
274855
  return { id: id17, diagram: diagram2 };
@@ -274824,7 +274919,7 @@ var detector18 = /* @__PURE__ */ __name((txt, config2 = {}) => {
274824
274919
  }, "detector");
274825
274920
  var loader18 = /* @__PURE__ */ __name(async () => {
274826
274921
  const { diagram: diagram2 } = await __vitePreload(async () => {
274827
- const { diagram: diagram22 } = await import("./flowDiagram-4HSFHLVR-CjBlaiPH.js");
274922
+ const { diagram: diagram22 } = await import("./flowDiagram-4HSFHLVR-_Arrrk_3.js");
274828
274923
  return { diagram: diagram22 };
274829
274924
  }, true ? __vite__mapDeps([14,15,16,1,2]) : void 0, import.meta.url);
274830
274925
  return { id: id18, diagram: diagram2 };
@@ -274841,7 +274936,7 @@ var detector19 = /* @__PURE__ */ __name((txt) => {
274841
274936
  }, "detector");
274842
274937
  var loader19 = /* @__PURE__ */ __name(async () => {
274843
274938
  const { diagram: diagram2 } = await __vitePreload(async () => {
274844
- const { diagram: diagram22 } = await import("./timeline-definition-BDJGKUSR-ClHwwcwA.js");
274939
+ const { diagram: diagram22 } = await import("./timeline-definition-BDJGKUSR-0y2wZWef.js");
274845
274940
  return { diagram: diagram22 };
274846
274941
  }, true ? __vite__mapDeps([37,25,1,2]) : void 0, import.meta.url);
274847
274942
  return { id: id19, diagram: diagram2 };
@@ -274858,7 +274953,7 @@ var detector20 = /* @__PURE__ */ __name((txt) => {
274858
274953
  }, "detector");
274859
274954
  var loader20 = /* @__PURE__ */ __name(async () => {
274860
274955
  const { diagram: diagram2 } = await __vitePreload(async () => {
274861
- const { diagram: diagram22 } = await import("./mindmap-definition-ALO5MXBD-e-VrUTAA.js");
274956
+ const { diagram: diagram22 } = await import("./mindmap-definition-ALO5MXBD-B5SNv6RZ.js");
274862
274957
  return { diagram: diagram22 };
274863
274958
  }, true ? __vite__mapDeps([38,39,1,2]) : void 0, import.meta.url);
274864
274959
  return { id: id20, diagram: diagram2 };
@@ -274875,7 +274970,7 @@ var detector21 = /* @__PURE__ */ __name((txt) => {
274875
274970
  }, "detector");
274876
274971
  var loader21 = /* @__PURE__ */ __name(async () => {
274877
274972
  const { diagram: diagram2 } = await __vitePreload(async () => {
274878
- const { diagram: diagram22 } = await import("./kanban-definition-NDS4AKOZ-BrBwgyJQ.js");
274973
+ const { diagram: diagram22 } = await import("./kanban-definition-NDS4AKOZ-B1zGbozL.js");
274879
274974
  return { diagram: diagram22 };
274880
274975
  }, true ? __vite__mapDeps([40,1,2]) : void 0, import.meta.url);
274881
274976
  return { id: id21, diagram: diagram2 };
@@ -274892,7 +274987,7 @@ var detector22 = /* @__PURE__ */ __name((txt) => {
274892
274987
  }, "detector");
274893
274988
  var loader22 = /* @__PURE__ */ __name(async () => {
274894
274989
  const { diagram: diagram2 } = await __vitePreload(async () => {
274895
- const { diagram: diagram22 } = await import("./sankeyDiagram-QLVOVGJD-C1MZHoLs.js");
274990
+ const { diagram: diagram22 } = await import("./sankeyDiagram-QLVOVGJD-DIFNjSQ_.js");
274896
274991
  return { diagram: diagram22 };
274897
274992
  }, true ? __vite__mapDeps([41,1,2]) : void 0, import.meta.url);
274898
274993
  return { id: id22, diagram: diagram2 };
@@ -274909,7 +275004,7 @@ var detector23 = /* @__PURE__ */ __name((txt) => {
274909
275004
  }, "detector");
274910
275005
  var loader23 = /* @__PURE__ */ __name(async () => {
274911
275006
  const { diagram: diagram2 } = await __vitePreload(async () => {
274912
- const { diagram: diagram22 } = await import("./diagram-VNBRO52H-CCeijHj7.js");
275007
+ const { diagram: diagram22 } = await import("./diagram-VNBRO52H-q41sVUvc.js");
274913
275008
  return { diagram: diagram22 };
274914
275009
  }, true ? __vite__mapDeps([42,19,21,8,10,11,1,2]) : void 0, import.meta.url);
274915
275010
  return { id: id23, diagram: diagram2 };
@@ -274925,7 +275020,7 @@ var detector24 = /* @__PURE__ */ __name((txt) => {
274925
275020
  }, "detector");
274926
275021
  var loader24 = /* @__PURE__ */ __name(async () => {
274927
275022
  const { diagram: diagram2 } = await __vitePreload(async () => {
274928
- const { diagram: diagram22 } = await import("./diagram-SSKATNLV-BxlaHBtJ.js");
275023
+ const { diagram: diagram22 } = await import("./diagram-SSKATNLV-BCxxN7T6.js");
274929
275024
  return { diagram: diagram22 };
274930
275025
  }, true ? __vite__mapDeps([43,19,21,8,10,11,1,2]) : void 0, import.meta.url);
274931
275026
  return { id: id24, diagram: diagram2 };
@@ -274941,7 +275036,7 @@ var detector25 = /* @__PURE__ */ __name((txt) => {
274941
275036
  }, "detector");
274942
275037
  var loader25 = /* @__PURE__ */ __name(async () => {
274943
275038
  const { diagram: diagram2 } = await __vitePreload(async () => {
274944
- const { diagram: diagram22 } = await import("./blockDiagram-JOT3LUYC-CKjlYfeC.js");
275039
+ const { diagram: diagram22 } = await import("./blockDiagram-JOT3LUYC-BW-Yo0Fe.js");
274945
275040
  return { diagram: diagram22 };
274946
275041
  }, true ? __vite__mapDeps([44,11,8,7,16,1,2]) : void 0, import.meta.url);
274947
275042
  return { id: id25, diagram: diagram2 };
@@ -274958,7 +275053,7 @@ var detector26 = /* @__PURE__ */ __name((txt) => {
274958
275053
  }, "detector");
274959
275054
  var loader26 = /* @__PURE__ */ __name(async () => {
274960
275055
  const { diagram: diagram2 } = await __vitePreload(async () => {
274961
- const { diagram: diagram22 } = await import("./architectureDiagram-IEHRJDOE-BE1k5yn0.js");
275056
+ const { diagram: diagram22 } = await import("./architectureDiagram-IEHRJDOE-iKnn0iSS.js");
274962
275057
  return { diagram: diagram22 };
274963
275058
  }, true ? __vite__mapDeps([45,19,20,21,8,10,11,39,1,2]) : void 0, import.meta.url);
274964
275059
  return { id: id26, diagram: diagram2 };
@@ -314762,6 +314857,193 @@ const LogBlock = ({ log: log3, isUser }) => {
314762
314857
  /* @__PURE__ */ jsxRuntimeExports.jsx(LogContainer, { isUser, children: log3 })
314763
314858
  ] });
314764
314859
  };
314860
+ const ControlsContainer = styled$1(Box, {
314861
+ shouldForwardProp: (prop) => prop !== "isUser" && prop !== "inline"
314862
+ })(({ isUser, inline: inline2 }) => ({
314863
+ position: inline2 ? "static" : "absolute",
314864
+ bottom: inline2 ? "auto" : isUser ? 8 : -12,
314865
+ // Position below the message
314866
+ display: "flex",
314867
+ alignItems: "center",
314868
+ justifyContent: isUser ? "flex-end" : "flex-start",
314869
+ width: inline2 ? "auto" : "100%",
314870
+ opacity: inline2 ? 1 : 0,
314871
+ transition: "opacity 0.2s ease-in-out",
314872
+ zIndex: 1
314873
+ }));
314874
+ const ControlsWrapper = styled$1(Box)(() => ({
314875
+ display: "flex",
314876
+ alignItems: "flex-start"
314877
+ }));
314878
+ const StyledIconButton = styled$1(IconButton)(({ theme: theme2 }) => ({
314879
+ color: theme2.palette.text.secondary,
314880
+ width: "34px",
314881
+ height: "34px",
314882
+ "&:hover": {
314883
+ color: theme2.palette.primary.main,
314884
+ backgroundColor: alpha$1(theme2.palette.primary.main, 0.1)
314885
+ }
314886
+ }));
314887
+ const MessageControls = ({
314888
+ isUser,
314889
+ content: content2,
314890
+ sx,
314891
+ messageId,
314892
+ agentId,
314893
+ inline: inline2 = false
314894
+ }) => {
314895
+ const [copied, setCopied] = reactExports.useState(false);
314896
+ const { data: credentialsData, isLoading: isLoadingCredentials } = useCredentials();
314897
+ const {
314898
+ playSpeech,
314899
+ stopSpeech,
314900
+ replaySpeech,
314901
+ loadingMessageId,
314902
+ playingMessageId,
314903
+ audioCache
314904
+ } = useSpeechStore();
314905
+ const isPlaying = playingMessageId === messageId;
314906
+ const isLoading = loadingMessageId === messageId;
314907
+ const hasAudio = audioCache.has(messageId);
314908
+ const isRadientApiKeyConfigured = reactExports.useMemo(
314909
+ () => credentialsData?.keys?.includes("RADIENT_API_KEY"),
314910
+ [credentialsData?.keys]
314911
+ );
314912
+ const canEnableSpeechFeature = reactExports.useMemo(
314913
+ () => isRadientApiKeyConfigured && !isLoadingCredentials,
314914
+ [isRadientApiKeyConfigured, isLoadingCredentials]
314915
+ );
314916
+ const showCopyButton = content2;
314917
+ const handleCopy = async () => {
314918
+ try {
314919
+ if (content2) {
314920
+ await navigator.clipboard.writeText(content2);
314921
+ setCopied(true);
314922
+ setTimeout(() => setCopied(false), 2e3);
314923
+ }
314924
+ } catch (error) {
314925
+ console.error("Failed to copy text:", error);
314926
+ }
314927
+ };
314928
+ const handlePlay = () => {
314929
+ if (agentId && content2) {
314930
+ playSpeech(messageId, agentId, content2);
314931
+ }
314932
+ };
314933
+ const handleReplay = () => {
314934
+ replaySpeech(messageId);
314935
+ };
314936
+ const handleStop = () => {
314937
+ stopSpeech();
314938
+ };
314939
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
314940
+ ControlsContainer,
314941
+ {
314942
+ isUser,
314943
+ inline: inline2,
314944
+ className: inline2 ? void 0 : "message-controls",
314945
+ sx,
314946
+ children: showCopyButton && /* @__PURE__ */ jsxRuntimeExports.jsxs(ControlsWrapper, { children: [
314947
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: copied ? "Copied!" : "Copy message", placement: "top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(StyledIconButton, { size: "small", onClick: handleCopy, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 16 }) }) }),
314948
+ !isUser && (isPlaying ? /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: "Stop", placement: "top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(StyledIconButton, { size: "small", onClick: handleStop, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Square, { size: 16 }) }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
314949
+ Tooltip$1,
314950
+ {
314951
+ title: !canEnableSpeechFeature ? "Sign in to Radient in the settings page to enable text to speech" : isLoading ? "Loading" : hasAudio ? "Replay Speech" : "Speak Aloud",
314952
+ placement: "top",
314953
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
314954
+ StyledIconButton,
314955
+ {
314956
+ size: "small",
314957
+ onClick: hasAudio ? handleReplay : handlePlay,
314958
+ disabled: isLoading || !canEnableSpeechFeature,
314959
+ children: isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Volume2, { size: 16 })
314960
+ }
314961
+ ) })
314962
+ }
314963
+ ))
314964
+ ] })
314965
+ }
314966
+ );
314967
+ };
314968
+ const formatMessageDateTime = (dateTimeString) => {
314969
+ if (!dateTimeString) return "";
314970
+ try {
314971
+ const messageDate = dateTimeString instanceof Date ? dateTimeString : new Date(dateTimeString);
314972
+ const now2 = /* @__PURE__ */ new Date();
314973
+ const yesterday = new Date(now2);
314974
+ yesterday.setDate(now2.getDate() - 1);
314975
+ if (messageDate.toDateString() === now2.toDateString()) {
314976
+ return format$3(messageDate, "h:mm a");
314977
+ }
314978
+ if (messageDate.toDateString() === yesterday.toDateString()) {
314979
+ return "Yesterday";
314980
+ }
314981
+ const oneWeekAgo = new Date(now2);
314982
+ oneWeekAgo.setDate(now2.getDate() - 7);
314983
+ if (messageDate > oneWeekAgo) {
314984
+ return format$3(messageDate, "EEEE");
314985
+ }
314986
+ return format$3(messageDate, "yyyy-MM-dd");
314987
+ } catch (error) {
314988
+ console.error("Error formatting date:", error);
314989
+ return "";
314990
+ }
314991
+ };
314992
+ const getFullDateTime = (dateTimeString) => {
314993
+ if (!dateTimeString) return "";
314994
+ try {
314995
+ const date2 = dateTimeString instanceof Date ? dateTimeString : new Date(dateTimeString);
314996
+ return date2.toLocaleString();
314997
+ } catch (error) {
314998
+ console.error("Error getting full date time:", error);
314999
+ return "";
315000
+ }
315001
+ };
315002
+ const StyledTimestamp = styled$1(Typography, {
315003
+ shouldForwardProp: (prop) => prop !== "isUser" && prop !== "inline"
315004
+ })(
315005
+ ({ isUser, theme: theme2, isSmallView, inline: inline2 }) => ({
315006
+ display: "block",
315007
+ marginTop: inline2 ? 0 : 8,
315008
+ textAlign: isUser ? "left" : "right",
315009
+ color: theme2.palette.text.secondary,
315010
+ fontSize: "0.7rem",
315011
+ width: inline2 ? "auto" : isUser ? "auto" : isSmallView ? "100%" : "calc(100% - 52px)",
315012
+ cursor: "help"
315013
+ // Indicate that hovering will show more information
315014
+ })
315015
+ );
315016
+ const MessageTimestamp = ({
315017
+ timestamp: timestamp2,
315018
+ isUser,
315019
+ sx,
315020
+ isSmallView,
315021
+ inline: inline2 = false
315022
+ }) => {
315023
+ const formattedTime = formatMessageDateTime(timestamp2);
315024
+ const fullDateTime = getFullDateTime(timestamp2);
315025
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
315026
+ Tooltip$1,
315027
+ {
315028
+ title: fullDateTime,
315029
+ arrow: true,
315030
+ placement: "bottom",
315031
+ enterDelay: 1200,
315032
+ enterNextDelay: 1200,
315033
+ sx,
315034
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
315035
+ StyledTimestamp,
315036
+ {
315037
+ variant: "caption",
315038
+ isUser,
315039
+ isSmallView,
315040
+ inline: inline2,
315041
+ children: formattedTime
315042
+ }
315043
+ )
315044
+ }
315045
+ );
315046
+ };
314765
315047
  const CodeContainer = styled$1(Box)({
314766
315048
  marginBottom: 16,
314767
315049
  width: "100%"
@@ -314967,6 +315249,7 @@ const VideoAttachment = reactExports.memo(
314967
315249
  }
314968
315250
  );
314969
315251
  VideoAttachment.displayName = "VideoAttachment";
315252
+ const localOperatorClient$1 = createLocalOperatorClient(apiConfig.baseUrl);
314970
315253
  const isWebUrl$2 = (path2) => {
314971
315254
  return path2.startsWith("http://") || path2.startsWith("https://");
314972
315255
  };
@@ -315038,6 +315321,26 @@ const getAttachmentUrl$2 = (client2, path2) => {
315038
315321
  }
315039
315322
  return path2;
315040
315323
  };
315324
+ const getCompactIcon = (action, executionType) => {
315325
+ switch (action) {
315326
+ case "DONE":
315327
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14 });
315328
+ case "ASK":
315329
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleHelp, { size: 14 });
315330
+ case "CODE":
315331
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { size: 14 });
315332
+ case "WRITE":
315333
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { size: 12 });
315334
+ case "EDIT":
315335
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(PencilLine, { size: 14 });
315336
+ case "READ":
315337
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Book, { size: 14 });
315338
+ case "DELEGATE":
315339
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Share2, { size: 14 });
315340
+ default:
315341
+ return executionType === "plan" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Lightbulb, { size: 14 }) : executionType === "action" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { size: 14 });
315342
+ }
315343
+ };
315041
315344
  const ActionBlock = ({
315042
315345
  message: message2,
315043
315346
  replacements,
@@ -315053,16 +315356,14 @@ const ActionBlock = ({
315053
315356
  filePath,
315054
315357
  conversationId,
315055
315358
  isLoading,
315056
- isSmallView
315359
+ isSmallView,
315360
+ compact = false,
315361
+ messageId,
315362
+ timestamp: timestamp2,
315363
+ agentId
315057
315364
  }) => {
315058
- const [isExpanded, setIsExpanded] = reactExports.useState(false);
315059
- const handleExpand = () => {
315060
- setIsExpanded(true);
315061
- };
315062
- const handleCollapse = (e3) => {
315063
- e3.stopPropagation();
315064
- setIsExpanded(false);
315065
- };
315365
+ const [isRowExpanded, setIsRowExpanded] = reactExports.useState(!compact);
315366
+ const [isDetailsExpanded, setIsDetailsExpanded] = reactExports.useState(false);
315066
315367
  const markdownStyleProps = reactExports.useMemo(
315067
315368
  () => ({
315068
315369
  fontSize: isSmallView ? "0.95rem" : "1.05rem",
@@ -315070,12 +315371,9 @@ const ActionBlock = ({
315070
315371
  }),
315071
315372
  [isSmallView]
315072
315373
  );
315073
- const client2 = reactExports.useMemo(() => {
315074
- return createLocalOperatorClient(apiConfig.baseUrl);
315075
- }, []);
315076
315374
  const getUrl2 = reactExports.useCallback(
315077
- (path2) => getAttachmentUrl$2(client2, path2),
315078
- [client2]
315375
+ (path2) => getAttachmentUrl$2(localOperatorClient$1, path2),
315376
+ []
315079
315377
  );
315080
315378
  const handleFileClick = reactExports.useCallback((filePath2) => {
315081
315379
  try {
@@ -315092,104 +315390,266 @@ const ActionBlock = ({
315092
315390
  const hasCollapsibleContent = Boolean(executionType === "action" && !!action);
315093
315391
  const fileLanguage = getLanguageFromExtension(filePath || "");
315094
315392
  const trimmedMessage = message2 ? message2.replace(/(```\w+\s*)+$/g, "").trimEnd() : message2;
315393
+ const compactPreviewText = trimmedMessage ? trimmedMessage.replace(/\s+/g, " ").trim() : action === "CODE" ? "Executing code" : "Working on your request";
315394
+ const compactIcon = reactExports.useMemo(
315395
+ () => getCompactIcon(action, executionType),
315396
+ [action, executionType]
315397
+ );
315398
+ const handleExpand = () => {
315399
+ setIsRowExpanded(true);
315400
+ setIsDetailsExpanded(true);
315401
+ };
315402
+ const handleCollapse = (e3) => {
315403
+ e3.stopPropagation();
315404
+ setIsDetailsExpanded(false);
315405
+ if (compact) {
315406
+ setIsRowExpanded(false);
315407
+ }
315408
+ };
315409
+ const handleCompactToggle = () => {
315410
+ if (!compact) return;
315411
+ setIsRowExpanded((previous2) => {
315412
+ const next2 = !previous2;
315413
+ setIsDetailsExpanded(next2);
315414
+ return next2;
315415
+ });
315416
+ };
315095
315417
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { position: "relative", width: "100%" }, children: [
315096
- message2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
315418
+ compact && !isRowExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(
315097
315419
  Box,
315098
315420
  {
315421
+ component: "button",
315422
+ type: "button",
315423
+ "aria-expanded": false,
315424
+ onClick: handleCompactToggle,
315099
315425
  sx: {
315100
- borderRadius: 2,
315101
- color: (theme2) => theme2.palette.text.primary,
315426
+ display: "flex",
315427
+ justifyContent: "flex-start",
315428
+ alignItems: "center",
315102
315429
  width: "100%",
315103
- wordBreak: "break-word",
315104
- overflowWrap: "break-word",
315105
- position: "relative",
315106
- mb: 2
315430
+ border: "none",
315431
+ background: "transparent",
315432
+ padding: "2px 0",
315433
+ cursor: "pointer",
315434
+ textAlign: "left",
315435
+ minHeight: 28
315107
315436
  },
315108
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
315109
- MarkdownRenderer,
315437
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
315438
+ Box,
315110
315439
  {
315111
- content: trimmedMessage,
315112
- styleProps: markdownStyleProps
315440
+ sx: (theme2) => ({
315441
+ display: "inline-flex",
315442
+ alignItems: "center",
315443
+ gap: 1,
315444
+ maxWidth: "100%",
315445
+ padding: "5px 10px",
315446
+ borderRadius: "999px",
315447
+ color: theme2.palette.text.secondary,
315448
+ backgroundColor: alpha$1(
315449
+ theme2.palette.common.black,
315450
+ theme2.palette.mode === "dark" ? 0.14 : 0.04
315451
+ )
315452
+ }),
315453
+ children: [
315454
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
315455
+ Box,
315456
+ {
315457
+ component: "span",
315458
+ sx: {
315459
+ width: 20,
315460
+ height: 20,
315461
+ borderRadius: "100%",
315462
+ display: "flex",
315463
+ alignItems: "center",
315464
+ justifyContent: "center",
315465
+ flexShrink: 0
315466
+ },
315467
+ children: compactIcon
315468
+ }
315469
+ ),
315470
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
315471
+ Typography,
315472
+ {
315473
+ variant: "body2",
315474
+ noWrap: true,
315475
+ component: "span",
315476
+ sx: {
315477
+ maxWidth: "100%",
315478
+ color: "inherit",
315479
+ fontSize: "0.82rem",
315480
+ lineHeight: 1.35,
315481
+ overflow: "hidden",
315482
+ textOverflow: "ellipsis",
315483
+ whiteSpace: "nowrap"
315484
+ },
315485
+ children: compactPreviewText
315486
+ }
315487
+ )
315488
+ ]
315113
315489
  }
315114
315490
  )
315115
315491
  }
315116
315492
  ),
315117
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
315118
- ExpandableActionElement,
315119
- {
315120
- executionType,
315121
- action,
315122
- isUser,
315123
- isExpanded,
315124
- onExpand: handleExpand,
315125
- onCollapse: handleCollapse,
315126
- hasCollapsibleContent,
315127
- isLoading: isLoading ?? false,
315128
- children: [
315129
- code2 && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: code2, isUser }),
315130
- fileContent && /* @__PURE__ */ jsxRuntimeExports.jsx(
315131
- CodeBlock,
315132
- {
315133
- header: "Content",
315134
- code: fileContent,
315135
- isUser,
315136
- language: fileLanguage
315137
- }
315138
- ),
315139
- replacements && /* @__PURE__ */ jsxRuntimeExports.jsx(
315140
- CodeBlock,
315493
+ (!compact || isRowExpanded) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
315494
+ message2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
315495
+ Box,
315496
+ {
315497
+ sx: {
315498
+ borderRadius: 2,
315499
+ color: (theme2) => theme2.palette.text.primary,
315500
+ width: "100%",
315501
+ wordBreak: "break-word",
315502
+ overflowWrap: "break-word",
315503
+ position: "relative",
315504
+ mb: 2
315505
+ },
315506
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
315507
+ MarkdownRenderer,
315141
315508
  {
315142
- header: "Replacements",
315143
- code: replacements,
315144
- isUser,
315145
- language: "diff"
315509
+ content: trimmedMessage,
315510
+ styleProps: markdownStyleProps
315146
315511
  }
315147
- ),
315148
- stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: stdout, isUser }),
315149
- stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: stderr, isUser }),
315150
- logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: logging, isUser })
315151
- ]
315152
- }
315153
- ),
315154
- files && files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2, mt: 2 }, children: files.filter((file) => isImage$2(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315155
- ImageAttachment,
315156
- {
315157
- file,
315158
- src: getUrl2(file),
315159
- onClick: handleFileClick,
315160
- conversationId
315161
- },
315162
- `${file}`
315163
- )) }),
315164
- files && files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: files.filter((file) => isVideo$2(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315165
- VideoAttachment,
315166
- {
315167
- file,
315168
- src: getUrl2(file),
315169
- onClick: handleFileClick,
315170
- conversationId
315171
- },
315172
- `${file}`
315173
- )) }),
315174
- files && files.length > 0 && files.some((file) => isAudio$2(file)) && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: files.filter((file) => isAudio$2(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315175
- AudioAttachment,
315176
- {
315177
- content: getUrl2(file),
315178
- isUser
315179
- },
315180
- `${file}`
315181
- )) }),
315182
- files && files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: files.filter(
315183
- (file) => !isImage$2(file) && !isVideo$2(file) && !isAudio$2(file)
315184
- ).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315185
- FileAttachment,
315186
- {
315187
- file,
315188
- onClick: handleFileClick,
315189
- conversationId
315190
- },
315191
- `${file}`
315192
- )) })
315512
+ )
315513
+ }
315514
+ ),
315515
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
315516
+ ExpandableActionElement,
315517
+ {
315518
+ executionType,
315519
+ action,
315520
+ isUser,
315521
+ isExpanded: isDetailsExpanded,
315522
+ onExpand: handleExpand,
315523
+ onCollapse: handleCollapse,
315524
+ hasCollapsibleContent,
315525
+ isLoading: isLoading ?? false,
315526
+ children: [
315527
+ code2 && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: code2, isUser }),
315528
+ fileContent && /* @__PURE__ */ jsxRuntimeExports.jsx(
315529
+ CodeBlock,
315530
+ {
315531
+ header: "Content",
315532
+ code: fileContent,
315533
+ isUser,
315534
+ language: fileLanguage
315535
+ }
315536
+ ),
315537
+ replacements && /* @__PURE__ */ jsxRuntimeExports.jsx(
315538
+ CodeBlock,
315539
+ {
315540
+ header: "Replacements",
315541
+ code: replacements,
315542
+ isUser,
315543
+ language: "diff"
315544
+ }
315545
+ ),
315546
+ stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: stdout, isUser }),
315547
+ stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: stderr, isUser }),
315548
+ logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: logging, isUser })
315549
+ ]
315550
+ }
315551
+ ),
315552
+ files && files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2, mt: 2 }, children: files.filter((file) => isImage$2(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315553
+ ImageAttachment,
315554
+ {
315555
+ file,
315556
+ src: getUrl2(file),
315557
+ onClick: handleFileClick,
315558
+ conversationId
315559
+ },
315560
+ `${file}`
315561
+ )) }),
315562
+ files && files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: files.filter((file) => isVideo$2(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315563
+ VideoAttachment,
315564
+ {
315565
+ file,
315566
+ src: getUrl2(file),
315567
+ onClick: handleFileClick,
315568
+ conversationId
315569
+ },
315570
+ `${file}`
315571
+ )) }),
315572
+ files && files.length > 0 && files.some((file) => isAudio$2(file)) && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: files.filter((file) => isAudio$2(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315573
+ AudioAttachment,
315574
+ {
315575
+ content: getUrl2(file),
315576
+ isUser
315577
+ },
315578
+ `${file}`
315579
+ )) }),
315580
+ files && files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: files.filter(
315581
+ (file) => !isImage$2(file) && !isVideo$2(file) && !isAudio$2(file)
315582
+ ).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315583
+ FileAttachment,
315584
+ {
315585
+ file,
315586
+ onClick: handleFileClick,
315587
+ conversationId
315588
+ },
315589
+ `${file}`
315590
+ )) }),
315591
+ isRowExpanded && messageId && timestamp2 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
315592
+ Box,
315593
+ {
315594
+ sx: {
315595
+ display: "flex",
315596
+ alignItems: "center",
315597
+ justifyContent: "space-between",
315598
+ gap: 1,
315599
+ mt: 1.25
315600
+ },
315601
+ children: [
315602
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
315603
+ MessageControls,
315604
+ {
315605
+ inline: true,
315606
+ isUser,
315607
+ content: trimmedMessage,
315608
+ messageId,
315609
+ agentId: agentId || conversationId
315610
+ }
315611
+ ),
315612
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
315613
+ MessageTimestamp,
315614
+ {
315615
+ inline: true,
315616
+ timestamp: timestamp2,
315617
+ isUser,
315618
+ isSmallView
315619
+ }
315620
+ )
315621
+ ]
315622
+ }
315623
+ ),
315624
+ compact && isRowExpanded && !hasCollapsibleContent && /* @__PURE__ */ jsxRuntimeExports.jsxs(
315625
+ Box,
315626
+ {
315627
+ component: "button",
315628
+ type: "button",
315629
+ onClick: handleCompactToggle,
315630
+ "aria-expanded": false,
315631
+ sx: (theme2) => ({
315632
+ marginTop: 1.25,
315633
+ display: "inline-flex",
315634
+ alignItems: "center",
315635
+ gap: 0.5,
315636
+ padding: "4px 8px",
315637
+ borderRadius: 1,
315638
+ border: "none",
315639
+ cursor: "pointer",
315640
+ backgroundColor: alpha$1(
315641
+ theme2.palette.common.black,
315642
+ theme2.palette.mode === "dark" ? 0.12 : 0.04
315643
+ ),
315644
+ color: theme2.palette.text.secondary
315645
+ }),
315646
+ children: [
315647
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { size: 14 }),
315648
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "caption", children: "Condense" })
315649
+ ]
315650
+ }
315651
+ )
315652
+ ] })
315193
315653
  ] });
315194
315654
  };
315195
315655
  const SectionHeader = styled$1(Box)(({ theme: theme2 }) => ({
@@ -315242,31 +315702,45 @@ const CollapsibleMessage = ({ children: children2, defaultCollapsed = true, hasC
315242
315702
  ] });
315243
315703
  };
315244
315704
  const StyledAvatar = styled$1(Avatar, {
315245
- shouldForwardProp: (prop) => prop !== "isUser"
315246
- })(({ isUser, theme: theme2 }) => ({
315705
+ shouldForwardProp: (prop) => prop !== "isUser" && prop !== "compact"
315706
+ })(({ isUser, compact, theme: theme2 }) => ({
315247
315707
  backgroundColor: isUser ? theme2.palette.userMessage.background : theme2.palette.icon.background,
315248
315708
  color: isUser ? "white" : theme2.palette.icon.text,
315249
315709
  boxShadow: isUser ? theme2.palette.userMessage.shadow : "none",
315250
- border: isUser ? `1px solid ${theme2.palette.userMessage.border}` : "none"
315710
+ border: isUser ? `1px solid ${theme2.palette.userMessage.border}` : "none",
315711
+ width: compact ? 34 : 40,
315712
+ height: compact ? 34 : 40
315251
315713
  }));
315252
- const MessageAvatar = ({ isUser }) => {
315253
- return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledAvatar, { isUser, children: isUser ? /* @__PURE__ */ jsxRuntimeExports.jsx(User, { size: 22, "aria-label": "User" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { size: 22, "aria-label": "Assistant" }) });
315714
+ const MessageAvatar = ({ isUser, compact }) => {
315715
+ const iconSize = compact ? 18 : 22;
315716
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledAvatar, { isUser, compact, children: isUser ? /* @__PURE__ */ jsxRuntimeExports.jsx(User, { size: iconSize, "aria-label": "User" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { size: iconSize, "aria-label": "Assistant" }) });
315254
315717
  };
315255
315718
  const StyledContainer = styled$1(Box, {
315256
- shouldForwardProp: (prop) => prop !== "isUser" && prop !== "isSmallView"
315257
- })(({ isUser, isSmallView }) => ({
315258
- display: "flex",
315259
- flexDirection: isUser ? "row-reverse" : "row",
315260
- alignItems: "flex-start",
315261
- gap: isSmallView ? 8 : 16,
315262
- marginBottom: isSmallView ? 8 : 12
315263
- }));
315719
+ shouldForwardProp: (prop) => prop !== "isUser" && prop !== "isSmallView" && prop !== "compact"
315720
+ })(
315721
+ ({ isUser, isSmallView, compact }) => ({
315722
+ display: "flex",
315723
+ flexDirection: isUser ? "row-reverse" : "row",
315724
+ alignItems: "flex-start",
315725
+ gap: compact ? isSmallView ? 6 : 10 : isSmallView ? 8 : 16,
315726
+ marginBottom: compact ? isSmallView ? 6 : 8 : isSmallView ? 8 : 12
315727
+ })
315728
+ );
315264
315729
  const MessageContainer = ({
315265
315730
  isUser,
315266
315731
  children: children2,
315267
- isSmallView
315732
+ isSmallView,
315733
+ compact
315268
315734
  }) => {
315269
- return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledContainer, { isUser, isSmallView, children: children2 });
315735
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
315736
+ StyledContainer,
315737
+ {
315738
+ isUser,
315739
+ isSmallView,
315740
+ compact,
315741
+ children: children2
315742
+ }
315743
+ );
315270
315744
  };
315271
315745
  const ContentContainer$2 = styled$1(Box)(() => ({
315272
315746
  marginBottom: 0
@@ -315335,181 +315809,6 @@ const ExpandableThinkingContent = ({
315335
315809
  ] });
315336
315810
  };
315337
315811
  ExpandableThinkingContent.displayName = "ExpandableThinkingContent";
315338
- const ControlsContainer = styled$1(Box, {
315339
- shouldForwardProp: (prop) => prop !== "isUser"
315340
- })(({ isUser }) => ({
315341
- position: "absolute",
315342
- bottom: isUser ? 8 : -12,
315343
- // Position below the message
315344
- display: "flex",
315345
- alignItems: "center",
315346
- justifyContent: isUser ? "flex-end" : "flex-start",
315347
- width: "100%",
315348
- opacity: 0,
315349
- transition: "opacity 0.2s ease-in-out",
315350
- zIndex: 1
315351
- }));
315352
- const ControlsWrapper = styled$1(Box)(() => ({
315353
- display: "flex",
315354
- alignItems: "flex-start"
315355
- }));
315356
- const StyledIconButton = styled$1(IconButton)(({ theme: theme2 }) => ({
315357
- color: theme2.palette.text.secondary,
315358
- width: "34px",
315359
- height: "34px",
315360
- "&:hover": {
315361
- color: theme2.palette.primary.main,
315362
- backgroundColor: alpha$1(theme2.palette.primary.main, 0.1)
315363
- }
315364
- }));
315365
- const MessageControls = ({
315366
- isUser,
315367
- content: content2,
315368
- sx,
315369
- messageId,
315370
- agentId
315371
- }) => {
315372
- const [copied, setCopied] = reactExports.useState(false);
315373
- const { data: credentialsData, isLoading: isLoadingCredentials } = useCredentials();
315374
- const {
315375
- playSpeech,
315376
- stopSpeech,
315377
- replaySpeech,
315378
- loadingMessageId,
315379
- playingMessageId,
315380
- audioCache
315381
- } = useSpeechStore();
315382
- const isPlaying = playingMessageId === messageId;
315383
- const isLoading = loadingMessageId === messageId;
315384
- const hasAudio = audioCache.has(messageId);
315385
- const isRadientApiKeyConfigured = reactExports.useMemo(
315386
- () => credentialsData?.keys?.includes("RADIENT_API_KEY"),
315387
- [credentialsData?.keys]
315388
- );
315389
- const canEnableSpeechFeature = reactExports.useMemo(
315390
- () => isRadientApiKeyConfigured && !isLoadingCredentials,
315391
- [isRadientApiKeyConfigured, isLoadingCredentials]
315392
- );
315393
- const showCopyButton = content2;
315394
- const handleCopy = async () => {
315395
- try {
315396
- if (content2) {
315397
- await navigator.clipboard.writeText(content2);
315398
- setCopied(true);
315399
- setTimeout(() => setCopied(false), 2e3);
315400
- }
315401
- } catch (error) {
315402
- console.error("Failed to copy text:", error);
315403
- }
315404
- };
315405
- const handlePlay = () => {
315406
- if (agentId && content2) {
315407
- playSpeech(messageId, agentId, content2);
315408
- }
315409
- };
315410
- const handleReplay = () => {
315411
- replaySpeech(messageId);
315412
- };
315413
- const handleStop = () => {
315414
- stopSpeech();
315415
- };
315416
- return /* @__PURE__ */ jsxRuntimeExports.jsx(ControlsContainer, { isUser, className: "message-controls", sx, children: showCopyButton && /* @__PURE__ */ jsxRuntimeExports.jsxs(ControlsWrapper, { children: [
315417
- /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: copied ? "Copied!" : "Copy message", placement: "top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(StyledIconButton, { size: "small", onClick: handleCopy, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 16 }) }) }),
315418
- !isUser && (isPlaying ? /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip$1, { title: "Stop", placement: "top", children: /* @__PURE__ */ jsxRuntimeExports.jsx(StyledIconButton, { size: "small", onClick: handleStop, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Square, { size: 16 }) }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
315419
- Tooltip$1,
315420
- {
315421
- title: !canEnableSpeechFeature ? "Sign in to Radient in the settings page to enable text to speech" : isLoading ? "Loading" : hasAudio ? "Replay Speech" : "Speak Aloud",
315422
- placement: "top",
315423
- children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
315424
- StyledIconButton,
315425
- {
315426
- size: "small",
315427
- onClick: hasAudio ? handleReplay : handlePlay,
315428
- disabled: isLoading || !canEnableSpeechFeature,
315429
- children: isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Volume2, { size: 16 })
315430
- }
315431
- ) })
315432
- }
315433
- ))
315434
- ] }) });
315435
- };
315436
- const formatMessageDateTime = (dateTimeString) => {
315437
- if (!dateTimeString) return "";
315438
- try {
315439
- const messageDate = dateTimeString instanceof Date ? dateTimeString : new Date(dateTimeString);
315440
- const now2 = /* @__PURE__ */ new Date();
315441
- const yesterday = new Date(now2);
315442
- yesterday.setDate(now2.getDate() - 1);
315443
- if (messageDate.toDateString() === now2.toDateString()) {
315444
- return format$3(messageDate, "h:mm a");
315445
- }
315446
- if (messageDate.toDateString() === yesterday.toDateString()) {
315447
- return "Yesterday";
315448
- }
315449
- const oneWeekAgo = new Date(now2);
315450
- oneWeekAgo.setDate(now2.getDate() - 7);
315451
- if (messageDate > oneWeekAgo) {
315452
- return format$3(messageDate, "EEEE");
315453
- }
315454
- return format$3(messageDate, "yyyy-MM-dd");
315455
- } catch (error) {
315456
- console.error("Error formatting date:", error);
315457
- return "";
315458
- }
315459
- };
315460
- const getFullDateTime = (dateTimeString) => {
315461
- if (!dateTimeString) return "";
315462
- try {
315463
- const date2 = dateTimeString instanceof Date ? dateTimeString : new Date(dateTimeString);
315464
- return date2.toLocaleString();
315465
- } catch (error) {
315466
- console.error("Error getting full date time:", error);
315467
- return "";
315468
- }
315469
- };
315470
- const StyledTimestamp = styled$1(Typography, {
315471
- shouldForwardProp: (prop) => prop !== "isUser"
315472
- })(
315473
- ({ isUser, theme: theme2, isSmallView }) => ({
315474
- display: "block",
315475
- marginTop: 8,
315476
- textAlign: isUser ? "left" : "right",
315477
- color: theme2.palette.text.secondary,
315478
- fontSize: "0.7rem",
315479
- width: isUser ? "auto" : isSmallView ? "100%" : "calc(100% - 52px)",
315480
- cursor: "help"
315481
- // Indicate that hovering will show more information
315482
- })
315483
- );
315484
- const MessageTimestamp = ({
315485
- timestamp: timestamp2,
315486
- isUser,
315487
- sx,
315488
- isSmallView
315489
- }) => {
315490
- const formattedTime = formatMessageDateTime(timestamp2);
315491
- const fullDateTime = getFullDateTime(timestamp2);
315492
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
315493
- Tooltip$1,
315494
- {
315495
- title: fullDateTime,
315496
- arrow: true,
315497
- placement: "bottom",
315498
- enterDelay: 1200,
315499
- enterNextDelay: 1200,
315500
- sx,
315501
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
315502
- StyledTimestamp,
315503
- {
315504
- variant: "caption",
315505
- isUser,
315506
- isSmallView,
315507
- children: formattedTime
315508
- }
315509
- )
315510
- }
315511
- );
315512
- };
315513
315812
  const isWebUrl$1 = (path2) => path2.startsWith("http://") || path2.startsWith("https://");
315514
315813
  const isImage$1 = (path2) => {
315515
315814
  const imageExtensions = [
@@ -315571,6 +315870,46 @@ const getAttachmentUrl$1 = (client2, path2) => {
315571
315870
  if (isAudio$1(path2)) return client2.static.getAudioUrl(normalizedPath);
315572
315871
  return path2;
315573
315872
  };
315873
+ const getStreamingPreviewText = (message2) => {
315874
+ const cleanedMessage = message2?.message?.replace(/\s+/g, " ").replace(/(```\w+\s*)+$/g, "").trim();
315875
+ if (cleanedMessage) {
315876
+ return cleanedMessage;
315877
+ }
315878
+ switch (message2?.action) {
315879
+ case "CODE":
315880
+ return "Executing code";
315881
+ case "READ":
315882
+ return "Reading content";
315883
+ case "WRITE":
315884
+ return "Writing content";
315885
+ case "EDIT":
315886
+ return "Editing content";
315887
+ case "ASK":
315888
+ return "Formulating a question";
315889
+ default:
315890
+ return "Working on your request";
315891
+ }
315892
+ };
315893
+ const getStreamingCompactIcon = (message2) => {
315894
+ switch (message2?.action) {
315895
+ case "DONE":
315896
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14 });
315897
+ case "ASK":
315898
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleHelp, { size: 14 });
315899
+ case "CODE":
315900
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { size: 14 });
315901
+ case "WRITE":
315902
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { size: 12 });
315903
+ case "EDIT":
315904
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(PencilLine, { size: 14 });
315905
+ case "READ":
315906
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Book, { size: 14 });
315907
+ case "DELEGATE":
315908
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Share2, { size: 14 });
315909
+ default:
315910
+ return message2?.execution_type === "plan" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Lightbulb, { size: 14 }) : message2?.execution_type === "action" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CodeXml, { size: 14 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { size: 14 });
315911
+ }
315912
+ };
315574
315913
  const StreamingContainer = styled$1(Box)(() => ({
315575
315914
  position: "relative",
315576
315915
  overflow: "hidden",
@@ -315603,30 +315942,13 @@ const StreamingMessage = ({
315603
315942
  className,
315604
315943
  conversationId,
315605
315944
  refetchOnComplete = true,
315606
- styleProps
315945
+ styleProps,
315946
+ compactInProgress = false
315607
315947
  }) => {
315608
- const { getStreamingMessage, isMessageStreamingComplete } = useStreamingMessagesStore();
315609
- const storeMessage = getStreamingMessage(messageId);
315610
- const isStoreMessageComplete = isMessageStreamingComplete(messageId);
315611
- const handleComplete = reactExports.useCallback(
315612
- (completedMessage) => {
315613
- setTimeout(() => {
315614
- if (onComplete) {
315615
- onComplete(completedMessage);
315616
- }
315617
- }, 50);
315618
- },
315619
- [onComplete]
315948
+ const storeMessage = useStreamingMessagesStore(
315949
+ (state2) => state2.streamingMessages[messageId] ?? null
315620
315950
  );
315621
- reactExports.useEffect(() => {
315622
- if (isStoreMessageComplete && storeMessage?.content && onComplete) {
315623
- const timer2 = setTimeout(() => {
315624
- onComplete(storeMessage.content);
315625
- }, 50);
315626
- return () => clearTimeout(timer2);
315627
- }
315628
- return void 0;
315629
- }, [isStoreMessageComplete, storeMessage, onComplete]);
315951
+ const isStoreMessageComplete = storeMessage?.isComplete ?? false;
315630
315952
  const {
315631
315953
  message: wsMessage,
315632
315954
  isStreamable,
@@ -315640,7 +315962,7 @@ const StreamingMessage = ({
315640
315962
  } = useStreamingMessage({
315641
315963
  messageId,
315642
315964
  autoConnect,
315643
- onComplete: handleComplete,
315965
+ onComplete,
315644
315966
  onUpdate,
315645
315967
  keepAlive,
315646
315968
  conversationId,
@@ -315699,30 +316021,6 @@ const StreamingMessage = ({
315699
316021
  () => status === "connected" && !isStoreMessageComplete,
315700
316022
  [status, isStoreMessageComplete]
315701
316023
  );
315702
- const shouldShowStreaming = reactExports.useMemo(() => {
315703
- return status === "connected" && !isStoreMessageComplete;
315704
- }, [status, isStoreMessageComplete]);
315705
- const hasCalledOnCompleteRef = reactExports.useRef(false);
315706
- reactExports.useEffect(() => {
315707
- if (!shouldShowStreaming && storeMessage?.content && onComplete && !hasCalledOnCompleteRef.current) {
315708
- hasCalledOnCompleteRef.current = true;
315709
- const timer2 = setTimeout(() => {
315710
- onComplete(storeMessage.content);
315711
- }, 50);
315712
- return () => clearTimeout(timer2);
315713
- }
315714
- return void 0;
315715
- }, [shouldShowStreaming, storeMessage, onComplete]);
315716
- reactExports.useEffect(() => {
315717
- hasCalledOnCompleteRef.current = false;
315718
- }, []);
315719
- reactExports.useEffect(() => {
315720
- return () => {
315721
- if (hasCalledOnCompleteRef.current) {
315722
- hasCalledOnCompleteRef.current = false;
315723
- }
315724
- };
315725
- }, []);
315726
316024
  const lastValidMessageRef = reactExports.useRef(null);
315727
316025
  const message2 = reactExports.useMemo(() => {
315728
316026
  if (wsMessage) {
@@ -315752,8 +316050,128 @@ const StreamingMessage = ({
315752
316050
  onConnectionControls(connectionControls);
315753
316051
  }
315754
316052
  }, [onConnectionControls, connectionControls]);
316053
+ const [isActionExpanded, setIsActionExpanded] = reactExports.useState(!compactInProgress);
316054
+ const [isThinkingExpanded, setIsThinkingExpanded] = reactExports.useState(false);
316055
+ const [isInProgressDetailsExpanded, setIsInProgressDetailsExpanded] = reactExports.useState(!compactInProgress);
316056
+ reactExports.useEffect(() => {
316057
+ if (!messageId) {
316058
+ return;
316059
+ }
316060
+ setIsActionExpanded(!compactInProgress);
316061
+ setIsThinkingExpanded(false);
316062
+ setIsInProgressDetailsExpanded(!compactInProgress);
316063
+ }, [messageId, compactInProgress]);
316064
+ const useCompactInProgressMode = compactInProgress && !isStoreMessageComplete;
316065
+ const showExpandedStreamingDetails = !useCompactInProgressMode || isInProgressDetailsExpanded;
316066
+ reactExports.useEffect(() => {
316067
+ if (useCompactInProgressMode && isInProgressDetailsExpanded) {
316068
+ setIsActionExpanded(true);
316069
+ }
316070
+ }, [useCompactInProgressMode, isInProgressDetailsExpanded]);
316071
+ const compactPreviewText = reactExports.useMemo(
316072
+ () => getStreamingPreviewText(message2),
316073
+ [message2]
316074
+ );
316075
+ const compactSummaryIcon = reactExports.useMemo(
316076
+ () => getStreamingCompactIcon(message2),
316077
+ [message2]
316078
+ );
316079
+ const toggleInProgressDetails = reactExports.useCallback(() => {
316080
+ if (!useCompactInProgressMode) return;
316081
+ setIsInProgressDetailsExpanded((prev2) => !prev2);
316082
+ }, [useCompactInProgressMode]);
316083
+ const compactSummaryLine = reactExports.useMemo(() => {
316084
+ if (!useCompactInProgressMode) {
316085
+ return null;
316086
+ }
316087
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
316088
+ Box,
316089
+ {
316090
+ component: "button",
316091
+ type: "button",
316092
+ "aria-expanded": isInProgressDetailsExpanded,
316093
+ onClick: toggleInProgressDetails,
316094
+ sx: {
316095
+ display: "flex",
316096
+ justifyContent: "flex-start",
316097
+ alignItems: "center",
316098
+ cursor: "pointer",
316099
+ minHeight: 28,
316100
+ opacity: 0.9,
316101
+ mb: showExpandedStreamingDetails ? 1 : 0,
316102
+ padding: 0,
316103
+ width: "100%",
316104
+ border: "none",
316105
+ background: "transparent",
316106
+ textAlign: "left"
316107
+ },
316108
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
316109
+ Box,
316110
+ {
316111
+ sx: (theme2) => ({
316112
+ display: "inline-flex",
316113
+ alignItems: "center",
316114
+ gap: 1,
316115
+ maxWidth: "100%",
316116
+ padding: "5px 10px",
316117
+ borderRadius: "999px",
316118
+ color: theme2.palette.text.secondary,
316119
+ backgroundColor: alpha$1(
316120
+ theme2.palette.common.black,
316121
+ theme2.palette.mode === "dark" ? 0.14 : 0.04
316122
+ )
316123
+ }),
316124
+ children: [
316125
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
316126
+ Box,
316127
+ {
316128
+ component: "span",
316129
+ sx: {
316130
+ width: 20,
316131
+ height: 20,
316132
+ borderRadius: "100%",
316133
+ display: "flex",
316134
+ alignItems: "center",
316135
+ justifyContent: "center",
316136
+ flexShrink: 0
316137
+ },
316138
+ children: compactSummaryIcon
316139
+ }
316140
+ ),
316141
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
316142
+ Typography,
316143
+ {
316144
+ variant: "body2",
316145
+ noWrap: true,
316146
+ sx: {
316147
+ maxWidth: "100%",
316148
+ fontSize: "0.82rem",
316149
+ lineHeight: 1.35,
316150
+ color: "inherit",
316151
+ overflow: "hidden",
316152
+ textOverflow: "ellipsis",
316153
+ whiteSpace: "nowrap"
316154
+ },
316155
+ children: compactPreviewText
316156
+ }
316157
+ ),
316158
+ isActivelyStreaming && /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 12, thickness: 4 })
316159
+ ]
316160
+ }
316161
+ )
316162
+ }
316163
+ );
316164
+ }, [
316165
+ useCompactInProgressMode,
316166
+ isInProgressDetailsExpanded,
316167
+ showExpandedStreamingDetails,
316168
+ compactSummaryIcon,
316169
+ compactPreviewText,
316170
+ isActivelyStreaming,
316171
+ toggleInProgressDetails
316172
+ ]);
315755
316173
  const statusIndicator = reactExports.useMemo(() => {
315756
- if (!showStatus) return null;
316174
+ if (!showStatus || useCompactInProgressMode) return null;
315757
316175
  switch (status) {
315758
316176
  case "connecting":
315759
316177
  case "reconnecting":
@@ -315809,7 +316227,7 @@ const StreamingMessage = ({
315809
316227
  default:
315810
316228
  return null;
315811
316229
  }
315812
- }, [status, showStatus]);
316230
+ }, [status, showStatus, useCompactInProgressMode]);
315813
316231
  const loadingIndicator = reactExports.useMemo(() => {
315814
316232
  if (!isLoading && !isRefetching) return null;
315815
316233
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { display: "flex", alignItems: "center", mt: 1 }, children: [
@@ -315866,8 +316284,6 @@ const StreamingMessage = ({
315866
316284
  }
315867
316285
  );
315868
316286
  }, [error]);
315869
- const [isActionExpanded, setIsActionExpanded] = reactExports.useState(false);
315870
- const [isThinkingExpanded, setIsThinkingExpanded] = reactExports.useState(false);
315871
316287
  const handleActionExpand = () => setIsActionExpanded(true);
315872
316288
  const handleActionCollapse = (e3) => {
315873
316289
  e3.stopPropagation();
@@ -315913,105 +316329,108 @@ const StreamingMessage = ({
315913
316329
  "data-streaming": isActivelyStreaming ? "true" : "false",
315914
316330
  children: [
315915
316331
  statusIndicator,
315916
- children2,
315917
- loadingIndicator,
315918
- message2?.thinking && /* @__PURE__ */ jsxRuntimeExports.jsx(
315919
- ExpandableThinkingContent,
315920
- {
315921
- thinking: message2.thinking,
315922
- isExpanded: isThinkingExpanded,
315923
- onExpand: handleThinkingExpand,
315924
- onCollapse: handleThinkingCollapse
315925
- }
315926
- ),
315927
- messageContent,
315928
- streamingLoader,
315929
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
315930
- ExpandableActionElement,
315931
- {
315932
- executionType: message2?.execution_type || "action",
315933
- action: message2?.action,
315934
- isUser: false,
315935
- isExpanded: isActionExpanded,
315936
- onExpand: handleActionExpand,
315937
- onCollapse: handleActionCollapse,
315938
- hasCollapsibleContent,
315939
- isLoading: isActivelyStreaming,
315940
- children: [
315941
- message2?.code && /* @__PURE__ */ jsxRuntimeExports.jsx(
315942
- CodeBlock,
315943
- {
315944
- code: message2.code,
315945
- isUser: false,
315946
- flexDirection: "column-reverse"
315947
- }
315948
- ),
315949
- message2?.content && /* @__PURE__ */ jsxRuntimeExports.jsx(
315950
- CodeBlock,
315951
- {
315952
- header: "Content",
315953
- code: message2.content,
315954
- isUser: false,
315955
- language: fileLanguage,
315956
- flexDirection: "column-reverse"
315957
- }
315958
- ),
315959
- message2?.replacements && /* @__PURE__ */ jsxRuntimeExports.jsx(
315960
- CodeBlock,
315961
- {
315962
- header: "Replacements",
315963
- code: message2.replacements,
315964
- isUser: false,
315965
- language: "diff",
315966
- flexDirection: "column-reverse"
315967
- }
315968
- ),
315969
- message2?.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser: false }),
315970
- message2?.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser: false }),
315971
- message2?.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser: false })
315972
- ]
315973
- }
315974
- ),
315975
- message2?.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2, mt: 2 }, children: message2.files.filter((file) => isImage$1(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315976
- ImageAttachment,
315977
- {
315978
- file,
315979
- src: getUrl2(file),
315980
- onClick: handleFileClick,
315981
- conversationId: conversationId ?? ""
315982
- },
315983
- `${messageId}-${file}`
315984
- )) }),
315985
- message2?.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isVideo$1(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315986
- VideoAttachment,
315987
- {
315988
- file,
315989
- src: getUrl2(file),
315990
- onClick: handleFileClick,
315991
- conversationId: conversationId ?? ""
315992
- },
315993
- `${messageId}-${file}`
315994
- )) }),
315995
- message2?.files && message2.files.length > 0 && message2.files.some((file) => isAudio$1(file)) && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isAudio$1(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
315996
- AudioAttachment,
315997
- {
315998
- content: getUrl2(file),
315999
- isUser: false
316000
- },
316001
- `${messageId}-${file}`
316002
- )) }),
316003
- message2?.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter(
316004
- (file) => !isImage$1(file) && !isVideo$1(file) && !isAudio$1(file)
316005
- ).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316006
- FileAttachment,
316007
- {
316008
- file,
316009
- onClick: handleFileClick,
316010
- conversationId: conversationId ?? ""
316011
- },
316012
- `${messageId}-${file}`
316013
- )) }),
316014
- errorDisplay,
316332
+ compactSummaryLine,
316333
+ showExpandedStreamingDetails && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
316334
+ children2,
316335
+ loadingIndicator,
316336
+ message2?.thinking && /* @__PURE__ */ jsxRuntimeExports.jsx(
316337
+ ExpandableThinkingContent,
316338
+ {
316339
+ thinking: message2.thinking,
316340
+ isExpanded: isThinkingExpanded,
316341
+ onExpand: handleThinkingExpand,
316342
+ onCollapse: handleThinkingCollapse
316343
+ }
316344
+ ),
316345
+ messageContent,
316346
+ streamingLoader,
316347
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
316348
+ ExpandableActionElement,
316349
+ {
316350
+ executionType: message2?.execution_type || "action",
316351
+ action: message2?.action,
316352
+ isUser: false,
316353
+ isExpanded: isActionExpanded,
316354
+ onExpand: handleActionExpand,
316355
+ onCollapse: handleActionCollapse,
316356
+ hasCollapsibleContent,
316357
+ isLoading: isActivelyStreaming,
316358
+ children: [
316359
+ message2?.code && /* @__PURE__ */ jsxRuntimeExports.jsx(
316360
+ CodeBlock,
316361
+ {
316362
+ code: message2.code,
316363
+ isUser: false,
316364
+ flexDirection: "column-reverse"
316365
+ }
316366
+ ),
316367
+ message2?.content && /* @__PURE__ */ jsxRuntimeExports.jsx(
316368
+ CodeBlock,
316369
+ {
316370
+ header: "Content",
316371
+ code: message2.content,
316372
+ isUser: false,
316373
+ language: fileLanguage,
316374
+ flexDirection: "column-reverse"
316375
+ }
316376
+ ),
316377
+ message2?.replacements && /* @__PURE__ */ jsxRuntimeExports.jsx(
316378
+ CodeBlock,
316379
+ {
316380
+ header: "Replacements",
316381
+ code: message2.replacements,
316382
+ isUser: false,
316383
+ language: "diff",
316384
+ flexDirection: "column-reverse"
316385
+ }
316386
+ ),
316387
+ message2?.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser: false }),
316388
+ message2?.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser: false }),
316389
+ message2?.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser: false })
316390
+ ]
316391
+ }
316392
+ ),
316393
+ message2?.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2, mt: 2 }, children: message2.files.filter((file) => isImage$1(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316394
+ ImageAttachment,
316395
+ {
316396
+ file,
316397
+ src: getUrl2(file),
316398
+ onClick: handleFileClick,
316399
+ conversationId: conversationId ?? ""
316400
+ },
316401
+ `${messageId}-${file}`
316402
+ )) }),
316403
+ message2?.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isVideo$1(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316404
+ VideoAttachment,
316405
+ {
316406
+ file,
316407
+ src: getUrl2(file),
316408
+ onClick: handleFileClick,
316409
+ conversationId: conversationId ?? ""
316410
+ },
316411
+ `${messageId}-${file}`
316412
+ )) }),
316413
+ message2?.files && message2.files.length > 0 && message2.files.some((file) => isAudio$1(file)) && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isAudio$1(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316414
+ AudioAttachment,
316415
+ {
316416
+ content: getUrl2(file),
316417
+ isUser: false
316418
+ },
316419
+ `${messageId}-${file}`
316420
+ )) }),
316421
+ message2?.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter(
316422
+ (file) => !isImage$1(file) && !isVideo$1(file) && !isAudio$1(file)
316423
+ ).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316424
+ FileAttachment,
316425
+ {
316426
+ file,
316427
+ onClick: handleFileClick,
316428
+ conversationId: conversationId ?? ""
316429
+ },
316430
+ `${messageId}-${file}`
316431
+ )) }),
316432
+ errorDisplay
316433
+ ] }),
316015
316434
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: scrollRef, style: { height: 1, width: 1, opacity: 0 } })
316016
316435
  ]
316017
316436
  }
@@ -316046,13 +316465,13 @@ const MessagePaper = React$1.memo(
316046
316465
  content: content2,
316047
316466
  message: message2,
316048
316467
  onMessageComplete,
316049
- isLastMessage,
316050
- isJobRunning,
316051
316468
  agentId,
316052
- isSmallView
316469
+ isSmallView,
316470
+ metadataMode = "default"
316053
316471
  }) => {
316054
316472
  const theme2 = useTheme$2();
316055
316473
  const messageContentRef = reactExports.useRef(null);
316474
+ const shouldRenderDefaultMetadata = metadataMode === "default";
316056
316475
  const { replies, remainingContent } = reactExports.useMemo(
316057
316476
  () => parseReplies(content2 || ""),
316058
316477
  [content2]
@@ -316064,6 +316483,7 @@ const MessagePaper = React$1.memo(
316064
316483
  }),
316065
316484
  [isSmallView]
316066
316485
  );
316486
+ const resolvedConversationId = message2?.conversation_id ?? agentId;
316067
316487
  if (isUser) {
316068
316488
  const childrenWithRemainingContent = React$1.Children.map(
316069
316489
  children2,
@@ -316107,7 +316527,7 @@ const MessagePaper = React$1.memo(
316107
316527
  ] })
316108
316528
  }
316109
316529
  ),
316110
- message2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
316530
+ message2 && shouldRenderDefaultMetadata && /* @__PURE__ */ jsxRuntimeExports.jsx(
316111
316531
  MessageControls,
316112
316532
  {
316113
316533
  isUser,
@@ -316124,39 +316544,26 @@ const MessagePaper = React$1.memo(
316124
316544
  () => message2?.is_streamable === true && message2?.is_complete === false && !isUser,
316125
316545
  [message2?.is_streamable, message2?.is_complete, isUser]
316126
316546
  );
316127
- const { isMessageStreamingComplete } = useStreamingMessagesStore();
316128
- const isStreamingActuallyComplete = reactExports.useMemo(() => {
316129
- if (!message2?.id) return true;
316130
- return isMessageStreamingComplete(message2.id);
316131
- }, [message2?.id, isMessageStreamingComplete]);
316547
+ const isStreamingActuallyComplete = useStreamingMessagesStore(
316548
+ (state2) => message2?.id ? state2.streamingMessages[message2.id]?.isComplete ?? false : true
316549
+ );
316132
316550
  const shouldShowStreaming = reactExports.useMemo(() => {
316133
316551
  if (!isStreamable) return false;
316134
316552
  if (isStreamingActuallyComplete) return false;
316135
- return isJobRunning;
316136
- }, [isStreamable, isStreamingActuallyComplete, isJobRunning]);
316137
- const hasHandledCompletionRef = reactExports.useRef(false);
316553
+ return true;
316554
+ }, [isStreamable, isStreamingActuallyComplete]);
316555
+ const completionNotifiedRef = reactExports.useRef(null);
316138
316556
  reactExports.useEffect(() => {
316139
- if (!shouldShowStreaming && message2 && !hasHandledCompletionRef.current) {
316140
- hasHandledCompletionRef.current = true;
316141
- const timer2 = setTimeout(() => {
316142
- if (onMessageComplete) {
316143
- onMessageComplete();
316144
- }
316145
- }, 50);
316146
- return () => clearTimeout(timer2);
316557
+ if (!message2?.id) return;
316558
+ if (shouldShowStreaming) {
316559
+ completionNotifiedRef.current = null;
316560
+ return;
316147
316561
  }
316148
- return void 0;
316149
- }, [shouldShowStreaming, message2, onMessageComplete]);
316150
- reactExports.useEffect(() => {
316151
- hasHandledCompletionRef.current = false;
316152
- }, []);
316153
- reactExports.useEffect(() => {
316154
- return () => {
316155
- if (hasHandledCompletionRef.current) {
316156
- hasHandledCompletionRef.current = false;
316157
- }
316158
- };
316159
- }, []);
316562
+ if (onMessageComplete && completionNotifiedRef.current !== message2.id) {
316563
+ completionNotifiedRef.current = message2.id;
316564
+ onMessageComplete();
316565
+ }
316566
+ }, [message2?.id, onMessageComplete, shouldShowStreaming]);
316160
316567
  const messageStyles = reactExports.useMemo(
316161
316568
  () => ({
316162
316569
  borderRadius: 2,
@@ -316170,34 +316577,6 @@ const MessagePaper = React$1.memo(
316170
316577
  }),
316171
316578
  [theme2.palette.text.primary, isSmallView]
316172
316579
  );
316173
- const {
316174
- containerRef: scrollRef,
316175
- scrollToBottom,
316176
- isFarFromBottom
316177
- } = useScrollToBottom();
316178
- const isNearBottom = !isFarFromBottom;
316179
- const shouldAutoScrollRef = reactExports.useRef(true);
316180
- reactExports.useEffect(() => {
316181
- if (!isLastMessage || !shouldShowStreaming || !message2) return;
316182
- shouldAutoScrollRef.current = isNearBottom;
316183
- const scrollInterval = setInterval(() => {
316184
- if (shouldAutoScrollRef.current) {
316185
- scrollToBottom();
316186
- }
316187
- }, 350);
316188
- return () => {
316189
- clearInterval(scrollInterval);
316190
- };
316191
- }, [
316192
- shouldShowStreaming,
316193
- message2,
316194
- scrollToBottom,
316195
- isNearBottom,
316196
- isLastMessage
316197
- ]);
316198
- reactExports.useEffect(() => {
316199
- shouldAutoScrollRef.current = isNearBottom;
316200
- }, [isNearBottom]);
316201
316580
  const streamingMessageComponent = reactExports.useMemo(() => {
316202
316581
  if (!shouldShowStreaming || !message2) return null;
316203
316582
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -316208,19 +316587,21 @@ const MessagePaper = React$1.memo(
316208
316587
  showStatus: false,
316209
316588
  keepAlive: true,
316210
316589
  sx: messageStyles,
316211
- conversationId: message2.conversation_id,
316590
+ conversationId: resolvedConversationId,
316212
316591
  refetchOnComplete: true,
316213
316592
  onComplete: () => {
316214
316593
  if (onMessageComplete) {
316215
316594
  onMessageComplete();
316216
316595
  }
316217
316596
  },
316218
- styleProps: markdownStyleProps
316597
+ styleProps: markdownStyleProps,
316598
+ compactInProgress: true
316219
316599
  }
316220
316600
  );
316221
316601
  }, [
316222
316602
  shouldShowStreaming,
316223
316603
  message2,
316604
+ resolvedConversationId,
316224
316605
  messageStyles,
316225
316606
  onMessageComplete,
316226
316607
  markdownStyleProps
@@ -316260,13 +316641,13 @@ const MessagePaper = React$1.memo(
316260
316641
  }
316261
316642
  ),
316262
316643
  childrenWithRemainingContent,
316263
- message2?.conversation_id && /* @__PURE__ */ jsxRuntimeExports.jsx(
316644
+ resolvedConversationId && /* @__PURE__ */ jsxRuntimeExports.jsx(
316264
316645
  TextSelectionControls,
316265
316646
  {
316266
316647
  agentId,
316267
316648
  targetRef: messageContentRef,
316268
316649
  isUser,
316269
- conversationId: message2.conversation_id,
316650
+ conversationId: resolvedConversationId,
316270
316651
  showSpeech: true,
316271
316652
  showCopy: true,
316272
316653
  showReply: true
@@ -316283,6 +316664,7 @@ const MessagePaper = React$1.memo(
316283
316664
  handleThinkingExpand,
316284
316665
  handleThinkingCollapse,
316285
316666
  agentId,
316667
+ resolvedConversationId,
316286
316668
  replies,
316287
316669
  remainingContent,
316288
316670
  markdownStyleProps
@@ -316301,7 +316683,7 @@ const MessagePaper = React$1.memo(
316301
316683
  children: [
316302
316684
  streamingMessageComponent,
316303
316685
  regularMessageComponents,
316304
- message2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
316686
+ message2 && shouldRenderDefaultMetadata && /* @__PURE__ */ jsxRuntimeExports.jsx(
316305
316687
  MessageTimestamp,
316306
316688
  {
316307
316689
  timestamp: message2.timestamp,
@@ -316316,7 +316698,7 @@ const MessagePaper = React$1.memo(
316316
316698
  }
316317
316699
  }
316318
316700
  ),
316319
- message2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
316701
+ message2 && shouldRenderDefaultMetadata && /* @__PURE__ */ jsxRuntimeExports.jsx(
316320
316702
  MessageControls,
316321
316703
  {
316322
316704
  isUser,
@@ -316334,8 +316716,7 @@ const MessagePaper = React$1.memo(
316334
316716
  // If not, a transition could be added here for when isStreamable changes.
316335
316717
  }
316336
316718
  }
316337
- ),
316338
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: scrollRef, style: { height: 1, width: 1, opacity: 0 } })
316719
+ )
316339
316720
  ]
316340
316721
  }
316341
316722
  );
@@ -316387,6 +316768,7 @@ const SecurityCheckHighlight = ({
316387
316768
  children2
316388
316769
  ] });
316389
316770
  };
316771
+ const localOperatorClient = createLocalOperatorClient(apiConfig.baseUrl);
316390
316772
  const isWebUrl = (path2) => {
316391
316773
  return path2.startsWith("http://") || path2.startsWith("https://");
316392
316774
  };
@@ -316495,12 +316877,9 @@ const MessageItem = reactExports.memo(
316495
316877
  }
316496
316878
  }
316497
316879
  }, [message2.files, conversationId, addMentionedFilesBatch]);
316498
- const client2 = reactExports.useMemo(() => {
316499
- return createLocalOperatorClient(apiConfig.baseUrl);
316500
- }, []);
316501
316880
  const getUrl2 = reactExports.useCallback(
316502
- (path2) => getAttachmentUrl(client2, path2),
316503
- [client2]
316881
+ (path2) => getAttachmentUrl(localOperatorClient, path2),
316882
+ []
316504
316883
  );
316505
316884
  const handleFileClick = reactExports.useCallback(async (filePath) => {
316506
316885
  try {
@@ -316524,205 +316903,233 @@ const MessageItem = reactExports.memo(
316524
316903
  return null;
316525
316904
  }
316526
316905
  const isUser = message2.role === "user";
316906
+ const isCompactAssistantMessage = !isUser && Boolean(message2.action);
316527
316907
  const isAction2 = message2.execution_type === "action";
316528
316908
  const isSecurityCheck = message2.execution_type === "security_check";
316529
316909
  const shouldUseActionBlock = message2.execution_type === "reflection" || message2.execution_type === "action";
316530
316910
  if (shouldUseActionBlock) {
316531
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(MessageContainer, { isUser, isSmallView, children: [
316532
- !isSmallView && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageAvatar, { isUser }),
316533
- /* @__PURE__ */ jsxRuntimeExports.jsx(
316534
- MessagePaper,
316535
- {
316536
- isUser,
316537
- content: message2.message,
316538
- isSmallView,
316539
- message: message2,
316540
- onMessageComplete,
316541
- isLastMessage: isLastMessage ?? false,
316542
- isJobRunning: !!currentExecution,
316543
- agentId: conversationId,
316544
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(
316545
- ActionBlock,
316546
- {
316547
- message: message2.message ?? "",
316548
- fileContent: message2.content,
316549
- replacements: message2.replacements,
316550
- action: message2.action,
316551
- executionType: message2.execution_type || "action",
316552
- isUser,
316553
- code: message2.code,
316554
- stdout: currentExecution?.stdout ?? message2.stdout,
316555
- stderr: currentExecution?.stderr ?? message2.stderr,
316556
- logging: currentExecution?.logging ?? message2.logging,
316557
- files: message2.files,
316558
- conversationId,
316559
- filePath: message2.file_path,
316560
- isLoading: isLastMessage && !!currentExecution,
316561
- isSmallView
316562
- }
316563
- )
316564
- }
316565
- )
316566
- ] });
316567
- }
316568
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(MessageContainer, { isUser, isSmallView, children: [
316569
- !isSmallView && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageAvatar, { isUser }),
316570
- isSecurityCheck ? /* @__PURE__ */ jsxRuntimeExports.jsx(SecurityCheckHighlight, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
316571
- MessagePaper,
316911
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
316912
+ MessageContainer,
316572
316913
  {
316573
316914
  isUser,
316574
- content: message2.message,
316575
316915
  isSmallView,
316576
- message: message2,
316577
- onMessageComplete,
316578
- isLastMessage: isLastMessage ?? false,
316579
- isJobRunning: !!currentExecution,
316580
- agentId: conversationId,
316916
+ compact: isCompactAssistantMessage,
316581
316917
  children: [
316582
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316583
- ImageAttachment,
316584
- {
316585
- file,
316586
- src: getUrl2(file),
316587
- onClick: handleFileClick,
316588
- conversationId
316589
- },
316590
- `${message2.id}-${file}`
316591
- )) }),
316592
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isVideo(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316593
- VideoAttachment,
316918
+ !isSmallView && /* @__PURE__ */ jsxRuntimeExports.jsx(
316919
+ MessageAvatar,
316594
316920
  {
316595
- file,
316596
- src: getUrl2(file),
316597
- onClick: handleFileClick,
316598
- conversationId
316599
- },
316600
- `${message2.id}-${file}`
316601
- )) }),
316602
- message2.message && !(message2.is_streamable && !message2.is_complete) && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
316603
- (() => {
316604
- const hasCollapsibleContent = isSecurityCheck && (message2.code || message2.stdout || message2.stderr || message2.logging);
316605
- const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
316606
- message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
316607
- message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
316608
- message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
316609
- message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
316610
- ] });
316611
- if (hasCollapsibleContent) {
316612
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
316613
- CollapsibleMessage,
316614
- {
316615
- defaultCollapsed: true,
316616
- hasContent: hasCollapsibleContent,
316617
- children: contentBlocks
316618
- }
316619
- );
316921
+ isUser,
316922
+ compact: isCompactAssistantMessage
316620
316923
  }
316621
- return contentBlocks;
316622
- })(),
316623
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter((file) => !isImage(file) && !isVideo(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316624
- FileAttachment,
316625
- {
316626
- file,
316627
- onClick: handleFileClick,
316628
- conversationId
316629
- },
316630
- `${message2.id}-${file}`
316631
- )) }),
316924
+ ),
316632
316925
  /* @__PURE__ */ jsxRuntimeExports.jsx(
316633
- MessageTimestamp,
316926
+ MessagePaper,
316634
316927
  {
316635
- timestamp: message2.timestamp,
316636
316928
  isUser,
316637
- isSmallView
316638
- }
316639
- )
316640
- ]
316641
- }
316642
- ) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
316643
- MessagePaper,
316644
- {
316645
- isUser,
316646
- content: message2.message,
316647
- message: message2,
316648
- isSmallView,
316649
- onMessageComplete,
316650
- isLastMessage: isLastMessage ?? false,
316651
- isJobRunning: !!currentExecution,
316652
- agentId: conversationId,
316653
- children: [
316654
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316655
- ImageAttachment,
316656
- {
316657
- file,
316658
- src: getUrl2(file),
316659
- onClick: handleFileClick,
316660
- conversationId
316661
- },
316662
- `${message2.id}-${file}`
316663
- )) }),
316664
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isVideo(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316665
- VideoAttachment,
316666
- {
316667
- file,
316668
- src: getUrl2(file),
316669
- onClick: handleFileClick,
316670
- conversationId
316671
- },
316672
- `${message2.id}-${file}`
316673
- )) }),
316674
- message2.files && message2.files.length > 0 && message2.files.some((file) => isAudio(file)) && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isAudio(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316675
- AudioAttachment,
316676
- {
316677
- content: getUrl2(file),
316678
- isUser
316679
- },
316680
- `${message2.id}-${file}`
316681
- )) }),
316682
- message2.message && !(message2.is_streamable && !message2.is_complete) && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
316683
- (() => {
316684
- const hasCollapsibleContent = isAction2 && (message2.code || message2.stdout || message2.stderr || message2.logging);
316685
- const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
316686
- message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
316687
- message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
316688
- message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
316689
- message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
316690
- ] });
316691
- if (hasCollapsibleContent) {
316692
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
316693
- CollapsibleMessage,
316929
+ content: message2.message,
316930
+ isSmallView,
316931
+ message: message2,
316932
+ onMessageComplete,
316933
+ isLastMessage: isLastMessage ?? false,
316934
+ isJobRunning: !!currentExecution,
316935
+ agentId: conversationId,
316936
+ metadataMode: "custom",
316937
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
316938
+ ActionBlock,
316694
316939
  {
316695
- defaultCollapsed: true,
316696
- hasContent: hasCollapsibleContent,
316697
- children: contentBlocks
316940
+ message: message2.message ?? "",
316941
+ fileContent: message2.content,
316942
+ replacements: message2.replacements,
316943
+ action: message2.action,
316944
+ executionType: message2.execution_type || "action",
316945
+ isUser,
316946
+ code: message2.code,
316947
+ stdout: currentExecution?.stdout ?? message2.stdout,
316948
+ stderr: currentExecution?.stderr ?? message2.stderr,
316949
+ logging: currentExecution?.logging ?? message2.logging,
316950
+ files: message2.files,
316951
+ conversationId,
316952
+ filePath: message2.file_path,
316953
+ isLoading: isLastMessage && !!currentExecution,
316954
+ isSmallView,
316955
+ compact: isCompactAssistantMessage,
316956
+ messageId: message2.id,
316957
+ timestamp: message2.timestamp,
316958
+ agentId: conversationId
316698
316959
  }
316699
- );
316700
- }
316701
- return contentBlocks;
316702
- })(),
316703
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter(
316704
- (file) => !isImage(file) && !isVideo(file) && !isAudio(file)
316705
- ).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316706
- FileAttachment,
316707
- {
316708
- file,
316709
- onClick: handleFileClick,
316710
- conversationId
316711
- },
316712
- `${message2.id}-${file}`
316713
- )) }),
316714
- /* @__PURE__ */ jsxRuntimeExports.jsx(
316715
- MessageTimestamp,
316716
- {
316717
- timestamp: message2.timestamp,
316718
- isUser,
316719
- isSmallView
316960
+ )
316720
316961
  }
316721
316962
  )
316722
316963
  ]
316723
316964
  }
316724
- )
316725
- ] });
316965
+ );
316966
+ }
316967
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
316968
+ MessageContainer,
316969
+ {
316970
+ isUser,
316971
+ isSmallView,
316972
+ compact: isCompactAssistantMessage,
316973
+ children: [
316974
+ !isSmallView && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageAvatar, { isUser, compact: isCompactAssistantMessage }),
316975
+ isSecurityCheck ? /* @__PURE__ */ jsxRuntimeExports.jsx(SecurityCheckHighlight, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
316976
+ MessagePaper,
316977
+ {
316978
+ isUser,
316979
+ content: message2.message,
316980
+ isSmallView,
316981
+ message: message2,
316982
+ onMessageComplete,
316983
+ isLastMessage: isLastMessage ?? false,
316984
+ isJobRunning: !!currentExecution,
316985
+ agentId: conversationId,
316986
+ children: [
316987
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316988
+ ImageAttachment,
316989
+ {
316990
+ file,
316991
+ src: getUrl2(file),
316992
+ onClick: handleFileClick,
316993
+ conversationId
316994
+ },
316995
+ `${message2.id}-${file}`
316996
+ )) }),
316997
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isVideo(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
316998
+ VideoAttachment,
316999
+ {
317000
+ file,
317001
+ src: getUrl2(file),
317002
+ onClick: handleFileClick,
317003
+ conversationId
317004
+ },
317005
+ `${message2.id}-${file}`
317006
+ )) }),
317007
+ message2.message && !(message2.is_streamable && !message2.is_complete) && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
317008
+ (() => {
317009
+ const hasCollapsibleContent = isSecurityCheck && (message2.code || message2.stdout || message2.stderr || message2.logging);
317010
+ const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
317011
+ message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
317012
+ message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
317013
+ message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
317014
+ message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
317015
+ ] });
317016
+ if (hasCollapsibleContent) {
317017
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
317018
+ CollapsibleMessage,
317019
+ {
317020
+ defaultCollapsed: true,
317021
+ hasContent: hasCollapsibleContent,
317022
+ children: contentBlocks
317023
+ }
317024
+ );
317025
+ }
317026
+ return contentBlocks;
317027
+ })(),
317028
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter((file) => !isImage(file) && !isVideo(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
317029
+ FileAttachment,
317030
+ {
317031
+ file,
317032
+ onClick: handleFileClick,
317033
+ conversationId
317034
+ },
317035
+ `${message2.id}-${file}`
317036
+ )) }),
317037
+ isUser && /* @__PURE__ */ jsxRuntimeExports.jsx(
317038
+ MessageTimestamp,
317039
+ {
317040
+ timestamp: message2.timestamp,
317041
+ isUser,
317042
+ isSmallView
317043
+ }
317044
+ )
317045
+ ]
317046
+ }
317047
+ ) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
317048
+ MessagePaper,
317049
+ {
317050
+ isUser,
317051
+ content: message2.message,
317052
+ message: message2,
317053
+ isSmallView,
317054
+ onMessageComplete,
317055
+ isLastMessage: isLastMessage ?? false,
317056
+ isJobRunning: !!currentExecution,
317057
+ agentId: conversationId,
317058
+ children: [
317059
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
317060
+ ImageAttachment,
317061
+ {
317062
+ file,
317063
+ src: getUrl2(file),
317064
+ onClick: handleFileClick,
317065
+ conversationId
317066
+ },
317067
+ `${message2.id}-${file}`
317068
+ )) }),
317069
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isVideo(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
317070
+ VideoAttachment,
317071
+ {
317072
+ file,
317073
+ src: getUrl2(file),
317074
+ onClick: handleFileClick,
317075
+ conversationId
317076
+ },
317077
+ `${message2.id}-${file}`
317078
+ )) }),
317079
+ message2.files && message2.files.length > 0 && message2.files.some((file) => isAudio(file)) && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mb: 2 }, children: message2.files.filter((file) => isAudio(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
317080
+ AudioAttachment,
317081
+ {
317082
+ content: getUrl2(file),
317083
+ isUser
317084
+ },
317085
+ `${message2.id}-${file}`
317086
+ )) }),
317087
+ message2.message && !(message2.is_streamable && !message2.is_complete) && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
317088
+ (() => {
317089
+ const hasCollapsibleContent = isAction2 && (message2.code || message2.stdout || message2.stderr || message2.logging);
317090
+ const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
317091
+ message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
317092
+ message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
317093
+ message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
317094
+ message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
317095
+ ] });
317096
+ if (hasCollapsibleContent) {
317097
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
317098
+ CollapsibleMessage,
317099
+ {
317100
+ defaultCollapsed: true,
317101
+ hasContent: hasCollapsibleContent,
317102
+ children: contentBlocks
317103
+ }
317104
+ );
317105
+ }
317106
+ return contentBlocks;
317107
+ })(),
317108
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter(
317109
+ (file) => !isImage(file) && !isVideo(file) && !isAudio(file)
317110
+ ).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
317111
+ FileAttachment,
317112
+ {
317113
+ file,
317114
+ onClick: handleFileClick,
317115
+ conversationId
317116
+ },
317117
+ `${message2.id}-${file}`
317118
+ )) }),
317119
+ isUser && /* @__PURE__ */ jsxRuntimeExports.jsx(
317120
+ MessageTimestamp,
317121
+ {
317122
+ timestamp: message2.timestamp,
317123
+ isUser,
317124
+ isSmallView
317125
+ }
317126
+ )
317127
+ ]
317128
+ }
317129
+ )
317130
+ ]
317131
+ }
317132
+ );
316726
317133
  }
316727
317134
  );
316728
317135
  const MessagesViewWrapper = styled$1(Box, {
@@ -316826,6 +317233,11 @@ const FullScreenCenteredContainer = styled$1(Box)({
316826
317233
  height: "100%",
316827
317234
  width: "100%"
316828
317235
  });
317236
+ const INITIAL_RENDERED_MESSAGES = 40;
317237
+ const BACKGROUND_HYDRATION_BATCH_SIZE = 25;
317238
+ const BACKGROUND_HYDRATION_INTERVAL_MS = 40;
317239
+ const FAST_SCROLL_HYDRATION_BATCH_SIZE = 120;
317240
+ const getInitialRenderedCount = (totalMessages) => totalMessages > INITIAL_RENDERED_MESSAGES ? INITIAL_RENDERED_MESSAGES : totalMessages;
316829
317241
  const MessagesView = React$1.memo(
316830
317242
  ({
316831
317243
  messages,
@@ -316841,33 +317253,106 @@ const MessagesView = React$1.memo(
316841
317253
  conversationId,
316842
317254
  isSmallView
316843
317255
  }) => {
317256
+ const [renderedMessageCount, setRenderedMessageCount] = reactExports.useState(
317257
+ () => getInitialRenderedCount(messages.length)
317258
+ );
317259
+ const previousConversationIdRef = reactExports.useRef(conversationId);
317260
+ const previousMessageCountRef = reactExports.useRef(messages.length);
316844
317261
  const collapsed = messages.length === 0 && !isLoadingMessages && !isFetchingMore;
317262
+ reactExports.useEffect(() => {
317263
+ const previousMessageCount = previousMessageCountRef.current;
317264
+ const hasConversationChanged = previousConversationIdRef.current !== conversationId;
317265
+ if (hasConversationChanged) {
317266
+ previousConversationIdRef.current = conversationId;
317267
+ setRenderedMessageCount(getInitialRenderedCount(messages.length));
317268
+ previousMessageCountRef.current = messages.length;
317269
+ return;
317270
+ }
317271
+ if (messages.length < previousMessageCount) {
317272
+ setRenderedMessageCount(
317273
+ (current) => Math.min(current, messages.length)
317274
+ );
317275
+ } else if (messages.length > previousMessageCount) {
317276
+ const delta = messages.length - previousMessageCount;
317277
+ setRenderedMessageCount((current) => {
317278
+ if (current >= previousMessageCount) {
317279
+ return messages.length;
317280
+ }
317281
+ return Math.min(messages.length, current + Math.min(delta, 1));
317282
+ });
317283
+ }
317284
+ previousMessageCountRef.current = messages.length;
317285
+ }, [conversationId, messages.length]);
317286
+ reactExports.useEffect(() => {
317287
+ if (renderedMessageCount >= messages.length) {
317288
+ return;
317289
+ }
317290
+ const timeoutId = window.setTimeout(() => {
317291
+ setRenderedMessageCount(
317292
+ (current) => Math.min(messages.length, current + BACKGROUND_HYDRATION_BATCH_SIZE)
317293
+ );
317294
+ }, BACKGROUND_HYDRATION_INTERVAL_MS);
317295
+ return () => {
317296
+ window.clearTimeout(timeoutId);
317297
+ };
317298
+ }, [messages.length, renderedMessageCount]);
317299
+ reactExports.useEffect(() => {
317300
+ const container = messagesContainerRef.current;
317301
+ if (!container || renderedMessageCount >= messages.length) {
317302
+ return;
317303
+ }
317304
+ const handlePrioritizeHistoryHydration = () => {
317305
+ const { scrollTop, scrollHeight, clientHeight } = container;
317306
+ const maxScrollValue = Math.abs(scrollHeight - clientHeight);
317307
+ const absScrollTop = Math.abs(scrollTop);
317308
+ const distanceFromTop = scrollTop < 0 ? maxScrollValue - absScrollTop : maxScrollValue - scrollTop;
317309
+ if (distanceFromTop < 260) {
317310
+ setRenderedMessageCount(
317311
+ (current) => Math.min(
317312
+ messages.length,
317313
+ current + FAST_SCROLL_HYDRATION_BATCH_SIZE
317314
+ )
317315
+ );
317316
+ }
317317
+ };
317318
+ container.addEventListener("scroll", handlePrioritizeHistoryHydration, {
317319
+ passive: true
317320
+ });
317321
+ return () => {
317322
+ container.removeEventListener(
317323
+ "scroll",
317324
+ handlePrioritizeHistoryHydration
317325
+ );
317326
+ };
317327
+ }, [messages.length, renderedMessageCount, messagesContainerRef]);
317328
+ const renderedMessages = reactExports.useMemo(() => {
317329
+ if (renderedMessageCount >= messages.length) {
317330
+ return messages;
317331
+ }
317332
+ return messages.slice(messages.length - renderedMessageCount);
317333
+ }, [messages, renderedMessageCount]);
317334
+ const hiddenMessageCount = messages.length - renderedMessages.length;
316845
317335
  const lastMessage = messages[messages.length - 1];
316846
- const { isMessageStreamingComplete } = useStreamingMessagesStore();
316847
- const lastStreamComplete = lastMessage?.id ? isMessageStreamingComplete(lastMessage.id) : false;
317336
+ const lastMessageId = lastMessage?.id ?? "";
317337
+ const lastStreamComplete = useStreamingMessagesStore(
317338
+ (state2) => state2.streamingMessages[lastMessageId]?.isComplete ?? false
317339
+ );
316848
317340
  const lastMessageIsStreaming = Boolean(
316849
317341
  lastMessage?.is_streamable && !(lastMessage?.is_complete || lastStreamComplete)
316850
317342
  );
316851
317343
  const handleMessageComplete = reactExports.useCallback(() => {
316852
- setTimeout(() => {
316853
- if (refetch) {
316854
- refetch();
316855
- }
316856
- }, 200);
317344
+ refetch?.();
316857
317345
  }, [refetch]);
316858
- reactExports.useEffect(() => {
316859
- if (messages.length > 0) {
316860
- const lastMessage2 = messages[messages.length - 1];
316861
- if (lastMessage2?.is_complete && lastMessage2?.is_streamable) {
316862
- console.debug("Last message completed:", lastMessage2.id);
316863
- }
316864
- }
316865
- }, [messages]);
316866
317346
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagesViewWrapper, { collapsed, children: [
316867
317347
  isFetchingMore && /* @__PURE__ */ jsxRuntimeExports.jsxs(LoadingMoreIndicator, { isSmallView, children: [
316868
317348
  /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 16, sx: { mr: 1 } }),
316869
317349
  "Loading older messages..."
316870
317350
  ] }),
317351
+ !isFetchingMore && hiddenMessageCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(LoadingMoreIndicator, { isSmallView, children: [
317352
+ "Rendering ",
317353
+ hiddenMessageCount,
317354
+ " earlier messages..."
317355
+ ] }),
316871
317356
  /* @__PURE__ */ jsxRuntimeExports.jsx(
316872
317357
  MessagesContainer,
316873
317358
  {
@@ -316889,8 +317374,8 @@ const MessagesView = React$1.memo(
316889
317374
  id: "messages-end-anchor"
316890
317375
  }
316891
317376
  ),
316892
- messages.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(CenteredMessagesContainer, { isSmallView, children: [
316893
- messages.map(
317377
+ renderedMessages.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(CenteredMessagesContainer, { isSmallView, children: [
317378
+ renderedMessages.map(
316894
317379
  (message2, index2) => message2.execution_type === "info" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
316895
317380
  InfoMessageDivider,
316896
317381
  {
@@ -316901,14 +317386,10 @@ const MessagesView = React$1.memo(
316901
317386
  ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
316902
317387
  MessageItem,
316903
317388
  {
316904
- message: {
316905
- ...message2,
316906
- conversation_id: conversationId
316907
- // Add conversation ID to message
316908
- },
317389
+ message: message2,
316909
317390
  conversationId,
316910
- currentExecution: index2 === messages.length - 1 && currentExecution ? currentExecution : void 0,
316911
- isLastMessage: index2 === messages.length - 1,
317391
+ currentExecution: index2 === renderedMessages.length - 1 && currentExecution ? currentExecution : void 0,
317392
+ isLastMessage: index2 === renderedMessages.length - 1,
316912
317393
  onMessageComplete: handleMessageComplete,
316913
317394
  isSmallView
316914
317395
  },
@@ -317450,14 +317931,20 @@ const ChatSidebarItem = ({
317450
317931
  agent.id
317451
317932
  );
317452
317933
  };
317453
- const MemoizedChatSidebarItem = reactExports.memo(ChatSidebarItem);
317454
- const ChatSidebar = ({
317934
+ const areChatSidebarItemsEqual = (prev2, next2) => {
317935
+ return prev2.isSelected === next2.isSelected && prev2.index === next2.index && prev2.agent.id === next2.agent.id && prev2.agent.name === next2.agent.name && prev2.agent.last_message === next2.agent.last_message && prev2.agent.last_message_datetime === next2.agent.last_message_datetime && prev2.onSelectConversation === next2.onSelectConversation && prev2.onNavigateToAgentSettings === next2.onNavigateToAgentSettings && prev2.onExportAgent === next2.onExportAgent && prev2.onClearAgentConversation === next2.onClearAgentConversation && prev2.onAgentDeleted === next2.onAgentDeleted && prev2.onUploadAgentToHub === next2.onUploadAgentToHub && prev2.getFullDateTime === next2.getFullDateTime && prev2.formatMessageDateTime === next2.formatMessageDateTime && prev2.truncateMessage === next2.truncateMessage;
317936
+ };
317937
+ const MemoizedChatSidebarItem = reactExports.memo(ChatSidebarItem, areChatSidebarItemsEqual);
317938
+ const ChatSidebarComponent = ({
317455
317939
  selectedConversation,
317456
317940
  onSelectConversation,
317457
317941
  onNavigateToAgentSettings
317458
317942
  }) => {
317459
317943
  const [searchQuery, setSearchQuery2] = reactExports.useState("");
317460
- const { openCreateAgentDialog } = useUiPreferencesStore();
317944
+ const openCreateAgentDialog = useUiPreferencesStore(
317945
+ (state2) => state2.openCreateAgentDialog
317946
+ );
317947
+ const debouncedSearchQuery = useDebouncedValue(searchQuery.trim(), 250);
317461
317948
  const [isImportDialogOpen, setIsImportDialogOpen] = reactExports.useState(false);
317462
317949
  const perPage = 50;
317463
317950
  const [isUploadDialogOpen, setIsUploadDialogOpen] = reactExports.useState(false);
@@ -317476,8 +317963,8 @@ const ChatSidebar = ({
317476
317963
  } = useAgents(
317477
317964
  page,
317478
317965
  perPage,
317479
- 5e3,
317480
- searchQuery,
317966
+ 0,
317967
+ debouncedSearchQuery || void 0,
317481
317968
  "last_message_datetime",
317482
317969
  "desc"
317483
317970
  );
@@ -317555,14 +318042,14 @@ const ChatSidebar = ({
317555
318042
  },
317556
318043
  [getAgentUploadValidationIssues]
317557
318044
  );
317558
- const handleCloseUploadDialog = () => {
318045
+ const handleCloseUploadDialog = reactExports.useCallback(() => {
317559
318046
  setIsUploadDialogOpen(false);
317560
318047
  setUploadAgent(null);
317561
318048
  setUploadValidationIssues([]);
317562
- };
317563
- const handleConfirmUpload = () => {
318049
+ }, []);
318050
+ const handleConfirmUpload = reactExports.useCallback(() => {
317564
318051
  handleCloseUploadDialog();
317565
- };
318052
+ }, [handleCloseUploadDialog]);
317566
318053
  const handleAgentCreated = reactExports.useCallback(
317567
318054
  (agentId) => {
317568
318055
  const fetchAndSelectAgent = async () => {
@@ -317609,10 +318096,10 @@ const ChatSidebar = ({
317609
318096
  [handleOpenUploadDialog]
317610
318097
  // handleOpenUploadDialog is stable as it's not in deps array of its own useCallback
317611
318098
  );
317612
- const truncateMessage = (message2, maxLength = 60) => {
318099
+ const truncateMessage = reactExports.useCallback((message2, maxLength = 60) => {
317613
318100
  if (!message2) return "";
317614
318101
  return message2.length > maxLength ? `${message2.substring(0, maxLength)}...` : message2;
317615
- };
318102
+ }, []);
317616
318103
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(SidebarContainer$2, { elevation: 0, "data-tour-tag": "agent-list-panel", children: [
317617
318104
  /* @__PURE__ */ jsxRuntimeExports.jsx(
317618
318105
  SidebarHeader$2,
@@ -317691,6 +318178,7 @@ const ChatSidebar = ({
317691
318178
  )
317692
318179
  ] });
317693
318180
  };
318181
+ const ChatSidebar = reactExports.memo(ChatSidebarComponent);
317694
318182
  const ErrorContainer$1 = styled$1(Paper)({
317695
318183
  display: "flex",
317696
318184
  flexDirection: "column",
@@ -317762,8 +318250,8 @@ const ChatPage = () => {
317762
318250
  const messageInputRef = reactExports.useRef(null);
317763
318251
  const { agentId, navigateToAgent } = useAgentRouteParam();
317764
318252
  const navigate = useNavigate();
317765
- const queryClient2 = useQueryClient();
317766
- const { isCanvasOpen, setCanvasOpen } = useUiPreferencesStore();
318253
+ const isCanvasOpen = useUiPreferencesStore((state2) => state2.isCanvasOpen);
318254
+ const setCanvasOpen = useUiPreferencesStore((state2) => state2.setCanvasOpen);
317767
318255
  reactExports.useEffect(() => {
317768
318256
  const handleKeyDown = (event) => {
317769
318257
  if (event.key === "c" && (event.metaKey || event.ctrlKey) && event.shiftKey) {
@@ -317776,7 +318264,12 @@ const ChatPage = () => {
317776
318264
  document.removeEventListener("keydown", handleKeyDown);
317777
318265
  };
317778
318266
  }, [isCanvasOpen, setCanvasOpen]);
317779
- const { setLastChatAgentId, getLastAgentId } = useAgentSelectionStore();
318267
+ const setLastChatAgentId = useAgentSelectionStore(
318268
+ (state2) => state2.setLastChatAgentId
318269
+ );
318270
+ const getLastAgentId = useAgentSelectionStore(
318271
+ (state2) => state2.getLastAgentId
318272
+ );
317780
318273
  const effectiveAgentId = agentId || getLastAgentId("chat");
317781
318274
  const conversationId = effectiveAgentId || void 0;
317782
318275
  const selectedConversation = effectiveAgentId || void 0;
@@ -317791,7 +318284,7 @@ const ChatPage = () => {
317791
318284
  () => createLocalOperatorClient(apiConfig.baseUrl),
317792
318285
  []
317793
318286
  );
317794
- const { getMessages } = useChatStore();
318287
+ const getMessages = useChatStore((state2) => state2.getMessages);
317795
318288
  const { data: agentData } = useAgent(conversationId);
317796
318289
  const {
317797
318290
  messages,
@@ -317804,14 +318297,13 @@ const ChatPage = () => {
317804
318297
  // Get the ref from the hook
317805
318298
  refetch
317806
318299
  } = useConversationMessages(conversationId);
317807
- const { addMessage } = useChatStore();
318300
+ const addMessage = useChatStore((state2) => state2.addMessage);
317808
318301
  const {
317809
318302
  currentJobId,
317810
318303
  setCurrentJobId,
317811
318304
  jobStatus,
317812
318305
  isLoading,
317813
318306
  setIsLoading,
317814
- checkForActiveJobs,
317815
318307
  currentExecution
317816
318308
  } = useJobPolling({
317817
318309
  conversationId,
@@ -317866,18 +318358,6 @@ const ChatPage = () => {
317866
318358
  }
317867
318359
  }, [agentId, isLoadingMessages, messages.length, scrollToBottom]);
317868
318360
  const previousConversationIdRef = reactExports.useRef(void 0);
317869
- reactExports.useEffect(() => {
317870
- if (conversationId) {
317871
- checkForActiveJobs(conversationId);
317872
- }
317873
- }, [conversationId, checkForActiveJobs]);
317874
- reactExports.useEffect(() => {
317875
- if (conversationId) {
317876
- queryClient2.invalidateQueries({
317877
- queryKey: [...conversationMessagesQueryKey, conversationId]
317878
- });
317879
- }
317880
- }, [conversationId, queryClient2]);
317881
318361
  const handleOpenOptions = reactExports.useCallback(() => {
317882
318362
  setIsOptionsSidebarOpen(true);
317883
318363
  }, []);