local-operator-ui 0.1.3 → 0.1.4

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 faQuestion, aF as faLightbulb, aG as faChevronRight, aH as faFile, aI as faUser, aJ as faEllipsisVertical, aK as faComment, aL as faChevronLeft, aM as faPlus, aN as faSearch, aO as faCommentSlash, aP as faArrowRight, aQ as faComments, aR as faTag, aS as faIdCard, aT as faCalendarAlt, aU as faCodeBranch, aV as faShieldAlt, aW as faArrowLeft, aX as requireReact, aY as LinearProgress, aZ as keyframes, a_ as faShield, a$ as faSignOut, b0 as faMagicWandSparkles, b1 as faBrain, b2 as faWandMagicSparkles, b3 as faExternalLinkAlt, b4 as faKey, b5 as faGlobe, b6 as faLock, b7 as faEdit, b8 as faSave, b9 as faEnvelope, ba as faCloudUploadAlt, bb as faHistory, bc as faListAlt, bd as library$1, be as icons$1, bf as CssBaseline, bg as ReactDOM$1, bh as ThemeProvider, bi as theme, bj as ErrorBoundary } from "./theme-DWJi6s4t.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.
@@ -30557,7 +30529,10 @@ const convertToMessage = (record) => {
30557
30529
  stderr: record.stderr,
30558
30530
  logging: record.logging,
30559
30531
  timestamp: record.timestamp ? new Date(record.timestamp) : /* @__PURE__ */ new Date(),
30560
- files: record.files
30532
+ files: record.files,
30533
+ action: record.action,
30534
+ execution_type: record.execution_type,
30535
+ task_classification: record.task_classification
30561
30536
  };
30562
30537
  };
30563
30538
  const useConversationMessages = (conversationId, pageSize2 = 20) => {
@@ -31115,7 +31090,7 @@ const SidebarContainer$6 = styled$1(Box)({
31115
31090
  width: 280,
31116
31091
  height: "100%"
31117
31092
  });
31118
- const ContentContainer$2 = styled$1(Box)({
31093
+ const ContentContainer$3 = styled$1(Box)({
31119
31094
  flexGrow: 1,
31120
31095
  height: "100%",
31121
31096
  overflow: "hidden"
@@ -31126,7 +31101,7 @@ const StyledDivider = styled$1(Divider)({
31126
31101
  const ChatLayout = ({ sidebar, content: content2 }) => {
31127
31102
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Container$1, { children: [
31128
31103
  /* @__PURE__ */ jsxRuntimeExports.jsx(SidebarContainer$6, { children: sidebar }),
31129
- /* @__PURE__ */ jsxRuntimeExports.jsx(ContentContainer$2, { children: content2 })
31104
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContentContainer$3, { children: content2 })
31130
31105
  ] });
31131
31106
  };
31132
31107
  const useAgentRouteParam = () => {
@@ -44583,6 +44558,308 @@ const getStatusText = (status) => {
44583
44558
  return "thinking";
44584
44559
  }
44585
44560
  };
44561
+ const HighlightContainer$1 = styled$1(Box, {
44562
+ shouldForwardProp: (prop) => prop !== "action" && prop !== "isUser"
44563
+ })(({ action }) => ({
44564
+ position: "relative",
44565
+ padding: "16px",
44566
+ borderRadius: "8px",
44567
+ marginBottom: "16px",
44568
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
44569
+ width: "100%",
44570
+ border: `1px solid ${action === "DONE" ? "rgba(76, 175, 80, 0.5)" : "rgba(33, 150, 243, 0.5)"}`,
44571
+ backgroundColor: action === "DONE" ? "rgba(76, 175, 80, 0.1)" : "rgba(33, 150, 243, 0.1)",
44572
+ transition: "all 0.2s ease",
44573
+ "&:hover": {
44574
+ boxShadow: "0 6px 16px rgba(0, 0, 0, 0.2)"
44575
+ }
44576
+ }));
44577
+ const ActionBadge = styled$1(Box, {
44578
+ shouldForwardProp: (prop) => prop !== "action"
44579
+ })(({ theme: theme2, action }) => ({
44580
+ position: "absolute",
44581
+ top: "-10px",
44582
+ right: "16px",
44583
+ padding: "4px 8px",
44584
+ borderRadius: "12px",
44585
+ fontSize: "0.7rem",
44586
+ fontWeight: "bold",
44587
+ backgroundColor: action === "DONE" ? theme2.palette.success.main : theme2.palette.info.main,
44588
+ color: "#fff",
44589
+ display: "flex",
44590
+ alignItems: "center",
44591
+ gap: "4px",
44592
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
44593
+ }));
44594
+ const ActionHighlight = ({
44595
+ children,
44596
+ action,
44597
+ isUser,
44598
+ taskClassification,
44599
+ executionType
44600
+ }) => {
44601
+ const shouldHighlight = (action === "DONE" || action === "ASK") && taskClassification !== "conversation" || executionType === "response" && taskClassification !== "conversation";
44602
+ if (!shouldHighlight) {
44603
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
44604
+ }
44605
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(HighlightContainer$1, { action, isUser, children: [
44606
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ActionBadge, { action, children: [
44607
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
44608
+ FontAwesomeIcon,
44609
+ {
44610
+ icon: action === "DONE" ? faCheck : faQuestion,
44611
+ size: "xs"
44612
+ }
44613
+ ),
44614
+ action === "DONE" ? "COMPLETE" : "QUESTION"
44615
+ ] }),
44616
+ children
44617
+ ] });
44618
+ };
44619
+ const MarkdownContent = styled$1(Box, {
44620
+ shouldForwardProp: (prop) => ![
44621
+ "fontSize",
44622
+ "lineHeight",
44623
+ "paragraphSpacing",
44624
+ "headingScale",
44625
+ "codeSize"
44626
+ ].includes(prop)
44627
+ })(
44628
+ ({
44629
+ fontSize = "1.05rem",
44630
+ lineHeight = 1.6,
44631
+ paragraphSpacing = "8px",
44632
+ headingScale = 1,
44633
+ codeSize = "0.85em"
44634
+ }) => ({
44635
+ wordBreak: "break-word",
44636
+ overflowWrap: "break-word",
44637
+ lineHeight,
44638
+ fontSize,
44639
+ "& code": {
44640
+ fontFamily: '"Roboto Mono", monospace',
44641
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
44642
+ padding: "3px 6px",
44643
+ borderRadius: "4px",
44644
+ fontSize: codeSize,
44645
+ whiteSpace: "pre-wrap",
44646
+ wordBreak: "break-word",
44647
+ color: "#e6e6e6"
44648
+ },
44649
+ "& pre": {
44650
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
44651
+ padding: "16px",
44652
+ borderRadius: "8px",
44653
+ overflowX: "auto",
44654
+ fontFamily: '"Roboto Mono", monospace',
44655
+ fontSize: codeSize,
44656
+ margin: "12px 0",
44657
+ maxWidth: "100%",
44658
+ border: "1px solid rgba(255, 255, 255, 0.1)"
44659
+ },
44660
+ "& pre code": {
44661
+ whiteSpace: "pre-wrap",
44662
+ wordBreak: "break-word",
44663
+ backgroundColor: "transparent",
44664
+ padding: 0,
44665
+ borderRadius: 0
44666
+ },
44667
+ "& h1": {
44668
+ fontSize: `calc(1.5rem * ${headingScale})`,
44669
+ fontWeight: 600,
44670
+ margin: "20px 0 12px 0",
44671
+ borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
44672
+ paddingBottom: "8px"
44673
+ },
44674
+ "& h2": {
44675
+ fontSize: `calc(1.3rem * ${headingScale})`,
44676
+ fontWeight: 600,
44677
+ margin: "18px 0 10px 0"
44678
+ },
44679
+ "& h3": {
44680
+ fontSize: `calc(1.1rem * ${headingScale})`,
44681
+ fontWeight: 600,
44682
+ margin: "16px 0 8px 0"
44683
+ },
44684
+ "& ul": {
44685
+ paddingLeft: "24px",
44686
+ margin: "10px 0"
44687
+ },
44688
+ "& li": {
44689
+ margin: "4px 0"
44690
+ },
44691
+ "& a": {
44692
+ color: "#90caf9",
44693
+ textDecoration: "none",
44694
+ borderBottom: "1px dotted rgba(144, 202, 249, 0.5)",
44695
+ transition: "all 0.2s ease",
44696
+ "&:hover": {
44697
+ textDecoration: "none",
44698
+ borderBottom: "1px solid #90caf9",
44699
+ color: "#bbdefb"
44700
+ }
44701
+ },
44702
+ "& strong": {
44703
+ fontWeight: 600,
44704
+ color: "#e6e6e6"
44705
+ },
44706
+ "& em": {
44707
+ fontStyle: "italic",
44708
+ color: "#e0e0e0"
44709
+ },
44710
+ "& br": {
44711
+ display: "block",
44712
+ content: '""',
44713
+ marginTop: "8px"
44714
+ },
44715
+ "& p:first-of-type": {
44716
+ marginTop: "2px"
44717
+ },
44718
+ "& p": {
44719
+ margin: `${paragraphSpacing} 0`
44720
+ }
44721
+ })
44722
+ );
44723
+ const convertUrlsToMarkdownLinks = (text2) => {
44724
+ const urlRegex = /(?<!\]\()(https?:\/\/\S+?)([,.;:!?"'\)\]]+)?(?=\s|$)/g;
44725
+ return text2.replace(
44726
+ urlRegex,
44727
+ (_match, url, punctuation) => `[${url}](${url})${punctuation || ""}`
44728
+ );
44729
+ };
44730
+ const MarkdownRenderer = reactExports.memo(
44731
+ ({ content: content2, styleProps }) => {
44732
+ const processedContent = reactExports.useMemo(() => {
44733
+ return convertUrlsToMarkdownLinks(content2.trim());
44734
+ }, [content2]);
44735
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownContent, { ...styleProps, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44736
+ Markdown,
44737
+ {
44738
+ components: {
44739
+ a: ({ href, children }) => /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children })
44740
+ },
44741
+ children: processedContent
44742
+ }
44743
+ ) });
44744
+ }
44745
+ );
44746
+ const BlockContainer = styled$1(Box)(() => ({
44747
+ width: "95%",
44748
+ cursor: "pointer",
44749
+ transition: "all 0.2s ease",
44750
+ marginLeft: 56,
44751
+ "&:hover": {
44752
+ opacity: 0.9
44753
+ }
44754
+ }));
44755
+ const BlockHeader = styled$1(Box, {
44756
+ shouldForwardProp: (prop) => prop !== "executionType" && prop !== "isUser"
44757
+ })(
44758
+ ({ theme: theme2, executionType }) => ({
44759
+ display: "flex",
44760
+ alignItems: "center",
44761
+ padding: "8px 12px",
44762
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
44763
+ borderLeft: `3px solid ${executionType === "plan" ? theme2.palette.grey[600] : theme2.palette.grey[600]}`
44764
+ })
44765
+ );
44766
+ const BlockIcon = styled$1(Box)(({ theme: theme2 }) => ({
44767
+ marginRight: 8,
44768
+ display: "flex",
44769
+ alignItems: "center",
44770
+ justifyContent: "flex-start",
44771
+ color: theme2.palette.grey[500]
44772
+ }));
44773
+ const BlockTitle = styled$1(Typography)(({ theme: theme2 }) => ({
44774
+ fontWeight: 500,
44775
+ fontSize: "0.85rem",
44776
+ color: theme2.palette.grey[500]
44777
+ }));
44778
+ const BlockContent = styled$1(Typography)(({ theme: theme2 }) => ({
44779
+ fontSize: "0.85rem",
44780
+ color: theme2.palette.grey[400],
44781
+ overflow: "hidden",
44782
+ textOverflow: "ellipsis",
44783
+ marginTop: 2
44784
+ }));
44785
+ const ExpandedContent = styled$1(Box)(({ theme: theme2 }) => ({
44786
+ padding: "12px 16px",
44787
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
44788
+ borderBottomLeftRadius: 4,
44789
+ borderBottomRightRadius: 4,
44790
+ fontSize: "0.85rem",
44791
+ color: theme2.palette.grey[300],
44792
+ borderLeft: `3px solid ${theme2.palette.grey[600]}`,
44793
+ marginLeft: 0
44794
+ }));
44795
+ const BackgroundBlock = ({
44796
+ content: content2,
44797
+ action,
44798
+ executionType,
44799
+ isUser
44800
+ }) => {
44801
+ const [isExpanded, setIsExpanded] = reactExports.useState(false);
44802
+ const toggleExpand = () => {
44803
+ setIsExpanded(!isExpanded);
44804
+ };
44805
+ const getTitle = () => {
44806
+ switch (action) {
44807
+ case "DONE":
44808
+ return "Task Complete";
44809
+ case "ASK":
44810
+ return "Asking a Question";
44811
+ default:
44812
+ return executionType === "plan" ? "Planning" : "Reflection";
44813
+ }
44814
+ };
44815
+ const getIcon = () => {
44816
+ switch (action) {
44817
+ case "DONE":
44818
+ return faCheck;
44819
+ case "ASK":
44820
+ return faQuestion;
44821
+ default:
44822
+ return executionType === "plan" ? faLightbulb : faCommentDots;
44823
+ }
44824
+ };
44825
+ const getTruncatedContent = (content22, maxLength = 140) => {
44826
+ return content22.length > maxLength ? `${content22.slice(0, maxLength)}...` : content22;
44827
+ };
44828
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(BlockContainer, { onClick: toggleExpand, children: [
44829
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(BlockHeader, { executionType, isUser, children: [
44830
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BlockIcon, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: getIcon(), size: "sm" }) }),
44831
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { flexGrow: 1 }, children: [
44832
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BlockTitle, { variant: "subtitle2", children: getTitle() }),
44833
+ !isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(BlockContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44834
+ MarkdownRenderer,
44835
+ {
44836
+ content: getTruncatedContent(content2),
44837
+ styleProps: {
44838
+ fontSize: "0.85rem",
44839
+ lineHeight: 1.5,
44840
+ paragraphSpacing: "4px",
44841
+ headingScale: 0.9,
44842
+ codeSize: "0.85em"
44843
+ }
44844
+ }
44845
+ ) })
44846
+ ] })
44847
+ ] }),
44848
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Collapse, { in: isExpanded, timeout: "auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ExpandedContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
44849
+ MarkdownRenderer,
44850
+ {
44851
+ content: content2,
44852
+ styleProps: {
44853
+ fontSize: "0.85rem",
44854
+ lineHeight: 1.5,
44855
+ paragraphSpacing: "4px",
44856
+ headingScale: 0.9,
44857
+ codeSize: "0.85em"
44858
+ }
44859
+ }
44860
+ ) }) })
44861
+ ] });
44862
+ };
44586
44863
  function _objectWithoutPropertiesLoose(r, e) {
44587
44864
  if (null == r) return {};
44588
44865
  var t = {};
@@ -81904,179 +82181,135 @@ function ft(n2) {
81904
82181
  }
81905
82182
  return React.memo(l2);
81906
82183
  }
81907
- const MarkdownContent = styled$1(Box)({
81908
- 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",
81936
- 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"
81963
- },
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"
81973
- }
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"
81993
- }
82184
+ const CodeContainer$3 = styled$1(Box)({
82185
+ marginBottom: 16,
82186
+ width: "100%"
81994
82187
  });
81995
- const convertUrlsToMarkdownLinks = (text2) => {
81996
- const urlRegex = /(?<!\]\()(https?:\/\/\S+?)([,.;:!?"'\)\]]+)?(?=\s|$)/g;
81997
- return text2.replace(
81998
- urlRegex,
81999
- (_match, url, punctuation) => `[${url}](${url})${punctuation || ""}`
82000
- );
82001
- };
82002
- const MarkdownRenderer = reactExports.memo(
82003
- ({ content: content2 }) => {
82004
- const processedContent = reactExports.useMemo(() => {
82005
- return convertUrlsToMarkdownLinks(content2.trim());
82006
- }, [content2]);
82007
- return /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82008
- Markdown,
82188
+ const SectionLabel$4 = styled$1(Typography)(({ theme: theme2 }) => ({
82189
+ display: "block",
82190
+ marginBottom: 4,
82191
+ color: theme2.palette.text.secondary
82192
+ }));
82193
+ const SyntaxHighlighterStyles = ft`
82194
+ .react-syntax-highlighter-code-block * {
82195
+ font-family: 'Roboto Mono', monospace !important;
82196
+ }
82197
+ `;
82198
+ const CodeBlock = ({ code: code2 }) => {
82199
+ if (!code2) return null;
82200
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer$3, { children: [
82201
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$4, { variant: "caption", children: "Code" }),
82202
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SyntaxHighlighterStyles, {}),
82203
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
82204
+ highlighter,
82009
82205
  {
82010
- components: {
82011
- a: ({ href, children }) => /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children })
82206
+ language: "python",
82207
+ style: atomOneDark,
82208
+ customStyle: {
82209
+ borderRadius: "8px",
82210
+ fontSize: "0.85rem",
82211
+ width: "100%",
82212
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.2)",
82213
+ padding: "0.75rem"
82214
+ },
82215
+ codeTagProps: {
82216
+ style: {
82217
+ fontFamily: '"Roboto Mono", monospace !important'
82218
+ }
82012
82219
  },
82013
- children: processedContent
82220
+ className: "react-syntax-highlighter-code-block",
82221
+ wrapLines: true,
82222
+ wrapLongLines: true,
82223
+ children: code2
82014
82224
  }
82015
- ) });
82016
- }
82017
- );
82018
- const MessageContainer = styled$1(Box, {
82019
- shouldForwardProp: (prop) => prop !== "isUser"
82020
- })(({ isUser }) => ({
82225
+ )
82226
+ ] });
82227
+ };
82228
+ const SectionHeader = styled$1(Box)(({ theme: theme2 }) => ({
82021
82229
  display: "flex",
82022
- flexDirection: isUser ? "row-reverse" : "row",
82023
- alignItems: "flex-start",
82024
- gap: 16,
82025
- marginBottom: 16
82230
+ alignItems: "center",
82231
+ marginBottom: 8,
82232
+ cursor: "pointer",
82233
+ userSelect: "none",
82234
+ "&:hover": {
82235
+ backgroundColor: "rgba(255, 255, 255, 0.05)"
82236
+ },
82237
+ borderRadius: 4,
82238
+ padding: "4px 8px",
82239
+ color: theme2.palette.primary.main,
82240
+ transition: "all 0.2s ease"
82026
82241
  }));
82027
- const UserAvatar$1 = styled$1(Avatar, {
82242
+ const SectionLabel$3 = styled$1(Typography)(({ theme: theme2 }) => ({
82243
+ display: "block",
82244
+ color: theme2.palette.primary.main,
82245
+ fontWeight: 500,
82246
+ fontSize: "0.85rem"
82247
+ }));
82248
+ const ToggleButton$1 = styled$1(IconButton)({
82249
+ padding: 2,
82250
+ marginRight: 4
82251
+ });
82252
+ const CollapsibleMessage = ({ children, defaultCollapsed = true, hasContent }) => {
82253
+ const [isCollapsed, setIsCollapsed] = reactExports.useState(defaultCollapsed);
82254
+ if (!hasContent) {
82255
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
82256
+ }
82257
+ const toggleCollapse = () => {
82258
+ setIsCollapsed(!isCollapsed);
82259
+ };
82260
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { width: "100%" }, children: [
82261
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionHeader, { onClick: toggleCollapse, children: [
82262
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToggleButton$1, { size: "small", disableRipple: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
82263
+ FontAwesomeIcon,
82264
+ {
82265
+ icon: isCollapsed ? faChevronRight : faChevronDown,
82266
+ size: "sm"
82267
+ }
82268
+ ) }),
82269
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$3, { variant: "caption", children: isCollapsed ? "Show technical details" : "Hide technical details" })
82270
+ ] }),
82271
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Collapse, { in: !isCollapsed, timeout: "auto", children })
82272
+ ] });
82273
+ };
82274
+ const CodeContainer$2 = styled$1(Box)({
82275
+ marginBottom: 16,
82276
+ width: "100%"
82277
+ });
82278
+ const SectionLabel$2 = styled$1(Typography)(({ theme: theme2 }) => ({
82279
+ display: "block",
82280
+ marginBottom: 4,
82281
+ color: theme2.palette.error.light
82282
+ }));
82283
+ const ErrorContainer$2 = styled$1(Box, {
82028
82284
  shouldForwardProp: (prop) => prop !== "isUser"
82029
82285
  })(({ 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"
82033
- }));
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%"
82286
+ fontFamily: '"Roboto Mono", monospace',
82287
+ fontSize: "0.85rem",
82288
+ backgroundColor: "rgba(255, 0, 0, 0.1)",
82289
+ borderRadius: "8px",
82290
+ padding: 12,
82291
+ maxHeight: "200px",
82292
+ overflow: "auto",
82293
+ whiteSpace: "pre-wrap",
82294
+ color: isUser ? theme2.palette.error.main : theme2.palette.error.light,
82295
+ width: "100%",
82296
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82297
+ "&::-webkit-scrollbar": {
82298
+ width: "6px"
82043
82299
  },
82044
- width: "auto",
82045
- padding: 16,
82046
- borderRadius: 8,
82047
- wordBreak: "break-word",
82048
- overflowWrap: "break-word",
82049
- position: "relative"
82300
+ "&::-webkit-scrollbar-thumb": {
82301
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
82302
+ borderRadius: "3px"
82303
+ }
82050
82304
  }));
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
82063
- }
82064
- );
82305
+ const ErrorBlock = ({ error, isUser }) => {
82306
+ if (!error || error === "[No error output]") return null;
82307
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer$2, { children: [
82308
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$2, { variant: "caption", children: "Error" }),
82309
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorContainer$2, { isUser, children: error })
82310
+ ] });
82065
82311
  };
82066
- const AttachmentImage = styled$1("img")({
82067
- maxWidth: "100%",
82068
- maxHeight: 200,
82069
- borderRadius: 8,
82070
- marginBottom: 8,
82071
- boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
82072
- cursor: "pointer",
82073
- transition: "transform 0.2s ease, box-shadow 0.2s ease",
82074
- "&:hover": {
82075
- transform: "scale(1.02)",
82076
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.25)"
82077
- }
82078
- });
82079
- const FileAttachment = styled$1(Box)(() => ({
82312
+ const FileAttachmentContainer = styled$1(Box)(() => ({
82080
82313
  display: "flex",
82081
82314
  alignItems: "center",
82082
82315
  padding: "8px 12px",
@@ -82115,88 +82348,82 @@ const FileName = styled$1(Typography)({
82115
82348
  textDecoration: "underline"
82116
82349
  }
82117
82350
  });
82118
- const isWebUrl = (path) => {
82119
- return path.startsWith("http://") || path.startsWith("https://");
82351
+ const getFileName$1 = (path) => {
82352
+ const parts = path.split(/[/\\]/);
82353
+ return parts[parts.length - 1];
82120
82354
  };
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));
82355
+ const FileAttachment = ({ file, onClick }) => {
82356
+ const handleClick = () => {
82357
+ onClick(file);
82358
+ };
82359
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
82360
+ FileAttachmentContainer,
82361
+ {
82362
+ onClick: handleClick,
82363
+ title: `Click to open ${getFileName$1(file)}`,
82364
+ children: [
82365
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faFile, size: "sm" }) }),
82366
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileName, { variant: "body2", children: getFileName$1(file) })
82367
+ ]
82368
+ }
82369
+ );
82142
82370
  };
82371
+ const AttachmentImage = styled$1("img")({
82372
+ maxWidth: "100%",
82373
+ maxHeight: 200,
82374
+ borderRadius: 8,
82375
+ marginBottom: 8,
82376
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
82377
+ cursor: "pointer",
82378
+ transition: "transform 0.2s ease, box-shadow 0.2s ease",
82379
+ "&:hover": {
82380
+ transform: "scale(1.02)",
82381
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.25)"
82382
+ }
82383
+ });
82143
82384
  const getFileName = (path) => {
82144
82385
  const parts = path.split(/[/\\]/);
82145
82386
  return parts[parts.length - 1];
82146
82387
  };
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;
82388
+ const ImageAttachment = ({
82389
+ file,
82390
+ src,
82391
+ onClick
82392
+ }) => {
82393
+ const handleClick = () => {
82394
+ onClick(file);
82395
+ };
82396
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82397
+ AttachmentImage,
82398
+ {
82399
+ src,
82400
+ alt: getFileName(file),
82401
+ onClick: handleClick,
82402
+ title: `Click to open ${getFileName(file)}`
82403
+ }
82404
+ );
82153
82405
  };
82154
- const SectionLabel = styled$1(Typography)(({ theme: theme2 }) => ({
82406
+ const CodeContainer$1 = styled$1(Box)({
82407
+ marginBottom: 16,
82408
+ width: "100%"
82409
+ });
82410
+ const SectionLabel$1 = styled$1(Typography)(({ theme: theme2 }) => ({
82155
82411
  display: "block",
82156
82412
  marginBottom: 4,
82157
82413
  color: theme2.palette.text.secondary
82158
82414
  }));
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, {
82415
+ const LogContainer = styled$1(Box, {
82189
82416
  shouldForwardProp: (prop) => prop !== "isUser"
82190
- })(({ isUser }) => ({
82417
+ })(({ isUser, theme: theme2 }) => ({
82191
82418
  fontFamily: '"Roboto Mono", monospace',
82192
82419
  fontSize: "0.85rem",
82193
- backgroundColor: "rgba(255, 0, 0, 0.1)",
82420
+ backgroundColor: "rgba(0, 0, 0, 0.3)",
82194
82421
  borderRadius: "8px",
82195
82422
  padding: 12,
82196
82423
  maxHeight: "200px",
82197
82424
  overflow: "auto",
82198
82425
  whiteSpace: "pre-wrap",
82199
- color: isUser ? "error.main" : "error.light",
82426
+ color: isUser ? theme2.palette.info.main : theme2.palette.info.light,
82200
82427
  width: "100%",
82201
82428
  boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82202
82429
  "&::-webkit-scrollbar": {
@@ -82207,36 +82434,187 @@ const ErrorContainer$2 = styled$1(Box, {
82207
82434
  borderRadius: "3px"
82208
82435
  }
82209
82436
  }));
82210
- const LogContainer = styled$1(Box, {
82437
+ const LogBlock = ({ log, isUser }) => {
82438
+ if (!log || log === "[No logger output]") return null;
82439
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer$1, { children: [
82440
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel$1, { variant: "caption", children: "Logs" }),
82441
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LogContainer, { isUser, children: log })
82442
+ ] });
82443
+ };
82444
+ const StyledAvatar = styled$1(Avatar, {
82445
+ shouldForwardProp: (prop) => prop !== "isUser"
82446
+ })(({ isUser, theme: theme2 }) => ({
82447
+ backgroundColor: isUser ? "rgba(66, 133, 244, 0.9)" : "rgba(56, 201, 106, 0.2)",
82448
+ color: isUser ? "white" : theme2.palette.primary.main,
82449
+ boxShadow: isUser ? "0 2px 8px rgba(66, 133, 244, 0.25)" : "none"
82450
+ }));
82451
+ const MessageAvatar = ({ isUser }) => {
82452
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledAvatar, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: isUser ? faUser : faRobot, size: "sm" }) });
82453
+ };
82454
+ const StyledContainer$1 = styled$1(Box, {
82211
82455
  shouldForwardProp: (prop) => prop !== "isUser"
82212
82456
  })(({ isUser }) => ({
82457
+ display: "flex",
82458
+ flexDirection: isUser ? "row-reverse" : "row",
82459
+ alignItems: "flex-start",
82460
+ gap: 16,
82461
+ marginBottom: 16
82462
+ }));
82463
+ const MessageContainer = ({
82464
+ isUser,
82465
+ children
82466
+ }) => {
82467
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledContainer$1, { isUser, children });
82468
+ };
82469
+ const ContentContainer$2 = styled$1(Box)(() => ({
82470
+ marginBottom: 16
82471
+ }));
82472
+ const MessageContent = ({ content: content2 }) => {
82473
+ if (!content2) return null;
82474
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ContentContainer$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(MarkdownRenderer, { content: content2 }) });
82475
+ };
82476
+ const StyledPaper$1 = styled$1(Paper)(({ theme: theme2 }) => ({
82477
+ [theme2.breakpoints.down("sm")]: {
82478
+ maxWidth: "85%"
82479
+ },
82480
+ [theme2.breakpoints.between("sm", "md")]: {
82481
+ maxWidth: "75%"
82482
+ },
82483
+ [theme2.breakpoints.up("md")]: {
82484
+ maxWidth: "65%"
82485
+ },
82486
+ width: "auto",
82487
+ padding: 16,
82488
+ borderRadius: 8,
82489
+ wordBreak: "break-word",
82490
+ overflowWrap: "break-word",
82491
+ position: "relative"
82492
+ }));
82493
+ const MessagePaper = ({
82494
+ isUser,
82495
+ elevation = isUser ? 2 : 1,
82496
+ children
82497
+ }) => {
82498
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82499
+ StyledPaper$1,
82500
+ {
82501
+ elevation,
82502
+ sx: {
82503
+ backgroundColor: isUser ? "rgba(66, 133, 244, 0.15)" : (theme2) => theme2.palette.background.paper,
82504
+ border: isUser ? "1px solid rgba(66, 133, 244, 0.3)" : "1px solid rgba(255, 255, 255, 0.1)",
82505
+ boxShadow: isUser ? "0 4px 12px rgba(0, 0, 0, 0.15)" : "0 2px 8px rgba(0, 0, 0, 0.1)",
82506
+ color: isUser ? (theme2) => theme2.palette.text.primary : "inherit"
82507
+ },
82508
+ children
82509
+ }
82510
+ );
82511
+ };
82512
+ const StyledTimestamp = styled$1(Typography, {
82513
+ shouldForwardProp: (prop) => prop !== "isUser"
82514
+ })(({ isUser, theme: theme2 }) => ({
82515
+ display: "block",
82516
+ marginTop: 8,
82517
+ textAlign: isUser ? "left" : "right",
82518
+ color: theme2.palette.text.secondary,
82519
+ fontSize: "0.7rem"
82520
+ }));
82521
+ const MessageTimestamp = ({
82522
+ timestamp,
82523
+ isUser
82524
+ }) => {
82525
+ const formattedTime = timestamp.toLocaleTimeString([], {
82526
+ hour: "2-digit",
82527
+ minute: "2-digit"
82528
+ });
82529
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledTimestamp, { variant: "caption", isUser, children: formattedTime });
82530
+ };
82531
+ const CodeContainer = styled$1(Box)({
82532
+ marginBottom: 16,
82533
+ width: "100%"
82534
+ });
82535
+ const SectionLabel = styled$1(Typography)(({ theme: theme2 }) => ({
82536
+ display: "block",
82537
+ marginBottom: 4,
82538
+ color: theme2.palette.text.secondary
82539
+ }));
82540
+ const OutputContainer = styled$1(Box)({
82213
82541
  fontFamily: '"Roboto Mono", monospace',
82214
82542
  fontSize: "0.85rem",
82215
82543
  backgroundColor: "rgba(0, 0, 0, 0.3)",
82216
82544
  borderRadius: "8px",
82217
82545
  padding: 12,
82218
- maxHeight: "200px",
82546
+ maxHeight: "300px",
82219
82547
  overflow: "auto",
82220
- whiteSpace: "pre-wrap",
82221
- color: isUser ? "info.main" : "info.light",
82548
+ whiteSpace: "pre",
82222
82549
  width: "100%",
82223
82550
  boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
82551
+ color: "inherit",
82552
+ overflowX: "auto",
82224
82553
  "&::-webkit-scrollbar": {
82225
- width: "6px"
82554
+ width: "6px",
82555
+ height: "6px"
82226
82556
  },
82227
82557
  "&::-webkit-scrollbar-thumb": {
82228
82558
  backgroundColor: "rgba(255, 255, 255, 0.1)",
82229
82559
  borderRadius: "3px"
82560
+ },
82561
+ "&::-webkit-scrollbar-corner": {
82562
+ backgroundColor: "rgba(0, 0, 0, 0.3)"
82230
82563
  }
82231
- }));
82232
- const SyntaxHighlighterStyles = ft`
82233
- .react-syntax-highlighter-code-block * {
82234
- font-family: 'Roboto Mono', monospace !important;
82564
+ });
82565
+ const OutputBlock = ({ output }) => {
82566
+ if (!output) return null;
82567
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(CodeContainer, { children: [
82568
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { variant: "caption", children: "Output" }),
82569
+ /* @__PURE__ */ jsxRuntimeExports.jsx(OutputContainer, { children: output })
82570
+ ] });
82571
+ };
82572
+ const HighlightContainer = styled$1(Box, {
82573
+ shouldForwardProp: (prop) => prop !== "isUser"
82574
+ })(() => ({
82575
+ position: "relative",
82576
+ padding: "16px",
82577
+ borderRadius: "8px",
82578
+ marginBottom: "16px",
82579
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
82580
+ width: "100%",
82581
+ border: "1px solid rgba(255, 193, 7, 0.5)",
82582
+ backgroundColor: "rgba(255, 193, 7, 0.1)",
82583
+ transition: "all 0.2s ease",
82584
+ "&:hover": {
82585
+ boxShadow: "0 6px 16px rgba(0, 0, 0, 0.2)"
82235
82586
  }
82236
- `;
82237
- const StatusIndicator = styled$1(Box, {
82587
+ }));
82588
+ const SecurityBadge = styled$1(Box)(({ theme: theme2 }) => ({
82589
+ position: "absolute",
82590
+ top: "-10px",
82591
+ right: "16px",
82592
+ padding: "4px 8px",
82593
+ borderRadius: "12px",
82594
+ fontSize: "0.7rem",
82595
+ fontWeight: "bold",
82596
+ backgroundColor: theme2.palette.warning.main,
82597
+ color: "#fff",
82598
+ display: "flex",
82599
+ alignItems: "center",
82600
+ gap: "4px",
82601
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
82602
+ }));
82603
+ const SecurityCheckHighlight = ({
82604
+ children,
82605
+ isUser
82606
+ }) => {
82607
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(HighlightContainer, { isUser, children: [
82608
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(SecurityBadge, { children: [
82609
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FontAwesomeIcon, { icon: faExclamationTriangle, size: "xs" }),
82610
+ "AI SECURITY BLOCK"
82611
+ ] }),
82612
+ children
82613
+ ] });
82614
+ };
82615
+ const StyledStatusIndicator = styled$1(Box, {
82238
82616
  shouldForwardProp: (prop) => prop !== "status"
82239
- })(({ status }) => ({
82617
+ })(({ status, theme: theme2 }) => ({
82240
82618
  marginTop: 8,
82241
82619
  display: "inline-block",
82242
82620
  paddingLeft: 8,
@@ -82245,31 +82623,59 @@ const StatusIndicator = styled$1(Box, {
82245
82623
  paddingBottom: 4,
82246
82624
  borderRadius: "4px",
82247
82625
  fontSize: "0.75rem",
82248
- backgroundColor: status === "error" ? "error.dark" : status === "success" ? "success.dark" : "info.dark",
82626
+ backgroundColor: status === "error" ? theme2.palette.error.dark : status === "success" ? theme2.palette.success.dark : theme2.palette.info.dark,
82249
82627
  color: "white",
82250
82628
  boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
82251
82629
  }));
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
- }));
82630
+ const StatusIndicator = ({ status }) => {
82631
+ if (!status) return null;
82632
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(StyledStatusIndicator, { status, children: status });
82633
+ };
82634
+ const isWebUrl = (path) => {
82635
+ return path.startsWith("http://") || path.startsWith("https://");
82636
+ };
82637
+ const isImage = (path) => {
82638
+ const imageExtensions = [
82639
+ ".jpg",
82640
+ ".jpeg",
82641
+ ".png",
82642
+ ".gif",
82643
+ ".webp",
82644
+ ".bmp",
82645
+ ".svg",
82646
+ ".tiff",
82647
+ ".tif",
82648
+ ".ico",
82649
+ ".heic",
82650
+ ".heif",
82651
+ ".avif",
82652
+ ".jfif",
82653
+ ".pjpeg",
82654
+ ".pjp"
82655
+ ];
82656
+ const lowerPath = path.toLowerCase();
82657
+ return imageExtensions.some((ext) => lowerPath.endsWith(ext));
82658
+ };
82659
+ const getAttachmentUrl = (client, path) => {
82660
+ if (isImage(path) && !path.startsWith("http")) {
82661
+ const normalizedPath = path.startsWith("file://") ? path : `file://${path}`;
82662
+ return client.static.getImageUrl(normalizedPath);
82663
+ }
82664
+ return path;
82665
+ };
82261
82666
  const MessageItem = reactExports.memo(
82262
82667
  ({ message: message2 }) => {
82668
+ const shouldHide = (message2.action === "DONE" || message2.action === "ASK") && message2.execution_type === "action" && message2.task_classification === "conversation";
82669
+ if (shouldHide) {
82670
+ return null;
82671
+ }
82263
82672
  const isUser = message2.role === "user";
82673
+ const isAction = message2.execution_type === "action";
82674
+ const isSecurityCheck = message2.execution_type === "security_check";
82675
+ const isPlanOrReflection = message2.execution_type === "plan" || message2.execution_type === "reflection" || isAction && (message2.action === "DONE" || message2.action === "ASK") && message2.task_classification !== "conversation";
82264
82676
  const client = reactExports.useMemo(() => {
82265
82677
  return createLocalOperatorClient(apiConfig.baseUrl);
82266
82678
  }, []);
82267
- const formattedTimestamp = reactExports.useMemo(() => {
82268
- return message2.timestamp.toLocaleTimeString([], {
82269
- hour: "2-digit",
82270
- minute: "2-digit"
82271
- });
82272
- }, [message2.timestamp]);
82273
82679
  const getUrl = reactExports.useCallback(
82274
82680
  (path) => getAttachmentUrl(client, path),
82275
82681
  [client]
@@ -82286,109 +82692,112 @@ const MessageItem = reactExports.memo(
82286
82692
  console.error("Error opening file:", error);
82287
82693
  }
82288
82694
  }, []);
82289
- const handleImageClick = reactExports.useCallback(
82290
- (filePath) => {
82291
- handleFileClick(filePath);
82292
- },
82293
- [handleFileClick]
82294
- );
82695
+ if (isPlanOrReflection && message2.message) {
82696
+ const executionType = isAction && message2.action === "DONE" ? "action" : message2.execution_type || "action";
82697
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82698
+ BackgroundBlock,
82699
+ {
82700
+ content: message2.message,
82701
+ action: message2.action,
82702
+ executionType,
82703
+ isUser
82704
+ }
82705
+ );
82706
+ }
82295
82707
  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: [
82708
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageAvatar, { isUser }),
82709
+ isSecurityCheck ? /* @__PURE__ */ jsxRuntimeExports.jsx(SecurityCheckHighlight, { isUser, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagePaper, { isUser, children: [
82298
82710
  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,
82711
+ ImageAttachment,
82300
82712
  {
82713
+ file,
82301
82714
  src: getUrl(file),
82302
- alt: getFileName(file),
82303
- onClick: () => handleImageClick(file),
82304
- title: `Click to open ${getFileName(file)}`
82715
+ onClick: handleFileClick
82305
82716
  },
82306
82717
  `${message2.id}-${file}`
82307
82718
  )) }),
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,
82319
- {
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
- ]
82719
+ message2.message && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
82720
+ (() => {
82721
+ const hasCollapsibleContent = isSecurityCheck && (message2.code || message2.stdout || message2.stderr || message2.logging);
82722
+ const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
82723
+ message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
82724
+ message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
82725
+ message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
82726
+ message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
82727
+ ] });
82728
+ if (hasCollapsibleContent) {
82729
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82730
+ CollapsibleMessage,
82731
+ {
82732
+ defaultCollapsed: true,
82733
+ hasContent: hasCollapsibleContent,
82734
+ children: contentBlocks
82735
+ }
82736
+ );
82360
82737
  }
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(
82738
+ return contentBlocks;
82739
+ })(),
82740
+ message2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: message2.status }),
82741
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter((file) => !isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
82379
82742
  FileAttachment,
82380
82743
  {
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
- ]
82744
+ file,
82745
+ onClick: handleFileClick
82387
82746
  },
82388
82747
  `${message2.id}-${file}`
82389
82748
  )) }),
82390
- /* @__PURE__ */ jsxRuntimeExports.jsx(Timestamp, { variant: "caption", isUser, children: formattedTimestamp })
82391
- ] })
82749
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageTimestamp, { timestamp: message2.timestamp, isUser })
82750
+ ] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
82751
+ ActionHighlight,
82752
+ {
82753
+ action: message2.action || "CODE",
82754
+ taskClassification: message2.task_classification || "",
82755
+ isUser,
82756
+ executionType: message2.execution_type,
82757
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(MessagePaper, { isUser, children: [
82758
+ 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(
82759
+ ImageAttachment,
82760
+ {
82761
+ file,
82762
+ src: getUrl(file),
82763
+ onClick: handleFileClick
82764
+ },
82765
+ `${message2.id}-${file}`
82766
+ )) }),
82767
+ message2.message && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { content: message2.message, isUser }),
82768
+ (() => {
82769
+ const hasCollapsibleContent = isAction && (message2.code || message2.stdout || message2.stderr || message2.logging);
82770
+ const contentBlocks = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
82771
+ message2.code && /* @__PURE__ */ jsxRuntimeExports.jsx(CodeBlock, { code: message2.code, isUser }),
82772
+ message2.stdout && /* @__PURE__ */ jsxRuntimeExports.jsx(OutputBlock, { output: message2.stdout, isUser }),
82773
+ message2.stderr && /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBlock, { error: message2.stderr, isUser }),
82774
+ message2.logging && /* @__PURE__ */ jsxRuntimeExports.jsx(LogBlock, { log: message2.logging, isUser })
82775
+ ] });
82776
+ if (hasCollapsibleContent) {
82777
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
82778
+ CollapsibleMessage,
82779
+ {
82780
+ defaultCollapsed: true,
82781
+ hasContent: hasCollapsibleContent,
82782
+ children: contentBlocks
82783
+ }
82784
+ );
82785
+ }
82786
+ return contentBlocks;
82787
+ })(),
82788
+ message2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, { status: message2.status }),
82789
+ message2.files && message2.files.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { sx: { mt: 2 }, children: message2.files.filter((file) => !isImage(file)).map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
82790
+ FileAttachment,
82791
+ {
82792
+ file,
82793
+ onClick: handleFileClick
82794
+ },
82795
+ `${message2.id}-${file}`
82796
+ )) }),
82797
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MessageTimestamp, { timestamp: message2.timestamp, isUser })
82798
+ ] })
82799
+ }
82800
+ )
82392
82801
  ] });
82393
82802
  },
82394
82803
  (prevProps, nextProps) => {