@axiom-lattice/react-sdk 2.1.108 → 2.1.109

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,22 +2211,25 @@ 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
  }));
@@ -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,17 @@ 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 && refAgentType && !refDeleted && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_antd89.Tag, { style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: refAgentType }),
28723
+ !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
28724
  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
28725
  "div",
28396
28726
  {
@@ -28442,10 +28772,6 @@ var WorkflowNode = ({ data }) => {
28442
28772
  "\xD7",
28443
28773
  innerConcurrency ?? 5
28444
28774
  ] }),
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
28775
  !hasRuntime && maxRetries ? /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(import_antd89.Tag, { style: { margin: 0, fontSize: 10, padding: "0 5px", lineHeight: "16px" }, children: [
28450
28776
  "\u21BB ",
28451
28777
  maxRetries
@@ -28704,19 +29030,22 @@ function StepDetailPopover({ step }) {
28704
29030
  function matchStepByName(steps, dslNode) {
28705
29031
  return steps.find((s) => s.stepName === dslNode.name) ?? null;
28706
29032
  }
28707
- function dslNodeToData(n, runState, pending) {
29033
+ function dslNodeToData(n, runState, pending, agentNameMap) {
29034
+ const refAgent = n.ref && agentNameMap ? agentNameMap.get(n.ref) : void 0;
28708
29035
  return {
28709
29036
  nodeType: n.type,
28710
29037
  name: n.name,
28711
29038
  description: n.description,
28712
29039
  ref: n.ref,
29040
+ refAgentName: refAgent?.name,
29041
+ refAgentType: refAgent?.type,
29042
+ refDeleted: n.ref && agentNameMap ? !refAgent : void 0,
28713
29043
  outputKey: n.output?.key,
28714
29044
  nodeSchema: n.output?.schema,
28715
29045
  config: n.config,
28716
29046
  status: n.status,
28717
29047
  source: n.source,
28718
29048
  innerRef: n.node?.ref,
28719
- reduceRef: n.reduce?.ref,
28720
29049
  inputTemplate: n.input?.template,
28721
29050
  ask: n.ask,
28722
29051
  condition: n.condition,
@@ -28764,7 +29093,7 @@ function GroupLabelNode() {
28764
29093
  }, children: "Parallel" })
28765
29094
  ] });
28766
29095
  }
28767
- function buildGraph(dsl) {
29096
+ function buildGraph(dsl, agentNameMap) {
28768
29097
  const canvasNodes = dsl.nodes;
28769
29098
  const canvasEdges = dsl.edges;
28770
29099
  const parallelGroups = resolveParallelGroups(canvasNodes);
@@ -28800,7 +29129,7 @@ function buildGraph(dsl) {
28800
29129
  id: n.id,
28801
29130
  type: "workflow",
28802
29131
  position: pos,
28803
- data: { ...dslNodeToData(n) }
29132
+ data: { ...dslNodeToData(n, void 0, void 0, agentNameMap) }
28804
29133
  };
28805
29134
  });
28806
29135
  for (const group of parallelGroups) {
@@ -28822,7 +29151,7 @@ function buildGraph(dsl) {
28822
29151
  id: child.id,
28823
29152
  type: "workflow",
28824
29153
  position: { x: childStartX + i * (NODE_WIDTH + NODE_GAP), y: childY },
28825
- data: { ...dslNodeToData(child), parallelGroup: true },
29154
+ data: { ...dslNodeToData(child, void 0, void 0, agentNameMap), parallelGroup: true },
28826
29155
  style: { zIndex: 2 }
28827
29156
  });
28828
29157
  }
@@ -28860,7 +29189,7 @@ function buildGraph(dsl) {
28860
29189
  }
28861
29190
  return { nodes: reactNodes, edges: reactEdges };
28862
29191
  }
28863
- function buildRuntimeGraph(dsl, steps) {
29192
+ function buildRuntimeGraph(dsl, steps, _unused, agentNameMap) {
28864
29193
  const canvasNodes = dsl.nodes;
28865
29194
  const canvasEdges = dsl.edges;
28866
29195
  const parallelGroups = resolveParallelGroups(canvasNodes);
@@ -28900,7 +29229,7 @@ function buildRuntimeGraph(dsl, steps) {
28900
29229
  type: "workflow",
28901
29230
  position: pos,
28902
29231
  style: isTerminal ? { width: NODE_WIDTH, height: NODE_HEIGHT } : void 0,
28903
- data: dslNodeToData(n, runState, !step && !isTerminal)
29232
+ data: dslNodeToData(n, runState, !step && !isTerminal, agentNameMap)
28904
29233
  };
28905
29234
  });
28906
29235
  for (const group of parallelGroups) {
@@ -28923,7 +29252,7 @@ function buildRuntimeGraph(dsl, steps) {
28923
29252
  id: child.id,
28924
29253
  type: "workflow",
28925
29254
  position: { x: childStartX + i * (NODE_WIDTH + NODE_GAP), y: childY },
28926
- data: { ...dslNodeToData(child, runState, !step), parallelGroup: true },
29255
+ data: { ...dslNodeToData(child, runState, !step, agentNameMap), parallelGroup: true },
28927
29256
  style: { zIndex: 2 }
28928
29257
  });
28929
29258
  }
@@ -28974,6 +29303,7 @@ var WorkflowCanvas = ({
28974
29303
  dsl,
28975
29304
  steps,
28976
29305
  assistantId,
29306
+ agentNameMap,
28977
29307
  onNodeClick,
28978
29308
  height = "100%"
28979
29309
  }) => {
@@ -28983,8 +29313,8 @@ var WorkflowCanvas = ({
28983
29313
  groupLabel: GroupLabelNode
28984
29314
  }), []);
28985
29315
  const { nodes: initialNodes, edges: initialEdges } = (0, import_react96.useMemo)(
28986
- () => isRuntime ? buildRuntimeGraph(dsl, steps) : buildGraph(dsl),
28987
- [dsl, steps, isRuntime]
29316
+ () => isRuntime ? buildRuntimeGraph(dsl, steps, void 0, agentNameMap) : buildGraph(dsl, agentNameMap),
29317
+ [dsl, steps, isRuntime, agentNameMap]
28988
29318
  );
28989
29319
  const [nodes, setNodes, onNodesChange] = (0, import_react97.useNodesState)(initialNodes);
28990
29320
  const [edges, setEdges, onEdgesChange] = (0, import_react97.useEdgesState)(initialEdges);
@@ -30670,6 +31000,7 @@ function WorkflowFlowInner({
30670
31000
  onCreate,
30671
31001
  onDelete,
30672
31002
  dsl,
31003
+ agentNameMap,
30673
31004
  onSpecClick,
30674
31005
  environmentConfig
30675
31006
  }) {
@@ -30697,7 +31028,7 @@ function WorkflowFlowInner({
30697
31028
  };
30698
31029
  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
31030
  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..." }) }),
31031
+ 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
31032
  !listOpen && /* @__PURE__ */ (0, import_jsx_runtime125.jsx)("div", { style: {
30702
31033
  position: "absolute",
30703
31034
  top: 12,
@@ -30945,12 +31276,18 @@ var WorkflowAutomationView = () => {
30945
31276
  const [dsl, setDsl] = (0, import_react105.useState)(null);
30946
31277
  const [graphDef, setGraphDef] = (0, import_react105.useState)(null);
30947
31278
  const [agentConfigs, setAgentConfigs] = (0, import_react105.useState)([]);
31279
+ const [agentNameMap, setAgentNameMap] = (0, import_react105.useState)(/* @__PURE__ */ new Map());
30948
31280
  const fetchAllAssistants = (0, import_react105.useCallback)(async () => {
30949
31281
  try {
30950
31282
  const res = await get("/api/assistants");
30951
31283
  if (res.success && res.data?.records) {
30952
31284
  const cfgs = [];
31285
+ const nameMap = /* @__PURE__ */ new Map();
30953
31286
  for (const a of res.data.records) {
31287
+ if (a.id && a.name) {
31288
+ const def = typeof a.graphDefinition === "object" && a.graphDefinition !== null ? a.graphDefinition : void 0;
31289
+ nameMap.set(a.id, { name: a.name, type: def?.type ?? "unknown" });
31290
+ }
30954
31291
  if (!a.graphDefinition) continue;
30955
31292
  if (typeof a.graphDefinition === "string") {
30956
31293
  try {
@@ -30962,6 +31299,7 @@ var WorkflowAutomationView = () => {
30962
31299
  }
30963
31300
  }
30964
31301
  setAgentConfigs(cfgs);
31302
+ setAgentNameMap(nameMap);
30965
31303
  }
30966
31304
  } catch {
30967
31305
  }
@@ -31198,6 +31536,7 @@ var WorkflowAutomationView = () => {
31198
31536
  onCreate: () => setCreateModalOpen(true),
31199
31537
  onDelete: handleDelete,
31200
31538
  dsl,
31539
+ agentNameMap,
31201
31540
  onSpecClick: () => setSpecModalOpen(true),
31202
31541
  environmentConfig
31203
31542
  }