@axiom-lattice/react-sdk 2.1.96 → 2.1.98

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.
package/dist/index.mjs CHANGED
@@ -97,8 +97,8 @@ var AuthProvider = ({
97
97
  onLoginSuccess?.(userData, tenantList || []);
98
98
  return { requiresTenantSelection, hasTenants };
99
99
  } catch (err) {
100
- const message28 = err instanceof Error ? err.message : "Login failed";
101
- setError(message28);
100
+ const message30 = err instanceof Error ? err.message : "Login failed";
101
+ setError(message30);
102
102
  throw err;
103
103
  } finally {
104
104
  setIsLoading(false);
@@ -122,8 +122,8 @@ var AuthProvider = ({
122
122
  }
123
123
  return { message: data.message || "Registration successful!", token: data.data?.token };
124
124
  } catch (err) {
125
- const message28 = err instanceof Error ? err.message : "Registration failed";
126
- setError(message28);
125
+ const message30 = err instanceof Error ? err.message : "Registration failed";
126
+ setError(message30);
127
127
  throw err;
128
128
  } finally {
129
129
  setIsLoading(false);
@@ -182,8 +182,8 @@ var AuthProvider = ({
182
182
  }
183
183
  onTenantSelected?.(tenantData);
184
184
  } catch (err) {
185
- const message28 = err instanceof Error ? err.message : "Failed to select tenant";
186
- setError(message28);
185
+ const message30 = err instanceof Error ? err.message : "Failed to select tenant";
186
+ setError(message30);
187
187
  throw err;
188
188
  } finally {
189
189
  setIsLoading(false);
@@ -222,8 +222,8 @@ var AuthProvider = ({
222
222
  setTenants(tenantList);
223
223
  sessionStorage.setItem("lattice_tenants", JSON.stringify(tenantList));
224
224
  } catch (err) {
225
- const message28 = err instanceof Error ? err.message : "Failed to fetch tenants";
226
- setError(message28);
225
+ const message30 = err instanceof Error ? err.message : "Failed to fetch tenants";
226
+ setError(message30);
227
227
  } finally {
228
228
  setIsLoading(false);
229
229
  }
@@ -253,8 +253,8 @@ var AuthProvider = ({
253
253
  setUser(data);
254
254
  sessionStorage.setItem("lattice_user", JSON.stringify(data));
255
255
  } catch (err) {
256
- const message28 = err instanceof Error ? err.message : "Failed to refresh user";
257
- setError(message28);
256
+ const message30 = err instanceof Error ? err.message : "Failed to refresh user";
257
+ setError(message30);
258
258
  } finally {
259
259
  setIsLoading(false);
260
260
  }
@@ -290,8 +290,8 @@ var AuthProvider = ({
290
290
  const result = await response.json();
291
291
  return result;
292
292
  } catch (err) {
293
- const message28 = err instanceof Error ? err.message : "Failed to change password";
294
- setError(message28);
293
+ const message30 = err instanceof Error ? err.message : "Failed to change password";
294
+ setError(message30);
295
295
  throw err;
296
296
  } finally {
297
297
  setIsLoading(false);
@@ -510,7 +510,7 @@ function useChat(threadId, assistantId, options = {}) {
510
510
  throw new Error("Thread ID is required to send messages");
511
511
  }
512
512
  const { input, command, streaming = true } = data;
513
- const { message: message28, files, ...rest } = input || {};
513
+ const { message: message30, files, ...rest } = input || {};
514
514
  setState((prev) => ({
515
515
  ...prev,
516
516
  isLoading: true,
@@ -519,7 +519,7 @@ function useChat(threadId, assistantId, options = {}) {
519
519
  }));
520
520
  const userMessage = {
521
521
  id: uuidv4(),
522
- content: message28 || command?.resume?.message || "",
522
+ content: message30 || command?.resume?.message || "",
523
523
  files,
524
524
  role: "human"
525
525
  };
@@ -1555,8 +1555,8 @@ function convertThreadToConversationThread(thread, label) {
1555
1555
  function getThreadMetadata(label) {
1556
1556
  return label ? { label } : {};
1557
1557
  }
1558
- function generateLabelFromMessage(message28) {
1559
- const cleanMessage = message28.replace(/```attachments[\s\S]*?```/g, "").trim();
1558
+ function generateLabelFromMessage(message30) {
1559
+ const cleanMessage = message30.replace(/```attachments[\s\S]*?```/g, "").trim();
1560
1560
  if (!cleanMessage) {
1561
1561
  return "";
1562
1562
  }
@@ -2029,7 +2029,7 @@ function AgentThreadProvider({
2029
2029
  throw new Error("Thread ID is required to send messages");
2030
2030
  }
2031
2031
  const { input, command, streaming = true, mode } = data;
2032
- const { message: message28, files, ...rest } = input || {};
2032
+ const { message: message30, files, ...rest } = input || {};
2033
2033
  setState((prev) => ({
2034
2034
  ...prev,
2035
2035
  isLoading: true,
@@ -2038,7 +2038,7 @@ function AgentThreadProvider({
2038
2038
  }));
2039
2039
  const userMessage = {
2040
2040
  id: uuidv42(),
2041
- content: message28 || command?.resume?.message || "",
2041
+ content: message30 || command?.resume?.message || "",
2042
2042
  files,
2043
2043
  role: "human"
2044
2044
  };
@@ -2056,8 +2056,8 @@ function AgentThreadProvider({
2056
2056
  ]
2057
2057
  }));
2058
2058
  const isFirstMessage = messageCountRef.current === 0;
2059
- if (isFirstMessage && message28 && conversationContext) {
2060
- const label = generateLabelFromMessage(message28);
2059
+ if (isFirstMessage && message30 && conversationContext) {
2060
+ const label = generateLabelFromMessage(message30);
2061
2061
  if (label) {
2062
2062
  conversationContext.updateThread({
2063
2063
  id: threadId,
@@ -3954,8 +3954,8 @@ function useTenants(options) {
3954
3954
  const { data } = await response.json();
3955
3955
  setTenants(data || []);
3956
3956
  } catch (err) {
3957
- const message28 = err instanceof Error ? err.message : "Failed to fetch tenants";
3958
- setError(message28);
3957
+ const message30 = err instanceof Error ? err.message : "Failed to fetch tenants";
3958
+ setError(message30);
3959
3959
  } finally {
3960
3960
  setIsLoading(false);
3961
3961
  }
@@ -3997,8 +3997,8 @@ function useUsers(options) {
3997
3997
  const { data } = await response.json();
3998
3998
  setUsers(data || []);
3999
3999
  } catch (err) {
4000
- const message28 = err instanceof Error ? err.message : "Failed to fetch users";
4001
- setError(message28);
4000
+ const message30 = err instanceof Error ? err.message : "Failed to fetch users";
4001
+ setError(message30);
4002
4002
  } finally {
4003
4003
  setIsLoading(false);
4004
4004
  }
@@ -4235,8 +4235,8 @@ var FilePanelToggle = () => {
4235
4235
  };
4236
4236
 
4237
4237
  // src/components/Chat/PinToMenuButton.tsx
4238
- import React74, { useState as useState82, useEffect as useEffect57, useCallback as useCallback42 } from "react";
4239
- import { Button as Button60, Input as Input19, Modal as Modal24, Tooltip as Tooltip26, message as message22 } from "antd";
4238
+ import React74, { useState as useState82, useCallback as useCallback43, useEffect as useEffect57 } from "react";
4239
+ import { Button as Button60, Input as Input19, Modal as Modal24, Tooltip as Tooltip26, AutoComplete, message as message23 } from "antd";
4240
4240
  import { Pin } from "lucide-react";
4241
4241
 
4242
4242
  // src/context/WorkspaceContext.tsx
@@ -4244,16 +4244,16 @@ import React73, {
4244
4244
  createContext as createContext9,
4245
4245
  useContext as useContext11,
4246
4246
  useState as useState81,
4247
- useCallback as useCallback41,
4247
+ useCallback as useCallback42,
4248
4248
  useEffect as useEffect56,
4249
4249
  useRef as useRef30
4250
4250
  } from "react";
4251
4251
  import { WorkspaceClient, Client as Client3 } from "@axiom-lattice/client-sdk";
4252
4252
 
4253
4253
  // src/components/Chat/WorkspaceResourceManager.tsx
4254
- import { useMemo as useMemo35, useEffect as useEffect55, useRef as useRef29, useState as useState80 } from "react";
4255
- import { FolderOpen as FolderOpen3, Activity as Activity4, Database as Database7, Plug as Plug2, Bot as Bot5, Wrench as Wrench2, Zap as Zap2, LogOut as LogOut3, Building2 as Building23, Key, Share2, History, Inbox as Inbox3, FlaskConical as FlaskConical3 } from "lucide-react";
4256
- import { Modal as Modal23, Avatar as Avatar12, Popover as Popover3, Button as Button59 } from "antd";
4254
+ import React72, { useMemo as useMemo35, useEffect as useEffect55, useRef as useRef29, useState as useState80, useCallback as useCallback41 } from "react";
4255
+ import { FolderOpen as FolderOpen3, Activity as Activity4, Database as Database7, Plug as Plug2, Bot as Bot5, Wrench as Wrench2, Zap as Zap2, LogOut as LogOut3, Building2 as Building23, Key, Share2, History, Inbox as Inbox3, FlaskConical as FlaskConical3, PinOff } from "lucide-react";
4256
+ import { Modal as Modal23, Avatar as Avatar12, Popover as Popover3, Button as Button59, message as message22 } from "antd";
4257
4257
 
4258
4258
  // src/components/Chat/ColumnLayout.tsx
4259
4259
  import { PanelLeft, X } from "lucide-react";
@@ -5277,7 +5277,7 @@ var ColumnLayout = ({
5277
5277
 
5278
5278
  // src/components/Chat/Menu.tsx
5279
5279
  import React8, { useState as useState22, useEffect as useEffect15, useMemo as useMemo3, useCallback as useCallback18 } from "react";
5280
- import { Drawer } from "antd";
5280
+ import { Drawer, Dropdown } from "antd";
5281
5281
  import { Plus, ChevronRight, ChevronDown, Cpu, PanelLeftClose } from "lucide-react";
5282
5282
  import { createStyles as createStyles4 } from "antd-style";
5283
5283
  import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
@@ -5383,7 +5383,8 @@ var Menu = ({
5383
5383
  onCollapsedChange,
5384
5384
  className,
5385
5385
  style,
5386
- footer
5386
+ footer,
5387
+ getContextMenuItems
5387
5388
  }) => {
5388
5389
  const { styles: menuStyles } = useMenuStyles();
5389
5390
  const { styles } = useStyle();
@@ -5450,17 +5451,21 @@ var Menu = ({
5450
5451
  /* @__PURE__ */ jsx15("div", { className: styles.iconModeLogo, children: logo || logoIcon || /* @__PURE__ */ jsx15(Cpu, { size: 28, color: "#1677ff" }) }),
5451
5452
  /* @__PURE__ */ jsx15("div", { className: styles.iconModeContainer, children: groupedItems.map(({ group, items: items2 }, groupIndex) => /* @__PURE__ */ jsxs6(React8.Fragment, { children: [
5452
5453
  groupIndex > 0 && /* @__PURE__ */ jsx15("div", { className: styles.iconModeDivider }),
5453
- /* @__PURE__ */ jsx15("div", { className: styles.iconModeGroup, children: items2.map((item) => /* @__PURE__ */ jsx15(
5454
- "button",
5455
- {
5456
- className: styles.iconModeButton,
5457
- onClick: () => handleItemClick(item),
5458
- title: item.name,
5459
- "aria-label": item.name,
5460
- children: /* @__PURE__ */ jsx15("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%" }, children: item.icon })
5461
- },
5462
- item.id
5463
- )) })
5454
+ /* @__PURE__ */ jsx15("div", { className: styles.iconModeGroup, children: items2.map((item) => {
5455
+ const ctxItems = getContextMenuItems?.(item);
5456
+ const btn = /* @__PURE__ */ jsx15(
5457
+ "button",
5458
+ {
5459
+ className: styles.iconModeButton,
5460
+ onClick: () => handleItemClick(item),
5461
+ title: item.name,
5462
+ "aria-label": item.name,
5463
+ children: /* @__PURE__ */ jsx15("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%" }, children: item.icon })
5464
+ },
5465
+ item.id
5466
+ );
5467
+ return ctxItems ? /* @__PURE__ */ jsx15(Dropdown, { menu: { items: ctxItems }, trigger: ["contextMenu"], children: btn }, item.id) : btn;
5468
+ }) })
5464
5469
  ] }, group || `group-${groupIndex}`)) }),
5465
5470
  showToggle && /* @__PURE__ */ jsx15(
5466
5471
  "button",
@@ -5499,22 +5504,25 @@ var Menu = ({
5499
5504
  items2.map((item) => {
5500
5505
  const isInline = item.inline ?? false;
5501
5506
  const isExpanded2 = expandedInlineDrawers.has(item.id);
5507
+ const ctxItems = getContextMenuItems?.(item);
5508
+ const btn = /* @__PURE__ */ jsxs6(
5509
+ "button",
5510
+ {
5511
+ className: `${styles.menuItemExpanded} ${isCollapsed ? "collapsed" : ""} ${isExpanded2 ? styles.menuItemExpandedActive : ""}`,
5512
+ onClick: () => handleItemClick(item),
5513
+ title: isCollapsed ? item.name : void 0,
5514
+ "aria-label": item.name,
5515
+ "aria-expanded": isExpanded2,
5516
+ children: [
5517
+ /* @__PURE__ */ jsx15("span", { className: "menu-icon", children: item.icon }),
5518
+ /* @__PURE__ */ jsx15("span", { className: "menu-label", children: item.name }),
5519
+ isInline && !isCollapsed && /* @__PURE__ */ jsx15("span", { className: styles.inlineDrawerIndicator, children: isExpanded2 ? /* @__PURE__ */ jsx15(ChevronDown, { size: 16 }) : /* @__PURE__ */ jsx15(ChevronRight, { size: 16 }) })
5520
+ ]
5521
+ }
5522
+ );
5523
+ const buttonWithContextMenu = ctxItems ? /* @__PURE__ */ jsx15(Dropdown, { menu: { items: ctxItems }, trigger: ["contextMenu"], children: btn }, item.id) : /* @__PURE__ */ jsx15(React8.Fragment, { children: btn }, item.id);
5502
5524
  return /* @__PURE__ */ jsxs6(React8.Fragment, { children: [
5503
- /* @__PURE__ */ jsxs6(
5504
- "button",
5505
- {
5506
- className: `${styles.menuItemExpanded} ${isCollapsed ? "collapsed" : ""} ${isExpanded2 ? styles.menuItemExpandedActive : ""}`,
5507
- onClick: () => handleItemClick(item),
5508
- title: isCollapsed ? item.name : void 0,
5509
- "aria-label": item.name,
5510
- "aria-expanded": isExpanded2,
5511
- children: [
5512
- /* @__PURE__ */ jsx15("span", { className: "menu-icon", children: item.icon }),
5513
- /* @__PURE__ */ jsx15("span", { className: "menu-label", children: item.name }),
5514
- isInline && !isCollapsed && /* @__PURE__ */ jsx15("span", { className: styles.inlineDrawerIndicator, children: isExpanded2 ? /* @__PURE__ */ jsx15(ChevronDown, { size: 16 }) : /* @__PURE__ */ jsx15(ChevronRight, { size: 16 }) })
5515
- ]
5516
- }
5517
- ),
5525
+ buttonWithContextMenu,
5518
5526
  isInline && isExpanded2 && !isCollapsed && /* @__PURE__ */ jsx15("div", { className: styles.inlineDrawerContainer, children: item.content })
5519
5527
  ] }, item.id);
5520
5528
  })
@@ -5677,7 +5685,8 @@ function encodeId(contentType, contentConfig, itemId) {
5677
5685
  const projectId = contentConfig.projectId || "";
5678
5686
  const assistantId = contentConfig.assistantId || "";
5679
5687
  const fileName = encodeURIComponent(contentConfig.fileName || "");
5680
- return `${CUSTOM_MENU_ID_PREFIX}:file:${resourcePath}:${workspaceId}:${projectId}:${assistantId}:${fileName}:${itemId}`;
5688
+ const tenantId = contentConfig.tenantId || "";
5689
+ return `${CUSTOM_MENU_ID_PREFIX}:file:${resourcePath}:${workspaceId}:${projectId}:${assistantId}:${fileName}:${tenantId}:${itemId}`;
5681
5690
  }
5682
5691
  return `${CUSTOM_MENU_ID_PREFIX}:unknown::${itemId}`;
5683
5692
  }
@@ -5696,14 +5705,23 @@ function parseCustomMenuId(id) {
5696
5705
  };
5697
5706
  }
5698
5707
  if (contentType === "file" && parts.length >= 8) {
5708
+ const payload = decodeURIComponent(parts[2]);
5709
+ const workspaceId = parts[3] ?? void 0;
5710
+ const projectId = parts[4] ?? void 0;
5711
+ const assistantId = parts[5] ?? void 0;
5712
+ const fileName = decodeURIComponent(parts[6] || "");
5713
+ const hasTenantId = parts.length >= 9;
5714
+ const tenantId = hasTenantId ? parts[7] ?? void 0 : void 0;
5715
+ const dbId = parts.slice(hasTenantId ? 8 : 7).join(":");
5699
5716
  return {
5700
5717
  contentType,
5701
- payload: decodeURIComponent(parts[2]),
5702
- workspaceId: parts[3] ?? void 0,
5703
- projectId: parts[4] ?? void 0,
5704
- assistantId: parts[5] ?? void 0,
5705
- fileName: decodeURIComponent(parts[6] || ""),
5706
- dbId: parts.slice(7).join(":")
5718
+ payload,
5719
+ workspaceId,
5720
+ projectId,
5721
+ assistantId,
5722
+ fileName,
5723
+ tenantId,
5724
+ dbId
5707
5725
  };
5708
5726
  }
5709
5727
  return {
@@ -5713,7 +5731,8 @@ function parseCustomMenuId(id) {
5713
5731
  };
5714
5732
  }
5715
5733
  function menuItemToSideMenuItemConfig(item) {
5716
- const encodedId = encodeId(item.contentType, item.contentConfig, item.id);
5734
+ const contentConfigWithTenant = item.tenantId ? { ...item.contentConfig, tenantId: item.tenantId } : item.contentConfig;
5735
+ const encodedId = encodeId(item.contentType, contentConfigWithTenant, item.id);
5717
5736
  return {
5718
5737
  id: encodedId,
5719
5738
  type: "route",
@@ -13499,11 +13518,11 @@ var ConfirmFeedback = ({
13499
13518
  data,
13500
13519
  interactive = true
13501
13520
  }) => {
13502
- const { message: message28, type, config, feedback, options } = data ?? {};
13521
+ const { message: message30, type, config, feedback, options } = data ?? {};
13503
13522
  const { sendMessage } = useAgentChat();
13504
13523
  const [clicked, setClicked] = useState36(false);
13505
13524
  return /* @__PURE__ */ jsxs22(Space9, { direction: "vertical", style: { width: "100%" }, children: [
13506
- /* @__PURE__ */ jsx31(MDResponse, { content: message28 }),
13525
+ /* @__PURE__ */ jsx31(MDResponse, { content: message30 }),
13507
13526
  options ? /* @__PURE__ */ jsx31(Space9, { style: { justifyContent: "flex-end", width: "100%" }, children: options?.map((option) => /* @__PURE__ */ jsx31(
13508
13527
  Button17,
13509
13528
  {
@@ -13826,7 +13845,7 @@ var useSideAppOpener = () => {
13826
13845
  import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
13827
13846
  var { Text: Text16 } = Typography16;
13828
13847
  var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = true }) => {
13829
- const { dataSource, message: message28 } = data ?? {};
13848
+ const { dataSource, message: message30 } = data ?? {};
13830
13849
  const [expandedRowKeys, setExpandedRowKeys] = useState38([]);
13831
13850
  const openSideApp = useSideAppOpener();
13832
13851
  const processedData = dataSource?.map((item, index) => ({
@@ -13925,7 +13944,7 @@ var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = t
13925
13944
  type: "text/csv;charset=utf-8;"
13926
13945
  });
13927
13946
  const link = document.createElement("a");
13928
- const filename = `${message28 || "data"}_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
13947
+ const filename = `${message30 || "data"}_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
13929
13948
  link.href = URL.createObjectURL(blob);
13930
13949
  link.download = filename;
13931
13950
  document.body.appendChild(link);
@@ -13946,7 +13965,7 @@ var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = t
13946
13965
  tableLayout: "fixed",
13947
13966
  style: { width: "100% !important" },
13948
13967
  title: () => /* @__PURE__ */ jsxs24(Flex, { justify: "space-between", align: "center", children: [
13949
- /* @__PURE__ */ jsx33(Space11, { children: /* @__PURE__ */ jsx33(Text16, { strong: true, style: { fontSize: 16 }, children: message28 || "" }) }),
13968
+ /* @__PURE__ */ jsx33(Space11, { children: /* @__PURE__ */ jsx33(Text16, { strong: true, style: { fontSize: 16 }, children: message30 || "" }) }),
13950
13969
  /* @__PURE__ */ jsxs24(Space11, { children: [
13951
13970
  /* @__PURE__ */ jsx33(
13952
13971
  Button19,
@@ -13968,8 +13987,8 @@ var GenericDataTable = ({ data, interactive = true, default_open_in_side_app = t
13968
13987
  onClick: () => {
13969
13988
  openSideApp({
13970
13989
  component_key: "generic_data_table",
13971
- message: message28 || "",
13972
- data: { dataSource, message: message28 }
13990
+ message: message30 || "",
13991
+ data: { dataSource, message: message30 }
13973
13992
  });
13974
13993
  },
13975
13994
  children: /* @__PURE__ */ jsx33(ExpandAltOutlined, {})
@@ -16645,7 +16664,7 @@ import {
16645
16664
  } from "react";
16646
16665
  import { jsx as jsx53 } from "react/jsx-runtime";
16647
16666
  var LazyBubble = ({
16648
- message: message28,
16667
+ message: message30,
16649
16668
  renderContent,
16650
16669
  autoLoadRightPanel
16651
16670
  }) => {
@@ -16676,10 +16695,10 @@ var LazyBubble = ({
16676
16695
  autoLoadRightPanel?.();
16677
16696
  }, []);
16678
16697
  const getPlaceholder = () => {
16679
- const estimatedHeight = message28.content ? Math.min(100, message28.content.length / 5) : 100;
16698
+ const estimatedHeight = message30.content ? Math.min(100, message30.content.length / 5) : 100;
16680
16699
  return /* @__PURE__ */ jsx53("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
16681
16700
  };
16682
- return /* @__PURE__ */ jsx53(ErrorBoundary, { children: /* @__PURE__ */ jsx53("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message28) : getPlaceholder() }) });
16701
+ return /* @__PURE__ */ jsx53(ErrorBoundary, { children: /* @__PURE__ */ jsx53("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message30) : getPlaceholder() }) });
16683
16702
  };
16684
16703
  var MemoizedBubbleList = memo(
16685
16704
  ({
@@ -16710,8 +16729,8 @@ var MessageList = ({
16710
16729
  messageLengthRef.current = messages?.length;
16711
16730
  }
16712
16731
  }, [messages?.length]);
16713
- const renderContent = useCallback25((message28) => {
16714
- const { content } = message28;
16732
+ const renderContent = useCallback25((message30) => {
16733
+ const { content } = message30;
16715
16734
  try {
16716
16735
  const json = JSON.parse(content);
16717
16736
  if (json.action && json.message) {
@@ -16719,7 +16738,7 @@ var MessageList = ({
16719
16738
  }
16720
16739
  } catch (error) {
16721
16740
  }
16722
- const tool_calls_md = message28.tool_calls?.map((tool_call) => {
16741
+ const tool_calls_md = message30.tool_calls?.map((tool_call) => {
16723
16742
  return `\`\`\`tool_call
16724
16743
  ${JSON.stringify(tool_call)}
16725
16744
  \`\`\``;
@@ -16728,17 +16747,17 @@ ${JSON.stringify(tool_call)}
16728
16747
  return /* @__PURE__ */ jsx53(Space21, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx53(MDResponse, { content: content_md }) });
16729
16748
  }, []);
16730
16749
  const items = useMemo11(
16731
- () => messages.map((message28, index) => ({
16732
- key: message28.id,
16733
- role: message28.role,
16750
+ () => messages.map((message30, index) => ({
16751
+ key: message30.id,
16752
+ role: message30.role,
16734
16753
  typing: false,
16735
16754
  content: /* @__PURE__ */ jsx53(
16736
16755
  LazyBubble,
16737
16756
  {
16738
- message: message28,
16757
+ message: message30,
16739
16758
  renderContent,
16740
16759
  autoLoadRightPanel: () => {
16741
- const { content, role: role2 } = message28;
16760
+ const { content, role: role2 } = message30;
16742
16761
  const isNewAddedMessage = messageLengthRef.current > 1 && messageLengthRef.current + 1 === messages.length;
16743
16762
  if (index === messages.length - 1 && isNewAddedMessage && role2 === "ai") {
16744
16763
  try {
@@ -17763,7 +17782,7 @@ var AgentHeader = ({
17763
17782
 
17764
17783
  // src/components/Chat/ThreadManagementButtons.tsx
17765
17784
  import { useCallback as useCallback27, useContext as useContext9 } from "react";
17766
- import { Tooltip as Tooltip12, Button as Button35, Dropdown } from "antd";
17785
+ import { Tooltip as Tooltip12, Button as Button35, Dropdown as Dropdown2 } from "antd";
17767
17786
  import { HistoryOutlined, PlusOutlined as PlusOutlined8 } from "@ant-design/icons";
17768
17787
  import { Fragment as Fragment11, jsx as jsx66, jsxs as jsxs45 } from "react/jsx-runtime";
17769
17788
  var CreateThreadButton = () => {
@@ -17835,7 +17854,7 @@ var ThreadListButton = () => {
17835
17854
  ] : []
17836
17855
  ];
17837
17856
  return /* @__PURE__ */ jsx66(Tooltip12, { title: "Conversation History", children: /* @__PURE__ */ jsx66(
17838
- Dropdown,
17857
+ Dropdown2,
17839
17858
  {
17840
17859
  menu: { items },
17841
17860
  trigger: ["click"],
@@ -23225,12 +23244,12 @@ var formatDate3 = (timestamp) => {
23225
23244
  });
23226
23245
  };
23227
23246
  var MailboxDetailModal = ({
23228
- message: message28,
23247
+ message: message30,
23229
23248
  visible,
23230
23249
  onClose
23231
23250
  }) => {
23232
23251
  const { styles } = useStyles14();
23233
- if (!message28) return null;
23252
+ if (!message30) return null;
23234
23253
  return /* @__PURE__ */ jsx87(
23235
23254
  Modal16,
23236
23255
  {
@@ -23253,12 +23272,12 @@ var MailboxDetailModal = ({
23253
23272
  children: /* @__PURE__ */ jsxs64("div", { className: styles.modalContent, children: [
23254
23273
  /* @__PURE__ */ jsxs64("div", { className: styles.header, children: [
23255
23274
  /* @__PURE__ */ jsx87("div", { className: styles.messageIcon, children: /* @__PURE__ */ jsx87(Mail2, { size: 20 }) }),
23256
- /* @__PURE__ */ jsx87(Text36, { className: styles.messageId, children: message28.id }),
23257
- !message28.read && /* @__PURE__ */ jsx87(Tag21, { color: "red", children: "Unread" })
23275
+ /* @__PURE__ */ jsx87(Text36, { className: styles.messageId, children: message30.id }),
23276
+ !message30.read && /* @__PURE__ */ jsx87(Tag21, { color: "red", children: "Unread" })
23258
23277
  ] }),
23259
23278
  /* @__PURE__ */ jsxs64(Title12, { level: 4, className: styles.title, children: [
23260
23279
  "Message from ",
23261
- message28.from
23280
+ message30.from
23262
23281
  ] }),
23263
23282
  /* @__PURE__ */ jsxs64("div", { className: styles.metaSection, children: [
23264
23283
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
@@ -23268,11 +23287,11 @@ var MailboxDetailModal = ({
23268
23287
  "div",
23269
23288
  {
23270
23289
  className: styles.avatar,
23271
- style: { background: getAvatarColor7(message28.from) },
23272
- children: getInitials7(message28.from)
23290
+ style: { background: getAvatarColor7(message30.from) },
23291
+ children: getInitials7(message30.from)
23273
23292
  }
23274
23293
  ),
23275
- /* @__PURE__ */ jsx87("span", { children: message28.from })
23294
+ /* @__PURE__ */ jsx87("span", { children: message30.from })
23276
23295
  ] })
23277
23296
  ] }),
23278
23297
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
@@ -23282,29 +23301,29 @@ var MailboxDetailModal = ({
23282
23301
  "div",
23283
23302
  {
23284
23303
  className: styles.avatar,
23285
- style: { background: getAvatarColor7(message28.to) },
23286
- children: getInitials7(message28.to)
23304
+ style: { background: getAvatarColor7(message30.to) },
23305
+ children: getInitials7(message30.to)
23287
23306
  }
23288
23307
  ),
23289
- /* @__PURE__ */ jsx87("span", { children: message28.to })
23308
+ /* @__PURE__ */ jsx87("span", { children: message30.to })
23290
23309
  ] })
23291
23310
  ] }),
23292
23311
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
23293
23312
  /* @__PURE__ */ jsx87(Text36, { className: styles.metaLabel, children: "Time" }),
23294
23313
  /* @__PURE__ */ jsxs64("div", { className: styles.metaValue, children: [
23295
23314
  /* @__PURE__ */ jsx87(Calendar2, { size: 14 }),
23296
- /* @__PURE__ */ jsx87("span", { children: formatDate3(message28.timestamp) })
23315
+ /* @__PURE__ */ jsx87("span", { children: formatDate3(message30.timestamp) })
23297
23316
  ] })
23298
23317
  ] }),
23299
23318
  /* @__PURE__ */ jsxs64("div", { className: styles.metaItem, children: [
23300
23319
  /* @__PURE__ */ jsx87(Text36, { className: styles.metaLabel, children: "Type" }),
23301
- /* @__PURE__ */ jsx87("div", { className: styles.metaValue, children: /* @__PURE__ */ jsx87(Tag21, { color: message28.type === "broadcast" ? "blue" : "default", children: message28.type }) })
23320
+ /* @__PURE__ */ jsx87("div", { className: styles.metaValue, children: /* @__PURE__ */ jsx87(Tag21, { color: message30.type === "broadcast" ? "blue" : "default", children: message30.type }) })
23302
23321
  ] })
23303
23322
  ] }),
23304
23323
  /* @__PURE__ */ jsx87(Divider8, {}),
23305
23324
  /* @__PURE__ */ jsxs64("div", { className: styles.contentSection, children: [
23306
23325
  /* @__PURE__ */ jsx87(Text36, { className: styles.contentLabel, children: "Message Content" }),
23307
- /* @__PURE__ */ jsx87("div", { className: styles.contentBox, children: /* @__PURE__ */ jsx87(Paragraph2, { className: styles.messageContent, children: message28.content }) })
23326
+ /* @__PURE__ */ jsx87("div", { className: styles.contentBox, children: /* @__PURE__ */ jsx87(Paragraph2, { className: styles.messageContent, children: message30.content }) })
23308
23327
  ] })
23309
23328
  ] })
23310
23329
  }
@@ -23533,26 +23552,26 @@ var MessageGroupComponent = ({ group, styles, defaultExpanded = true, onMessageC
23533
23552
  ]
23534
23553
  }
23535
23554
  ),
23536
- isExpanded && /* @__PURE__ */ jsx88("div", { className: styles.listGroupContent, children: group.messages.map((message28) => /* @__PURE__ */ jsxs65(
23555
+ isExpanded && /* @__PURE__ */ jsx88("div", { className: styles.listGroupContent, children: group.messages.map((message30) => /* @__PURE__ */ jsxs65(
23537
23556
  "div",
23538
23557
  {
23539
- className: `${styles.listItem} ${!message28.read ? styles.listItemUnread : ""}`,
23540
- onClick: () => onMessageClick(message28),
23558
+ className: `${styles.listItem} ${!message30.read ? styles.listItemUnread : ""}`,
23559
+ onClick: () => onMessageClick(message30),
23541
23560
  children: [
23542
- /* @__PURE__ */ jsx88("div", { className: styles.listItemIcon, children: !message28.read ? /* @__PURE__ */ jsx88("div", { className: styles.unreadBadge }) : /* @__PURE__ */ jsx88(Circle2, { size: 8, style: { color: "#d9d9d9" } }) }),
23561
+ /* @__PURE__ */ jsx88("div", { className: styles.listItemIcon, children: !message30.read ? /* @__PURE__ */ jsx88("div", { className: styles.unreadBadge }) : /* @__PURE__ */ jsx88(Circle2, { size: 8, style: { color: "#d9d9d9" } }) }),
23543
23562
  /* @__PURE__ */ jsxs65("div", { className: styles.listItemContent, children: [
23544
- /* @__PURE__ */ jsx88("span", { className: styles.listItemPreview, children: getMessagePreview(message28.content) }),
23563
+ /* @__PURE__ */ jsx88("span", { className: styles.listItemPreview, children: getMessagePreview(message30.content) }),
23545
23564
  /* @__PURE__ */ jsxs65("span", { className: styles.listItemMeta, children: [
23546
23565
  "To: ",
23547
- message28.to,
23566
+ message30.to,
23548
23567
  " \u2022 ",
23549
- message28.type
23568
+ message30.type
23550
23569
  ] })
23551
23570
  ] }),
23552
- /* @__PURE__ */ jsx88("div", { className: styles.listItemRight, children: /* @__PURE__ */ jsx88("span", { className: styles.listItemDate, children: formatDate4(message28.timestamp) }) })
23571
+ /* @__PURE__ */ jsx88("div", { className: styles.listItemRight, children: /* @__PURE__ */ jsx88("span", { className: styles.listItemDate, children: formatDate4(message30.timestamp) }) })
23553
23572
  ]
23554
23573
  },
23555
- message28.id
23574
+ message30.id
23556
23575
  )) })
23557
23576
  ] });
23558
23577
  };
@@ -23563,12 +23582,12 @@ var MailboxPanel = ({ data }) => {
23563
23582
  const { teamMailbox = [] } = data || {};
23564
23583
  const messageGroups = useMemo17(() => {
23565
23584
  const groupsMap = /* @__PURE__ */ new Map();
23566
- teamMailbox.forEach((message28) => {
23567
- const sender = message28.from;
23585
+ teamMailbox.forEach((message30) => {
23586
+ const sender = message30.from;
23568
23587
  if (!groupsMap.has(sender)) {
23569
23588
  groupsMap.set(sender, []);
23570
23589
  }
23571
- groupsMap.get(sender).push(message28);
23590
+ groupsMap.get(sender).push(message30);
23572
23591
  });
23573
23592
  const groups = Array.from(groupsMap.entries()).map(([sender, messages]) => ({
23574
23593
  sender,
@@ -23585,8 +23604,8 @@ var MailboxPanel = ({ data }) => {
23585
23604
  return groups;
23586
23605
  }, [teamMailbox]);
23587
23606
  const totalUnread = teamMailbox.filter((m) => !m.read).length;
23588
- const handleMessageClick = (message28) => {
23589
- setSelectedMessage(message28);
23607
+ const handleMessageClick = (message30) => {
23608
+ setSelectedMessage(message30);
23590
23609
  setModalVisible(true);
23591
23610
  };
23592
23611
  const handleCloseModal = () => {
@@ -25430,11 +25449,11 @@ var StreamingHTMLRenderer = ({
25430
25449
  if (!iframe || event.source !== iframe.contentWindow) {
25431
25450
  return;
25432
25451
  }
25433
- const message28 = event.data;
25434
- if (!message28 || typeof message28 !== "object") {
25452
+ const message30 = event.data;
25453
+ if (!message30 || typeof message30 !== "object") {
25435
25454
  return;
25436
25455
  }
25437
- switch (message28.type) {
25456
+ switch (message30.type) {
25438
25457
  case "iframe-ready":
25439
25458
  console.log("[StreamingHTMLRenderer] Iframe ready");
25440
25459
  isReadyRef.current = true;
@@ -25449,26 +25468,26 @@ var StreamingHTMLRenderer = ({
25449
25468
  }
25450
25469
  break;
25451
25470
  case "iframe-height":
25452
- if (typeof message28.height === "number" && message28.height > 0) {
25453
- setIframeHeight(message28.height);
25471
+ if (typeof message30.height === "number" && message30.height > 0) {
25472
+ setIframeHeight(message30.height);
25454
25473
  }
25455
25474
  break;
25456
25475
  case "iframe-error": {
25457
25476
  const streamingError = {
25458
25477
  type: "RENDER_ERROR",
25459
- message: message28.error || "Unknown iframe error"
25478
+ message: message30.error || "Unknown iframe error"
25460
25479
  };
25461
25480
  onError?.(streamingError);
25462
25481
  break;
25463
25482
  }
25464
25483
  case "widget-prompt":
25465
- if (typeof message28.text === "string") {
25466
- onPrompt?.(message28.text);
25484
+ if (typeof message30.text === "string") {
25485
+ onPrompt?.(message30.text);
25467
25486
  }
25468
25487
  break;
25469
25488
  case "widget-open-link":
25470
- if (typeof message28.url === "string") {
25471
- window.open(message28.url, "_blank", "noopener,noreferrer");
25489
+ if (typeof message30.url === "string") {
25490
+ window.open(message30.url, "_blank", "noopener,noreferrer");
25472
25491
  }
25473
25492
  break;
25474
25493
  }
@@ -28607,8 +28626,8 @@ var TopologyRuntimeView = () => {
28607
28626
  setRuns((prev) => prev.filter((r) => r.id !== runId));
28608
28627
  setSelectedRun((prev) => prev?.id === runId ? null : prev);
28609
28628
  } catch (err) {
28610
- const message28 = err instanceof Error ? err.message : "Failed to delete run";
28611
- setError(message28);
28629
+ const message30 = err instanceof Error ? err.message : "Failed to delete run";
28630
+ setError(message30);
28612
28631
  }
28613
28632
  }, [del]);
28614
28633
  const refreshRuns = useCallback37(async () => {
@@ -30187,7 +30206,7 @@ var WorkflowAutomationView = () => {
30187
30206
  // src/components/Eval/EvalPanel.tsx
30188
30207
  import React66, { useState as useState75, useMemo as useMemo31 } from "react";
30189
30208
  import { createStyles as createStyles34 } from "antd-style";
30190
- import { Button as Button55, Card as Card28, Typography as Typography59, Row as Row4, Col as Col4, Tag as Tag29, theme as theme15, Dropdown as Dropdown2, Popconfirm as Popconfirm11, message as message18 } from "antd";
30209
+ import { Button as Button55, Card as Card28, Typography as Typography59, Row as Row4, Col as Col4, Tag as Tag29, theme as theme15, Dropdown as Dropdown3, Popconfirm as Popconfirm11, message as message18 } from "antd";
30191
30210
  import { Play as Play2, FlaskConical as FlaskConical2, TestTube2 as TestTube26, TrendingUp, CheckCircle as CheckCircle4, XCircle as XCircle3, ArrowRight as ArrowRight3, ChevronDown as ChevronDown5, Trash2 as Trash27, Clock as Clock5 } from "lucide-react";
30192
30211
 
30193
30212
  // src/components/Eval/EvalSuiteCardList.tsx
@@ -31021,7 +31040,7 @@ var EvalPanel = () => {
31021
31040
  ] }),
31022
31041
  /* @__PURE__ */ jsxs85("div", { className: styles.topRight, children: [
31023
31042
  /* @__PURE__ */ jsx117(
31024
- Dropdown2,
31043
+ Dropdown3,
31025
31044
  {
31026
31045
  menu: {
31027
31046
  items: projects.map((p) => ({
@@ -31244,7 +31263,7 @@ var EvalPanel = () => {
31244
31263
 
31245
31264
  // src/components/Chat/PersonalAssistantPage.tsx
31246
31265
  import { useEffect as useEffect52, useState as useState77, useCallback as useCallback40, useRef as useRef28 } from "react";
31247
- import { Card as Card29, Button as Button57, Input as Input18, Typography as Typography61, message as message20, Dropdown as Dropdown3, Modal as Modal21 } from "antd";
31266
+ import { Card as Card29, Button as Button57, Input as Input18, Typography as Typography61, message as message20, Dropdown as Dropdown4, Modal as Modal21 } from "antd";
31248
31267
  import { createStyles as createStyles36 } from "antd-style";
31249
31268
  import { Bot as Bot4, Sparkles as Sparkles3, ArrowRight as ArrowRight4, ArrowLeft as ArrowLeft3, Smile, Zap, Heart, Lightbulb, Edit3, MoreHorizontal, MessagesSquare as MessagesSquare2, Trash2 as Trash29 } from "lucide-react";
31250
31269
  import { Client as Client2 } from "@axiom-lattice/client-sdk";
@@ -31495,6 +31514,7 @@ var PersonalAssistantChannelModal = ({
31495
31514
  const [selectedId, setSelectedId] = useState76(null);
31496
31515
  const [formMode, setFormMode] = useState76("view");
31497
31516
  const [selectedChannel, setSelectedChannel] = useState76("lark");
31517
+ const [hasPickedChannel, setHasPickedChannel] = useState76(false);
31498
31518
  const [form] = Form9.useForm();
31499
31519
  const [allowOthers, setAllowOthers] = useState76(true);
31500
31520
  const [saving, setSaving] = useState76(false);
@@ -31509,6 +31529,7 @@ var PersonalAssistantChannelModal = ({
31509
31529
  const [qrCountdown, setQrCountdown] = useState76(0);
31510
31530
  const qrCodeRef = useRef27(null);
31511
31531
  const qrCountdownRef = useRef27(null);
31532
+ const bindingsLoadIdRef = useRef27(null);
31512
31533
  const clearQrCountdown = useCallback39(() => {
31513
31534
  if (qrCountdownRef.current) {
31514
31535
  clearInterval(qrCountdownRef.current);
@@ -31607,19 +31628,25 @@ var PersonalAssistantChannelModal = ({
31607
31628
  }
31608
31629
  }, [get]);
31609
31630
  const loadBindings = useCallback39(async (installationId) => {
31631
+ const requestId = installationId;
31632
+ bindingsLoadIdRef.current = requestId;
31610
31633
  setBindingsLoading(true);
31611
31634
  try {
31612
31635
  const res = await get(`/api/channel-bindings?channelInstallationId=${installationId}`);
31636
+ if (bindingsLoadIdRef.current !== requestId) return;
31613
31637
  if (res.success) {
31614
31638
  setBindings(res.data?.records ?? []);
31615
31639
  } else {
31616
31640
  message19.error(res.message || "Failed to load bindings");
31617
31641
  }
31618
31642
  } catch (error) {
31643
+ if (bindingsLoadIdRef.current !== requestId) return;
31619
31644
  console.error("Failed to load bindings:", error);
31620
31645
  message19.error("Failed to load bindings");
31621
31646
  } finally {
31622
- setBindingsLoading(false);
31647
+ if (bindingsLoadIdRef.current === requestId) {
31648
+ setBindingsLoading(false);
31649
+ }
31623
31650
  }
31624
31651
  }, [get]);
31625
31652
  useEffect51(() => {
@@ -31632,6 +31659,7 @@ var PersonalAssistantChannelModal = ({
31632
31659
  setSelectedId(null);
31633
31660
  setFormMode("view");
31634
31661
  setSelectedChannel("lark");
31662
+ setHasPickedChannel(false);
31635
31663
  form.resetFields();
31636
31664
  bindingForm.resetFields();
31637
31665
  setBindings([]);
@@ -31665,7 +31693,8 @@ var PersonalAssistantChannelModal = ({
31665
31693
  setSelectedId(installation.id);
31666
31694
  setFormMode("edit");
31667
31695
  setSelectedChannel(installation.channel);
31668
- setAllowOthers(!installation.rejectWhenNoBinding);
31696
+ setAllowOthers(installation.channel === "wechat" ? true : !installation.rejectWhenNoBinding);
31697
+ form.resetFields();
31669
31698
  if (installation.channel === "lark") {
31670
31699
  form.setFieldsValue({
31671
31700
  name: installation.name,
@@ -31687,6 +31716,7 @@ var PersonalAssistantChannelModal = ({
31687
31716
  setSelectedId(null);
31688
31717
  setFormMode("create");
31689
31718
  setSelectedChannel("lark");
31719
+ setHasPickedChannel(false);
31690
31720
  setBindings([]);
31691
31721
  setAllowOthers(true);
31692
31722
  form.resetFields();
@@ -31699,6 +31729,7 @@ var PersonalAssistantChannelModal = ({
31699
31729
  setSelectedId(null);
31700
31730
  }
31701
31731
  setFormMode("view");
31732
+ setHasPickedChannel(false);
31702
31733
  setBindings([]);
31703
31734
  form.resetFields();
31704
31735
  bindingForm.resetFields();
@@ -31784,7 +31815,7 @@ var PersonalAssistantChannelModal = ({
31784
31815
  const res = await post(
31785
31816
  "/api/channel-installations",
31786
31817
  {
31787
- channel: "lark",
31818
+ channel: selectedChannel,
31788
31819
  name: values.name,
31789
31820
  config,
31790
31821
  rejectWhenNoBinding: !allowOthers,
@@ -31797,6 +31828,7 @@ var PersonalAssistantChannelModal = ({
31797
31828
  setSelectedId(res.data.id);
31798
31829
  setFormMode("edit");
31799
31830
  setBindings([]);
31831
+ loadInstallations();
31800
31832
  message19.info("Now add users who can access this channel");
31801
31833
  } else {
31802
31834
  cancelForm();
@@ -31897,20 +31929,54 @@ var PersonalAssistantChannelModal = ({
31897
31929
  /* @__PURE__ */ jsx119(Text49, { style: { fontSize: 14, color: "var(--color-text-secondary, #666)" }, children: "Select a channel from the left or add a new one" })
31898
31930
  ] });
31899
31931
  }
31932
+ if (formMode === "create" && !hasPickedChannel) {
31933
+ return /* @__PURE__ */ jsxs86("div", { className: styles.rightBody, children: [
31934
+ /* @__PURE__ */ jsx119("div", { className: styles.formSectionTitle, children: "Choose Channel Type" }),
31935
+ /* @__PURE__ */ jsx119("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: channelOptions.map((opt) => /* @__PURE__ */ jsxs86(
31936
+ "div",
31937
+ {
31938
+ onClick: () => {
31939
+ setSelectedChannel(opt.value);
31940
+ setHasPickedChannel(true);
31941
+ form.resetFields();
31942
+ },
31943
+ style: {
31944
+ padding: "16px 20px",
31945
+ border: "2px solid var(--color-border, #d9d9d9)",
31946
+ borderRadius: 12,
31947
+ cursor: "pointer",
31948
+ display: "flex",
31949
+ alignItems: "center",
31950
+ gap: 12,
31951
+ transition: "border-color 0.2s, background 0.2s"
31952
+ },
31953
+ onMouseEnter: (e) => {
31954
+ e.currentTarget.style.borderColor = "var(--color-primary, #6366f1)";
31955
+ e.currentTarget.style.background = "var(--color-primary-bg, #f0f0ff)";
31956
+ },
31957
+ onMouseLeave: (e) => {
31958
+ e.currentTarget.style.borderColor = "var(--color-border, #d9d9d9)";
31959
+ e.currentTarget.style.background = "transparent";
31960
+ },
31961
+ children: [
31962
+ /* @__PURE__ */ jsx119(MessagesSquare, { size: 22, style: { opacity: 0.6 } }),
31963
+ /* @__PURE__ */ jsx119("div", { children: /* @__PURE__ */ jsx119(Text49, { strong: true, style: { fontSize: 14 }, children: opt.label }) })
31964
+ ]
31965
+ },
31966
+ opt.value
31967
+ )) })
31968
+ ] });
31969
+ }
31900
31970
  const isEdit = formMode === "edit" && selectedId !== null;
31901
31971
  return /* @__PURE__ */ jsxs86("div", { className: styles.rightBody, children: [
31902
- /* @__PURE__ */ jsx119("div", { className: styles.formSectionTitle, children: isEdit ? "Edit Channel" : "New Channel" }),
31972
+ /* @__PURE__ */ jsx119("div", { className: styles.formSectionTitle, children: isEdit ? "Edit Channel" : `New ${CHANNEL_LABEL_MAP[selectedChannel] || selectedChannel}` }),
31903
31973
  /* @__PURE__ */ jsxs86(Form9, { form, layout: "vertical", children: [
31904
- /* @__PURE__ */ jsx119(Form9.Item, { label: "Channel Type", children: /* @__PURE__ */ jsx119(
31974
+ isEdit && /* @__PURE__ */ jsx119(Form9.Item, { label: "Channel Type", children: /* @__PURE__ */ jsx119(
31905
31975
  Select9,
31906
31976
  {
31907
31977
  options: channelOptions,
31908
31978
  value: selectedChannel,
31909
- onChange: (val) => {
31910
- setSelectedChannel(val);
31911
- form.resetFields();
31912
- },
31913
- disabled: isEdit
31979
+ disabled: true
31914
31980
  }
31915
31981
  ) }),
31916
31982
  selectedChannel === "lark" && /* @__PURE__ */ jsxs86(Fragment23, { children: [
@@ -32055,7 +32121,7 @@ var PersonalAssistantChannelModal = ({
32055
32121
  }
32056
32122
  )
32057
32123
  ] }),
32058
- /* @__PURE__ */ jsxs86("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }, children: [
32124
+ selectedChannel !== "wechat" && /* @__PURE__ */ jsxs86("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }, children: [
32059
32125
  /* @__PURE__ */ jsxs86("div", { children: [
32060
32126
  /* @__PURE__ */ jsx119(Text49, { strong: true, style: { fontSize: 14 }, children: "Anyone can message" }),
32061
32127
  /* @__PURE__ */ jsx119("br", {}),
@@ -32064,7 +32130,7 @@ var PersonalAssistantChannelModal = ({
32064
32130
  /* @__PURE__ */ jsx119(Switch4, { checked: allowOthers, onChange: setAllowOthers })
32065
32131
  ] })
32066
32132
  ] }),
32067
- !allowOthers && isEdit && /* @__PURE__ */ jsxs86("div", { className: styles.bindingSection, children: [
32133
+ selectedChannel !== "wechat" && !allowOthers && isEdit && /* @__PURE__ */ jsxs86("div", { className: styles.bindingSection, children: [
32068
32134
  /* @__PURE__ */ jsx119("div", { className: styles.bindingHeader, children: "Who can chat" }),
32069
32135
  /* @__PURE__ */ jsx119("div", { className: styles.bindingHint, children: "Only people you add here can message your assistant" }),
32070
32136
  bindingsLoading ? /* @__PURE__ */ jsx119(Spin20, { size: "small", style: { display: "block", margin: "12px 0" } }) : bindings.length === 0 ? /* @__PURE__ */ jsx119(Text49, { type: "secondary", style: { fontSize: 12 }, children: "No contacts added yet" }) : /* @__PURE__ */ jsx119("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: bindings.map((b) => /* @__PURE__ */ jsxs86("div", { className: styles.contactItem, children: [
@@ -32098,7 +32164,7 @@ var PersonalAssistantChannelModal = ({
32098
32164
  name: "senderId",
32099
32165
  rules: [{ required: true, message: "Required" }],
32100
32166
  style: { flex: 1, marginBottom: 0 },
32101
- children: /* @__PURE__ */ jsx119(Input17, { size: "small", placeholder: "Feishu Open ID" })
32167
+ children: /* @__PURE__ */ jsx119(Input17, { size: "small", placeholder: selectedChannel === "wechat" ? "WeChat Open ID" : "Feishu Open ID" })
32102
32168
  }
32103
32169
  ),
32104
32170
  /* @__PURE__ */ jsx119(
@@ -32136,12 +32202,13 @@ var PersonalAssistantChannelModal = ({
32136
32202
  }
32137
32203
  )
32138
32204
  ] }),
32139
- !allowOthers && !isEdit && /* @__PURE__ */ jsx119("div", { className: styles.bindingSection, children: /* @__PURE__ */ jsx119(Text49, { type: "secondary", style: { fontSize: 12 }, children: "Once saved, come back here to add the people you'd like to chat with." }) })
32205
+ selectedChannel !== "wechat" && !allowOthers && !isEdit && /* @__PURE__ */ jsx119("div", { className: styles.bindingSection, children: /* @__PURE__ */ jsx119(Text49, { type: "secondary", style: { fontSize: 12 }, children: "Once saved, come back here to add the people you'd like to chat with." }) })
32140
32206
  ] });
32141
32207
  };
32142
32208
  const renderFooter = () => {
32143
32209
  if (formMode === "view") return null;
32144
32210
  const isEdit = formMode === "edit" && selectedId !== null;
32211
+ const isPicking = formMode === "create" && !hasPickedChannel;
32145
32212
  return /* @__PURE__ */ jsxs86("div", { className: styles.footer, children: [
32146
32213
  /* @__PURE__ */ jsx119("div", { children: isEdit && /* @__PURE__ */ jsx119(
32147
32214
  Popconfirm12,
@@ -32157,7 +32224,7 @@ var PersonalAssistantChannelModal = ({
32157
32224
  ) }),
32158
32225
  /* @__PURE__ */ jsxs86("div", { style: { display: "flex", gap: 8 }, children: [
32159
32226
  /* @__PURE__ */ jsx119(Button56, { onClick: cancelForm, children: "Cancel" }),
32160
- /* @__PURE__ */ jsx119(Button56, { type: "primary", loading: saving, onClick: handleSave, children: isEdit ? "Save" : "Create" })
32227
+ !isPicking && /* @__PURE__ */ jsx119(Button56, { type: "primary", loading: saving, onClick: handleSave, children: isEdit ? "Save" : "Create" })
32161
32228
  ] })
32162
32229
  ] });
32163
32230
  };
@@ -32376,7 +32443,7 @@ var PersonalAssistantPage = () => {
32376
32443
  }
32377
32444
  ),
32378
32445
  /* @__PURE__ */ jsx120(FilePanelToggle, {}),
32379
- /* @__PURE__ */ jsx120(Dropdown3, { menu: { items: moreItems }, trigger: ["click"], placement: "bottomRight", children: /* @__PURE__ */ jsx120(Button57, { type: "text", icon: /* @__PURE__ */ jsx120(MoreHorizontal, { size: 18 }) }) })
32446
+ /* @__PURE__ */ jsx120(Dropdown4, { menu: { items: moreItems }, trigger: ["click"], placement: "bottomRight", children: /* @__PURE__ */ jsx120(Button57, { type: "text", icon: /* @__PURE__ */ jsx120(MoreHorizontal, { size: 18 }) }) })
32380
32447
  ] })
32381
32448
  }
32382
32449
  ),
@@ -32564,15 +32631,10 @@ var FileView = ({ parsed }) => {
32564
32631
  path: resourcePath.startsWith("/") ? resourcePath : `/${resourcePath}`
32565
32632
  });
32566
32633
  if (parsed.assistantId) params.set("assistantId", parsed.assistantId);
32634
+ if (parsed.tenantId) params.set("tenantId", parsed.tenantId);
32567
32635
  const url = `${baseURL}/api/workspaces/${parsed.workspaceId}/projects/${parsed.projectId}/viewfile?${params}`;
32568
- return /* @__PURE__ */ jsx122(
32569
- "iframe",
32570
- {
32571
- src: url,
32572
- style: IFRAME_STYLE,
32573
- title: parsed.fileName || resourcePath.split("/").pop() || "File"
32574
- }
32575
- );
32636
+ const fileName = parsed.fileName || resourcePath.split("/").pop() || "File";
32637
+ return /* @__PURE__ */ jsx122("div", { style: { width: "100%", height: "100%", overflow: "hidden" }, children: /* @__PURE__ */ jsx122(FileRenderer, { fileUrl: url, fileName, showHeader: true }) });
32576
32638
  };
32577
32639
  var CustomMenuPage = ({ component_key }) => {
32578
32640
  const parsed = parseCustomMenuId(component_key);
@@ -32630,7 +32692,7 @@ var CustomMenuPage = ({ component_key }) => {
32630
32692
 
32631
32693
  // src/components/Chat/SharesPage.tsx
32632
32694
  import { useEffect as useEffect53, useState as useState78 } from "react";
32633
- import { Table as Table5, Button as Button58, Dropdown as Dropdown4, message as message21, Modal as Modal22, Tag as Tag30, Typography as Typography62 } from "antd";
32695
+ import { Table as Table5, Button as Button58, Dropdown as Dropdown5, message as message21, Modal as Modal22, Tag as Tag30, Typography as Typography62 } from "antd";
32634
32696
  import { CopyOutlined as CopyOutlined4, StopOutlined as StopOutlined3, MoreOutlined as MoreOutlined3 } from "@ant-design/icons";
32635
32697
  import { jsx as jsx123, jsxs as jsxs89 } from "react/jsx-runtime";
32636
32698
  var { Text: Text51 } = Typography62;
@@ -32706,7 +32768,7 @@ ${pwdText}`.trim());
32706
32768
  {
32707
32769
  title: "Actions",
32708
32770
  key: "actions",
32709
- render: (_, r) => /* @__PURE__ */ jsx123(Dropdown4, { trigger: ["click"], menu: { items: [
32771
+ render: (_, r) => /* @__PURE__ */ jsx123(Dropdown5, { trigger: ["click"], menu: { items: [
32710
32772
  {
32711
32773
  key: "copy",
32712
32774
  icon: /* @__PURE__ */ jsx123(CopyOutlined4, {}),
@@ -32737,7 +32799,7 @@ import {
32737
32799
  AppstoreOutlined,
32738
32800
  MoreOutlined as MoreOutlined4
32739
32801
  } from "@ant-design/icons";
32740
- import { Dropdown as Dropdown5, Tooltip as Tooltip25 } from "antd";
32802
+ import { Dropdown as Dropdown6, Tooltip as Tooltip25 } from "antd";
32741
32803
  import { createStyles as createStyles37 } from "antd-style";
32742
32804
  import { useEffect as useEffect54, useMemo as useMemo34, useState as useState79 } from "react";
32743
32805
  import { Fragment as Fragment25, jsx as jsx124, jsxs as jsxs90 } from "react/jsx-runtime";
@@ -33061,7 +33123,7 @@ var SideAppViewBrowser = ({ region = "side" }) => {
33061
33123
  /* @__PURE__ */ jsxs90("div", { className: styles.actions, children: [
33062
33124
  items.length > 0 && /* @__PURE__ */ jsx124("div", { className: styles.tabCounter, children: items.length }),
33063
33125
  items.length > 1 && /* @__PURE__ */ jsx124(
33064
- Dropdown5,
33126
+ Dropdown6,
33065
33127
  {
33066
33128
  menu: { items: dropdownItems },
33067
33129
  placement: "bottomRight",
@@ -33282,19 +33344,27 @@ var WorkspaceResourceManager = ({
33282
33344
  const [tenantModalOpen, setTenantModalOpen] = useState80(false);
33283
33345
  const [changePasswordOpen, setChangePasswordOpen] = useState80(false);
33284
33346
  const [fetchedCustomMenuItems, setFetchedCustomMenuItems] = useState80([]);
33285
- useEffect55(() => {
33286
- const fetchCustomMenu = async () => {
33287
- try {
33288
- const json = await get("/api/menu-items?menuTarget=workspace");
33289
- if (json.success && json.data?.records) {
33290
- const items = json.data.records.map(menuItemToSideMenuItemConfig);
33291
- setFetchedCustomMenuItems(items);
33292
- }
33293
- } catch {
33347
+ const { unpin: unpinMenuItem } = usePinMenuActions();
33348
+ const fetchCustomMenu = useCallback41(async () => {
33349
+ try {
33350
+ const json = await get("/api/menu-items?menuTarget=workspace");
33351
+ if (json.success && json.data?.records) {
33352
+ const items = json.data.records.map(menuItemToSideMenuItemConfig);
33353
+ setFetchedCustomMenuItems(items);
33294
33354
  }
33295
- };
33296
- fetchCustomMenu();
33355
+ } catch {
33356
+ }
33297
33357
  }, [get]);
33358
+ useEffect55(() => {
33359
+ fetchCustomMenu();
33360
+ }, [fetchCustomMenu]);
33361
+ useEffect55(() => {
33362
+ const handler = () => {
33363
+ fetchCustomMenu();
33364
+ };
33365
+ window.addEventListener("menu:refresh", handler);
33366
+ return () => window.removeEventListener("menu:refresh", handler);
33367
+ }, [fetchCustomMenu]);
33298
33368
  useEffect55(() => {
33299
33369
  for (const item of fetchedCustomMenuItems) {
33300
33370
  regsiterElement(item.id, {
@@ -33311,6 +33381,31 @@ var WorkspaceResourceManager = ({
33311
33381
  const merged = fetchedCustomMenuItems.length > 0 ? mergeMenuItems(DEFAULT_WORKSPACE_MENU_ITEMS, fetchedCustomMenuItems) : [...DEFAULT_WORKSPACE_MENU_ITEMS];
33312
33382
  return merged;
33313
33383
  }, [config.workspaceMenuItems, fetchedCustomMenuItems]);
33384
+ const getContextMenuItems = useCallback41(
33385
+ (item) => {
33386
+ if (!item.id.startsWith(CUSTOM_MENU_ID_PREFIX)) return null;
33387
+ const parts = item.id.split(":");
33388
+ const dbId = parts[parts.length - 1];
33389
+ if (!dbId) return null;
33390
+ return [
33391
+ {
33392
+ key: "unpin",
33393
+ icon: React72.createElement(PinOff, { size: 14 }),
33394
+ label: "Unpin from Menu",
33395
+ onClick: async () => {
33396
+ try {
33397
+ await unpinMenuItem(dbId);
33398
+ message22.success("Unpinned from menu");
33399
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
33400
+ } catch (err) {
33401
+ message22.error(err.message || "Failed to unpin");
33402
+ }
33403
+ }
33404
+ }
33405
+ ];
33406
+ },
33407
+ [unpinMenuItem]
33408
+ );
33314
33409
  const handleItemClick = (item) => {
33315
33410
  if (item.type === "action" && item.builtin === "switch-tenant") {
33316
33411
  setTenantModalOpen(true);
@@ -33400,6 +33495,7 @@ var WorkspaceResourceManager = ({
33400
33495
  {
33401
33496
  items: menuItems,
33402
33497
  onItemClick: handleItemClick,
33498
+ getContextMenuItems,
33403
33499
  logo,
33404
33500
  logoText: workspaceName || "Workspace",
33405
33501
  showToggle: true,
@@ -33580,14 +33676,14 @@ var WorkspaceContextProvider = ({
33580
33676
  transport: "sse"
33581
33677
  }, tenantId);
33582
33678
  }, [config.baseURL, config.apiKey, tenantId, isAuthenticated]);
33583
- const resetSelectedWorkspace = useCallback41(() => {
33679
+ const resetSelectedWorkspace = useCallback42(() => {
33584
33680
  setProjects([]);
33585
33681
  setWorkspaceId(null);
33586
33682
  sessionStorage.removeItem("workspaceId");
33587
33683
  setProjectId(defaultProjectId ?? null);
33588
33684
  sessionStorage.removeItem("projectId");
33589
33685
  }, [setProjects, setWorkspaceId, setProjectId, defaultProjectId]);
33590
- const resetWS = useCallback41(() => {
33686
+ const resetWS = useCallback42(() => {
33591
33687
  setWorkspaces([]);
33592
33688
  resetSelectedWorkspace();
33593
33689
  }, [resetSelectedWorkspace, setWorkspaces]);
@@ -33595,7 +33691,7 @@ var WorkspaceContextProvider = ({
33595
33691
  resetWS();
33596
33692
  refreshWorkspaces();
33597
33693
  }, [tenantId]);
33598
- const refreshWorkspaces = useCallback41(async () => {
33694
+ const refreshWorkspaces = useCallback42(async () => {
33599
33695
  setLoading(true);
33600
33696
  setError(null);
33601
33697
  try {
@@ -33607,7 +33703,7 @@ var WorkspaceContextProvider = ({
33607
33703
  setLoading(false);
33608
33704
  }
33609
33705
  }, [client]);
33610
- const refreshProjects = useCallback41(async (wsId) => {
33706
+ const refreshProjects = useCallback42(async (wsId) => {
33611
33707
  const targetWorkspaceId = wsId || workspaceId;
33612
33708
  if (!targetWorkspaceId) {
33613
33709
  setProjects([]);
@@ -33657,7 +33753,7 @@ var WorkspaceContextProvider = ({
33657
33753
  }
33658
33754
  prevWorkspaceId.current = workspaceId;
33659
33755
  }, [workspaceId, refreshProjects]);
33660
- const createWorkspace = useCallback41(async (data) => {
33756
+ const createWorkspace = useCallback42(async (data) => {
33661
33757
  setLoading(true);
33662
33758
  setError(null);
33663
33759
  try {
@@ -33672,7 +33768,7 @@ var WorkspaceContextProvider = ({
33672
33768
  setLoading(false);
33673
33769
  }
33674
33770
  }, [client, refreshWorkspaces]);
33675
- const updateWorkspace = useCallback41(async (id, updates) => {
33771
+ const updateWorkspace = useCallback42(async (id, updates) => {
33676
33772
  setLoading(true);
33677
33773
  setError(null);
33678
33774
  try {
@@ -33687,7 +33783,7 @@ var WorkspaceContextProvider = ({
33687
33783
  setLoading(false);
33688
33784
  }
33689
33785
  }, [client, refreshWorkspaces]);
33690
- const deleteWorkspace = useCallback41(async (id) => {
33786
+ const deleteWorkspace = useCallback42(async (id) => {
33691
33787
  setLoading(true);
33692
33788
  setError(null);
33693
33789
  try {
@@ -33704,7 +33800,7 @@ var WorkspaceContextProvider = ({
33704
33800
  setLoading(false);
33705
33801
  }
33706
33802
  }, [client, workspaceId, refreshWorkspaces]);
33707
- const createProject = useCallback41(async (wsId, data) => {
33803
+ const createProject = useCallback42(async (wsId, data) => {
33708
33804
  setLoading(true);
33709
33805
  setError(null);
33710
33806
  try {
@@ -33719,7 +33815,7 @@ var WorkspaceContextProvider = ({
33719
33815
  setLoading(false);
33720
33816
  }
33721
33817
  }, [client, refreshProjects]);
33722
- const updateProject = useCallback41(async (wsId, id, updates) => {
33818
+ const updateProject = useCallback42(async (wsId, id, updates) => {
33723
33819
  setLoading(true);
33724
33820
  setError(null);
33725
33821
  try {
@@ -33734,7 +33830,7 @@ var WorkspaceContextProvider = ({
33734
33830
  setLoading(false);
33735
33831
  }
33736
33832
  }, [client, refreshProjects]);
33737
- const deleteProject = useCallback41(async (wsId, id) => {
33833
+ const deleteProject = useCallback42(async (wsId, id) => {
33738
33834
  setLoading(true);
33739
33835
  setError(null);
33740
33836
  try {
@@ -33751,7 +33847,7 @@ var WorkspaceContextProvider = ({
33751
33847
  setLoading(false);
33752
33848
  }
33753
33849
  }, [client, projectId, refreshProjects]);
33754
- const listPath = useCallback41(
33850
+ const listPath = useCallback42(
33755
33851
  async (path = "/", assistantId) => {
33756
33852
  if (!workspaceId || !projectId) {
33757
33853
  return [];
@@ -33770,7 +33866,7 @@ var WorkspaceContextProvider = ({
33770
33866
  },
33771
33867
  [client, workspaceId, projectId]
33772
33868
  );
33773
- const listPathByFolder = useCallback41(
33869
+ const listPathByFolder = useCallback42(
33774
33870
  async (folder, assistantId) => {
33775
33871
  let normalizedPath = folder;
33776
33872
  if (normalizedPath.startsWith("~/")) {
@@ -33783,7 +33879,7 @@ var WorkspaceContextProvider = ({
33783
33879
  },
33784
33880
  [listPath]
33785
33881
  );
33786
- const uploadFile = useCallback41(
33882
+ const uploadFile = useCallback42(
33787
33883
  async (path, file, assistantId) => {
33788
33884
  if (!workspaceId || !projectId) {
33789
33885
  throw new Error("Workspace and project must be selected before uploading files");
@@ -33803,7 +33899,7 @@ var WorkspaceContextProvider = ({
33803
33899
  },
33804
33900
  [client, workspaceId, projectId]
33805
33901
  );
33806
- const uploadFileToFolder = useCallback41(
33902
+ const uploadFileToFolder = useCallback42(
33807
33903
  async (folder, file, assistantId) => {
33808
33904
  let normalizedFolder = folder;
33809
33905
  if (normalizedFolder.startsWith("~/")) {
@@ -33813,7 +33909,7 @@ var WorkspaceContextProvider = ({
33813
33909
  },
33814
33910
  [uploadFile]
33815
33911
  );
33816
- const getFileViewUrl = useCallback41(
33912
+ const getFileViewUrl = useCallback42(
33817
33913
  (filePath, assistantId) => {
33818
33914
  if (!workspaceId || !projectId) {
33819
33915
  return "";
@@ -33822,7 +33918,7 @@ var WorkspaceContextProvider = ({
33822
33918
  },
33823
33919
  [client, workspaceId, projectId]
33824
33920
  );
33825
- const shareFile = useCallback41(
33921
+ const shareFile = useCallback42(
33826
33922
  async (filePath, assistantId, options) => {
33827
33923
  if (!workspaceId || !projectId) {
33828
33924
  throw new Error("Workspace and project must be selected");
@@ -33835,13 +33931,13 @@ var WorkspaceContextProvider = ({
33835
33931
  },
33836
33932
  [client, workspaceId, projectId]
33837
33933
  );
33838
- const listShares = useCallback41(
33934
+ const listShares = useCallback42(
33839
33935
  async () => {
33840
33936
  return client.resources.listShares();
33841
33937
  },
33842
33938
  [client]
33843
33939
  );
33844
- const unshareFile = useCallback41(
33940
+ const unshareFile = useCallback42(
33845
33941
  async (token) => {
33846
33942
  await client.resources.unshare(token);
33847
33943
  },
@@ -33894,6 +33990,122 @@ var WorkspaceContextProvider = ({
33894
33990
 
33895
33991
  // src/components/Chat/PinToMenuButton.tsx
33896
33992
  import { Fragment as Fragment26, jsx as jsx127, jsxs as jsxs92 } from "react/jsx-runtime";
33993
+ function buildPinContentConfig(params) {
33994
+ const { contentType, assistantId, contentConfig, workspaceId, projectId } = params;
33995
+ if (contentType === "agent") {
33996
+ return {
33997
+ agentId: assistantId,
33998
+ workspaceId: workspaceId || void 0,
33999
+ projectId: projectId || void 0
34000
+ };
34001
+ }
34002
+ return {
34003
+ ...contentConfig,
34004
+ workspaceId: workspaceId || void 0,
34005
+ projectId: projectId || void 0
34006
+ };
34007
+ }
34008
+ async function checkPinStatus(get, params, enableCustomMenu) {
34009
+ const { contentType, assistantId, contentConfig, isMatch } = params;
34010
+ const hasTarget = contentType === "agent" ? !!assistantId : !!contentConfig;
34011
+ if (!hasTarget || !enableCustomMenu) {
34012
+ return { isPinned: false, pinnedId: null };
34013
+ }
34014
+ const json = await get("/api/menu-items?menuTarget=workspace");
34015
+ if (json.success && json.data?.records) {
34016
+ const matchFn = isMatch ?? ((cfg) => contentType === "agent" && cfg.agentId === assistantId);
34017
+ const pinned = json.data.records.find(
34018
+ (item) => item.contentType === contentType && matchFn(item.contentConfig)
34019
+ );
34020
+ if (pinned) {
34021
+ return { isPinned: true, pinnedId: pinned.id };
34022
+ }
34023
+ }
34024
+ return { isPinned: false, pinnedId: null };
34025
+ }
34026
+ async function pinItem(post, params) {
34027
+ const { contentType, name, group } = params;
34028
+ const contentConfig = buildPinContentConfig(params);
34029
+ const body = {
34030
+ menuTarget: "workspace",
34031
+ contentType,
34032
+ contentConfig,
34033
+ group: group?.trim() || void 0,
34034
+ name: name.trim(),
34035
+ sortOrder: 0
34036
+ };
34037
+ const json = await post(
34038
+ "/api/menu-items",
34039
+ body
34040
+ );
34041
+ if (!json.success) {
34042
+ throw new Error(json.message || "Failed to pin");
34043
+ }
34044
+ return { id: json.data.id };
34045
+ }
34046
+ async function unpinItem(del, pinnedId) {
34047
+ const json = await del(`/api/menu-items/${pinnedId}`);
34048
+ if (!json.success) {
34049
+ throw new Error(json.message || "Failed to unpin");
34050
+ }
34051
+ }
34052
+ function usePinMenuActions() {
34053
+ const workspaceCtx = React74.useContext(WorkspaceContext);
34054
+ const { config } = useLatticeChatShellContext();
34055
+ const { post, get, del } = useApi();
34056
+ const enableCustomMenu = config.enableCustomMenu ?? false;
34057
+ const check = useCallback43(
34058
+ async (params) => checkPinStatus(get, params, enableCustomMenu),
34059
+ [get, enableCustomMenu]
34060
+ );
34061
+ const pin = useCallback43(
34062
+ async (params) => pinItem(post, {
34063
+ ...params,
34064
+ workspaceId: workspaceCtx?.workspaceId,
34065
+ projectId: workspaceCtx?.projectId
34066
+ }),
34067
+ [post, workspaceCtx]
34068
+ );
34069
+ const unpin = useCallback43(
34070
+ async (pinnedId) => unpinItem(del, pinnedId),
34071
+ [del]
34072
+ );
34073
+ return { check, pin, unpin, enableCustomMenu, get };
34074
+ }
34075
+ function extractGroups(items) {
34076
+ const groups = /* @__PURE__ */ new Set();
34077
+ for (const item of items) {
34078
+ if (item.group?.trim()) {
34079
+ groups.add(item.group.trim());
34080
+ }
34081
+ }
34082
+ return Array.from(groups).sort();
34083
+ }
34084
+ function useMenuGroups() {
34085
+ const { config } = useLatticeChatShellContext();
34086
+ const defaultGroups = React74.useMemo(() => extractGroups(DEFAULT_WORKSPACE_MENU_ITEMS), []);
34087
+ const configGroups = React74.useMemo(
34088
+ () => extractGroups(config.workspaceMenuItems ?? []),
34089
+ [config.workspaceMenuItems]
34090
+ );
34091
+ return React74.useMemo(
34092
+ () => Array.from(/* @__PURE__ */ new Set([...defaultGroups, ...configGroups])).sort(),
34093
+ [defaultGroups, configGroups]
34094
+ );
34095
+ }
34096
+ async function fetchExistingGroups(get) {
34097
+ const json = await get("/api/menu-items?menuTarget=workspace");
34098
+ if (json.success && json.data?.records) {
34099
+ const groups = /* @__PURE__ */ new Set();
34100
+ for (const item of json.data.records) {
34101
+ if (item.group?.trim()) {
34102
+ groups.add(item.group.trim());
34103
+ }
34104
+ }
34105
+ return Array.from(groups).sort();
34106
+ }
34107
+ return [];
34108
+ }
33897
34109
  var MODAL_BODY_STYLE = {
33898
34110
  display: "flex",
33899
34111
  flexDirection: "column",
@@ -33908,9 +34120,7 @@ var PinToMenuButton = ({
33908
34120
  label,
33909
34121
  block
33910
34122
  }) => {
33911
- const workspaceCtx = React74.useContext(WorkspaceContext);
33912
- const { config } = useLatticeChatShellContext();
33913
- const { post, get, del } = useApi();
34123
+ const { check, pin, unpin, enableCustomMenu, get } = usePinMenuActions();
33914
34124
  const [open, setOpen] = useState82(false);
33915
34125
  const [group, setGroup] = useState82("");
33916
34126
  const [name, setName] = useState82("");
@@ -33918,77 +34128,61 @@ var PinToMenuButton = ({
33918
34128
  const [isPinned, setIsPinned] = useState82(false);
33919
34129
  const [pinnedItemId, setPinnedItemId] = useState82(null);
33920
34130
  const [checking, setChecking] = useState82(true);
34131
+ const staticGroups = useMenuGroups();
34132
+ const [existingGroups, setExistingGroups] = useState82(staticGroups);
34133
+ useEffect57(() => {
34134
+ setExistingGroups(staticGroups);
34135
+ }, [staticGroups]);
34136
+ useEffect57(() => {
34137
+ if (open) {
34138
+ fetchExistingGroups(get).then((apiGroups) => {
34139
+ setExistingGroups(Array.from(/* @__PURE__ */ new Set([...staticGroups, ...apiGroups])).sort());
34140
+ });
34141
+ }
34142
+ }, [open]);
33921
34143
  const hasTarget = contentType === "agent" ? !!assistantId : !!externalContentConfig;
33922
- const checkPinned = useCallback42(async () => {
33923
- if (!hasTarget || !config.enableCustomMenu) {
34144
+ const checkPinned = useCallback43(async () => {
34145
+ if (!hasTarget || !enableCustomMenu) {
33924
34146
  setChecking(false);
33925
34147
  return;
33926
34148
  }
33927
34149
  setChecking(true);
33928
34150
  try {
33929
- const json = await get(
33930
- "/api/menu-items?menuTarget=workspace"
33931
- );
33932
- if (json.success && json.data?.records) {
33933
- const matchFn = isMatch ?? ((cfg) => {
33934
- return contentType === "agent" && cfg.agentId === assistantId;
33935
- });
33936
- const pinned = json.data.records.find(
33937
- (item) => item.contentType === contentType && matchFn(item.contentConfig)
33938
- );
33939
- if (pinned) {
33940
- setIsPinned(true);
33941
- setPinnedItemId(pinned.id);
33942
- } else {
33943
- setIsPinned(false);
33944
- setPinnedItemId(null);
33945
- }
33946
- }
34151
+ const result = await check({ contentType, assistantId, contentConfig: externalContentConfig, isMatch });
34152
+ setIsPinned(result.isPinned);
34153
+ setPinnedItemId(result.pinnedId);
33947
34154
  } catch {
33948
34155
  } finally {
33949
34156
  setChecking(false);
33950
34157
  }
33951
- }, [hasTarget, config.enableCustomMenu, get, contentType, assistantId, isMatch]);
34158
+ }, [hasTarget, enableCustomMenu, check, contentType, assistantId, externalContentConfig, isMatch]);
33952
34159
  useEffect57(() => {
33953
34160
  checkPinned();
33954
34161
  }, [checkPinned]);
33955
- if (!hasTarget || !config.enableCustomMenu) return null;
34162
+ if (!hasTarget || !enableCustomMenu) return null;
33956
34163
  const handlePin = async () => {
33957
34164
  if (!name.trim()) {
33958
- message22.warning("Please enter a menu name");
34165
+ message23.warning("Please enter a menu name");
33959
34166
  return;
33960
34167
  }
33961
34168
  setLoading(true);
33962
34169
  try {
33963
- const contentConfig = contentType === "agent" ? {
33964
- agentId: assistantId,
33965
- workspaceId: workspaceCtx?.workspaceId || void 0,
33966
- projectId: workspaceCtx?.projectId || void 0
33967
- } : {
33968
- ...externalContentConfig,
33969
- workspaceId: workspaceCtx?.workspaceId || void 0,
33970
- projectId: workspaceCtx?.projectId || void 0
33971
- };
33972
- const body = {
33973
- menuTarget: "workspace",
34170
+ await pin({
33974
34171
  contentType,
33975
- contentConfig,
33976
- group: group.trim() || void 0,
34172
+ assistantId,
34173
+ contentConfig: externalContentConfig,
34174
+ isMatch,
33977
34175
  name: name.trim(),
33978
- sortOrder: 0
33979
- };
33980
- const json = await post("/api/menu-items", body);
33981
- if (json.success) {
33982
- message22.success("Pinned to menu");
33983
- setOpen(false);
33984
- setGroup("");
33985
- setName("");
33986
- checkPinned();
33987
- } else {
33988
- message22.error(json.message || "Failed to pin");
33989
- }
33990
- } catch {
33991
- message22.error("Failed to pin to menu");
34176
+ group: group.trim() || void 0
34177
+ });
34178
+ message23.success("Pinned to menu");
34179
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
34180
+ setOpen(false);
34181
+ setGroup("");
34182
+ setName("");
34183
+ checkPinned();
34184
+ } catch (err) {
34185
+ message23.error(err.message || "Failed to pin to menu");
33992
34186
  } finally {
33993
34187
  setLoading(false);
33994
34188
  }
@@ -33997,16 +34191,13 @@ var PinToMenuButton = ({
33997
34191
  if (!pinnedItemId) return;
33998
34192
  setLoading(true);
33999
34193
  try {
34000
- const json = await del(`/api/menu-items/${pinnedItemId}`);
34001
- if (json.success) {
34002
- message22.success("Unpinned from menu");
34003
- setIsPinned(false);
34004
- setPinnedItemId(null);
34005
- } else {
34006
- message22.error(json.message || "Failed to unpin");
34007
- }
34008
- } catch {
34009
- message22.error("Failed to unpin from menu");
34194
+ await unpin(pinnedItemId);
34195
+ message23.success("Unpinned from menu");
34196
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
34197
+ setIsPinned(false);
34198
+ setPinnedItemId(null);
34199
+ } catch (err) {
34200
+ message23.error(err.message || "Failed to unpin from menu");
34010
34201
  } finally {
34011
34202
  setLoading(false);
34012
34203
  }
@@ -34060,11 +34251,13 @@ var PinToMenuButton = ({
34060
34251
  }
34061
34252
  ),
34062
34253
  /* @__PURE__ */ jsx127(
34063
- Input19,
34254
+ AutoComplete,
34064
34255
  {
34065
- placeholder: "Group (optional, e.g. Process)",
34256
+ placeholder: "Group (optional, select or type new)",
34066
34257
  value: group,
34067
- onChange: (e) => setGroup(e.target.value)
34258
+ options: existingGroups.map((g) => ({ value: g })),
34259
+ onChange: (val) => setGroup(val),
34260
+ filterOption: (inputValue, option) => option?.value?.toUpperCase().includes(inputValue.toUpperCase()) ?? false
34068
34261
  }
34069
34262
  )
34070
34263
  ] })
@@ -34077,8 +34270,8 @@ var PinToMenuButton = ({
34077
34270
  import { createStyles as createStyles40 } from "antd-style";
34078
34271
 
34079
34272
  // src/components/Chat/ProjectSelector.tsx
34080
- import { useState as useState83, useCallback as useCallback43, useMemo as useMemo36, useRef as useRef31 } from "react";
34081
- import { Modal as Modal25, Input as Input20, Button as Button61, message as message23 } from "antd";
34273
+ import { useState as useState83, useCallback as useCallback44, useMemo as useMemo36, useRef as useRef31 } from "react";
34274
+ import { Modal as Modal25, Input as Input20, Button as Button61, message as message24 } from "antd";
34082
34275
  import { createStyles as createStyles38 } from "antd-style";
34083
34276
  import { Folder, ChevronDown as ChevronDown6, Building2 as Building24 } from "lucide-react";
34084
34277
  import { Fragment as Fragment27, jsx as jsx128, jsxs as jsxs93 } from "react/jsx-runtime";
@@ -34327,20 +34520,20 @@ var ProjectSelector = ({
34327
34520
  const currentWorkspace = useMemo36(() => {
34328
34521
  return workspaces.find((w) => w.id === workspaceId);
34329
34522
  }, [workspaces, workspaceId]);
34330
- const handleSelectProject = useCallback43((selectedProjectId) => {
34523
+ const handleSelectProject = useCallback44((selectedProjectId) => {
34331
34524
  setProject(selectedProjectId);
34332
34525
  setIsProjectListOpen(false);
34333
34526
  }, [setProject]);
34334
- const handleWorkspaceClick = useCallback43(() => {
34527
+ const handleWorkspaceClick = useCallback44(() => {
34335
34528
  setProject(null);
34336
34529
  }, [setProject]);
34337
- const toggleProjectList = useCallback43(() => {
34530
+ const toggleProjectList = useCallback44(() => {
34338
34531
  setIsProjectListOpen((prev) => !prev);
34339
34532
  }, []);
34340
- const toggleWorkspaceList = useCallback43(() => {
34533
+ const toggleWorkspaceList = useCallback44(() => {
34341
34534
  setIsWorkspaceListOpen((prev) => !prev);
34342
34535
  }, []);
34343
- const validateProjectName = useCallback43((name) => {
34536
+ const validateProjectName = useCallback44((name) => {
34344
34537
  const trimmed = name.trim();
34345
34538
  if (!trimmed) return "Project name is required";
34346
34539
  if (trimmed.length > PROJECT_NAME_MAX_LENGTH) {
@@ -34348,10 +34541,10 @@ var ProjectSelector = ({
34348
34541
  }
34349
34542
  return null;
34350
34543
  }, []);
34351
- const handleOpenModal = useCallback43((e) => {
34544
+ const handleOpenModal = useCallback44((e) => {
34352
34545
  e.stopPropagation();
34353
34546
  if (!workspaceId) {
34354
- message23.warning("Please select a workspace first");
34547
+ message24.warning("Please select a workspace first");
34355
34548
  return;
34356
34549
  }
34357
34550
  setProjectName("");
@@ -34359,7 +34552,7 @@ var ProjectSelector = ({
34359
34552
  setIsModalOpen(true);
34360
34553
  setTimeout(() => projectNameInputRef.current?.input?.focus(), 100);
34361
34554
  }, [workspaceId]);
34362
- const handleCloseModal = useCallback43(() => {
34555
+ const handleCloseModal = useCallback44(() => {
34363
34556
  setIsModalOpen(false);
34364
34557
  setProjectName("");
34365
34558
  setValidationError(null);
@@ -34369,7 +34562,7 @@ var ProjectSelector = ({
34369
34562
  setProjectName(value);
34370
34563
  setValidationError(validateProjectName(value));
34371
34564
  };
34372
- const handleCreateProject = useCallback43(async () => {
34565
+ const handleCreateProject = useCallback44(async () => {
34373
34566
  if (!workspaceId) return;
34374
34567
  const trimmed = projectName.trim();
34375
34568
  const error = validateProjectName(trimmed);
@@ -34385,7 +34578,7 @@ var ProjectSelector = ({
34385
34578
  setProjectName("");
34386
34579
  setValidationError(null);
34387
34580
  setProject(project.id);
34388
- message23.success(`Project "${project.name}" created`);
34581
+ message24.success(`Project "${project.name}" created`);
34389
34582
  } catch (err) {
34390
34583
  const errMsg = err instanceof Error ? err.message : "Failed to create project";
34391
34584
  setValidationError(errMsg);
@@ -34488,13 +34681,13 @@ var ProjectSelector = ({
34488
34681
  };
34489
34682
 
34490
34683
  // src/components/Chat/ToolPanelFiles.tsx
34491
- import { useCallback as useCallback44, useEffect as useEffect58, useMemo as useMemo37, useState as useState85 } from "react";
34492
- import { message as message24 } from "antd";
34684
+ import { useCallback as useCallback46, useEffect as useEffect59, useMemo as useMemo37, useState as useState85 } from "react";
34685
+ import { message as message26 } from "antd";
34493
34686
 
34494
34687
  // src/components/Chat/FileDirectoryPanel.tsx
34495
- import React76, { useState as useState84 } from "react";
34496
- import { Spin as Spin23, Dropdown as Dropdown6, Button as Button62 } from "antd";
34497
- import { ChevronRight as ChevronRight8, FolderOpen as FolderOpen4, Upload } from "lucide-react";
34688
+ import React76, { useState as useState84, useCallback as useCallback45, useEffect as useEffect58 } from "react";
34689
+ import { Spin as Spin23, Dropdown as Dropdown7, Button as Button62, Input as Input21, Modal as Modal26, AutoComplete as AutoComplete2, message as message25 } from "antd";
34690
+ import { ChevronRight as ChevronRight8, FolderOpen as FolderOpen4, Upload, Pin as Pin2 } from "lucide-react";
34498
34691
  import { createStyles as createStyles39 } from "antd-style";
34499
34692
  import { MoreOutlined as MoreOutlined5, LinkOutlined as LinkOutlined5, DownloadOutlined as DownloadOutlined4, EyeOutlined } from "@ant-design/icons";
34500
34693
  import { Fragment as Fragment28, jsx as jsx129, jsxs as jsxs94 } from "react/jsx-runtime";
@@ -34711,6 +34904,11 @@ var getFileName = (path) => {
34711
34904
  return parts[parts.length - 1];
34712
34905
  };
34713
34906
  var getEntryName = (entry) => getFileName(entry.name || entry.path);
34907
+ var MODAL_BODY_STYLE2 = {
34908
+ display: "flex",
34909
+ flexDirection: "column",
34910
+ gap: 12
34911
+ };
34714
34912
  var FileDirectoryPanel = ({
34715
34913
  workspaceId,
34716
34914
  projectId,
@@ -34730,6 +34928,116 @@ var FileDirectoryPanel = ({
34730
34928
  const { currentAssistant } = useAssistantContext();
34731
34929
  const { getFileViewUrl } = useWorkspaceContext();
34732
34930
  const [sharePath, setSharePath] = useState84(null);
34931
+ const { check: checkPin, pin: doPin, unpin: doUnpin, enableCustomMenu, get } = usePinMenuActions();
34932
+ const staticGroups = useMenuGroups();
34933
+ const [existingGroups, setExistingGroups] = useState84(staticGroups);
34934
+ useEffect58(() => {
34935
+ setExistingGroups(staticGroups);
34936
+ }, [staticGroups]);
34937
+ const [pinStates, setPinStates] = useState84({});
34938
+ const [pinModalPath, setPinModalPath] = useState84(null);
34939
+ const [pinName, setPinName] = useState84("");
34940
+ const [pinGroup, setPinGroup] = useState84("");
34941
+ const [pinLoading, setPinLoading] = useState84(false);
34942
+ useEffect58(() => {
34943
+ if (pinModalPath) {
34944
+ fetchExistingGroups(get).then((apiGroups) => {
34945
+ setExistingGroups(Array.from(/* @__PURE__ */ new Set([...staticGroups, ...apiGroups])).sort());
34946
+ });
34947
+ }
34948
+ }, [pinModalPath]);
34949
+ const handleDropdownOpen = useCallback45(
34950
+ (filePath, open) => {
34951
+ if (!open || !enableCustomMenu) return;
34952
+ setPinStates((prev) => {
34953
+ if (prev[filePath]) return prev;
34954
+ return {
34955
+ ...prev,
34956
+ [filePath]: { isPinned: false, pinnedId: null, loading: true }
34957
+ };
34958
+ });
34959
+ const params = {
34960
+ contentType: "file",
34961
+ contentConfig: {
34962
+ resourcePath: filePath,
34963
+ assistantId: currentAssistant?.id || "",
34964
+ fileName: filePath.split("/").pop() || filePath
34965
+ },
34966
+ isMatch: (cfg) => cfg.resourcePath === filePath
34967
+ };
34968
+ checkPin(params).then((result) => {
34969
+ setPinStates((prev) => ({
34970
+ ...prev,
34971
+ [filePath]: { ...result, loading: false }
34972
+ }));
34973
+ }).catch(() => {
34974
+ setPinStates((prev) => ({
34975
+ ...prev,
34976
+ [filePath]: { isPinned: false, pinnedId: null, loading: false }
34977
+ }));
34978
+ });
34979
+ },
34980
+ [enableCustomMenu, checkPin, currentAssistant?.id]
34981
+ );
34982
+ const handlePinSubmit = async () => {
34983
+ if (!pinModalPath || !pinName.trim()) {
34984
+ message25.warning("Please enter a menu name");
34985
+ return;
34986
+ }
34987
+ setPinLoading(true);
34988
+ try {
34989
+ const fileName = pinModalPath.split("/").pop() || pinModalPath;
34990
+ await doPin({
34991
+ contentType: "file",
34992
+ name: pinName.trim(),
34993
+ group: pinGroup.trim() || void 0,
34994
+ contentConfig: {
34995
+ resourcePath: pinModalPath,
34996
+ assistantId: currentAssistant?.id || "",
34997
+ fileName
34998
+ },
34999
+ isMatch: (cfg) => cfg.resourcePath === pinModalPath
35000
+ });
35001
+ message25.success("Pinned to menu");
35002
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
35003
+ setPinModalPath(null);
35004
+ setPinName("");
35005
+ setPinGroup("");
35006
+ setPinStates((prev) => {
35007
+ const copy = { ...prev };
35008
+ delete copy[pinModalPath];
35009
+ return copy;
35010
+ });
35011
+ } catch (err) {
35012
+ message25.error(err.message || "Failed to pin");
35013
+ } finally {
35014
+ setPinLoading(false);
35015
+ }
35016
+ };
35017
+ const handleUnpin = useCallback45(
35018
+ async (filePath, pinnedId) => {
35019
+ setPinStates((prev) => ({
35020
+ ...prev,
35021
+ [filePath]: { ...prev[filePath], loading: true }
35022
+ }));
35023
+ try {
35024
+ await doUnpin(pinnedId);
35025
+ message25.success("Unpinned from menu");
35026
+ window.dispatchEvent(new CustomEvent("menu:refresh"));
35027
+ setPinStates((prev) => ({
35028
+ ...prev,
35029
+ [filePath]: { isPinned: false, pinnedId: null, loading: false }
35030
+ }));
35031
+ } catch (err) {
35032
+ message25.error(err.message || "Failed to unpin");
35033
+ setPinStates((prev) => ({
35034
+ ...prev,
35035
+ [filePath]: { ...prev[filePath], loading: false }
35036
+ }));
35037
+ }
35038
+ },
35039
+ [doUnpin]
35040
+ );
34733
35041
  const renderEntry = React76.useCallback((entry, depth) => {
34734
35042
  const entryName = getEntryName(entry);
34735
35043
  if (entry.is_dir) {
@@ -34788,23 +35096,34 @@ var FileDirectoryPanel = ({
34788
35096
  }
34789
35097
  ),
34790
35098
  /* @__PURE__ */ jsx129(
34791
- PinToMenuButton,
34792
- {
34793
- contentType: "file",
34794
- contentConfig: {
34795
- resourcePath: entry.path,
34796
- assistantId: currentAssistant?.id || "",
34797
- fileName: entry.path.split("/").pop() || entry.path
34798
- },
34799
- isMatch: (cfg) => cfg.resourcePath === entry.path
34800
- }
34801
- ),
34802
- /* @__PURE__ */ jsx129(
34803
- Dropdown6,
35099
+ Dropdown7,
34804
35100
  {
34805
35101
  trigger: ["click"],
35102
+ onOpenChange: (open) => handleDropdownOpen(entry.path, open),
34806
35103
  menu: {
34807
35104
  items: [
35105
+ ...enableCustomMenu ? pinStates[entry.path]?.isPinned ? [
35106
+ {
35107
+ key: "unpin",
35108
+ icon: /* @__PURE__ */ jsx129(Pin2, { size: 14 }),
35109
+ label: "Unpin from Menu",
35110
+ onClick: () => {
35111
+ const state = pinStates[entry.path];
35112
+ if (state?.pinnedId) handleUnpin(entry.path, state.pinnedId);
35113
+ }
35114
+ }
35115
+ ] : [
35116
+ {
35117
+ key: "pin",
35118
+ icon: /* @__PURE__ */ jsx129(Pin2, { size: 14 }),
35119
+ label: "Pin to Menu",
35120
+ onClick: () => {
35121
+ setPinModalPath(entry.path);
35122
+ setPinName("");
35123
+ setPinGroup("");
35124
+ }
35125
+ }
35126
+ ] : [],
34808
35127
  {
34809
35128
  key: "preview",
34810
35129
  icon: /* @__PURE__ */ jsx129(EyeOutlined, {}),
@@ -34842,7 +35161,7 @@ var FileDirectoryPanel = ({
34842
35161
  }
34843
35162
  )
34844
35163
  ] }, entry.path);
34845
- }, [directoryChildren, directoryExpanded, directoryLoading, onAssetClick, onToggleDirectory, styles, getFileViewUrl, currentAssistant?.id]);
35164
+ }, [directoryChildren, directoryExpanded, directoryLoading, onAssetClick, onToggleDirectory, styles, getFileViewUrl, currentAssistant?.id, enableCustomMenu, pinStates, handleDropdownOpen, handleUnpin]);
34846
35165
  if (!projectId) {
34847
35166
  return /* @__PURE__ */ jsx129("div", { className: styles.emptyState, children: "Please select a project to browse files" });
34848
35167
  }
@@ -34899,6 +35218,37 @@ var FileDirectoryPanel = ({
34899
35218
  fileName: sharePath.split("/").pop(),
34900
35219
  onClose: () => setSharePath(null)
34901
35220
  }
35221
+ ),
35222
+ /* @__PURE__ */ jsx129(
35223
+ Modal26,
35224
+ {
35225
+ title: "Pin to Menu",
35226
+ open: !!pinModalPath,
35227
+ onOk: handlePinSubmit,
35228
+ onCancel: () => setPinModalPath(null),
35229
+ confirmLoading: pinLoading,
35230
+ okText: "Pin",
35231
+ children: /* @__PURE__ */ jsxs94("div", { style: MODAL_BODY_STYLE2, children: [
35232
+ /* @__PURE__ */ jsx129(
35233
+ Input21,
35234
+ {
35235
+ placeholder: "Menu name (required)",
35236
+ value: pinName,
35237
+ onChange: (e) => setPinName(e.target.value)
35238
+ }
35239
+ ),
35240
+ /* @__PURE__ */ jsx129(
35241
+ AutoComplete2,
35242
+ {
35243
+ placeholder: "Group (optional, select or type new)",
35244
+ value: pinGroup,
35245
+ options: existingGroups.map((g) => ({ value: g })),
35246
+ onChange: (val) => setPinGroup(val),
35247
+ filterOption: (inputValue, option) => option?.value?.toUpperCase().includes(inputValue.toUpperCase()) ?? false
35248
+ }
35249
+ )
35250
+ ] })
35251
+ }
34902
35252
  )
34903
35253
  ] });
34904
35254
  };
@@ -34926,7 +35276,7 @@ var ToolPanelFiles = () => {
34926
35276
  const resourceFolders = useMemo37(() => {
34927
35277
  return config.resourceFolders && config.resourceFolders.length > 0 ? config.resourceFolders : [{ name: "/", displayName: "Project Assets", allowUpload: true }];
34928
35278
  }, [config.resourceFolders]);
34929
- const loadAssetsForFolder = useCallback44(
35279
+ const loadAssetsForFolder = useCallback46(
34930
35280
  async (folder, clearSubdirectoryCache = true) => {
34931
35281
  if (!workspaceId || !projectId) {
34932
35282
  setFolderEntries((prev) => ({ ...prev, [folder.name]: [] }));
@@ -34966,7 +35316,7 @@ var ToolPanelFiles = () => {
34966
35316
  },
34967
35317
  [workspaceId, projectId, listPathByFolder, currentAssistant?.id]
34968
35318
  );
34969
- const handleToggleDirectory = useCallback44(async (path) => {
35319
+ const handleToggleDirectory = useCallback46(async (path) => {
34970
35320
  const isExpanded = directoryExpanded[path] || false;
34971
35321
  if (isExpanded) {
34972
35322
  setDirectoryExpanded((prev) => ({ ...prev, [path]: false }));
@@ -34984,15 +35334,15 @@ var ToolPanelFiles = () => {
34984
35334
  setDirectoryLoading((prev) => ({ ...prev, [path]: false }));
34985
35335
  }
34986
35336
  }, [directoryExpanded, listPath, currentAssistant?.id]);
34987
- useEffect58(() => {
35337
+ useEffect59(() => {
34988
35338
  resourceFolders.forEach((folder) => {
34989
35339
  void loadAssetsForFolder(folder, false);
34990
35340
  });
34991
35341
  }, [resourceFolders, loadAssetsForFolder]);
34992
- const handleAssetClick = useCallback44((asset) => {
35342
+ const handleAssetClick = useCallback46((asset) => {
34993
35343
  const fileUrl = getFileViewUrl(asset.path, currentAssistant?.id);
34994
35344
  if (!fileUrl) {
34995
- message24.warning("Please select a workspace and project first.");
35345
+ message26.warning("Please select a workspace and project first.");
34996
35346
  return;
34997
35347
  }
34998
35348
  openSideApp({
@@ -35005,9 +35355,9 @@ var ToolPanelFiles = () => {
35005
35355
  message: `Preview: ${asset.name || asset.path}`
35006
35356
  });
35007
35357
  }, [getFileViewUrl, openSideApp, currentAssistant?.id]);
35008
- const handleUploadFolder = useCallback44(async (folderName) => {
35358
+ const handleUploadFolder = useCallback46(async (folderName) => {
35009
35359
  if (!workspaceId || !projectId) {
35010
- message24.warning("Please select a workspace and project before uploading.");
35360
+ message26.warning("Please select a workspace and project before uploading.");
35011
35361
  return;
35012
35362
  }
35013
35363
  const input = document.createElement("input");
@@ -35021,14 +35371,14 @@ var ToolPanelFiles = () => {
35021
35371
  setUploadingFolder(folderName);
35022
35372
  try {
35023
35373
  await uploadFileToFolder(folderName, file, currentAssistant?.id);
35024
- message24.success(`Uploaded "${file.name}" successfully`);
35374
+ message26.success(`Uploaded "${file.name}" successfully`);
35025
35375
  const folder = resourceFolders.find((item) => item.name === folderName);
35026
35376
  if (folder) {
35027
35377
  await loadAssetsForFolder(folder);
35028
35378
  }
35029
35379
  } catch (error) {
35030
35380
  const errMsg = error instanceof Error ? error.message : "Failed to upload file";
35031
- message24.error(errMsg);
35381
+ message26.error(errMsg);
35032
35382
  } finally {
35033
35383
  setUploadingFolder(null);
35034
35384
  input.remove();
@@ -35131,7 +35481,7 @@ var LatticeChat = (props) => {
35131
35481
  import { useContext as useContext12 } from "react";
35132
35482
 
35133
35483
  // src/components/Chat/ChatSidebar.tsx
35134
- import { useState as useState86, useMemo as useMemo38, useCallback as useCallback46 } from "react";
35484
+ import { useState as useState86, useMemo as useMemo38, useCallback as useCallback48 } from "react";
35135
35485
  import { Drawer as Drawer3, Avatar as Avatar13, Popover as Popover4, Button as Button63 } from "antd";
35136
35486
  import {
35137
35487
  History as History2,
@@ -35142,10 +35492,10 @@ import {
35142
35492
  } from "lucide-react";
35143
35493
 
35144
35494
  // src/components/Chat/ThreadHistoryMenuContent.tsx
35145
- import React78, { useCallback as useCallback45 } from "react";
35495
+ import React78, { useCallback as useCallback47 } from "react";
35146
35496
  import { createStyles as createStyles41 } from "antd-style";
35147
35497
  import { MessageSquare as MessageSquare4, Trash2 as Trash210 } from "lucide-react";
35148
- import { message as message25, Modal as Modal26 } from "antd";
35498
+ import { message as message27, Modal as Modal27 } from "antd";
35149
35499
  import { jsx as jsx132, jsxs as jsxs96 } from "react/jsx-runtime";
35150
35500
  var useStyles24 = createStyles41(({ token, css }) => ({
35151
35501
  container: css`
@@ -35256,10 +35606,10 @@ var ThreadHistoryMenuContent = () => {
35256
35606
  deleteThread,
35257
35607
  isLoading
35258
35608
  } = useConversationContext();
35259
- const handleDeleteThread = useCallback45(
35609
+ const handleDeleteThread = useCallback47(
35260
35610
  async (e, threadIdToDelete) => {
35261
35611
  e.stopPropagation();
35262
- Modal26.confirm({
35612
+ Modal27.confirm({
35263
35613
  title: "Delete Conversation",
35264
35614
  content: "Are you sure you want to delete this conversation? This action cannot be undone.",
35265
35615
  okText: "Delete",
@@ -35268,9 +35618,9 @@ var ThreadHistoryMenuContent = () => {
35268
35618
  onOk: async () => {
35269
35619
  try {
35270
35620
  await deleteThread(threadIdToDelete);
35271
- message25.success("Conversation deleted");
35621
+ message27.success("Conversation deleted");
35272
35622
  } catch (error) {
35273
- message25.error("Failed to delete conversation");
35623
+ message27.error("Failed to delete conversation");
35274
35624
  }
35275
35625
  }
35276
35626
  });
@@ -35383,7 +35733,7 @@ var ChatSidebar = ({
35383
35733
  const items = customMenuItems.length > 0 ? [...customMenuItems] : [...DEFAULT_MENU_ITEMS];
35384
35734
  return items.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
35385
35735
  }, [customMenuItems]);
35386
- const handleMenuClick = useCallback46(async (item) => {
35736
+ const handleMenuClick = useCallback48(async (item) => {
35387
35737
  if (item.builtin === "settings") {
35388
35738
  setSettingsModalOpen(true);
35389
35739
  onSettingsClick?.();
@@ -35406,17 +35756,17 @@ var ChatSidebar = ({
35406
35756
  }
35407
35757
  }
35408
35758
  }, [onSettingsClick, setSettingsModalOpen, createThread, logout]);
35409
- const handleCloseDrawer = useCallback46((itemId) => {
35759
+ const handleCloseDrawer = useCallback48((itemId) => {
35410
35760
  setDrawerStates((prev) => ({ ...prev, [itemId]: false }));
35411
35761
  }, []);
35412
- const handleNewAnalysis = useCallback46(async () => {
35762
+ const handleNewAnalysis = useCallback48(async () => {
35413
35763
  try {
35414
35764
  await createThread("New Analysis");
35415
35765
  } catch (error) {
35416
35766
  console.error("Failed to create new thread:", error);
35417
35767
  }
35418
35768
  }, [createThread]);
35419
- const renderDrawerContent = useCallback46((item) => {
35769
+ const renderDrawerContent = useCallback48((item) => {
35420
35770
  switch (item.builtin) {
35421
35771
  case "thread-history":
35422
35772
  return /* @__PURE__ */ jsx133(ThreadHistoryMenuContent, {});
@@ -35629,12 +35979,12 @@ var LatticeChatView = (props) => {
35629
35979
  };
35630
35980
 
35631
35981
  // src/components/Chat/SettingsModal.tsx
35632
- import { useState as useState87, useEffect as useEffect59, useRef as useRef32 } from "react";
35982
+ import { useState as useState87, useEffect as useEffect60, useRef as useRef32 } from "react";
35633
35983
  import {
35634
- Modal as Modal27,
35635
- Input as Input21,
35984
+ Modal as Modal28,
35985
+ Input as Input22,
35636
35986
  Button as Button64,
35637
- message as message26,
35987
+ message as message28,
35638
35988
  notification as notification5,
35639
35989
  Typography as Typography63,
35640
35990
  Alert as Alert9,
@@ -35658,7 +36008,7 @@ import {
35658
36008
  import { createStyles as createStyles42 } from "antd-style";
35659
36009
  import { Fragment as Fragment31, jsx as jsx135, jsxs as jsxs98 } from "react/jsx-runtime";
35660
36010
  var { Text: Text52, Title: Title18 } = Typography63;
35661
- var { TextArea: TextArea9 } = Input21;
36011
+ var { TextArea: TextArea9 } = Input22;
35662
36012
  var useStyles25 = createStyles42(({ token, css }) => ({
35663
36013
  // settingsModal: css`
35664
36014
  // .ant-modal {
@@ -36043,7 +36393,7 @@ var SettingsModal = ({
36043
36393
  });
36044
36394
  const [serverConfigs, setServerConfigs] = useState87({});
36045
36395
  const connectionsRef = useRef32(connections);
36046
- useEffect59(() => {
36396
+ useEffect60(() => {
36047
36397
  connectionsRef.current = connections;
36048
36398
  }, [connections]);
36049
36399
  const [activeTabKey, setActiveTabKey] = useState87(
@@ -36194,7 +36544,7 @@ var SettingsModal = ({
36194
36544
  }
36195
36545
  } catch (error) {
36196
36546
  console.error("Failed to load configuration:", error);
36197
- message26.error("Failed to load current configuration");
36547
+ message28.error("Failed to load current configuration");
36198
36548
  }
36199
36549
  };
36200
36550
  const loadModelsConfig = async (serverId) => {
@@ -36245,7 +36595,7 @@ var SettingsModal = ({
36245
36595
  console.error("Failed to load models configuration:", error);
36246
36596
  }
36247
36597
  };
36248
- useEffect59(() => {
36598
+ useEffect60(() => {
36249
36599
  if (open && activeTabKey) {
36250
36600
  initializeServerConfig(activeTabKey);
36251
36601
  const connection = connections.find((c) => c.id === activeTabKey);
@@ -36254,7 +36604,7 @@ var SettingsModal = ({
36254
36604
  }
36255
36605
  }
36256
36606
  }, [open, activeTabKey]);
36257
- useEffect59(() => {
36607
+ useEffect60(() => {
36258
36608
  if (open && activeTabKey) {
36259
36609
  const connection = connections.find((c) => c.id === activeTabKey);
36260
36610
  if (connection?.connected) {
@@ -36268,7 +36618,7 @@ var SettingsModal = ({
36268
36618
  }, [open, activeTabKey, activeMenu]);
36269
36619
  const handleAddServer = async () => {
36270
36620
  if (!newServerUrl.trim()) {
36271
- message26.error("Please enter a server URL");
36621
+ message28.error("Please enter a server URL");
36272
36622
  return;
36273
36623
  }
36274
36624
  let normalizedUrl = newServerUrl.trim();
@@ -36331,12 +36681,12 @@ var SettingsModal = ({
36331
36681
  const handleSave = async () => {
36332
36682
  const connection = connections.find((c) => c.id === activeTabKey);
36333
36683
  if (!connection || !connection.connected) {
36334
- message26.error("Please connect to a server first");
36684
+ message28.error("Please connect to a server first");
36335
36685
  return;
36336
36686
  }
36337
36687
  const url = connection.url;
36338
36688
  if (!url) {
36339
- message26.error("Please connect to a server first");
36689
+ message28.error("Please connect to a server first");
36340
36690
  return;
36341
36691
  }
36342
36692
  try {
@@ -36400,7 +36750,7 @@ var SettingsModal = ({
36400
36750
  const data = await response.json();
36401
36751
  if (response.ok && data.success) {
36402
36752
  if (data.requiresRestart && data.requiresRestart.length > 0) {
36403
- message26.warning(
36753
+ message28.warning(
36404
36754
  `Configuration saved. Please restart the server for ${data.requiresRestart.join(
36405
36755
  ", "
36406
36756
  )} to take effect.`,
@@ -36414,12 +36764,12 @@ var SettingsModal = ({
36414
36764
  }
36415
36765
  if (data.warnings && data.warnings.length > 0) {
36416
36766
  data.warnings.forEach((warning) => {
36417
- message26.warning(warning, 5);
36767
+ message28.warning(warning, 5);
36418
36768
  });
36419
36769
  }
36420
36770
  onClose();
36421
36771
  } else {
36422
- message26.error(data.error || "Failed to save configuration");
36772
+ message28.error(data.error || "Failed to save configuration");
36423
36773
  }
36424
36774
  } else if (activeMenu === "models") {
36425
36775
  const validModels = config.models.filter(
@@ -36444,12 +36794,12 @@ var SettingsModal = ({
36444
36794
  });
36445
36795
  onClose();
36446
36796
  } else {
36447
- message26.error(data.error || "Failed to save model configuration");
36797
+ message28.error(data.error || "Failed to save model configuration");
36448
36798
  }
36449
36799
  }
36450
36800
  } catch (error) {
36451
36801
  console.error("Failed to save configuration:", error);
36452
- message26.error(error.message || "Failed to save configuration");
36802
+ message28.error(error.message || "Failed to save configuration");
36453
36803
  } finally {
36454
36804
  setLoading(false);
36455
36805
  }
@@ -36624,7 +36974,7 @@ QUEUE_NAME=tasks`,
36624
36974
  /* @__PURE__ */ jsxs98("div", { children: [
36625
36975
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Key *" }),
36626
36976
  /* @__PURE__ */ jsx135(
36627
- Input21,
36977
+ Input22,
36628
36978
  {
36629
36979
  placeholder: "e.g., default, gpt-4, claude",
36630
36980
  value: model.key,
@@ -36655,7 +37005,7 @@ QUEUE_NAME=tasks`,
36655
37005
  /* @__PURE__ */ jsxs98("div", { children: [
36656
37006
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Model Name *" }),
36657
37007
  /* @__PURE__ */ jsx135(
36658
- Input21,
37008
+ Input22,
36659
37009
  {
36660
37010
  placeholder: "e.g., gpt-4, claude-3-opus, kimi-k2-250905",
36661
37011
  value: model.model,
@@ -36667,7 +37017,7 @@ QUEUE_NAME=tasks`,
36667
37017
  /* @__PURE__ */ jsxs98("div", { children: [
36668
37018
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "API Key" }),
36669
37019
  /* @__PURE__ */ jsx135(
36670
- Input21.Password,
37020
+ Input22.Password,
36671
37021
  {
36672
37022
  placeholder: "Enter your API key",
36673
37023
  value: model.apiKey,
@@ -36680,7 +37030,7 @@ QUEUE_NAME=tasks`,
36680
37030
  /* @__PURE__ */ jsxs98("div", { children: [
36681
37031
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Base URL" }),
36682
37032
  /* @__PURE__ */ jsx135(
36683
- Input21,
37033
+ Input22,
36684
37034
  {
36685
37035
  placeholder: "e.g., https://api.openai.com/v1",
36686
37036
  value: model.baseURL,
@@ -36704,7 +37054,7 @@ QUEUE_NAME=tasks`,
36704
37054
  /* @__PURE__ */ jsxs98("div", { style: { flex: 1 }, children: [
36705
37055
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Max Tokens" }),
36706
37056
  /* @__PURE__ */ jsx135(
36707
- Input21,
37057
+ Input22,
36708
37058
  {
36709
37059
  type: "number",
36710
37060
  placeholder: "e.g., 4096",
@@ -36721,7 +37071,7 @@ QUEUE_NAME=tasks`,
36721
37071
  /* @__PURE__ */ jsxs98("div", { style: { flex: 1 }, children: [
36722
37072
  /* @__PURE__ */ jsx135(Text52, { className: styles.formLabel, children: "Temperature" }),
36723
37073
  /* @__PURE__ */ jsx135(
36724
- Input21,
37074
+ Input22,
36725
37075
  {
36726
37076
  type: "number",
36727
37077
  step: "0.1",
@@ -36881,7 +37231,7 @@ QUEUE_NAME=tasks`,
36881
37231
  }));
36882
37232
  return /* @__PURE__ */ jsxs98(Fragment31, { children: [
36883
37233
  /* @__PURE__ */ jsx135(
36884
- Modal27,
37234
+ Modal28,
36885
37235
  {
36886
37236
  open,
36887
37237
  onCancel: onClose,
@@ -36923,7 +37273,7 @@ QUEUE_NAME=tasks`,
36923
37273
  }
36924
37274
  ),
36925
37275
  /* @__PURE__ */ jsx135(
36926
- Modal27,
37276
+ Modal28,
36927
37277
  {
36928
37278
  title: "Add New Server",
36929
37279
  open: showAddServerModal,
@@ -36940,7 +37290,7 @@ QUEUE_NAME=tasks`,
36940
37290
  /* @__PURE__ */ jsxs98("div", { children: [
36941
37291
  /* @__PURE__ */ jsx135(Text52, { strong: true, style: { display: "block", marginBottom: 8 }, children: "Server Name" }),
36942
37292
  /* @__PURE__ */ jsx135(
36943
- Input21,
37293
+ Input22,
36944
37294
  {
36945
37295
  placeholder: "e.g., Production Server",
36946
37296
  value: newServerName,
@@ -36953,7 +37303,7 @@ QUEUE_NAME=tasks`,
36953
37303
  /* @__PURE__ */ jsxs98("div", { children: [
36954
37304
  /* @__PURE__ */ jsx135(Text52, { strong: true, style: { display: "block", marginBottom: 8 }, children: "Server URL *" }),
36955
37305
  /* @__PURE__ */ jsx135(
36956
- Input21,
37306
+ Input22,
36957
37307
  {
36958
37308
  placeholder: "e.g., http://localhost:4001",
36959
37309
  value: newServerUrl,
@@ -36966,7 +37316,7 @@ QUEUE_NAME=tasks`,
36966
37316
  /* @__PURE__ */ jsxs98("div", { children: [
36967
37317
  /* @__PURE__ */ jsx135(Text52, { strong: true, style: { display: "block", marginBottom: 8 }, children: "API Key" }),
36968
37318
  /* @__PURE__ */ jsx135(
36969
- Input21.Password,
37319
+ Input22.Password,
36970
37320
  {
36971
37321
  placeholder: "Optional: Enter API key for authentication",
36972
37322
  value: newServerApiKey,
@@ -37034,20 +37384,20 @@ var LatticeChatShell = (props) => {
37034
37384
  };
37035
37385
 
37036
37386
  // src/components/Chat/ChannelInstallationsDrawerContent.tsx
37037
- import { useEffect as useEffect60, useState as useState88 } from "react";
37387
+ import { useEffect as useEffect61, useState as useState88 } from "react";
37038
37388
  import {
37039
37389
  Button as Button65,
37040
37390
  Card as Card30,
37041
37391
  Form as Form10,
37042
- Input as Input22,
37043
- Modal as Modal28,
37392
+ Input as Input23,
37393
+ Modal as Modal29,
37044
37394
  Popconfirm as Popconfirm14,
37045
37395
  Spin as Spin24,
37046
37396
  Tag as Tag32,
37047
37397
  Typography as Typography64,
37048
- message as message27
37398
+ message as message29
37049
37399
  } from "antd";
37050
- import { Edit2 as Edit24, Plus as Plus10, RadioTower, Trash2 as Trash211 } from "lucide-react";
37400
+ import { Edit2 as Edit24, Plus as Plus9, RadioTower, Trash2 as Trash211 } from "lucide-react";
37051
37401
  import { jsx as jsx138, jsxs as jsxs100 } from "react/jsx-runtime";
37052
37402
  var { Text: Text53, Title: Title19 } = Typography64;
37053
37403
  var ChannelInstallationsDrawerContent = () => {
@@ -37066,17 +37416,17 @@ var ChannelInstallationsDrawerContent = () => {
37066
37416
  setInstallations(result.data?.records ?? []);
37067
37417
  } else {
37068
37418
  setInstallations([]);
37069
- message27.error(result.message || "Failed to load channel installations");
37419
+ message29.error(result.message || "Failed to load channel installations");
37070
37420
  }
37071
37421
  } catch (error) {
37072
37422
  console.error("Failed to load channel installations:", error);
37073
37423
  setInstallations([]);
37074
- message27.error("Failed to load channel installations");
37424
+ message29.error("Failed to load channel installations");
37075
37425
  } finally {
37076
37426
  setLoading(false);
37077
37427
  }
37078
37428
  };
37079
- useEffect60(() => {
37429
+ useEffect61(() => {
37080
37430
  loadInstallations();
37081
37431
  }, []);
37082
37432
  const handleDelete = async (installation) => {
@@ -37088,13 +37438,13 @@ var ChannelInstallationsDrawerContent = () => {
37088
37438
  setInstallations(
37089
37439
  (current) => current.filter((item) => item.id !== installation.id)
37090
37440
  );
37091
- message27.success("Installation deleted");
37441
+ message29.success("Installation deleted");
37092
37442
  } else {
37093
- message27.error(result.message || "Failed to delete installation");
37443
+ message29.error(result.message || "Failed to delete installation");
37094
37444
  }
37095
37445
  } catch (error) {
37096
37446
  console.error("Failed to delete channel installation:", error);
37097
- message27.error("Failed to delete installation");
37447
+ message29.error("Failed to delete installation");
37098
37448
  }
37099
37449
  };
37100
37450
  return /* @__PURE__ */ jsxs100("div", { style: { height: "100%", display: "flex", flexDirection: "column" }, children: [
@@ -37112,7 +37462,7 @@ var ChannelInstallationsDrawerContent = () => {
37112
37462
  Button65,
37113
37463
  {
37114
37464
  type: "primary",
37115
- icon: /* @__PURE__ */ jsx138(Plus10, { size: 16 }),
37465
+ icon: /* @__PURE__ */ jsx138(Plus9, { size: 16 }),
37116
37466
  onClick: () => {
37117
37467
  setEditingInstallation(null);
37118
37468
  setFormModalOpen(true);
@@ -37224,7 +37574,7 @@ var ChannelInstallationsDrawerContent = () => {
37224
37574
  };
37225
37575
  var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCancel, onSave }) => {
37226
37576
  const [form] = Form10.useForm();
37227
- useEffect60(() => {
37577
+ useEffect61(() => {
37228
37578
  if (installation) {
37229
37579
  const config = installation.config;
37230
37580
  form.setFieldsValue({
@@ -37257,10 +37607,10 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37257
37607
  payload2
37258
37608
  );
37259
37609
  if (result2.success) {
37260
- message27.success("Installation updated");
37610
+ message29.success("Installation updated");
37261
37611
  onSave();
37262
37612
  } else {
37263
- message27.error(result2.message || "Failed to update installation");
37613
+ message29.error(result2.message || "Failed to update installation");
37264
37614
  }
37265
37615
  return;
37266
37616
  }
@@ -37274,20 +37624,20 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37274
37624
  payload
37275
37625
  );
37276
37626
  if (result.success) {
37277
- message27.success("Installation created");
37627
+ message29.success("Installation created");
37278
37628
  onSave();
37279
37629
  } else {
37280
- message27.error(result.message || "Failed to create installation");
37630
+ message29.error(result.message || "Failed to create installation");
37281
37631
  }
37282
37632
  } catch (error) {
37283
37633
  console.error("Failed to save channel installation:", error);
37284
- message27.error(
37634
+ message29.error(
37285
37635
  installation ? "Failed to update installation" : "Failed to create installation"
37286
37636
  );
37287
37637
  }
37288
37638
  };
37289
37639
  return /* @__PURE__ */ jsx138(
37290
- Modal28,
37640
+ Modal29,
37291
37641
  {
37292
37642
  open,
37293
37643
  title: installation ? "Edit Installation" : "Add Installation",
@@ -37296,15 +37646,15 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37296
37646
  okText: installation ? "Save" : "Create",
37297
37647
  destroyOnHidden: true,
37298
37648
  children: /* @__PURE__ */ jsxs100(Form10, { form, layout: "vertical", children: [
37299
- /* @__PURE__ */ jsx138(Form10.Item, { label: "Channel", children: /* @__PURE__ */ jsx138(Input22, { value: "lark", disabled: true }) }),
37300
- /* @__PURE__ */ jsx138(Form10.Item, { name: "name", label: "Name", children: /* @__PURE__ */ jsx138(Input22, {}) }),
37649
+ /* @__PURE__ */ jsx138(Form10.Item, { label: "Channel", children: /* @__PURE__ */ jsx138(Input23, { value: "lark", disabled: true }) }),
37650
+ /* @__PURE__ */ jsx138(Form10.Item, { name: "name", label: "Name", children: /* @__PURE__ */ jsx138(Input23, {}) }),
37301
37651
  /* @__PURE__ */ jsx138(
37302
37652
  Form10.Item,
37303
37653
  {
37304
37654
  name: "appId",
37305
37655
  label: "App ID",
37306
37656
  rules: [{ required: true, message: "App ID is required" }],
37307
- children: /* @__PURE__ */ jsx138(Input22, {})
37657
+ children: /* @__PURE__ */ jsx138(Input23, {})
37308
37658
  }
37309
37659
  ),
37310
37660
  /* @__PURE__ */ jsx138(
@@ -37313,11 +37663,11 @@ var LarkChannelInstallationFormModal = ({ installation, open, post, put, onCance
37313
37663
  name: "appSecret",
37314
37664
  label: "App Secret",
37315
37665
  rules: [{ required: true, message: "App Secret is required" }],
37316
- children: /* @__PURE__ */ jsx138(Input22, {})
37666
+ children: /* @__PURE__ */ jsx138(Input23, {})
37317
37667
  }
37318
37668
  ),
37319
- /* @__PURE__ */ jsx138(Form10.Item, { name: "verificationToken", label: "Verification Token", children: /* @__PURE__ */ jsx138(Input22, {}) }),
37320
- /* @__PURE__ */ jsx138(Form10.Item, { name: "encryptKey", label: "Encrypt Key", children: /* @__PURE__ */ jsx138(Input22, {}) })
37669
+ /* @__PURE__ */ jsx138(Form10.Item, { name: "verificationToken", label: "Verification Token", children: /* @__PURE__ */ jsx138(Input23, {}) }),
37670
+ /* @__PURE__ */ jsx138(Form10.Item, { name: "encryptKey", label: "Encrypt Key", children: /* @__PURE__ */ jsx138(Input23, {}) })
37321
37671
  ] })
37322
37672
  }
37323
37673
  );