local-operator-ui 0.1.3 → 0.1.5

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.
@@ -1,4 +1,4 @@
1
- import { c as createStyled, r as resolveProps, u as useTheme, a as reactExports, b as clsx, d as useForkRef, j as jsxRuntimeExports, e as capitalize, f as composeClasses, g as createTheme, h as generateUtilityClass, i as generateUtilityClasses, k as useDefaultProps, s as styled$1, m as memoTheme, l as getDefaultExportFromCjs, n as requireReactDom, _ as _inheritsLoose, o as _objectWithoutPropertiesLoose$1, R as React, T as TransitionGroupContext, p as duration, q as useTheme$1, t as useTimeout, v as useId, B as ButtonBase, w as alpha, x as createSimplePaletteValueFilter, C as CircularProgress, P as Paper, y as darken, z as lighten, A as useEventCallback, D as setRef, E as useEnhancedEffect, F as useRtl, G as globalCss, H as formatMuiErrorMessage, I as rootShouldForwardProp, J as Typography, K as deepmerge, L as extendSxProp, M as resolveBreakpointValues, N as handleBreakpoints, O as getPath, Q as isFocusVisible, S as typographyClasses, U as slotShouldForwardProp, V as clamp, W as emphasize, X as Timeout, Y as React$1, Z as Box, $ as FontAwesomeIcon, a0 as faRobot, a1 as faSliders, a2 as Button, a3 as faExclamationTriangle, a4 as faCheck, a5 as faTimes, a6 as faEraser, a7 as faPen, a8 as faInfoCircle, a9 as faGear, aa as faServer, ab as faStar, ac as faTrash, ad as faCommentDots, ae as faCode, af as faHome, ag as faDownload, ah as faFileAlt, ai as faDesktop, aj as faImage, ak as faMusic, al as faVideo, am as faLaptop, an as faUsers, ao as faDatabase, ap as faBoxOpen, aq as faBook, ar as faHdd, as as faBox, at as faArchive, au as faNetworkWired, av as faFolder, aw as faFolderOpen, ax as faClock, ay as faChevronDown, az as faTools, aA as faArrowDown, aB as faPaperclip, aC as faStop, aD as faPaperPlane, aE as faUser, aF as faFile, aG as faEllipsisVertical, aH as faComment, aI as faChevronLeft, aJ as faChevronRight, aK as faPlus, aL as faSearch, aM as faCommentSlash, aN as faArrowRight, aO as faComments, aP as faTag, aQ as faIdCard, aR as faCalendarAlt, aS as faCodeBranch, aT as faShieldAlt, aU as faArrowLeft, aV as requireReact, aW as LinearProgress, aX as keyframes, aY as faShield, aZ as faSignOut, a_ as faLightbulb, a$ as faMagicWandSparkles, b0 as faBrain, b1 as faWandMagicSparkles, b2 as faExternalLinkAlt, b3 as faKey, b4 as faGlobe, b5 as faLock, b6 as faEdit, b7 as faSave, b8 as faEnvelope, b9 as faCloudUploadAlt, ba as faHistory, bb as faListAlt, bc as library$1, bd as icons$1, be as CssBaseline, bf as ReactDOM$1, bg as ThemeProvider, bh as theme, bi as ErrorBoundary } from "./theme-D7qnOAQJ.js";
1
+ import { c as createStyled, r as resolveProps, u as useTheme, a as reactExports, b as clsx, d as useForkRef, j as jsxRuntimeExports, e as capitalize, f as composeClasses, g as createTheme, h as generateUtilityClass, i as generateUtilityClasses, k as useDefaultProps, s as styled$1, m as memoTheme, l as getDefaultExportFromCjs, n as requireReactDom, _ as _inheritsLoose, o as _objectWithoutPropertiesLoose$1, R as React, T as TransitionGroupContext, p as duration, q as useTheme$1, t as useTimeout, v as useId, B as ButtonBase, w as alpha, x as createSimplePaletteValueFilter, C as CircularProgress, P as Paper, y as darken, z as lighten, A as useEventCallback, D as setRef, E as useEnhancedEffect, F as useRtl, G as globalCss, H as formatMuiErrorMessage, I as rootShouldForwardProp, J as Typography, K as deepmerge, L as extendSxProp, M as resolveBreakpointValues, N as handleBreakpoints, O as getPath, Q as isFocusVisible, S as typographyClasses, U as slotShouldForwardProp, V as clamp, W as emphasize, X as Timeout, Y as React$1, Z as Box, $ as FontAwesomeIcon, a0 as faRobot, a1 as faSliders, a2 as Button, a3 as faExclamationTriangle, a4 as faCheck, a5 as faTimes, a6 as faEraser, a7 as faPen, a8 as faInfoCircle, a9 as faGear, aa as faServer, ab as faStar, ac as faTrash, ad as faCommentDots, ae as faCode, af as faHome, ag as faDownload, ah as faFileAlt, ai as faDesktop, aj as faImage, ak as faMusic, al as faVideo, am as faLaptop, an as faUsers, ao as faDatabase, ap as faBoxOpen, aq as faBook, ar as faHdd, as as faBox, at as faArchive, au as faNetworkWired, av as faFolder, aw as faFolderOpen, ax as faClock, ay as faChevronDown, az as faTools, aA as faArrowDown, aB as faPaperclip, aC as faStop, aD as faPaperPlane, aE as keyframes, aF as faChevronUp, aG as faQuestion, aH as faLightbulb, aI as faChevronRight, aJ as faFile, aK as faUser, aL as faEllipsisVertical, aM as faComment, aN as faChevronLeft, aO as faPlus, aP as faSearch, aQ as faCommentSlash, aR as faArrowRight, aS as faComments, aT as faTag, aU as faIdCard, aV as faCalendarAlt, aW as faCodeBranch, aX as faShieldAlt, aY as faArrowLeft, aZ as requireReact, a_ as LinearProgress, a$ as faShield, b0 as faSignOut, b1 as faMagicWandSparkles, b2 as faBrain, b3 as faWandMagicSparkles, b4 as faExternalLinkAlt, b5 as faKey, b6 as faGlobe, b7 as faLock, b8 as faEdit, b9 as faSave, ba as faEnvelope, bb as faCloudUploadAlt, bc as faHistory, bd as faListAlt, be as library$1, bf as icons$1, bg as CssBaseline, bh as ReactDOM$1, bi as ThemeProvider, bj as theme, bk as ErrorBoundary } from "./theme-CHCNkogj.js";
2
2
  const styled = createStyled();
3
3
  function getThemeProps(params) {
4
4
  const {
@@ -25356,34 +25356,6 @@ const AgentsApi = {
25356
25356
  }
25357
25357
  return response.json();
25358
25358
  },
25359
- /**
25360
- * Get agent conversation history
25361
- * Retrieve the conversation history for a specific agent.
25362
- *
25363
- * @param baseUrl - The base URL of the Local Operator API
25364
- * @param agentId - ID of the agent to get conversation for
25365
- * @param page - Page number (default: 1)
25366
- * @param perPage - Number of messages per page (default: 10)
25367
- * @returns Promise resolving to the agent conversation history
25368
- * @throws Error if the request fails
25369
- */
25370
- async getAgentConversation(baseUrl, agentId, page = 1, perPage = 20) {
25371
- const url = new URL(`${baseUrl}/v1/agents/${agentId}/conversation`);
25372
- url.searchParams.append("page", page.toString());
25373
- url.searchParams.append("per_page", perPage.toString());
25374
- const response = await fetch(url.toString(), {
25375
- method: "GET",
25376
- headers: {
25377
- Accept: "application/json"
25378
- }
25379
- });
25380
- if (!response.ok) {
25381
- throw new Error(
25382
- `Get agent conversation request failed: ${response.status} ${response.statusText}`
25383
- );
25384
- }
25385
- return response.json();
25386
- },
25387
25359
  /**
25388
25360
  * Get agent execution history
25389
25361
  * Retrieve the execution history for a specific agent.
@@ -25872,8 +25844,18 @@ const getImageUrl = (baseUrl, imagePath) => {
25872
25844
  const encodedPath = encodeURIComponent(normalizedPath);
25873
25845
  return `${normalizedBaseUrl}/v1/static/images?path=${encodedPath}`;
25874
25846
  };
25847
+ const getVideoUrl = (baseUrl, videoPath) => {
25848
+ const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
25849
+ let normalizedPath = videoPath;
25850
+ if (normalizedPath.startsWith("file://")) {
25851
+ normalizedPath = normalizedPath.substring(7);
25852
+ }
25853
+ const encodedPath = encodeURIComponent(normalizedPath);
25854
+ return `${normalizedBaseUrl}/v1/static/videos?path=${encodedPath}`;
25855
+ };
25875
25856
  const StaticApi = {
25876
- getImageUrl
25857
+ getImageUrl,
25858
+ getVideoUrl
25877
25859
  };
25878
25860
  class LocalOperatorClient {
25879
25861
  baseUrl;
@@ -30557,7 +30539,10 @@ const convertToMessage = (record) => {
30557
30539
  stderr: record.stderr,
30558
30540
  logging: record.logging,
30559
30541
  timestamp: record.timestamp ? new Date(record.timestamp) : /* @__PURE__ */ new Date(),
30560
- files: record.files
30542
+ files: record.files,
30543
+ action: record.action,
30544
+ execution_type: record.execution_type,
30545
+ task_classification: record.task_classification
30561
30546
  };
30562
30547
  };
30563
30548
  const useConversationMessages = (conversationId, pageSize2 = 20) => {
@@ -30763,8 +30748,15 @@ const useJobPolling = ({
30763
30748
  conversationId,
30764
30749
  addMessage
30765
30750
  }) => {
30766
- const [currentJobId, setCurrentJobId] = reactExports.useState(null);
30751
+ const [currentJobId, setCurrentJobIdInternal] = reactExports.useState(null);
30767
30752
  const [isLoading, setIsLoading] = reactExports.useState(false);
30753
+ const [currentExecution, setCurrentExecution] = reactExports.useState(null);
30754
+ const setCurrentJobId = reactExports.useCallback((jobId) => {
30755
+ setCurrentJobIdInternal(jobId);
30756
+ if (jobId === null) {
30757
+ setCurrentExecution(null);
30758
+ }
30759
+ }, []);
30768
30760
  const queryClient2 = useQueryClient();
30769
30761
  const { getMessages, setMessages } = useChatStore();
30770
30762
  const lastProcessedJobDataRef = reactExports.useRef(null);
@@ -30811,7 +30803,13 @@ const useJobPolling = ({
30811
30803
  return false;
30812
30804
  }
30813
30805
  },
30814
- [client.jobs, currentJobId, shouldEnableQuery, getConnectivityError]
30806
+ [
30807
+ client.jobs,
30808
+ currentJobId,
30809
+ shouldEnableQuery,
30810
+ getConnectivityError,
30811
+ setCurrentJobId
30812
+ ]
30815
30813
  );
30816
30814
  reactExports.useEffect(() => {
30817
30815
  if (conversationId !== previousConversationIdRef.current) {
@@ -30858,7 +30856,13 @@ const useJobPolling = ({
30858
30856
  }
30859
30857
  }
30860
30858
  previousConversationIdRef.current = conversationId;
30861
- }, [conversationId, client.jobs, shouldEnableQuery, getConnectivityError]);
30859
+ }, [
30860
+ conversationId,
30861
+ client.jobs,
30862
+ shouldEnableQuery,
30863
+ getConnectivityError,
30864
+ setCurrentJobId
30865
+ ]);
30862
30866
  const updateConversationMessages = reactExports.useCallback(
30863
30867
  async (agentId) => {
30864
30868
  if (!agentId) return;
@@ -30947,7 +30951,7 @@ const useJobPolling = ({
30947
30951
  setCurrentJobId(null);
30948
30952
  setIsLoading(false);
30949
30953
  },
30950
- [conversationId, addMessage, updateConversationMessages]
30954
+ [conversationId, addMessage, updateConversationMessages, setCurrentJobId]
30951
30955
  );
30952
30956
  const {
30953
30957
  data: jobData,
@@ -30981,6 +30985,9 @@ const useJobPolling = ({
30981
30985
  const jobDataSignature = `${jobData.id}-${jobData.status}-${dataUpdatedAt}`;
30982
30986
  if (jobDataSignature !== lastProcessedJobDataRef.current) {
30983
30987
  lastProcessedJobDataRef.current = jobDataSignature;
30988
+ if (jobData.current_execution) {
30989
+ setCurrentExecution(jobData.current_execution);
30990
+ }
30984
30991
  if (jobData.status === "processing") {
30985
30992
  const debounceTimeout = setTimeout(() => {
30986
30993
  updateConversationMessages(conversationId);
@@ -30989,6 +30996,7 @@ const useJobPolling = ({
30989
30996
  }
30990
30997
  if (jobData.status === "completed" || jobData.status === "failed") {
30991
30998
  handleJobCompletion(jobData);
30999
+ setCurrentExecution(null);
30992
31000
  }
30993
31001
  }
30994
31002
  return void 0;
@@ -30997,7 +31005,9 @@ const useJobPolling = ({
30997
31005
  dataUpdatedAt,
30998
31006
  handleJobCompletion,
30999
31007
  conversationId,
31000
- updateConversationMessages
31008
+ updateConversationMessages,
31009
+ setCurrentExecution,
31010
+ setCurrentJobId
31001
31011
  ]);
31002
31012
  reactExports.useEffect(() => {
31003
31013
  if (error) {
@@ -31013,7 +31023,8 @@ const useJobPolling = ({
31013
31023
  jobStatus: jobData?.status || null,
31014
31024
  isLoading,
31015
31025
  setIsLoading,
31016
- checkForActiveJobs
31026
+ checkForActiveJobs,
31027
+ currentExecution
31017
31028
  };
31018
31029
  };
31019
31030
  const useScrollToBottom = (dependencies = [], threshold = 300, buttonThreshold = 50) => {
@@ -31115,7 +31126,7 @@ const SidebarContainer$6 = styled$1(Box)({
31115
31126
  width: 280,
31116
31127
  height: "100%"
31117
31128
  });
31118
- const ContentContainer$2 = styled$1(Box)({
31129
+ const ContentContainer$4 = styled$1(Box)({
31119
31130
  flexGrow: 1,
31120
31131
  height: "100%",
31121
31132
  overflow: "hidden"
@@ -31126,7 +31137,7 @@ const StyledDivider = styled$1(Divider)({
31126
31137
  const ChatLayout = ({ sidebar, content: content2 }) => {
31127
31138
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Container$1, { children: [
31128
31139
  /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarContainer$6, { children: sidebar }),
31129
- /* @__PURE__ */ jsxRuntimeExports.jsx(ContentContainer$2, { children: content2 })
31140
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContentContainer$4, { children: content2 })
31130
31141
  ] });
31131
31142
  };
31132
31143
  const useAgentRouteParam = () => {
@@ -31553,6 +31564,9 @@ const useClearAgentConversation = () => {
31553
31564
  queryClient2.invalidateQueries({
31554
31565
  queryKey: ["agent", variables.agentId, "conversation"]
31555
31566
  });
31567
+ queryClient2.invalidateQueries({
31568
+ queryKey: ["conversation-messages", variables.agentId]
31569
+ });
31556
31570
  clearChatMessages(variables.agentId);
31557
31571
  clearMessageHistory(variables.agentId);
31558
31572
  y$1.success("Conversation cleared successfully");
@@ -43000,12 +43014,19 @@ const ModelSelect = ({
43000
43014
  }, [hostingId]);
43001
43015
  const { refreshModels } = useModels();
43002
43016
  const previousHostingIdRef = reactExports.useRef(null);
43017
+ const refreshTimeRef = reactExports.useRef(null);
43003
43018
  reactExports.useEffect(() => {
43004
43019
  if (hostingId && previousHostingIdRef.current !== hostingId) {
43005
43020
  previousHostingIdRef.current = hostingId;
43006
43021
  const timeoutId = setTimeout(() => {
43007
- refreshModels();
43008
- }, 0);
43022
+ const now = Date.now();
43023
+ const lastRefreshTime = refreshTimeRef.current;
43024
+ const THROTTLE_DURATION = 2e3;
43025
+ if (!lastRefreshTime || now - lastRefreshTime > THROTTLE_DURATION) {
43026
+ refreshModels();
43027
+ refreshTimeRef.current = now;
43028
+ }
43029
+ }, 100);
43009
43030
  return () => clearTimeout(timeoutId);
43010
43031
  }
43011
43032
  return void 0;
@@ -44525,64 +44546,6 @@ const MessageInput = ({
44525
44546
  )
44526
44547
  ] });
44527
44548
  };
44528
- const LoadingIndicator = ({ status, agentName = "Agent" }) => {
44529
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
44530
- Box,
44531
- {
44532
- sx: {
44533
- display: "flex",
44534
- alignItems: "center",
44535
- gap: 2
44536
- },
44537
- children: [
44538
- /* @__PURE__ */ jsxRuntimeExports.jsx(
44539
- Avatar,
44540
- {
44541
- sx: {
44542
- bgcolor: "rgba(56, 201, 106, 0.2)",
44543
- color: "primary.main"
44544
- },
44545
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faRobot, size: "sm" })
44546
- }
44547
- ),
44548
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
44549
- Box,
44550
- {
44551
- sx: {
44552
- bgcolor: "background.paper",
44553
- p: 2,
44554
- borderRadius: 2,
44555
- border: "1px solid rgba(255, 255, 255, 0.1)",
44556
- display: "flex",
44557
- alignItems: "center",
44558
- gap: 1
44559
- },
44560
- children: [
44561
- /* @__PURE__ */ jsxRuntimeExports.jsx(CircularProgress, { size: 16, color: "primary" }),
44562
- /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body2", children: status ? `${agentName} is ${getStatusText(status)}...` : `${agentName} is thinking...` })
44563
- ]
44564
- }
44565
- )
44566
- ]
44567
- }
44568
- );
44569
- };
44570
- const getStatusText = (status) => {
44571
- switch (status) {
44572
- case "pending":
44573
- return "waiting to start";
44574
- case "processing":
44575
- return "thinking";
44576
- case "completed":
44577
- return "finishing up";
44578
- case "failed":
44579
- return "having trouble";
44580
- case "cancelled":
44581
- return "was cancelled";
44582
- default:
44583
- return "thinking";
44584
- }
44585
- };
44586
44549
  function _objectWithoutPropertiesLoose(r, e) {
44587
44550
  if (null == r) return {};
44588
44551
  var t = {};
@@ -81904,94 +81867,434 @@ function ft(n2) {
81904
81867
  }
81905
81868
  return React.memo(l2);
81906
81869
  }
81907
- const MarkdownContent = styled$1(Box)({
81870
+ const SyntaxHighlighterStyles$1 = ft`
81871
+ .loading-syntax-highlighter * {
81872
+ font-family: 'Roboto Mono', monospace !important;
81873
+ }
81874
+ `;
81875
+ const dotAnimation = keyframes`
81876
+ 0%, 100% { opacity: 0.3; }
81877
+ 50% { opacity: 1; }
81878
+ `;
81879
+ const textStrobeAnimation = keyframes`
81880
+ 0% { opacity: 0.6; }
81881
+ 50% { opacity: 1; }
81882
+ 100% { opacity: 0.6; }
81883
+ `;
81884
+ const LoadingContainer$5 = styled$1(Box)(() => ({
81885
+ display: "flex",
81886
+ alignItems: "center",
81887
+ gap: 0
81888
+ }));
81889
+ const AgentAvatar$2 = styled$1(Avatar)(({ theme: theme2 }) => ({
81890
+ backgroundColor: "rgba(56, 201, 106, 0.2)",
81891
+ color: theme2.palette.primary.main
81892
+ }));
81893
+ const ContentContainer$3 = styled$1(Box)(() => ({
81894
+ display: "flex",
81895
+ flexDirection: "column",
81896
+ gap: 8,
81897
+ maxWidth: "calc(100% - 60px)"
81898
+ }));
81899
+ const StatusContainer = styled$1(Box)(() => ({
81900
+ display: "flex",
81901
+ alignItems: "center",
81902
+ gap: 8
81903
+ }));
81904
+ const StatusText = styled$1(Typography)(({ theme: theme2 }) => ({
81905
+ color: theme2.palette.text.secondary,
81906
+ display: "flex",
81907
+ marginLeft: 16,
81908
+ position: "relative",
81909
+ animation: `${textStrobeAnimation} 3s ease-in-out infinite`
81910
+ }));
81911
+ const StatusTextContent = styled$1("span")(() => ({
81908
81912
  wordBreak: "break-word",
81909
- overflowWrap: "break-word",
81910
- lineHeight: 1.6,
81911
- fontSize: "1.05rem",
81912
- "& code": {
81913
- fontFamily: '"Roboto Mono", monospace',
81914
- backgroundColor: "rgba(0, 0, 0, 0.3)",
81915
- padding: "3px 6px",
81916
- borderRadius: "4px",
81917
- fontSize: "0.85em",
81918
- whiteSpace: "pre-wrap",
81919
- wordBreak: "break-word",
81920
- color: "#e6e6e6"
81921
- },
81922
- "& pre": {
81923
- backgroundColor: "rgba(0, 0, 0, 0.3)",
81924
- padding: "16px",
81925
- borderRadius: "8px",
81926
- overflowX: "auto",
81927
- fontFamily: '"Roboto Mono", monospace',
81928
- fontSize: "0.85em",
81929
- margin: "12px 0",
81930
- maxWidth: "100%",
81931
- border: "1px solid rgba(255, 255, 255, 0.1)"
81932
- },
81933
- "& pre code": {
81934
- whiteSpace: "pre-wrap",
81935
- wordBreak: "break-word",
81913
+ display: "inline"
81914
+ }));
81915
+ const StatusControls = styled$1("span")(() => ({
81916
+ display: "inline-flex",
81917
+ alignItems: "center",
81918
+ marginLeft: 4,
81919
+ whiteSpace: "nowrap"
81920
+ }));
81921
+ const DotContainer = styled$1("span")(() => ({
81922
+ display: "inline-flex",
81923
+ alignItems: "center",
81924
+ position: "relative",
81925
+ zIndex: 2,
81926
+ marginLeft: 4
81927
+ }));
81928
+ const Dot = styled$1("span")(({ theme: theme2, delay }) => ({
81929
+ width: 4,
81930
+ height: 4,
81931
+ borderRadius: "50%",
81932
+ backgroundColor: theme2.palette.text.secondary,
81933
+ margin: "0 1px",
81934
+ animation: `${dotAnimation} 1.4s infinite ease-in-out`,
81935
+ animationDelay: `${delay}s`
81936
+ }));
81937
+ const CodeToggleButton = styled$1(Button)(({ theme: theme2 }) => ({
81938
+ color: theme2.palette.text.secondary,
81939
+ padding: "0 4px",
81940
+ minWidth: "auto",
81941
+ textTransform: "none",
81942
+ marginLeft: 8,
81943
+ height: "auto",
81944
+ fontSize: "0.75rem",
81945
+ lineHeight: 1,
81946
+ opacity: 0.7,
81947
+ borderRadius: "12px",
81948
+ transition: "all 0.2s ease",
81949
+ position: "relative",
81950
+ zIndex: 2,
81951
+ "&:hover": {
81936
81952
  backgroundColor: "transparent",
81937
- padding: 0,
81938
- borderRadius: 0
81939
- },
81940
- "& h1": {
81941
- fontSize: "1.5rem",
81942
- fontWeight: 600,
81943
- margin: "20px 0 12px 0",
81944
- borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
81945
- paddingBottom: "8px"
81946
- },
81947
- "& h2": {
81948
- fontSize: "1.3rem",
81949
- fontWeight: 600,
81950
- margin: "18px 0 10px 0"
81951
- },
81952
- "& h3": {
81953
- fontSize: "1.1rem",
81954
- fontWeight: 600,
81955
- margin: "16px 0 8px 0"
81956
- },
81957
- "& ul": {
81958
- paddingLeft: "24px",
81959
- margin: "10px 0"
81960
- },
81961
- "& li": {
81962
- margin: "4px 0"
81953
+ opacity: 1,
81954
+ color: theme2.palette.primary.light
81963
81955
  },
81964
- "& a": {
81965
- color: "#90caf9",
81966
- textDecoration: "none",
81967
- borderBottom: "1px dotted rgba(144, 202, 249, 0.5)",
81968
- transition: "all 0.2s ease",
81969
- "&:hover": {
81970
- textDecoration: "none",
81971
- borderBottom: "1px solid #90caf9",
81972
- color: "#bbdefb"
81956
+ "& .MuiButton-startIcon": {
81957
+ marginRight: 2,
81958
+ marginLeft: 0
81959
+ }
81960
+ }));
81961
+ const CodeContainer$4 = styled$1(Box)(() => ({
81962
+ maxWidth: "100%",
81963
+ marginLeft: 16,
81964
+ marginTop: 8
81965
+ }));
81966
+ const LoadingCodeBlock = ({ code: code2 }) => {
81967
+ if (!code2) return null;
81968
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
81969
+ Box,
81970
+ {
81971
+ sx: {
81972
+ width: "100%",
81973
+ maxHeight: "300px",
81974
+ overflow: "auto",
81975
+ "&::-webkit-scrollbar": {
81976
+ width: "6px",
81977
+ height: "6px"
81978
+ },
81979
+ "&::-webkit-scrollbar-thumb": {
81980
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
81981
+ borderRadius: "3px"
81982
+ },
81983
+ "&::-webkit-scrollbar-corner": {
81984
+ backgroundColor: "rgba(0, 0, 0, 0.3)"
81985
+ },
81986
+ borderRadius: "8px"
81987
+ },
81988
+ children: [
81989
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SyntaxHighlighterStyles$1, {}),
81990
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
81991
+ highlighter,
81992
+ {
81993
+ language: "python",
81994
+ style: atomOneDark,
81995
+ customStyle: {
81996
+ fontSize: "0.85rem",
81997
+ width: "100%",
81998
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.2)",
81999
+ padding: "0.75rem",
82000
+ margin: 0
82001
+ // Remove margin to make it more compact
82002
+ },
82003
+ codeTagProps: {
82004
+ style: {
82005
+ fontFamily: '"Roboto Mono", monospace !important'
82006
+ }
82007
+ },
82008
+ className: "loading-syntax-highlighter",
82009
+ wrapLines: true,
82010
+ wrapLongLines: true,
82011
+ children: code2
82012
+ }
82013
+ )
82014
+ ]
81973
82015
  }
81974
- },
81975
- "& strong": {
81976
- fontWeight: 600,
81977
- color: "#e6e6e6"
81978
- },
81979
- "& em": {
81980
- fontStyle: "italic",
81981
- color: "#e0e0e0"
81982
- },
81983
- "& br": {
81984
- display: "block",
81985
- content: '""',
81986
- marginTop: "8px"
81987
- },
81988
- "& p:first-of-type": {
81989
- marginTop: "2px"
81990
- },
81991
- "& p": {
81992
- margin: "8px 0"
82016
+ );
82017
+ };
82018
+ const getStatusText = (status) => {
82019
+ switch (status) {
82020
+ case "pending":
82021
+ return "Waiting to start";
82022
+ case "processing":
82023
+ return "Thinking";
82024
+ case "completed":
82025
+ return "Finishing up";
82026
+ case "failed":
82027
+ return "Had trouble";
82028
+ case "cancelled":
82029
+ return "Had to stop";
82030
+ default:
82031
+ return "Thinking";
82032
+ }
82033
+ };
82034
+ const getDetailedStatusText = (status, execution) => {
82035
+ if (execution.action) {
82036
+ switch (execution.action) {
82037
+ case "CODE":
82038
+ return "Executing code";
82039
+ case "WRITE":
82040
+ return "Writing content";
82041
+ case "EDIT":
82042
+ return "Editing content";
82043
+ case "READ":
82044
+ return "Reading content";
82045
+ case "ASK":
82046
+ return "Formulating a question";
82047
+ case "DONE":
82048
+ return "Completing the task";
82049
+ case "BYE":
82050
+ return "Ending the conversation";
82051
+ }
82052
+ }
82053
+ if (execution.execution_type) {
82054
+ switch (execution.execution_type) {
82055
+ case "plan":
82056
+ return "Planning my approach";
82057
+ case "action":
82058
+ return "Thinking";
82059
+ case "reflection":
82060
+ return "Reflecting on next steps";
82061
+ case "response":
82062
+ return "Writing a response";
82063
+ case "security_check":
82064
+ return "Performing security checks";
82065
+ case "classification":
82066
+ return "Thinking about my response";
82067
+ case "system":
82068
+ return "Processing system tasks";
82069
+ case "user_input":
82070
+ return "Processing your input";
82071
+ }
82072
+ }
82073
+ return status ? getStatusText(status) : "thinking";
82074
+ };
82075
+ const LoadingIndicator = ({ status, currentExecution, scrollToBottom }) => {
82076
+ const statusText = currentExecution ? getDetailedStatusText(status, currentExecution) : status ? getStatusText(status) : "Thinking";
82077
+ const codeSnippet = currentExecution?.code || null;
82078
+ const message2 = currentExecution?.message || null;
82079
+ const [isCodeExpanded, setIsCodeExpanded] = reactExports.useState(false);
82080
+ const { ref, scrollToBottom: scrollToBottomHook } = useScrollToBottom(
82081
+ [status, currentExecution, message2],
82082
+ 300,
82083
+ // Default threshold
82084
+ 50
82085
+ // Default button threshold
82086
+ );
82087
+ reactExports.useEffect(() => {
82088
+ if (codeSnippet && isCodeExpanded) {
82089
+ requestAnimationFrame(() => {
82090
+ if (scrollToBottomHook) {
82091
+ scrollToBottomHook();
82092
+ } else if (scrollToBottom) {
82093
+ scrollToBottom();
82094
+ }
82095
+ });
82096
+ }
82097
+ }, [codeSnippet, isCodeExpanded, scrollToBottom, scrollToBottomHook]);
82098
+ const toggleCodeExpansion = () => {
82099
+ setIsCodeExpanded((prev2) => !prev2);
82100
+ };
82101
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(LoadingContainer$5, { children: [
82102
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, style: { height: 0, width: 0 } }),
82103
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AgentAvatar$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faRobot, size: "sm" }) }),
82104
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContentContainer$3, { children: [
82105
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusContainer, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(StatusText, { variant: "body2", children: [
82106
+ /* @__PURE__ */ jsxRuntimeExports.jsx(StatusTextContent, { children: message2 ? message2 : `${statusText}` }),
82107
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(StatusControls, { children: [
82108
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DotContainer, { children: [
82109
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Dot, { delay: 0 }),
82110
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Dot, { delay: 0.2 }),
82111
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Dot, { delay: 0.4 })
82112
+ ] }),
82113
+ codeSnippet && /* @__PURE__ */ jsxRuntimeExports.jsx(
82114
+ CodeToggleButton,
82115
+ {
82116
+ onClick: toggleCodeExpansion,
82117
+ size: "small",
82118
+ variant: "text",
82119
+ startIcon: /* @__PURE__ */ jsxRuntimeExports.jsx(
82120
+ FontAwesomeIcon,
82121
+ {
82122
+ icon: isCodeExpanded ? faChevronUp : faChevronDown,
82123
+ size: "xs",
82124
+ style: { fontSize: "0.75rem" }
82125
+ }
82126
+ ),
82127
+ children: isCodeExpanded ? "(Hide code)" : "(Show code)"
82128
+ }
82129
+ )
82130
+ ] })
82131
+ ] }) }),
82132
+ codeSnippet && isCodeExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeContainer$4, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingCodeBlock, { code: codeSnippet }) })
82133
+ ] })
82134
+ ] });
82135
+ };
82136
+ const HighlightContainer$1 = styled$1(Box, {
82137
+ shouldForwardProp: (prop) => prop !== "action" && prop !== "isUser"
82138
+ })(({ action }) => ({
82139
+ position: "relative",
82140
+ padding: "16px",
82141
+ borderRadius: "8px",
82142
+ marginBottom: "16px",
82143
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
82144
+ width: "100%",
82145
+ border: `1px solid ${action === "DONE" ? "rgba(76, 175, 80, 0.5)" : "rgba(33, 150, 243, 0.5)"}`,
82146
+ backgroundColor: action === "DONE" ? "rgba(76, 175, 80, 0.1)" : "rgba(33, 150, 243, 0.1)",
82147
+ transition: "all 0.2s ease",
82148
+ "&:hover": {
82149
+ boxShadow: "0 6px 16px rgba(0, 0, 0, 0.2)"
81993
82150
  }
81994
- });
82151
+ }));
82152
+ const ActionBadge = styled$1(Box, {
82153
+ shouldForwardProp: (prop) => prop !== "action"
82154
+ })(({ theme: theme2, action }) => ({
82155
+ position: "absolute",
82156
+ top: "-10px",
82157
+ right: "16px",
82158
+ padding: "4px 8px",
82159
+ borderRadius: "12px",
82160
+ fontSize: "0.7rem",
82161
+ fontWeight: "bold",
82162
+ backgroundColor: action === "DONE" ? theme2.palette.success.main : theme2.palette.info.main,
82163
+ color: "#fff",
82164
+ display: "flex",
82165
+ alignItems: "center",
82166
+ gap: "4px",
82167
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
82168
+ }));
82169
+ const ActionHighlight = ({
82170
+ children,
82171
+ action,
82172
+ isUser,
82173
+ taskClassification,
82174
+ executionType
82175
+ }) => {
82176
+ const shouldHighlight = (action === "DONE" || action === "ASK") && taskClassification !== "conversation" || executionType === "response" && taskClassification !== "conversation";
82177
+ if (!shouldHighlight) {
82178
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
82179
+ }
82180
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(HighlightContainer$1, { action, isUser, children: [
82181
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ActionBadge, { action, children: [
82182
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
82183
+ FontAwesomeIcon,
82184
+ {
82185
+ icon: action === "DONE" ? faCheck : faQuestion,
82186
+ size: "xs"
82187
+ }
82188
+ ),
82189
+ action === "DONE" ? "COMPLETE" : "QUESTION"
82190
+ ] }),
82191
+ children
82192
+ ] });
82193
+ };
82194
+ const MarkdownContent = styled$1(Box, {
82195
+ shouldForwardProp: (prop) => ![
82196
+ "fontSize",
82197
+ "lineHeight",
82198
+ "paragraphSpacing",
82199
+ "headingScale",
82200
+ "codeSize"
82201
+ ].includes(prop)
82202
+ })(
82203
+ ({
82204
+ fontSize = "1.05rem",
82205
+ lineHeight = 1.6,
82206
+ paragraphSpacing = "8px",
82207
+ headingScale = 1,
82208
+ codeSize = "0.85em"
82209
+ }) => ({
82210
+ wordBreak: "break-word",
82211
+ overflowWrap: "break-word",
82212
+ lineHeight,
82213
+ fontSize,
82214
+ "& code": {
82215
+ fontFamily: '"Roboto Mono", monospace',
82216
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
82217
+ padding: "3px 6px",
82218
+ borderRadius: "4px",
82219
+ fontSize: codeSize,
82220
+ whiteSpace: "pre-wrap",
82221
+ wordBreak: "break-word",
82222
+ color: "#e6e6e6"
82223
+ },
82224
+ "& pre": {
82225
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
82226
+ padding: "16px",
82227
+ borderRadius: "8px",
82228
+ overflowX: "auto",
82229
+ fontFamily: '"Roboto Mono", monospace',
82230
+ fontSize: codeSize,
82231
+ margin: "12px 0",
82232
+ maxWidth: "100%",
82233
+ border: "1px solid rgba(255, 255, 255, 0.1)"
82234
+ },
82235
+ "& pre code": {
82236
+ whiteSpace: "pre-wrap",
82237
+ wordBreak: "break-word",
82238
+ backgroundColor: "transparent",
82239
+ padding: 0,
82240
+ borderRadius: 0
82241
+ },
82242
+ "& h1": {
82243
+ fontSize: `calc(1.5rem * ${headingScale})`,
82244
+ fontWeight: 600,
82245
+ margin: "20px 0 12px 0",
82246
+ borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
82247
+ paddingBottom: "8px"
82248
+ },
82249
+ "& h2": {
82250
+ fontSize: `calc(1.3rem * ${headingScale})`,
82251
+ fontWeight: 600,
82252
+ margin: "18px 0 10px 0"
82253
+ },
82254
+ "& h3": {
82255
+ fontSize: `calc(1.1rem * ${headingScale})`,
82256
+ fontWeight: 600,
82257
+ margin: "16px 0 8px 0"
82258
+ },
82259
+ "& ul": {
82260
+ paddingLeft: "24px",
82261
+ margin: "10px 0"
82262
+ },
82263
+ "& li": {
82264
+ margin: "4px 0"
82265
+ },
82266
+ "& a": {
82267
+ color: "#90caf9",
82268
+ textDecoration: "none",
82269
+ borderBottom: "1px dotted rgba(144, 202, 249, 0.5)",
82270
+ transition: "all 0.2s ease",
82271
+ "&:hover": {
82272
+ textDecoration: "none",
82273
+ borderBottom: "1px solid #90caf9",
82274
+ color: "#bbdefb"
82275
+ }
82276
+ },
82277
+ "& strong": {
82278
+ fontWeight: 600,
82279
+ color: "#e6e6e6"
82280
+ },
82281
+ "& em": {
82282
+ fontStyle: "italic",
82283
+ color: "#e0e0e0"
82284
+ },
82285
+ "& br": {
82286
+ display: "block",
82287
+ content: '""',
82288
+ marginTop: "8px"
82289
+ },
82290
+ "& p:first-of-type": {
82291
+ marginTop: "2px"
82292
+ },
82293
+ "& p": {
82294
+ margin: `${paragraphSpacing} 0`
82295
+ }
82296
+ })
82297
+ );
81995
82298
  const convertUrlsToMarkdownLinks = (text2) => {
81996
82299
  const urlRegex = /(?<!\]\()(https?:\/\/\S+?)([,.;:!?"'\)\]]+)?(?=\s|$)/g;
81997
82300
  return text2.replace(
@@ -82000,11 +82303,11 @@ const convertUrlsToMarkdownLinks = (text2) => {
82000
82303
  );
82001
82304
  };
82002
82305
  const MarkdownRenderer = reactExports.memo(
82003
- ({ content: content2 }) => {
82306
+ ({ content: content2, styleProps }) => {
82004
82307
  const processedContent = reactExports.useMemo(() => {
82005
82308
  return convertUrlsToMarkdownLinks(content2.trim());
82006
82309
  }, [content2]);
82007
- return /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82310
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownContent, { ...styleProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82008
82311
  Markdown,
82009
82312
  {
82010
82313
  components: {
@@ -82015,68 +82318,252 @@ const MarkdownRenderer = reactExports.memo(
82015
82318
  ) });
82016
82319
  }
82017
82320
  );
82018
- const MessageContainer = styled$1(Box, {
82019
- shouldForwardProp: (prop) => prop !== "isUser"
82020
- })(({ isUser }) => ({
82321
+ const BlockContainer = styled$1(Box)(() => ({
82322
+ width: "95%",
82323
+ cursor: "pointer",
82324
+ transition: "all 0.2s ease",
82325
+ marginLeft: 56,
82326
+ "&:hover": {
82327
+ opacity: 0.9
82328
+ }
82329
+ }));
82330
+ const BlockHeader = styled$1(Box, {
82331
+ shouldForwardProp: (prop) => prop !== "executionType" && prop !== "isUser"
82332
+ })(
82333
+ ({ theme: theme2, executionType }) => ({
82334
+ display: "flex",
82335
+ alignItems: "center",
82336
+ padding: "8px 12px",
82337
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
82338
+ borderLeft: `3px solid ${executionType === "plan" ? theme2.palette.grey[600] : theme2.palette.grey[600]}`
82339
+ })
82340
+ );
82341
+ const BlockIcon = styled$1(Box)(({ theme: theme2 }) => ({
82342
+ marginRight: 8,
82021
82343
  display: "flex",
82022
- flexDirection: isUser ? "row-reverse" : "row",
82023
- alignItems: "flex-start",
82024
- gap: 16,
82025
- marginBottom: 16
82344
+ alignItems: "center",
82345
+ justifyContent: "flex-start",
82346
+ color: theme2.palette.grey[500]
82026
82347
  }));
82027
- const UserAvatar$1 = styled$1(Avatar, {
82028
- shouldForwardProp: (prop) => prop !== "isUser"
82029
- })(({ isUser, theme: theme2 }) => ({
82030
- backgroundColor: isUser ? "rgba(66, 133, 244, 0.9)" : "rgba(56, 201, 106, 0.2)",
82031
- color: isUser ? "white" : theme2.palette.primary.main,
82032
- boxShadow: isUser ? "0 2px 8px rgba(66, 133, 244, 0.25)" : "none"
82348
+ const BlockTitle = styled$1(Typography)(({ theme: theme2 }) => ({
82349
+ fontWeight: 500,
82350
+ fontSize: "0.85rem",
82351
+ color: theme2.palette.grey[500]
82033
82352
  }));
82034
- const StyledPaper$1 = styled$1(Paper)(({ theme: theme2 }) => ({
82035
- [theme2.breakpoints.down("sm")]: {
82036
- maxWidth: "85%"
82037
- },
82038
- [theme2.breakpoints.between("sm", "md")]: {
82039
- maxWidth: "75%"
82040
- },
82041
- [theme2.breakpoints.up("md")]: {
82042
- maxWidth: "65%"
82043
- },
82044
- width: "auto",
82045
- padding: 16,
82046
- borderRadius: 8,
82047
- wordBreak: "break-word",
82048
- overflowWrap: "break-word",
82049
- position: "relative"
82353
+ const BlockContent = styled$1(Typography)(({ theme: theme2 }) => ({
82354
+ fontSize: "0.85rem",
82355
+ color: theme2.palette.grey[400],
82356
+ overflow: "hidden",
82357
+ textOverflow: "ellipsis",
82358
+ marginTop: 2
82050
82359
  }));
82051
- const MessagePaper = ({ isUser, elevation, children }) => {
82052
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
82053
- StyledPaper$1,
82054
- {
82055
- elevation,
82056
- sx: {
82057
- backgroundColor: isUser ? "rgba(66, 133, 244, 0.15)" : (theme2) => theme2.palette.background.paper,
82058
- border: isUser ? "1px solid rgba(66, 133, 244, 0.3)" : "1px solid rgba(255, 255, 255, 0.1)",
82059
- boxShadow: isUser ? "0 4px 12px rgba(0, 0, 0, 0.15)" : "0 2px 8px rgba(0, 0, 0, 0.1)",
82060
- color: isUser ? (theme2) => theme2.palette.text.primary : "inherit"
82061
- },
82062
- children
82360
+ const ExpandedContent = styled$1(Box)(({ theme: theme2 }) => ({
82361
+ padding: "12px 16px",
82362
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
82363
+ borderBottomLeftRadius: 4,
82364
+ borderBottomRightRadius: 4,
82365
+ fontSize: "0.85rem",
82366
+ color: theme2.palette.grey[300],
82367
+ borderLeft: `3px solid ${theme2.palette.grey[600]}`,
82368
+ marginLeft: 0
82369
+ }));
82370
+ const BackgroundBlock = ({
82371
+ content: content2,
82372
+ action,
82373
+ executionType,
82374
+ isUser
82375
+ }) => {
82376
+ const [isExpanded, setIsExpanded] = reactExports.useState(false);
82377
+ const toggleExpand = () => {
82378
+ setIsExpanded(!isExpanded);
82379
+ };
82380
+ const getTitle = () => {
82381
+ switch (action) {
82382
+ case "DONE":
82383
+ return "Task Complete";
82384
+ case "ASK":
82385
+ return "Asking a Question";
82386
+ default:
82387
+ return executionType === "plan" ? "Planning" : "Reflection";
82063
82388
  }
82064
- );
82389
+ };
82390
+ const getIcon = () => {
82391
+ switch (action) {
82392
+ case "DONE":
82393
+ return faCheck;
82394
+ case "ASK":
82395
+ return faQuestion;
82396
+ default:
82397
+ return executionType === "plan" ? faLightbulb : faCommentDots;
82398
+ }
82399
+ };
82400
+ const getTruncatedContent = (content22, maxLength = 140) => {
82401
+ return content22.length > maxLength ? `${content22.slice(0, maxLength)}...` : content22;
82402
+ };
82403
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(BlockContainer, { onClick: toggleExpand, children: [
82404
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(BlockHeader, { executionType, isUser, children: [
82405
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BlockIcon, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: getIcon(), size: "sm" }) }),
82406
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { flexGrow: 1 }, children: [
82407
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BlockTitle, { variant: "subtitle2", children: getTitle() }),
82408
+ !isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(BlockContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82409
+ MarkdownRenderer,
82410
+ {
82411
+ content: getTruncatedContent(content2),
82412
+ styleProps: {
82413
+ fontSize: "0.85rem",
82414
+ lineHeight: 1.5,
82415
+ paragraphSpacing: "4px",
82416
+ headingScale: 0.9,
82417
+ codeSize: "0.85em"
82418
+ }
82419
+ }
82420
+ ) })
82421
+ ] })
82422
+ ] }),
82423
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Collapse, { in: isExpanded, timeout: "auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82424
+ MarkdownRenderer,
82425
+ {
82426
+ content: content2,
82427
+ styleProps: {
82428
+ fontSize: "0.85rem",
82429
+ lineHeight: 1.5,
82430
+ paragraphSpacing: "4px",
82431
+ headingScale: 0.9,
82432
+ codeSize: "0.85em"
82433
+ }
82434
+ }
82435
+ ) }) })
82436
+ ] });
82065
82437
  };
82066
- const AttachmentImage = styled$1("img")({
82067
- maxWidth: "100%",
82068
- maxHeight: 200,
82069
- borderRadius: 8,
82438
+ const CodeContainer$3 = styled$1(Box)({
82439
+ marginBottom: 16,
82440
+ width: "100%"
82441
+ });
82442
+ const SectionLabel$4 = styled$1(Typography)(({ theme: theme2 }) => ({
82443
+ display: "block",
82444
+ marginBottom: 4,
82445
+ color: theme2.palette.text.secondary
82446
+ }));
82447
+ const SyntaxHighlighterStyles = ft`
82448
+ .react-syntax-highlighter-code-block * {
82449
+ font-family: 'Roboto Mono', monospace !important;
82450
+ }
82451
+ `;
82452
+ const CodeBlock = ({ code: code2 }) => {
82453
+ if (!code2) return null;
82454
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer$3, { children: [
82455
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$4, { variant: "caption", children: "Code" }),
82456
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SyntaxHighlighterStyles, {}),
82457
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
82458
+ highlighter,
82459
+ {
82460
+ language: "python",
82461
+ style: atomOneDark,
82462
+ customStyle: {
82463
+ borderRadius: "8px",
82464
+ fontSize: "0.85rem",
82465
+ width: "100%",
82466
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.2)",
82467
+ padding: "0.75rem"
82468
+ },
82469
+ codeTagProps: {
82470
+ style: {
82471
+ fontFamily: '"Roboto Mono", monospace !important'
82472
+ }
82473
+ },
82474
+ className: "react-syntax-highlighter-code-block",
82475
+ wrapLines: true,
82476
+ wrapLongLines: true,
82477
+ children: code2
82478
+ }
82479
+ )
82480
+ ] });
82481
+ };
82482
+ const SectionHeader = styled$1(Box)(({ theme: theme2 }) => ({
82483
+ display: "flex",
82484
+ alignItems: "center",
82070
82485
  marginBottom: 8,
82071
- boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
82072
82486
  cursor: "pointer",
82073
- transition: "transform 0.2s ease, box-shadow 0.2s ease",
82487
+ userSelect: "none",
82074
82488
  "&:hover": {
82075
- transform: "scale(1.02)",
82076
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.25)"
82489
+ backgroundColor: "rgba(255, 255, 255, 0.05)"
82490
+ },
82491
+ borderRadius: 4,
82492
+ padding: "4px 8px",
82493
+ color: theme2.palette.primary.main,
82494
+ transition: "all 0.2s ease"
82495
+ }));
82496
+ const SectionLabel$3 = styled$1(Typography)(({ theme: theme2 }) => ({
82497
+ display: "block",
82498
+ color: theme2.palette.primary.main,
82499
+ fontWeight: 500,
82500
+ fontSize: "0.85rem"
82501
+ }));
82502
+ const ToggleButton$1 = styled$1(IconButton)({
82503
+ padding: 2,
82504
+ marginRight: 4
82505
+ });
82506
+ const CollapsibleMessage = ({ children, defaultCollapsed = true, hasContent }) => {
82507
+ const [isCollapsed, setIsCollapsed] = reactExports.useState(defaultCollapsed);
82508
+ if (!hasContent) {
82509
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
82077
82510
  }
82511
+ const toggleCollapse = () => {
82512
+ setIsCollapsed(!isCollapsed);
82513
+ };
82514
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { width: "100%" }, children: [
82515
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionHeader, { onClick: toggleCollapse, children: [
82516
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToggleButton$1, { size: "small", disableRipple: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82517
+ FontAwesomeIcon,
82518
+ {
82519
+ icon: isCollapsed ? faChevronRight : faChevronDown,
82520
+ size: "sm"
82521
+ }
82522
+ ) }),
82523
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$3, { variant: "caption", children: isCollapsed ? "Show technical details" : "Hide technical details" })
82524
+ ] }),
82525
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Collapse, { in: !isCollapsed, timeout: "auto", children })
82526
+ ] });
82527
+ };
82528
+ const CodeContainer$2 = styled$1(Box)({
82529
+ marginBottom: 16,
82530
+ width: "100%"
82078
82531
  });
82079
- const FileAttachment = styled$1(Box)(() => ({
82532
+ const SectionLabel$2 = styled$1(Typography)(({ theme: theme2 }) => ({
82533
+ display: "block",
82534
+ marginBottom: 4,
82535
+ color: theme2.palette.error.light
82536
+ }));
82537
+ const ErrorContainer$2 = styled$1(Box, {
82538
+ shouldForwardProp: (prop) => prop !== "isUser"
82539
+ })(({ isUser, theme: theme2 }) => ({
82540
+ fontFamily: '"Roboto Mono", monospace',
82541
+ fontSize: "0.85rem",
82542
+ backgroundColor: "rgba(255, 0, 0, 0.1)",
82543
+ borderRadius: "8px",
82544
+ padding: 12,
82545
+ maxHeight: "200px",
82546
+ overflow: "auto",
82547
+ whiteSpace: "pre-wrap",
82548
+ color: isUser ? theme2.palette.error.main : theme2.palette.error.light,
82549
+ width: "100%",
82550
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82551
+ "&::-webkit-scrollbar": {
82552
+ width: "6px"
82553
+ },
82554
+ "&::-webkit-scrollbar-thumb": {
82555
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
82556
+ borderRadius: "3px"
82557
+ }
82558
+ }));
82559
+ const ErrorBlock = ({ error, isUser }) => {
82560
+ if (!error || error === "[No error output]") return null;
82561
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer$2, { children: [
82562
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$2, { variant: "caption", children: "Error" }),
82563
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorContainer$2, { isUser, children: error })
82564
+ ] });
82565
+ };
82566
+ const FileAttachmentContainer = styled$1(Box)(() => ({
82080
82567
  display: "flex",
82081
82568
  alignItems: "center",
82082
82569
  padding: "8px 12px",
@@ -82115,88 +82602,82 @@ const FileName = styled$1(Typography)({
82115
82602
  textDecoration: "underline"
82116
82603
  }
82117
82604
  });
82118
- const isWebUrl = (path) => {
82119
- return path.startsWith("http://") || path.startsWith("https://");
82605
+ const getFileName$2 = (path) => {
82606
+ const parts = path.split(/[/\\]/);
82607
+ return parts[parts.length - 1];
82120
82608
  };
82121
- const isImage = (path) => {
82122
- const imageExtensions = [
82123
- ".jpg",
82124
- ".jpeg",
82125
- ".png",
82126
- ".gif",
82127
- ".webp",
82128
- ".bmp",
82129
- ".svg",
82130
- ".tiff",
82131
- ".tif",
82132
- ".ico",
82133
- ".heic",
82134
- ".heif",
82135
- ".avif",
82136
- ".jfif",
82137
- ".pjpeg",
82138
- ".pjp"
82139
- ];
82140
- const lowerPath = path.toLowerCase();
82141
- return imageExtensions.some((ext) => lowerPath.endsWith(ext));
82609
+ const FileAttachment = ({ file, onClick }) => {
82610
+ const handleClick = () => {
82611
+ onClick(file);
82612
+ };
82613
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
82614
+ FileAttachmentContainer,
82615
+ {
82616
+ onClick: handleClick,
82617
+ title: `Click to open ${getFileName$2(file)}`,
82618
+ children: [
82619
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faFile, size: "sm" }) }),
82620
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileName, { variant: "body2", children: getFileName$2(file) })
82621
+ ]
82622
+ }
82623
+ );
82142
82624
  };
82143
- const getFileName = (path) => {
82625
+ const AttachmentImage = styled$1("img")({
82626
+ maxWidth: "100%",
82627
+ maxHeight: 200,
82628
+ borderRadius: 8,
82629
+ marginBottom: 8,
82630
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
82631
+ cursor: "pointer",
82632
+ transition: "transform 0.2s ease, box-shadow 0.2s ease",
82633
+ "&:hover": {
82634
+ transform: "scale(1.02)",
82635
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.25)"
82636
+ }
82637
+ });
82638
+ const getFileName$1 = (path) => {
82144
82639
  const parts = path.split(/[/\\]/);
82145
82640
  return parts[parts.length - 1];
82146
82641
  };
82147
- const getAttachmentUrl = (client, path) => {
82148
- if (isImage(path) && !path.startsWith("http")) {
82149
- const normalizedPath = path.startsWith("file://") ? path : `file://${path}`;
82150
- return client.static.getImageUrl(normalizedPath);
82151
- }
82152
- return path;
82642
+ const ImageAttachment = ({
82643
+ file,
82644
+ src,
82645
+ onClick
82646
+ }) => {
82647
+ const handleClick = () => {
82648
+ onClick(file);
82649
+ };
82650
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82651
+ AttachmentImage,
82652
+ {
82653
+ src,
82654
+ alt: getFileName$1(file),
82655
+ onClick: handleClick,
82656
+ title: `Click to open ${getFileName$1(file)}`
82657
+ }
82658
+ );
82153
82659
  };
82154
- const SectionLabel = styled$1(Typography)(({ theme: theme2 }) => ({
82660
+ const CodeContainer$1 = styled$1(Box)({
82661
+ marginBottom: 16,
82662
+ width: "100%"
82663
+ });
82664
+ const SectionLabel$1 = styled$1(Typography)(({ theme: theme2 }) => ({
82155
82665
  display: "block",
82156
82666
  marginBottom: 4,
82157
82667
  color: theme2.palette.text.secondary
82158
82668
  }));
82159
- const CodeContainer = styled$1(Box)({
82160
- marginBottom: 16,
82161
- width: "100%"
82162
- });
82163
- const OutputContainer = styled$1(Box)({
82164
- fontFamily: '"Roboto Mono", monospace',
82165
- fontSize: "0.85rem",
82166
- backgroundColor: "rgba(0, 0, 0, 0.3)",
82167
- borderRadius: "8px",
82168
- padding: 12,
82169
- maxHeight: "300px",
82170
- overflow: "auto",
82171
- whiteSpace: "pre",
82172
- width: "100%",
82173
- boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82174
- color: "inherit",
82175
- overflowX: "auto",
82176
- "&::-webkit-scrollbar": {
82177
- width: "6px",
82178
- height: "6px"
82179
- },
82180
- "&::-webkit-scrollbar-thumb": {
82181
- backgroundColor: "rgba(255, 255, 255, 0.1)",
82182
- borderRadius: "3px"
82183
- },
82184
- "&::-webkit-scrollbar-corner": {
82185
- backgroundColor: "rgba(0, 0, 0, 0.3)"
82186
- }
82187
- });
82188
- const ErrorContainer$2 = styled$1(Box, {
82669
+ const LogContainer = styled$1(Box, {
82189
82670
  shouldForwardProp: (prop) => prop !== "isUser"
82190
- })(({ isUser }) => ({
82671
+ })(({ isUser, theme: theme2 }) => ({
82191
82672
  fontFamily: '"Roboto Mono", monospace',
82192
82673
  fontSize: "0.85rem",
82193
- backgroundColor: "rgba(255, 0, 0, 0.1)",
82674
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
82194
82675
  borderRadius: "8px",
82195
82676
  padding: 12,
82196
82677
  maxHeight: "200px",
82197
82678
  overflow: "auto",
82198
82679
  whiteSpace: "pre-wrap",
82199
- color: isUser ? "error.main" : "error.light",
82680
+ color: isUser ? theme2.palette.info.main : theme2.palette.info.light,
82200
82681
  width: "100%",
82201
82682
  boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82202
82683
  "&::-webkit-scrollbar": {
@@ -82207,36 +82688,187 @@ const ErrorContainer$2 = styled$1(Box, {
82207
82688
  borderRadius: "3px"
82208
82689
  }
82209
82690
  }));
82210
- const LogContainer = styled$1(Box, {
82691
+ const LogBlock = ({ log, isUser }) => {
82692
+ if (!log || log === "[No logger output]") return null;
82693
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer$1, { children: [
82694
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$1, { variant: "caption", children: "Logs" }),
82695
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LogContainer, { isUser, children: log })
82696
+ ] });
82697
+ };
82698
+ const StyledAvatar = styled$1(Avatar, {
82699
+ shouldForwardProp: (prop) => prop !== "isUser"
82700
+ })(({ isUser, theme: theme2 }) => ({
82701
+ backgroundColor: isUser ? "rgba(66, 133, 244, 0.9)" : "rgba(56, 201, 106, 0.2)",
82702
+ color: isUser ? "white" : theme2.palette.primary.main,
82703
+ boxShadow: isUser ? "0 2px 8px rgba(66, 133, 244, 0.25)" : "none"
82704
+ }));
82705
+ const MessageAvatar = ({ isUser }) => {
82706
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledAvatar, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: isUser ? faUser : faRobot, size: "sm" }) });
82707
+ };
82708
+ const StyledContainer$1 = styled$1(Box, {
82211
82709
  shouldForwardProp: (prop) => prop !== "isUser"
82212
82710
  })(({ isUser }) => ({
82711
+ display: "flex",
82712
+ flexDirection: isUser ? "row-reverse" : "row",
82713
+ alignItems: "flex-start",
82714
+ gap: 16,
82715
+ marginBottom: 16
82716
+ }));
82717
+ const MessageContainer = ({
82718
+ isUser,
82719
+ children
82720
+ }) => {
82721
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledContainer$1, { isUser, children });
82722
+ };
82723
+ const ContentContainer$2 = styled$1(Box)(() => ({
82724
+ marginBottom: 16
82725
+ }));
82726
+ const MessageContent = ({ content: content2 }) => {
82727
+ if (!content2) return null;
82728
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ContentContainer$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownRenderer, { content: content2 }) });
82729
+ };
82730
+ const StyledPaper$1 = styled$1(Paper)(({ theme: theme2 }) => ({
82731
+ [theme2.breakpoints.down("sm")]: {
82732
+ maxWidth: "85%"
82733
+ },
82734
+ [theme2.breakpoints.between("sm", "md")]: {
82735
+ maxWidth: "75%"
82736
+ },
82737
+ [theme2.breakpoints.up("md")]: {
82738
+ maxWidth: "65%"
82739
+ },
82740
+ width: "auto",
82741
+ padding: 16,
82742
+ borderRadius: 8,
82743
+ wordBreak: "break-word",
82744
+ overflowWrap: "break-word",
82745
+ position: "relative"
82746
+ }));
82747
+ const MessagePaper = ({
82748
+ isUser,
82749
+ elevation = isUser ? 2 : 1,
82750
+ children
82751
+ }) => {
82752
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82753
+ StyledPaper$1,
82754
+ {
82755
+ elevation,
82756
+ sx: {
82757
+ backgroundColor: isUser ? "rgba(66, 133, 244, 0.15)" : (theme2) => theme2.palette.background.paper,
82758
+ border: isUser ? "1px solid rgba(66, 133, 244, 0.3)" : "1px solid rgba(255, 255, 255, 0.1)",
82759
+ boxShadow: isUser ? "0 4px 12px rgba(0, 0, 0, 0.15)" : "0 2px 8px rgba(0, 0, 0, 0.1)",
82760
+ color: isUser ? (theme2) => theme2.palette.text.primary : "inherit"
82761
+ },
82762
+ children
82763
+ }
82764
+ );
82765
+ };
82766
+ const StyledTimestamp = styled$1(Typography, {
82767
+ shouldForwardProp: (prop) => prop !== "isUser"
82768
+ })(({ isUser, theme: theme2 }) => ({
82769
+ display: "block",
82770
+ marginTop: 8,
82771
+ textAlign: isUser ? "left" : "right",
82772
+ color: theme2.palette.text.secondary,
82773
+ fontSize: "0.7rem"
82774
+ }));
82775
+ const MessageTimestamp = ({
82776
+ timestamp,
82777
+ isUser
82778
+ }) => {
82779
+ const formattedTime = timestamp.toLocaleTimeString([], {
82780
+ hour: "2-digit",
82781
+ minute: "2-digit"
82782
+ });
82783
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledTimestamp, { variant: "caption", isUser, children: formattedTime });
82784
+ };
82785
+ const CodeContainer = styled$1(Box)({
82786
+ marginBottom: 16,
82787
+ width: "100%"
82788
+ });
82789
+ const SectionLabel = styled$1(Typography)(({ theme: theme2 }) => ({
82790
+ display: "block",
82791
+ marginBottom: 4,
82792
+ color: theme2.palette.text.secondary
82793
+ }));
82794
+ const OutputContainer = styled$1(Box)({
82213
82795
  fontFamily: '"Roboto Mono", monospace',
82214
82796
  fontSize: "0.85rem",
82215
82797
  backgroundColor: "rgba(0, 0, 0, 0.3)",
82216
82798
  borderRadius: "8px",
82217
82799
  padding: 12,
82218
- maxHeight: "200px",
82800
+ maxHeight: "300px",
82219
82801
  overflow: "auto",
82220
- whiteSpace: "pre-wrap",
82221
- color: isUser ? "info.main" : "info.light",
82802
+ whiteSpace: "pre",
82222
82803
  width: "100%",
82223
82804
  boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82805
+ color: "inherit",
82806
+ overflowX: "auto",
82224
82807
  "&::-webkit-scrollbar": {
82225
- width: "6px"
82808
+ width: "6px",
82809
+ height: "6px"
82226
82810
  },
82227
82811
  "&::-webkit-scrollbar-thumb": {
82228
82812
  backgroundColor: "rgba(255, 255, 255, 0.1)",
82229
82813
  borderRadius: "3px"
82814
+ },
82815
+ "&::-webkit-scrollbar-corner": {
82816
+ backgroundColor: "rgba(0, 0, 0, 0.3)"
82230
82817
  }
82231
- }));
82232
- const SyntaxHighlighterStyles = ft`
82233
- .react-syntax-highlighter-code-block * {
82234
- font-family: 'Roboto Mono', monospace !important;
82818
+ });
82819
+ const OutputBlock = ({ output }) => {
82820
+ if (!output) return null;
82821
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer, { children: [
82822
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { variant: "caption", children: "Output" }),
82823
+ /* @__PURE__ */ jsxRuntimeExports.jsx(OutputContainer, { children: output })
82824
+ ] });
82825
+ };
82826
+ const HighlightContainer = styled$1(Box, {
82827
+ shouldForwardProp: (prop) => prop !== "isUser"
82828
+ })(() => ({
82829
+ position: "relative",
82830
+ padding: "16px",
82831
+ borderRadius: "8px",
82832
+ marginBottom: "16px",
82833
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
82834
+ width: "100%",
82835
+ border: "1px solid rgba(255, 193, 7, 0.5)",
82836
+ backgroundColor: "rgba(255, 193, 7, 0.1)",
82837
+ transition: "all 0.2s ease",
82838
+ "&:hover": {
82839
+ boxShadow: "0 6px 16px rgba(0, 0, 0, 0.2)"
82235
82840
  }
82236
- `;
82237
- const StatusIndicator = styled$1(Box, {
82841
+ }));
82842
+ const SecurityBadge = styled$1(Box)(({ theme: theme2 }) => ({
82843
+ position: "absolute",
82844
+ top: "-10px",
82845
+ right: "16px",
82846
+ padding: "4px 8px",
82847
+ borderRadius: "12px",
82848
+ fontSize: "0.7rem",
82849
+ fontWeight: "bold",
82850
+ backgroundColor: theme2.palette.warning.main,
82851
+ color: "#fff",
82852
+ display: "flex",
82853
+ alignItems: "center",
82854
+ gap: "4px",
82855
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
82856
+ }));
82857
+ const SecurityCheckHighlight = ({
82858
+ children,
82859
+ isUser
82860
+ }) => {
82861
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(HighlightContainer, { isUser, children: [
82862
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SecurityBadge, { children: [
82863
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faExclamationTriangle, size: "xs" }),
82864
+ "AI SECURITY BLOCK"
82865
+ ] }),
82866
+ children
82867
+ ] });
82868
+ };
82869
+ const StyledStatusIndicator = styled$1(Box, {
82238
82870
  shouldForwardProp: (prop) => prop !== "status"
82239
- })(({ status }) => ({
82871
+ })(({ status, theme: theme2 }) => ({
82240
82872
  marginTop: 8,
82241
82873
  display: "inline-block",
82242
82874
  paddingLeft: 8,
@@ -82245,31 +82877,118 @@ const StatusIndicator = styled$1(Box, {
82245
82877
  paddingBottom: 4,
82246
82878
  borderRadius: "4px",
82247
82879
  fontSize: "0.75rem",
82248
- backgroundColor: status === "error" ? "error.dark" : status === "success" ? "success.dark" : "info.dark",
82880
+ backgroundColor: status === "error" ? theme2.palette.error.dark : status === "success" ? theme2.palette.success.dark : theme2.palette.info.dark,
82249
82881
  color: "white",
82250
82882
  boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
82251
82883
  }));
82252
- const Timestamp = styled$1(Typography, {
82253
- shouldForwardProp: (prop) => prop !== "isUser"
82254
- })(({ isUser, theme: theme2 }) => ({
82255
- display: "block",
82256
- marginTop: 8,
82257
- textAlign: isUser ? "left" : "right",
82258
- color: theme2.palette.text.secondary,
82259
- fontSize: "0.7rem"
82260
- }));
82884
+ const StatusIndicator = ({ status }) => {
82885
+ if (!status) return null;
82886
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledStatusIndicator, { status, children: status });
82887
+ };
82888
+ const AttachmentVideo = styled$1("video")({
82889
+ maxWidth: "100%",
82890
+ maxHeight: 300,
82891
+ borderRadius: 8,
82892
+ marginBottom: 8,
82893
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
82894
+ cursor: "pointer",
82895
+ transition: "transform 0.2s ease, box-shadow 0.2s ease",
82896
+ "&:hover": {
82897
+ transform: "scale(1.02)",
82898
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.25)"
82899
+ }
82900
+ });
82901
+ const getFileName = (path) => {
82902
+ const parts = path.split(/[/\\]/);
82903
+ return parts[parts.length - 1];
82904
+ };
82905
+ const VideoAttachment = ({
82906
+ file,
82907
+ src,
82908
+ onClick
82909
+ }) => {
82910
+ const handleClick = () => {
82911
+ onClick(file);
82912
+ };
82913
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82914
+ AttachmentVideo,
82915
+ {
82916
+ src,
82917
+ controls: true,
82918
+ preload: "metadata",
82919
+ onClick: handleClick,
82920
+ title: `Click to open ${getFileName(file)}`
82921
+ }
82922
+ );
82923
+ };
82924
+ const isWebUrl = (path) => {
82925
+ return path.startsWith("http://") || path.startsWith("https://");
82926
+ };
82927
+ const isImage = (path) => {
82928
+ const imageExtensions = [
82929
+ ".jpg",
82930
+ ".jpeg",
82931
+ ".png",
82932
+ ".gif",
82933
+ ".webp",
82934
+ ".bmp",
82935
+ ".svg",
82936
+ ".tiff",
82937
+ ".tif",
82938
+ ".ico",
82939
+ ".heic",
82940
+ ".heif",
82941
+ ".avif",
82942
+ ".jfif",
82943
+ ".pjpeg",
82944
+ ".pjp"
82945
+ ];
82946
+ const lowerPath = path.toLowerCase();
82947
+ return imageExtensions.some((ext) => lowerPath.endsWith(ext));
82948
+ };
82949
+ const isVideo = (path) => {
82950
+ const videoExtensions = [
82951
+ ".mp4",
82952
+ ".webm",
82953
+ ".ogg",
82954
+ ".mov",
82955
+ ".avi",
82956
+ ".wmv",
82957
+ ".flv",
82958
+ ".mkv",
82959
+ ".m4v",
82960
+ ".3gp",
82961
+ ".3g2"
82962
+ ];
82963
+ const lowerPath = path.toLowerCase();
82964
+ return videoExtensions.some((ext) => lowerPath.endsWith(ext));
82965
+ };
82966
+ const getAttachmentUrl = (client, path) => {
82967
+ if (path.startsWith("http")) {
82968
+ return path;
82969
+ }
82970
+ const normalizedPath = path.startsWith("file://") ? path : `file://${path}`;
82971
+ if (isImage(path)) {
82972
+ return client.static.getImageUrl(normalizedPath);
82973
+ }
82974
+ if (isVideo(path)) {
82975
+ return client.static.getVideoUrl(normalizedPath);
82976
+ }
82977
+ return path;
82978
+ };
82261
82979
  const MessageItem = reactExports.memo(
82262
82980
  ({ message: message2 }) => {
82981
+ const shouldHide = (message2.action === "DONE" || message2.action === "ASK") && message2.execution_type === "action" && message2.task_classification === "conversation";
82982
+ if (shouldHide) {
82983
+ return null;
82984
+ }
82263
82985
  const isUser = message2.role === "user";
82986
+ const isAction = message2.execution_type === "action";
82987
+ const isSecurityCheck = message2.execution_type === "security_check";
82988
+ const isPlanOrReflection = message2.execution_type === "plan" || message2.execution_type === "reflection" || isAction && (message2.action === "DONE" || message2.action === "ASK") && message2.task_classification !== "conversation";
82264
82989
  const client = reactExports.useMemo(() => {
82265
82990
  return createLocalOperatorClient(apiConfig.baseUrl);
82266
82991
  }, []);
82267
- const formattedTimestamp = reactExports.useMemo(() => {
82268
- return message2.timestamp.toLocaleTimeString([], {
82269
- hour: "2-digit",
82270
- minute: "2-digit"
82271
- });
82272
- }, [message2.timestamp]);
82273
82992
  const getUrl = reactExports.useCallback(
82274
82993
  (path) => getAttachmentUrl(client, path),
82275
82994
  [client]
@@ -82286,109 +83005,130 @@ const MessageItem = reactExports.memo(
82286
83005
  console.error("Error opening file:", error);
82287
83006
  }
82288
83007
  }, []);
82289
- const handleImageClick = reactExports.useCallback(
82290
- (filePath) => {
82291
- handleFileClick(filePath);
82292
- },
82293
- [handleFileClick]
82294
- );
83008
+ if (isPlanOrReflection && message2.message) {
83009
+ const executionType = isAction && message2.action === "DONE" ? "action" : message2.execution_type || "action";
83010
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
83011
+ BackgroundBlock,
83012
+ {
83013
+ content: message2.message,
83014
+ action: message2.action,
83015
+ executionType,
83016
+ isUser
83017
+ }
83018
+ );
83019
+ }
82295
83020
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(MessageContainer, { isUser, children: [
82296
- /* @__PURE__ */ jsxRuntimeExports.jsx(UserAvatar$1, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: isUser ? faUser : faRobot, size: "sm" }) }),
82297
- /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagePaper, { elevation: isUser ? 2 : 1, isUser, children: [
83021
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageAvatar, { isUser }),
83022
+ isSecurityCheck ? /* @__PURE__ */ jsxRuntimeExports.jsx(SecurityCheckHighlight, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagePaper, { isUser, children: [
82298
83023
  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(
82299
- AttachmentImage,
83024
+ ImageAttachment,
82300
83025
  {
83026
+ file,
82301
83027
  src: getUrl(file),
82302
- alt: getFileName(file),
82303
- onClick: () => handleImageClick(file),
82304
- title: `Click to open ${getFileName(file)}`
83028
+ onClick: handleFileClick
82305
83029
  },
82306
83030
  `${message2.id}-${file}`
82307
83031
  )) }),
82308
- message2.message && /* @__PURE__ */ jsxRuntimeExports.jsx(
82309
- Box,
82310
- {
82311
- sx: {
82312
- mb: message2.code || message2.stdout || message2.stderr || message2.logging ? 2 : 0
82313
- },
82314
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownRenderer, { content: message2.message })
82315
- }
82316
- ),
82317
- message2.code && /* @__PURE__ */ jsxRuntimeExports.jsxs(
82318
- CodeContainer,
83032
+ 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(
83033
+ VideoAttachment,
82319
83034
  {
82320
- sx: {
82321
- mb: message2.stdout || message2.stderr || message2.logging ? 2 : 0
82322
- },
82323
- children: [
82324
- /* @__PURE__ */ jsxRuntimeExports.jsx(SyntaxHighlighterStyles, {}),
82325
- /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { variant: "caption", children: "Code" }),
82326
- /* @__PURE__ */ jsxRuntimeExports.jsx(
82327
- highlighter,
82328
- {
82329
- language: "python",
82330
- style: atomOneDark,
82331
- customStyle: {
82332
- borderRadius: "8px",
82333
- fontSize: "0.85rem",
82334
- width: "100%",
82335
- boxShadow: "0 2px 6px rgba(0, 0, 0, 0.2)",
82336
- padding: "0.75rem"
82337
- },
82338
- codeTagProps: {
82339
- style: {
82340
- fontFamily: '"Roboto Mono", monospace !important'
82341
- }
82342
- },
82343
- className: "react-syntax-highlighter-code-block",
82344
- wrapLines: true,
82345
- wrapLongLines: true,
82346
- children: message2.code
82347
- }
82348
- )
82349
- ]
82350
- }
82351
- ),
82352
- message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsxs(
82353
- CodeContainer,
82354
- {
82355
- sx: { mb: message2.stderr || message2.logging ? 2 : 0 },
82356
- children: [
82357
- /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { variant: "caption", children: "Output" }),
82358
- /* @__PURE__ */ jsxRuntimeExports.jsx(OutputContainer, { children: message2.stdout })
82359
- ]
83035
+ file,
83036
+ src: getUrl(file),
83037
+ onClick: handleFileClick
83038
+ },
83039
+ `${message2.id}-${file}`
83040
+ )) }),
83041
+ message2.message && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
83042
+ (() => {
83043
+ const hasCollapsibleContent = isSecurityCheck && (message2.code || message2.stdout || message2.stderr || message2.logging);
83044
+ const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
83045
+ message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
83046
+ message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
83047
+ message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
83048
+ message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
83049
+ ] });
83050
+ if (hasCollapsibleContent) {
83051
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
83052
+ CollapsibleMessage,
83053
+ {
83054
+ defaultCollapsed: true,
83055
+ hasContent: hasCollapsibleContent,
83056
+ children: contentBlocks
83057
+ }
83058
+ );
82360
83059
  }
82361
- ),
82362
- message2.stderr && message2.stderr !== "[No error output]" && /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer, { sx: { mb: message2.logging ? 2 : 0 }, children: [
82363
- /* @__PURE__ */ jsxRuntimeExports.jsx(
82364
- SectionLabel,
82365
- {
82366
- variant: "caption",
82367
- sx: { color: isUser ? "error.main" : "error.light" },
82368
- children: "Error"
82369
- }
82370
- ),
82371
- /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorContainer$2, { isUser, children: message2.stderr })
82372
- ] }),
82373
- message2.logging && message2.logging !== "[No logger output]" && /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer, { sx: { mb: message2.formatted_print ? 2 : 0 }, children: [
82374
- /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { variant: "caption", children: "Logs" }),
82375
- /* @__PURE__ */ jsxRuntimeExports.jsx(LogContainer, { isUser, children: message2.logging })
82376
- ] }),
82377
- message2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: message2.status, children: message2.status }),
82378
- message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter((file) => !isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
83060
+ return contentBlocks;
83061
+ })(),
83062
+ message2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: message2.status }),
83063
+ 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(
82379
83064
  FileAttachment,
82380
83065
  {
82381
- onClick: () => handleFileClick(file),
82382
- title: `Click to open ${getFileName(file)}`,
82383
- children: [
82384
- /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faFile, size: "sm" }) }),
82385
- /* @__PURE__ */ jsxRuntimeExports.jsx(FileName, { variant: "body2", children: getFileName(file) })
82386
- ]
83066
+ file,
83067
+ onClick: handleFileClick
82387
83068
  },
82388
83069
  `${message2.id}-${file}`
82389
83070
  )) }),
82390
- /* @__PURE__ */ jsxRuntimeExports.jsx(Timestamp, { variant: "caption", isUser, children: formattedTimestamp })
82391
- ] })
83071
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageTimestamp, { timestamp: message2.timestamp, isUser })
83072
+ ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
83073
+ ActionHighlight,
83074
+ {
83075
+ action: message2.action || "CODE",
83076
+ taskClassification: message2.task_classification || "",
83077
+ isUser,
83078
+ executionType: message2.execution_type,
83079
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagePaper, { isUser, children: [
83080
+ 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(
83081
+ ImageAttachment,
83082
+ {
83083
+ file,
83084
+ src: getUrl(file),
83085
+ onClick: handleFileClick
83086
+ },
83087
+ `${message2.id}-${file}`
83088
+ )) }),
83089
+ 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(
83090
+ VideoAttachment,
83091
+ {
83092
+ file,
83093
+ src: getUrl(file),
83094
+ onClick: handleFileClick
83095
+ },
83096
+ `${message2.id}-${file}`
83097
+ )) }),
83098
+ message2.message && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
83099
+ (() => {
83100
+ const hasCollapsibleContent = isAction && (message2.code || message2.stdout || message2.stderr || message2.logging);
83101
+ const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
83102
+ message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
83103
+ message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
83104
+ message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
83105
+ message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
83106
+ ] });
83107
+ if (hasCollapsibleContent) {
83108
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
83109
+ CollapsibleMessage,
83110
+ {
83111
+ defaultCollapsed: true,
83112
+ hasContent: hasCollapsibleContent,
83113
+ children: contentBlocks
83114
+ }
83115
+ );
83116
+ }
83117
+ return contentBlocks;
83118
+ })(),
83119
+ message2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: message2.status }),
83120
+ 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(
83121
+ FileAttachment,
83122
+ {
83123
+ file,
83124
+ onClick: handleFileClick
83125
+ },
83126
+ `${message2.id}-${file}`
83127
+ )) }),
83128
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageTimestamp, { timestamp: message2.timestamp, isUser })
83129
+ ] })
83130
+ }
83131
+ )
82392
83132
  ] });
82393
83133
  },
82394
83134
  (prevProps, nextProps) => {
@@ -82441,8 +83181,10 @@ const MessagesView = ({
82441
83181
  isFetchingMore,
82442
83182
  jobStatus,
82443
83183
  agentName,
83184
+ currentExecution,
82444
83185
  messagesContainerRef,
82445
- messagesEndRef
83186
+ messagesEndRef,
83187
+ scrollToBottom
82446
83188
  }) => {
82447
83189
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
82448
83190
  isFetchingMore && /* @__PURE__ */ jsxRuntimeExports.jsxs(LoadingMoreIndicator, { children: [
@@ -82467,7 +83209,15 @@ const MessagesView = ({
82467
83209
  ),
82468
83210
  /* @__PURE__ */ jsxRuntimeExports.jsx(Typography, { variant: "body1", children: "No messages yet. Start a conversation!" })
82469
83211
  ] }),
82470
- isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingIndicator, { status: jobStatus, agentName }),
83212
+ isLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(
83213
+ LoadingIndicator,
83214
+ {
83215
+ status: jobStatus,
83216
+ agentName,
83217
+ currentExecution,
83218
+ scrollToBottom
83219
+ }
83220
+ ),
82471
83221
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: messagesEndRef })
82472
83222
  ] })
82473
83223
  ] });
@@ -82521,6 +83271,7 @@ const ChatContent = ({
82521
83271
  isFetchingMore,
82522
83272
  isFarFromBottom,
82523
83273
  jobStatus,
83274
+ currentExecution,
82524
83275
  messagesContainerRef,
82525
83276
  messagesEndRef,
82526
83277
  scrollToBottom,
@@ -82559,8 +83310,10 @@ const ChatContent = ({
82559
83310
  isFetchingMore,
82560
83311
  jobStatus,
82561
83312
  agentName,
83313
+ currentExecution,
82562
83314
  messagesContainerRef,
82563
- messagesEndRef
83315
+ messagesEndRef,
83316
+ scrollToBottom
82564
83317
  }
82565
83318
  )
82566
83319
  ) : (
@@ -85011,7 +85764,8 @@ const ChatPage = () => {
85011
85764
  jobStatus,
85012
85765
  isLoading,
85013
85766
  setIsLoading,
85014
- checkForActiveJobs
85767
+ checkForActiveJobs,
85768
+ currentExecution
85015
85769
  } = useJobPolling({
85016
85770
  conversationId,
85017
85771
  addMessage
@@ -85247,6 +86001,7 @@ Store messages: ${JSON.stringify(getMessages(conversationId || ""), null, 2)}`;
85247
86001
  isFetchingMore,
85248
86002
  isFarFromBottom,
85249
86003
  jobStatus,
86004
+ currentExecution,
85250
86005
  messagesContainerRef,
85251
86006
  messagesEndRef,
85252
86007
  scrollToBottom,
@@ -89822,6 +90577,26 @@ const UserProfileSidebar = ({
89822
90577
  ) : null
89823
90578
  ] });
89824
90579
  };
90580
+ const useUiPreferencesStore = create$1()(
90581
+ persist(
90582
+ (set) => ({
90583
+ isSidebarCollapsed: false,
90584
+ toggleSidebar: () => {
90585
+ set((state) => ({
90586
+ isSidebarCollapsed: !state.isSidebarCollapsed
90587
+ }));
90588
+ },
90589
+ setSidebarCollapsed: (collapsed) => {
90590
+ set({
90591
+ isSidebarCollapsed: collapsed
90592
+ });
90593
+ }
90594
+ }),
90595
+ {
90596
+ name: "ui-preferences-storage"
90597
+ }
90598
+ )
90599
+ );
89825
90600
  const StyledDrawer = styled$1(Drawer, {
89826
90601
  shouldForwardProp: (prop) => prop !== "width"
89827
90602
  })(({ theme: theme2, width }) => ({
@@ -89937,12 +90712,10 @@ const ToggleButton = styled$1(IconButton)(() => ({
89937
90712
  }
89938
90713
  }));
89939
90714
  const SidebarNavigation = () => {
89940
- const [expanded, setExpanded] = reactExports.useState(true);
89941
90715
  const navigate = useNavigate();
89942
90716
  const currentView = useCurrentView();
89943
- const toggleSidebar = () => {
89944
- setExpanded(!expanded);
89945
- };
90717
+ const { isSidebarCollapsed, toggleSidebar } = useUiPreferencesStore();
90718
+ const expanded = !isSidebarCollapsed;
89946
90719
  const navItems = [
89947
90720
  {
89948
90721
  icon: faCode,
@@ -90017,6 +90790,7 @@ const SidebarNavigation = () => {
90017
90790
  onClick: toggleSidebar,
90018
90791
  size: "small",
90019
90792
  title: expanded ? "Collapse sidebar" : "Expand sidebar",
90793
+ "aria-label": expanded ? "Collapse sidebar" : "Expand sidebar",
90020
90794
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
90021
90795
  FontAwesomeIcon,
90022
90796
  {