@axiom-lattice/react-sdk 2.1.108 → 2.1.110

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.js CHANGED
@@ -1557,6 +1557,23 @@ var DEFAULT_MIDDLEWARE_TYPES = [
1557
1557
  { id: "update_entry", name: "update_entry", description: "Update an existing entry" },
1558
1558
  { id: "delete_entry", name: "delete_entry", description: "Delete an entry from a collection" }
1559
1559
  ]
1560
+ },
1561
+ {
1562
+ type: "eval",
1563
+ name: "Agent Eval",
1564
+ description: "Governance and testing: design test suites, run evaluations, analyze results. Best paired with the Skill plugin.",
1565
+ schema: {
1566
+ type: "object",
1567
+ title: "Agent Eval Configuration",
1568
+ description: "Enable agent evaluation capabilities",
1569
+ properties: {}
1570
+ },
1571
+ defaultConfig: {},
1572
+ tools: [
1573
+ { id: "read_eval", name: "read_eval", description: "Read-only: list/get projects, suites, cases, runs, results, reports" },
1574
+ { id: "manage_eval", name: "manage_eval", description: "Create, update, delete eval projects, suites, and test cases" },
1575
+ { id: "run_eval", name: "run_eval", description: "Start, abort, status, and resume evaluation runs" }
1576
+ ]
1560
1577
  }
1561
1578
  ];
1562
1579
  var DEFAULT_CONFIG = {
@@ -2080,6 +2097,8 @@ function AgentThreadProvider({
2080
2097
  const chunkMessageMerger = (0, import_react7.useRef)((0, import_client_sdk3.createSimpleMessageMerger)());
2081
2098
  const lastAgentStateCreatedAtRef = (0, import_react7.useRef)(null);
2082
2099
  const streamEndedByInterruptRef = (0, import_react7.useRef)(false);
2100
+ const currentThreadIdRef = (0, import_react7.useRef)(threadId);
2101
+ currentThreadIdRef.current = threadId;
2083
2102
  const messageCountRef = (0, import_react7.useRef)(0);
2084
2103
  const onToolCompletedRef = (0, import_react7.useRef)(onToolCompleted);
2085
2104
  onToolCompletedRef.current = onToolCompleted;
@@ -2192,29 +2211,32 @@ function AgentThreadProvider({
2192
2211
  console.error("Failed to parse todo list from chunk", e);
2193
2212
  }
2194
2213
  }
2195
- const updatedMessages = chunkMessageMerger.current.getMessages();
2196
2214
  const isStopSignal = interrupt !== void 0 || anyChunk.type === "message_failed";
2197
2215
  if (isStopSignal) {
2198
- setState((prev) => ({
2199
- ...prev,
2200
- todos: todos || prev.todos,
2201
- messages: updatedMessages,
2202
- isLoading: false,
2203
- interrupts: interrupt ? [interrupt] : void 0
2204
- }));
2216
+ setState((prev) => {
2217
+ if (currentThreadIdRef.current !== threadId) return prev;
2218
+ return {
2219
+ ...prev,
2220
+ todos: todos || prev.todos,
2221
+ messages: chunkMessageMerger.current.getMessages(),
2222
+ isLoading: false,
2223
+ interrupts: interrupt ? [interrupt] : void 0
2224
+ };
2225
+ });
2205
2226
  } else {
2206
2227
  startTransition(() => {
2228
+ if (currentThreadIdRef.current !== threadId) return;
2207
2229
  setState((prev) => ({
2208
2230
  ...prev,
2209
2231
  todos: todos || prev.todos,
2210
- messages: updatedMessages,
2232
+ messages: chunkMessageMerger.current.getMessages(),
2211
2233
  isLoading: true,
2212
2234
  interrupts: void 0
2213
2235
  }));
2214
2236
  });
2215
2237
  }
2216
2238
  },
2217
- [startTransition]
2239
+ [startTransition, threadId]
2218
2240
  );
2219
2241
  const sendMessage = (0, import_react7.useCallback)(
2220
2242
  async (data) => {
@@ -2589,6 +2611,20 @@ function AgentThreadProvider({
2589
2611
  }
2590
2612
  }
2591
2613
  }, [stopStreaming, assistantId, threadId, client]);
2614
+ (0, import_react7.useLayoutEffect)(() => {
2615
+ if (threadId && state.threadId !== threadId) {
2616
+ chunkMessageMerger.current.reset();
2617
+ setState((prev) => ({
2618
+ ...prev,
2619
+ threadId,
2620
+ messages: [],
2621
+ agentState: null,
2622
+ interrupts: void 0,
2623
+ isLoading: true,
2624
+ error: null
2625
+ }));
2626
+ }
2627
+ }, [threadId, state.threadId]);
2592
2628
  (0, import_react7.useEffect)(() => {
2593
2629
  if (threadId && clientAssistantId === assistantId) {
2594
2630
  lastAgentStateCreatedAtRef.current = null;
@@ -6794,6 +6830,55 @@ var useStyles5 = (0, import_antd_style8.createStyles)(({ css, token }) => ({
6794
6830
  flex-direction: column;
6795
6831
  gap: 4px;
6796
6832
  `,
6833
+ titleRow: css`
6834
+ display: flex;
6835
+ align-items: center;
6836
+ gap: 8px;
6837
+ `,
6838
+ tabs: css`
6839
+ margin-top: 12px;
6840
+
6841
+ .ant-tabs-nav {
6842
+ margin-bottom: 0;
6843
+
6844
+ &::before {
6845
+ border-bottom: none;
6846
+ }
6847
+ }
6848
+
6849
+ .ant-tabs-tab {
6850
+ padding: 4px 10px;
6851
+ margin: 0 2px 0 0;
6852
+ border-radius: 9999px;
6853
+ transition: background-color 0.15s ease;
6854
+ font-size: 13px;
6855
+
6856
+ &:hover {
6857
+ background-color: ${token.colorFillTertiary};
6858
+ }
6859
+
6860
+ .ant-tabs-tab-btn {
6861
+ font-size: 13px;
6862
+ }
6863
+ }
6864
+
6865
+ .ant-tabs-tab + .ant-tabs-tab {
6866
+ margin-left: 2px;
6867
+ }
6868
+
6869
+ .ant-tabs-tab-active {
6870
+ background-color: ${token.colorFillSecondary};
6871
+
6872
+ .ant-tabs-tab-btn {
6873
+ color: ${token.colorText};
6874
+ font-weight: 500;
6875
+ }
6876
+ }
6877
+
6878
+ .ant-tabs-ink-bar {
6879
+ display: none;
6880
+ }
6881
+ `,
6797
6882
  title: css`
6798
6883
  margin: 0;
6799
6884
  font-size: 24px;
@@ -6846,6 +6931,8 @@ var useStyles5 = (0, import_antd_style8.createStyles)(({ css, token }) => ({
6846
6931
  var EntityListShell = ({
6847
6932
  title,
6848
6933
  subtitle,
6934
+ titleBefore,
6935
+ titleAfter,
6849
6936
  headerLeft,
6850
6937
  headerRight,
6851
6938
  loading,
@@ -6858,7 +6945,10 @@ var EntityListShell = ({
6858
6945
  children,
6859
6946
  itemCount,
6860
6947
  itemName,
6861
- className
6948
+ className,
6949
+ tabs,
6950
+ activeTab,
6951
+ onTabChange
6862
6952
  }) => {
6863
6953
  const { styles } = useStyles5();
6864
6954
  const { token } = import_antd12.theme.useToken();
@@ -6866,8 +6956,21 @@ var EntityListShell = ({
6866
6956
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `${styles.container} ${className || ""}`, children: [
6867
6957
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: styles.header, children: [
6868
6958
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: styles.headerLeft, children: [
6869
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { className: styles.title, children: title }),
6870
- resolvedSubtitle && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: styles.subtitle, children: resolvedSubtitle })
6959
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: styles.titleRow, children: [
6960
+ titleBefore,
6961
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { className: styles.title, children: title }),
6962
+ titleAfter
6963
+ ] }),
6964
+ resolvedSubtitle && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: styles.subtitle, children: resolvedSubtitle }),
6965
+ tabs && tabs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: styles.tabs, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6966
+ import_antd11.Tabs,
6967
+ {
6968
+ type: "line",
6969
+ activeKey: activeTab,
6970
+ onChange: (key) => onTabChange?.(key),
6971
+ items: tabs.map((t) => ({ key: t.key, label: t.label }))
6972
+ }
6973
+ ) })
6871
6974
  ] }),
6872
6975
  (headerLeft || headerRight) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: styles.headerRight, children: [
6873
6976
  headerLeft,
@@ -6986,6 +7089,8 @@ var EntityListView = ({
6986
7089
  keyExtractor,
6987
7090
  title,
6988
7091
  itemName,
7092
+ titleBefore,
7093
+ titleAfter,
6989
7094
  renderIcon,
6990
7095
  renderPrimary,
6991
7096
  renderSecondary,
@@ -7008,7 +7113,10 @@ var EntityListView = ({
7008
7113
  renderEmpty,
7009
7114
  renderGridItem,
7010
7115
  renderListItem,
7011
- className
7116
+ className,
7117
+ tabs,
7118
+ activeTab,
7119
+ onTabChange
7012
7120
  }) => {
7013
7121
  const [viewMode, setViewMode] = (0, import_react29.useState)(defaultViewMode);
7014
7122
  const { styles } = useStyles7();
@@ -7033,8 +7141,13 @@ var EntityListView = ({
7033
7141
  emptyTitle,
7034
7142
  emptyDescription,
7035
7143
  renderEmpty,
7144
+ titleBefore,
7145
+ titleAfter,
7036
7146
  headerLeft,
7037
7147
  headerRight: headerRightContent,
7148
+ tabs,
7149
+ activeTab,
7150
+ onTabChange,
7038
7151
  children: null
7039
7152
  }
7040
7153
  );
@@ -7047,9 +7160,14 @@ var EntityListView = ({
7047
7160
  itemName,
7048
7161
  loading,
7049
7162
  isEmpty: false,
7163
+ titleBefore,
7164
+ titleAfter,
7050
7165
  headerLeft,
7051
7166
  headerRight: headerRightContent,
7052
7167
  className,
7168
+ tabs,
7169
+ activeTab,
7170
+ onTabChange,
7053
7171
  children: viewMode === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: styles.grid, children: [
7054
7172
  hasCreate && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EntityCreateTrigger, { viewMode: "grid", label: createLabel, onClick: onCreateClick }),
7055
7173
  items.map((item) => {
@@ -8488,7 +8606,7 @@ var ConnectionConfigDrawerContent = ({
8488
8606
  itemName: "connection",
8489
8607
  items: configs,
8490
8608
  loading,
8491
- headerLeft: onBack ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_antd15.Button, { type: "text", icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { fontSize: 16 }, children: "\u2190" }), onClick: onBack, style: { marginRight: 8 }, children: "Back" }) : void 0,
8609
+ titleBefore: onBack ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_antd15.Button, { type: "text", icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { fontSize: 16 }, children: "\u2190" }), onClick: onBack }) : void 0,
8492
8610
  keyExtractor: (c) => c.id,
8493
8611
  onItemClick: handleEdit,
8494
8612
  renderIcon: () => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { color: "#6366f1" }, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Plug2, { size: 20 }) }),
@@ -8830,12 +8948,25 @@ var ConnectionFormModal = ({
8830
8948
  // src/components/Chat/ConnectionsHub.tsx
8831
8949
  var import_jsx_runtime28 = require("react/jsx-runtime");
8832
8950
  var { Text: Text7 } = import_antd16.Typography;
8951
+ function categorize(types) {
8952
+ const connections = [];
8953
+ const tools = [];
8954
+ for (const t of types) {
8955
+ if (t.connectionSchema) {
8956
+ connections.push(t);
8957
+ } else {
8958
+ tools.push(t);
8959
+ }
8960
+ }
8961
+ return { connections, tools };
8962
+ }
8833
8963
  var ConnectionsHub = () => {
8834
8964
  const api = useApi();
8835
8965
  const { config } = useLatticeChatShellContext();
8836
- const [types, setTypes] = (0, import_react34.useState)([]);
8966
+ const [allTypes, setAllTypes] = (0, import_react34.useState)([]);
8837
8967
  const [loading, setLoading] = (0, import_react34.useState)(true);
8838
8968
  const [selectedType, setSelectedType] = (0, import_react34.useState)(null);
8969
+ const [activeTab, setActiveTab] = (0, import_react34.useState)("connections");
8839
8970
  const fetchedRef = (0, import_react34.useRef)(false);
8840
8971
  (0, import_react34.useEffect)(() => {
8841
8972
  if (fetchedRef.current) return;
@@ -8843,39 +8974,79 @@ var ConnectionsHub = () => {
8843
8974
  const endpoint = config.middlewareTypesEndpoint || "/api/middleware-types";
8844
8975
  api.get(endpoint).then((data) => {
8845
8976
  if (Array.isArray(data)) {
8846
- setTypes(data.filter((t) => t.connectionSchema));
8977
+ setAllTypes(data);
8847
8978
  }
8848
- }).catch(() => setTypes([])).finally(() => setLoading(false));
8979
+ }).catch(() => setAllTypes([])).finally(() => setLoading(false));
8849
8980
  }, []);
8981
+ const { connections, tools } = (0, import_react34.useMemo)(() => categorize(allTypes), [allTypes]);
8982
+ const visibleItems = (0, import_react34.useMemo)(() => {
8983
+ switch (activeTab) {
8984
+ case "all":
8985
+ return allTypes;
8986
+ case "connections":
8987
+ return connections;
8988
+ case "tools":
8989
+ return tools;
8990
+ }
8991
+ }, [activeTab, allTypes, connections, tools]);
8992
+ const handleItemClick = (t) => {
8993
+ if (t.connectionSchema) {
8994
+ setSelectedType(t.type);
8995
+ }
8996
+ };
8997
+ const emptyState = (0, import_react34.useMemo)(() => {
8998
+ switch (activeTab) {
8999
+ case "connections":
9000
+ return { title: "No connection plugins", description: "No plugins with connection management registered" };
9001
+ case "tools":
9002
+ return { title: "No tool plugins", description: "No tool-only plugins registered" };
9003
+ default:
9004
+ return { title: "No plugins", description: "No plugins registered" };
9005
+ }
9006
+ }, [activeTab]);
8850
9007
  if (selectedType) {
8851
9008
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
8852
9009
  ConnectionConfigDrawerContent,
8853
9010
  {
8854
9011
  connectionType: selectedType,
8855
- title: types.find((t) => t.type === selectedType)?.name,
9012
+ title: allTypes.find((t) => t.type === selectedType)?.name,
8856
9013
  onBack: () => setSelectedType(null)
8857
9014
  }
8858
9015
  );
8859
9016
  }
9017
+ const renderFooter = (t) => {
9018
+ if (t.connectionSchema) {
9019
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontSize: 11, color: "#999" }, children: [
9020
+ t.connectionSchema.hasTest && "test",
9021
+ t.connectionSchema.hasDiscover && "discover"
9022
+ ].filter(Boolean).join(" \xB7 ") || "connection" });
9023
+ }
9024
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_antd16.Tag, { style: { fontSize: 10, lineHeight: "16px", padding: "0 6px" }, children: "tool" });
9025
+ };
9026
+ const tabs = [
9027
+ { key: "all", label: `All (${allTypes.length})` },
9028
+ { key: "connections", label: `Connections (${connections.length})` },
9029
+ { key: "tools", label: `Tools (${tools.length})` }
9030
+ ];
8860
9031
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
8861
9032
  EntityListView,
8862
9033
  {
8863
9034
  title: "Plugins",
8864
9035
  itemName: "plugin",
8865
- items: types,
9036
+ items: visibleItems,
8866
9037
  loading,
8867
9038
  keyExtractor: (t) => t.type,
8868
- renderIcon: (t) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontSize: 20, fontWeight: 600, color: "#6366f1" }, children: t.name.charAt(0).toUpperCase() }),
9039
+ tabs,
9040
+ activeTab,
9041
+ onTabChange: (key) => setActiveTab(key),
9042
+ renderIcon: (t) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontSize: 20, fontWeight: 600, color: t.connectionSchema ? "#6366f1" : "#8c8c8c" }, children: t.name.charAt(0).toUpperCase() }),
8869
9043
  renderPrimary: (t) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Text7, { strong: true, style: { fontSize: 14 }, children: t.name }),
8870
9044
  renderSecondary: (t) => t.description || void 0,
8871
- renderFooter: (t) => t.connectionSchema ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontSize: 11, color: "#999" }, children: [
8872
- t.connectionSchema.hasTest && "test",
8873
- t.connectionSchema.hasDiscover && "discover"
8874
- ].filter(Boolean).join(" \xB7 ") || "connection" }) : void 0,
8875
- onItemClick: (t) => setSelectedType(t.type),
9045
+ renderFooter,
9046
+ onItemClick: handleItemClick,
8876
9047
  emptyIcon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontSize: 48, opacity: 0.3 }, children: "\u{1F50C}" }),
8877
- emptyTitle: "No connection types configured",
8878
- emptyDescription: "Register a plugin with connection capabilities to see it here",
9048
+ emptyTitle: emptyState.title,
9049
+ emptyDescription: emptyState.description,
8879
9050
  showViewToggle: false
8880
9051
  }
8881
9052
  );
@@ -13684,6 +13855,16 @@ var useStyles10 = (0, import_antd_style13.createStyles)(({ token, css }) => ({
13684
13855
  body: css`
13685
13856
  flex: 1;
13686
13857
  overflow: auto;
13858
+ & .ant-table-row .entry-row-actions {
13859
+ opacity: 0;
13860
+ transition: opacity 0.15s;
13861
+ @media (hover: none) {
13862
+ opacity: 1;
13863
+ }
13864
+ }
13865
+ & .ant-table-row:hover .entry-row-actions {
13866
+ opacity: 1;
13867
+ }
13687
13868
  `,
13688
13869
  countTag: css`
13689
13870
  font-size: 12px;
@@ -13699,6 +13880,37 @@ var useStyles10 = (0, import_antd_style13.createStyles)(({ token, css }) => ({
13699
13880
  justify-content: center;
13700
13881
  padding: 48px 0;
13701
13882
  gap: 8px;
13883
+ `,
13884
+ contentClamp: css`
13885
+ display: -webkit-box;
13886
+ -webkit-box-orient: vertical;
13887
+ overflow: hidden;
13888
+ line-height: 1.55;
13889
+ font-size: 13px;
13890
+ word-break: break-word;
13891
+ `,
13892
+ expandToggle: css`
13893
+ display: inline-flex;
13894
+ align-items: center;
13895
+ gap: 2px;
13896
+ font-size: 12px;
13897
+ color: ${token.colorPrimary};
13898
+ cursor: pointer;
13899
+ user-select: none;
13900
+ margin-top: 2px;
13901
+ line-height: 1;
13902
+ padding: 1px 4px;
13903
+ border-radius: 4px;
13904
+ transition: background 0.15s;
13905
+ &:hover {
13906
+ background: ${token.colorPrimaryBg};
13907
+ }
13908
+ `,
13909
+ expandedRow: css`
13910
+ & td {
13911
+ background: ${token.colorPrimaryBg} !important;
13912
+ transition: background 0.25s;
13913
+ }
13702
13914
  `
13703
13915
  }));
13704
13916
  var CollectionEntryTable = ({
@@ -13716,7 +13928,17 @@ var CollectionEntryTable = ({
13716
13928
  const [confirmLoading, setConfirmLoading] = (0, import_react47.useState)(false);
13717
13929
  const [searchQuery, setSearchQuery] = (0, import_react47.useState)("");
13718
13930
  const [searchResults, setSearchResults] = (0, import_react47.useState)(null);
13931
+ const [loadError, setLoadError] = (0, import_react47.useState)(false);
13932
+ const [expandedIds, setExpandedIds] = (0, import_react47.useState)(/* @__PURE__ */ new Set());
13719
13933
  const [form] = import_antd29.Form.useForm();
13934
+ const toggleExpand = (id) => {
13935
+ setExpandedIds((prev) => {
13936
+ const next = new Set(prev);
13937
+ if (next.has(id)) next.delete(id);
13938
+ else next.add(id);
13939
+ return next;
13940
+ });
13941
+ };
13720
13942
  const fetchEntries = (0, import_react47.useCallback)(async () => {
13721
13943
  if (!collectionName) return;
13722
13944
  setIsLoading(true);
@@ -13725,7 +13947,10 @@ var CollectionEntryTable = ({
13725
13947
  setEntries(res.data?.records || []);
13726
13948
  setSearchResults(null);
13727
13949
  setSearchQuery("");
13950
+ setLoadError(false);
13728
13951
  } catch {
13952
+ setLoadError(true);
13953
+ import_antd29.message.error("Failed to load entries");
13729
13954
  } finally {
13730
13955
  setIsLoading(false);
13731
13956
  }
@@ -13741,6 +13966,7 @@ var CollectionEntryTable = ({
13741
13966
  (0, import_react47.useEffect)(() => {
13742
13967
  fetchCollection();
13743
13968
  fetchEntries();
13969
+ setExpandedIds(/* @__PURE__ */ new Set());
13744
13970
  }, [fetchCollection, fetchEntries]);
13745
13971
  const handleSearch = async (q) => {
13746
13972
  doBackendSearch(q);
@@ -13774,6 +14000,13 @@ var CollectionEntryTable = ({
13774
14000
  setSearchResults(null);
13775
14001
  fetchEntries();
13776
14002
  };
14003
+ const refreshCurrentView = () => {
14004
+ if (searchResults !== null) {
14005
+ doBackendSearch();
14006
+ } else {
14007
+ fetchEntries();
14008
+ }
14009
+ };
13777
14010
  const fields = collection?.schema?.fields || [];
13778
14011
  const hasSearch = searchResults !== null;
13779
14012
  const displayEntries = searchResults || entries;
@@ -13810,12 +14043,14 @@ var CollectionEntryTable = ({
13810
14043
  ] })
13811
14044
  ] }),
13812
14045
  filterIcon: (f) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.Search, { size: 13, style: { color: f ? "#6366f1" : "#d1d5db" } }),
13813
- filtered: columnFilters[fieldKey] !== void 0
14046
+ filtered: columnFilters[fieldKey] !== void 0,
14047
+ filteredValue: columnFilters[fieldKey] !== void 0 ? [columnFilters[fieldKey]] : null
13814
14048
  });
13815
14049
  const enumFilter = (fieldKey, values) => ({
13816
14050
  filters: values.map((v) => ({ text: v, value: v })),
13817
14051
  filterIcon: (f) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.Search, { size: 13, style: { color: f ? "#6366f1" : "#d1d5db" } }),
13818
14052
  filtered: columnFilters[fieldKey] !== void 0,
14053
+ filteredValue: columnFilters[fieldKey] !== void 0 ? [columnFilters[fieldKey]] : null,
13819
14054
  onFilter: (value, _record) => {
13820
14055
  return true;
13821
14056
  },
@@ -13857,9 +14092,43 @@ var CollectionEntryTable = ({
13857
14092
  title: "Content",
13858
14093
  dataIndex: "content",
13859
14094
  key: "content",
13860
- ellipsis: true,
14095
+ ellipsis: false,
13861
14096
  ...textFilter("content"),
13862
- render: (text) => text ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { style: { lineHeight: 1.5 }, children: text.length > 120 ? text.slice(0, 120) + "\u2026" : text }) : null
14097
+ render: (text, record) => {
14098
+ if (!text) return null;
14099
+ const MAX = 120;
14100
+ const isLong = text.length > MAX;
14101
+ const expanded = isLong && expandedIds.has(record.id);
14102
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
14103
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
14104
+ "div",
14105
+ {
14106
+ className: styles.contentClamp,
14107
+ style: {
14108
+ WebkitLineClamp: expanded ? "unset" : 2
14109
+ },
14110
+ children: text
14111
+ }
14112
+ ),
14113
+ isLong && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
14114
+ "a",
14115
+ {
14116
+ className: styles.expandToggle,
14117
+ onClick: (e) => {
14118
+ e.stopPropagation();
14119
+ toggleExpand(record.id);
14120
+ },
14121
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
14122
+ "\u6536\u8D77 ",
14123
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.ChevronUp, { size: 12 })
14124
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
14125
+ "\u5C55\u5F00 ",
14126
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.ChevronDown, { size: 12 })
14127
+ ] })
14128
+ }
14129
+ )
14130
+ ] });
14131
+ }
13863
14132
  },
13864
14133
  ...fields.map((f) => ({
13865
14134
  title: f.key,
@@ -13884,9 +14153,9 @@ var CollectionEntryTable = ({
13884
14153
  title: "",
13885
14154
  key: "actions",
13886
14155
  width: 64,
13887
- render: (_, record) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_antd29.Space, { size: 0, children: [
14156
+ render: (_, record) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_antd29.Space, { size: 0, className: "entry-row-actions", onClick: (e) => e.stopPropagation(), children: [
13888
14157
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { type: "text", size: "small", style: iconMuted, onClick: () => handleEdit(record), children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.Pencil, { size: 14 }) }),
13889
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Popconfirm, { title: "Delete?", onConfirm: () => handleDelete(record.id), okText: "Delete", okType: "danger", placement: "left", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { type: "text", size: "small", danger: true, style: { opacity: 0.4 }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.Trash2, { size: 14 }) }) })
14158
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Popconfirm, { title: "Delete?", onConfirm: () => handleDelete(record.id), okText: "Delete", okType: "danger", placement: "left", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { type: "text", size: "small", danger: true, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.Trash2, { size: 14 }) }) })
13890
14159
  ] })
13891
14160
  }
13892
14161
  ];
@@ -13904,7 +14173,7 @@ var CollectionEntryTable = ({
13904
14173
  try {
13905
14174
  await del(`/api/collections/${collectionName}/entries/${id}`);
13906
14175
  import_antd29.message.success("Deleted");
13907
- fetchEntries();
14176
+ refreshCurrentView();
13908
14177
  } catch (err) {
13909
14178
  import_antd29.message.error(err?.message || "Failed");
13910
14179
  }
@@ -13919,9 +14188,10 @@ var CollectionEntryTable = ({
13919
14188
  if (v !== void 0 && v !== "") metadata[k] = v;
13920
14189
  }
13921
14190
  editingEntry ? await put(`/api/collections/${collectionName}/entries/${editingEntry.id}`, { content, metadata }) : await post(`/api/collections/${collectionName}/entries`, { content, metadata });
14191
+ import_antd29.message.success(editingEntry ? "Entry updated" : "Entry created");
13922
14192
  setModalOpen(false);
13923
14193
  form.resetFields();
13924
- fetchEntries();
14194
+ refreshCurrentView();
13925
14195
  } catch (err) {
13926
14196
  if (err?.errorFields) return;
13927
14197
  import_antd29.message.error(err?.message || "Failed");
@@ -13935,7 +14205,7 @@ var CollectionEntryTable = ({
13935
14205
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: styles.toolbarLeft, children: [
13936
14206
  onBack && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { type: "text", size: "small", icon: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.ArrowLeft, { size: 16 }), onClick: onBack }),
13937
14207
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text17, { strong: true, style: { fontSize: 14 }, children: collection?.label || collectionName }),
13938
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: styles.countTag, children: displayEntries.length }),
14208
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Tooltip, { title: hasSearch && displayEntries.length >= 50 ? "Semantic search returns at most 50 results" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: styles.countTag, children: hasSearch && displayEntries.length >= 50 ? "50+" : displayEntries.length }) }),
13939
14209
  hasSearch && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Tag, { color: "blue", style: { margin: 0 }, children: "semantic" })
13940
14210
  ] }),
13941
14211
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: styles.toolbarRight, children: [
@@ -13954,9 +14224,11 @@ var CollectionEntryTable = ({
13954
14224
  style: { width: 200 },
13955
14225
  placeholder: "Semantic search\u2026",
13956
14226
  value: searchQuery,
13957
- onChange: (e) => setSearchQuery(e.target.value),
14227
+ onChange: (e) => {
14228
+ setSearchQuery(e.target.value);
14229
+ if (!e.target.value) doBackendSearch("");
14230
+ },
13958
14231
  onSearch: handleSearch,
13959
- onClear: clearFilters,
13960
14232
  allowClear: true,
13961
14233
  loading: searching
13962
14234
  }
@@ -13974,8 +14246,19 @@ var CollectionEntryTable = ({
13974
14246
  loading: isLoading,
13975
14247
  size: "small",
13976
14248
  pagination: false,
14249
+ rowClassName: (record) => expandedIds.has(record.id) ? styles.expandedRow : "",
14250
+ onRow: (record) => ({
14251
+ onClick: () => handleEdit(record),
14252
+ style: { cursor: "pointer" }
14253
+ }),
13977
14254
  showHeader: displayEntries.length > 0,
13978
- locale: { emptyText: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: styles.emptyWrap, children: [
14255
+ locale: { emptyText: loadError ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: styles.emptyWrap, children: [
14256
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text17, { type: "secondary", children: "Failed to load entries" }),
14257
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { size: "small", onClick: fetchEntries, children: "Retry" })
14258
+ ] }) : hasSearch ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: styles.emptyWrap, children: [
14259
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text17, { type: "secondary", children: "No matching entries" }),
14260
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { size: "small", onClick: clearFilters, children: "Clear search & filters" })
14261
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: styles.emptyWrap, children: [
13979
14262
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Text17, { type: "secondary", children: "No entries yet" }),
13980
14263
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Button, { type: "primary", size: "small", icon: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react18.Plus, { size: 14 }), onClick: handleAdd, children: "Add your first entry" })
13981
14264
  ] }) }
@@ -13996,7 +14279,7 @@ var CollectionEntryTable = ({
13996
14279
  destroyOnClose: true,
13997
14280
  children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_antd29.Form, { form, layout: "vertical", style: { marginTop: 8 }, children: [
13998
14281
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Form.Item, { name: "content", label: "Content", rules: [{ required: true }], children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Input.TextArea, { rows: 4, placeholder: "Text content to index\u2026" }) }),
13999
- fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Form.Item, { name: f.key, label: f.key, rules: f.required ? [{ required: true }] : [], children: f.type === "enum" && f.enumValues ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Select, { placeholder: f.key, allowClear: true, options: f.enumValues.map((v) => ({ value: v, label: v })) }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Input, { placeholder: f.key }) }, f.key))
14282
+ fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Form.Item, { name: f.key, label: f.key, rules: f.required ? [{ required: true }] : [], children: f.type === "enum" && f.enumValues ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Select, { placeholder: f.key, allowClear: true, options: f.enumValues.map((v) => ({ value: v, label: v })) }) : f.type === "number" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.InputNumber, { style: { width: "100%" }, placeholder: f.key }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_antd29.Input, { placeholder: f.key }) }, f.key))
14000
14283
  ] })
14001
14284
  }
14002
14285
  )
@@ -14149,7 +14432,7 @@ var CollectionsPanel = () => {
14149
14432
  title: "",
14150
14433
  key: "actions",
14151
14434
  width: 100,
14152
- render: (_, record) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_antd30.Space, { children: [
14435
+ render: (_, record) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_antd30.Space, { onClick: (e) => e.stopPropagation(), children: [
14153
14436
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_antd30.Tooltip, { title: "Edit", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
14154
14437
  import_antd30.Button,
14155
14438
  {
@@ -17869,11 +18152,13 @@ var MemoizedBubbleList = (0, import_react62.memo)(
17869
18152
  MemoizedBubbleList.displayName = "MemoizedBubbleList";
17870
18153
  var MessageList = ({
17871
18154
  messages,
17872
- className
18155
+ className,
18156
+ isLoading = false
17873
18157
  }) => {
17874
18158
  const { styles } = useStyle();
17875
18159
  const openSideApp = useSideAppOpener();
17876
- const deferredMessages = (0, import_react62.useDeferredValue)(messages);
18160
+ const rawDeferred = (0, import_react62.useDeferredValue)(messages);
18161
+ const deferredMessages = isLoading ? rawDeferred : messages;
17877
18162
  const messageLengthRef = (0, import_react62.useRef)(deferredMessages?.length ?? 0);
17878
18163
  (0, import_react62.useEffect)(() => {
17879
18164
  if (deferredMessages?.length) {
@@ -17972,6 +18257,30 @@ ${JSON.stringify(
17972
18257
  }
17973
18258
  };
17974
18259
  if (items.length === 0) {
18260
+ if (isLoading) {
18261
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center" }, children: [
18262
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("style", { children: `
18263
+ @keyframes msg-typing {
18264
+ 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
18265
+ 30% { transform: translateY(-6px); opacity: 1; }
18266
+ }
18267
+ ` }),
18268
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { style: { display: "flex", gap: 6, padding: "12px 20px" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
18269
+ "div",
18270
+ {
18271
+ style: {
18272
+ width: 8,
18273
+ height: 8,
18274
+ borderRadius: "50%",
18275
+ background: "linear-gradient(135deg, #6366f1, #a855f7)",
18276
+ animation: "msg-typing 1.2s ease-in-out infinite",
18277
+ animationDelay: `${i * 0.2}s`
18278
+ }
18279
+ },
18280
+ i
18281
+ )) })
18282
+ ] });
18283
+ }
17975
18284
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { style: { flex: 1 } });
17976
18285
  }
17977
18286
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
@@ -21106,6 +21415,7 @@ ${nextContent}`;
21106
21415
  MessageList,
21107
21416
  {
21108
21417
  messages,
21418
+ isLoading,
21109
21419
  className: `${styles.messages} ${isTransitioning ? styles.entering : ""}`
21110
21420
  }
21111
21421
  ),
@@ -28004,7 +28314,7 @@ function parseAgent(raw) {
28004
28314
  id: nid(label),
28005
28315
  type: "agent",
28006
28316
  name: label,
28007
- ref: typeof config.ref === "string" ? config.ref : label,
28317
+ ref: typeof config.ref === "string" ? config.ref : void 0,
28008
28318
  input: { template: String(config.prompt ?? "") },
28009
28319
  output: { key: label, schema: toSchema(config.output) },
28010
28320
  ask: config.ask === true,
@@ -28051,6 +28361,16 @@ function normalize(name, steps) {
28051
28361
  itemKey: "item",
28052
28362
  input: { template: String(config.map.each?.prompt ?? "") },
28053
28363
  output: { key, schema: toSchema(config.map.each?.output) },
28364
+ node: {
28365
+ type: "agent",
28366
+ ref: typeof config.map.each?.ref === "string" ? config.map.each.ref : "",
28367
+ input: { template: String(config.map.each?.prompt ?? "") }
28368
+ },
28369
+ config: {
28370
+ batchSize: Number(config.map.batch) || void 0,
28371
+ maxConcurrency: Number(config.map.concurrency) || void 0,
28372
+ innerConcurrency: Number(config.map.concurrency) || void 0
28373
+ },
28054
28374
  condition: config.map.if !== void 0 ? String(config.map.if) : void 0
28055
28375
  });
28056
28376
  const fromNodes = typeof prevId === "string" ? [prevId] : prevId;
@@ -28198,7 +28518,7 @@ var CIRCLE_SIZE = 72;
28198
28518
  var CIRCLE_BORDER = 3;
28199
28519
  var WorkflowNode = ({ data }) => {
28200
28520
  if (!data) return null;
28201
- const { nodeType, name, description, ref, outputKey, nodeSchema, config, status: termStatus, source, innerRef, reduceRef, inputTemplate, ask, condition, runState, pending } = data;
28521
+ const { nodeType, name, description, ref, refAgentName, refAgentType, refDeleted, outputKey, nodeSchema, config, status: termStatus, source, innerRef, inputTemplate, ask, condition, runState, pending } = data;
28202
28522
  const meta = TYPE_META[nodeType] || TYPE_META.agent;
28203
28523
  const termMeta = TERMINAL_STATUS_META[termStatus || ""] || TERMINAL_STATUS_META.__default;
28204
28524
  const ssc = runState ? STEP_STATUS_CONFIG[runState.status] || STEP_STATUS_CONFIG.running : null;
@@ -28298,6 +28618,7 @@ var WorkflowNode = ({ data }) => {
28298
28618
  boxShadow: cardShadow,
28299
28619
  border: `1px solid #e5e7eb`,
28300
28620
  borderLeft: `3px solid ${leftBorderColor}`,
28621
+ borderStyle: ref ? "dashed" : "solid",
28301
28622
  overflow: "hidden",
28302
28623
  transition: "all 0.2s ease",
28303
28624
  ...pending ? { opacity: 0.5, borderStyle: "dashed" } : {}
@@ -28389,8 +28710,16 @@ var WorkflowNode = ({ data }) => {
28389
28710
  }
28390
28711
  ),
28391
28712
  /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { style: { display: "flex", gap: 4, marginTop: 6, flexWrap: "wrap" }, children: [
28392
- !hasRuntime && nodeType === "agent" && ref && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_antd89.Tag, { color: "purple", style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: ref }),
28393
- !hasRuntime && nodeType === "agent" && !ref && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_antd89.Tag, { color: "default", style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: "general" }),
28713
+ !hasRuntime && nodeType === "agent" && ref && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_antd89.Tooltip, { title: refDeleted ? `Agent "${ref}" no longer exists` : `Delegated to agent: ${refAgentName ?? ref}`, children: /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
28714
+ import_antd89.Tag,
28715
+ {
28716
+ color: refDeleted ? "red" : "purple",
28717
+ style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" },
28718
+ icon: /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_lucide_react34.Link2, { size: 10 }),
28719
+ children: refDeleted ? `[\u5DF2\u5220\u9664] ${ref}` : `\u2192 ${refAgentName ?? ref}`
28720
+ }
28721
+ ) }),
28722
+ !hasRuntime && nodeType === "agent" && !ref && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_antd89.Tag, { color: "default", style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: "inline" }),
28394
28723
  ask && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_antd89.Tooltip, { title: "This step requires human approval before continuing", children: /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
28395
28724
  "div",
28396
28725
  {
@@ -28442,10 +28771,6 @@ var WorkflowNode = ({ data }) => {
28442
28771
  "\xD7",
28443
28772
  innerConcurrency ?? 5
28444
28773
  ] }),
28445
- !hasRuntime && nodeType === "map" && reduceRef && /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(import_antd89.Tag, { color: "blue", style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: [
28446
- "\u2193 ",
28447
- reduceRef
28448
- ] }),
28449
28774
  !hasRuntime && maxRetries ? /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(import_antd89.Tag, { style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: [
28450
28775
  "\u21BB ",
28451
28776
  maxRetries
@@ -28704,19 +29029,22 @@ function StepDetailPopover({ step }) {
28704
29029
  function matchStepByName(steps, dslNode) {
28705
29030
  return steps.find((s) => s.stepName === dslNode.name) ?? null;
28706
29031
  }
28707
- function dslNodeToData(n, runState, pending) {
29032
+ function dslNodeToData(n, runState, pending, agentNameMap) {
29033
+ const refAgent = n.ref && agentNameMap ? agentNameMap.get(n.ref) : void 0;
28708
29034
  return {
28709
29035
  nodeType: n.type,
28710
29036
  name: n.name,
28711
29037
  description: n.description,
28712
29038
  ref: n.ref,
29039
+ refAgentName: refAgent?.name,
29040
+ refAgentType: refAgent?.type,
29041
+ refDeleted: n.ref && agentNameMap ? !refAgent : void 0,
28713
29042
  outputKey: n.output?.key,
28714
29043
  nodeSchema: n.output?.schema,
28715
29044
  config: n.config,
28716
29045
  status: n.status,
28717
29046
  source: n.source,
28718
29047
  innerRef: n.node?.ref,
28719
- reduceRef: n.reduce?.ref,
28720
29048
  inputTemplate: n.input?.template,
28721
29049
  ask: n.ask,
28722
29050
  condition: n.condition,
@@ -28764,7 +29092,7 @@ function GroupLabelNode() {
28764
29092
  }, children: "Parallel" })
28765
29093
  ] });
28766
29094
  }
28767
- function buildGraph(dsl) {
29095
+ function buildGraph(dsl, agentNameMap) {
28768
29096
  const canvasNodes = dsl.nodes;
28769
29097
  const canvasEdges = dsl.edges;
28770
29098
  const parallelGroups = resolveParallelGroups(canvasNodes);
@@ -28800,7 +29128,7 @@ function buildGraph(dsl) {
28800
29128
  id: n.id,
28801
29129
  type: "workflow",
28802
29130
  position: pos,
28803
- data: { ...dslNodeToData(n) }
29131
+ data: { ...dslNodeToData(n, void 0, void 0, agentNameMap) }
28804
29132
  };
28805
29133
  });
28806
29134
  for (const group of parallelGroups) {
@@ -28822,7 +29150,7 @@ function buildGraph(dsl) {
28822
29150
  id: child.id,
28823
29151
  type: "workflow",
28824
29152
  position: { x: childStartX + i * (NODE_WIDTH + NODE_GAP), y: childY },
28825
- data: { ...dslNodeToData(child), parallelGroup: true },
29153
+ data: { ...dslNodeToData(child, void 0, void 0, agentNameMap), parallelGroup: true },
28826
29154
  style: { zIndex: 2 }
28827
29155
  });
28828
29156
  }
@@ -28860,7 +29188,7 @@ function buildGraph(dsl) {
28860
29188
  }
28861
29189
  return { nodes: reactNodes, edges: reactEdges };
28862
29190
  }
28863
- function buildRuntimeGraph(dsl, steps) {
29191
+ function buildRuntimeGraph(dsl, steps, _unused, agentNameMap) {
28864
29192
  const canvasNodes = dsl.nodes;
28865
29193
  const canvasEdges = dsl.edges;
28866
29194
  const parallelGroups = resolveParallelGroups(canvasNodes);
@@ -28900,7 +29228,7 @@ function buildRuntimeGraph(dsl, steps) {
28900
29228
  type: "workflow",
28901
29229
  position: pos,
28902
29230
  style: isTerminal ? { width: NODE_WIDTH, height: NODE_HEIGHT } : void 0,
28903
- data: dslNodeToData(n, runState, !step && !isTerminal)
29231
+ data: dslNodeToData(n, runState, !step && !isTerminal, agentNameMap)
28904
29232
  };
28905
29233
  });
28906
29234
  for (const group of parallelGroups) {
@@ -28923,7 +29251,7 @@ function buildRuntimeGraph(dsl, steps) {
28923
29251
  id: child.id,
28924
29252
  type: "workflow",
28925
29253
  position: { x: childStartX + i * (NODE_WIDTH + NODE_GAP), y: childY },
28926
- data: { ...dslNodeToData(child, runState, !step), parallelGroup: true },
29254
+ data: { ...dslNodeToData(child, runState, !step, agentNameMap), parallelGroup: true },
28927
29255
  style: { zIndex: 2 }
28928
29256
  });
28929
29257
  }
@@ -28974,6 +29302,7 @@ var WorkflowCanvas = ({
28974
29302
  dsl,
28975
29303
  steps,
28976
29304
  assistantId,
29305
+ agentNameMap,
28977
29306
  onNodeClick,
28978
29307
  height = "100%"
28979
29308
  }) => {
@@ -28983,8 +29312,8 @@ var WorkflowCanvas = ({
28983
29312
  groupLabel: GroupLabelNode
28984
29313
  }), []);
28985
29314
  const { nodes: initialNodes, edges: initialEdges } = (0, import_react96.useMemo)(
28986
- () => isRuntime ? buildRuntimeGraph(dsl, steps) : buildGraph(dsl),
28987
- [dsl, steps, isRuntime]
29315
+ () => isRuntime ? buildRuntimeGraph(dsl, steps, void 0, agentNameMap) : buildGraph(dsl, agentNameMap),
29316
+ [dsl, steps, isRuntime, agentNameMap]
28988
29317
  );
28989
29318
  const [nodes, setNodes, onNodesChange] = (0, import_react97.useNodesState)(initialNodes);
28990
29319
  const [edges, setEdges, onEdgesChange] = (0, import_react97.useEdgesState)(initialEdges);
@@ -30670,6 +30999,7 @@ function WorkflowFlowInner({
30670
30999
  onCreate,
30671
31000
  onDelete,
30672
31001
  dsl,
31002
+ agentNameMap,
30673
31003
  onSpecClick,
30674
31004
  environmentConfig
30675
31005
  }) {
@@ -30697,7 +31027,7 @@ function WorkflowFlowInner({
30697
31027
  };
30698
31028
  return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)("div", { style: { display: "flex", height: "100%", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime125.jsxs)("div", { style: { flex: 1, position: "relative" }, children: [
30699
31029
  selected ? /* @__PURE__ */ (0, import_jsx_runtime125.jsxs)(import_jsx_runtime125.Fragment, { children: [
30700
- dsl ? /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(WorkflowCanvas_default, { dsl }) : /* @__PURE__ */ (0, import_jsx_runtime125.jsx)("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_antd96.Spin, { tip: "Loading workflow DSL..." }) }),
31030
+ dsl ? /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(WorkflowCanvas_default, { dsl, agentNameMap }) : /* @__PURE__ */ (0, import_jsx_runtime125.jsx)("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_antd96.Spin, { tip: "Loading workflow DSL..." }) }),
30701
31031
  !listOpen && /* @__PURE__ */ (0, import_jsx_runtime125.jsx)("div", { style: {
30702
31032
  position: "absolute",
30703
31033
  top: 12,
@@ -30945,12 +31275,18 @@ var WorkflowAutomationView = () => {
30945
31275
  const [dsl, setDsl] = (0, import_react105.useState)(null);
30946
31276
  const [graphDef, setGraphDef] = (0, import_react105.useState)(null);
30947
31277
  const [agentConfigs, setAgentConfigs] = (0, import_react105.useState)([]);
31278
+ const [agentNameMap, setAgentNameMap] = (0, import_react105.useState)(/* @__PURE__ */ new Map());
30948
31279
  const fetchAllAssistants = (0, import_react105.useCallback)(async () => {
30949
31280
  try {
30950
31281
  const res = await get("/api/assistants");
30951
31282
  if (res.success && res.data?.records) {
30952
31283
  const cfgs = [];
31284
+ const nameMap = /* @__PURE__ */ new Map();
30953
31285
  for (const a of res.data.records) {
31286
+ if (a.id && a.name) {
31287
+ const def = typeof a.graphDefinition === "object" && a.graphDefinition !== null ? a.graphDefinition : void 0;
31288
+ nameMap.set(a.id, { name: a.name, type: def?.type ?? "unknown" });
31289
+ }
30954
31290
  if (!a.graphDefinition) continue;
30955
31291
  if (typeof a.graphDefinition === "string") {
30956
31292
  try {
@@ -30962,6 +31298,7 @@ var WorkflowAutomationView = () => {
30962
31298
  }
30963
31299
  }
30964
31300
  setAgentConfigs(cfgs);
31301
+ setAgentNameMap(nameMap);
30965
31302
  }
30966
31303
  } catch {
30967
31304
  }
@@ -31198,6 +31535,7 @@ var WorkflowAutomationView = () => {
31198
31535
  onCreate: () => setCreateModalOpen(true),
31199
31536
  onDelete: handleDelete,
31200
31537
  dsl,
31538
+ agentNameMap,
31201
31539
  onSpecClick: () => setSpecModalOpen(true),
31202
31540
  environmentConfig
31203
31541
  }