@ash-ai/ui 1.0.0 → 1.0.2

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.cjs CHANGED
@@ -20,6 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ AgentConfigEditor: () => AgentConfigEditor,
24
+ AgentEvalRunner: () => AgentEvalRunner,
25
+ AgentKnowledgeBase: () => AgentKnowledgeBase,
26
+ AgentVersionManager: () => AgentVersionManager,
23
27
  BottomPanels: () => BottomPanels,
24
28
  Chat: () => Chat,
25
29
  ChatInput: () => ChatInput,
@@ -777,6 +781,33 @@ var RefreshCw = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg",
777
781
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
778
782
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8 16H3v5" })
779
783
  ] });
784
+ var Save = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
785
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }),
786
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7" }),
787
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7 3v4a1 1 0 0 0 1 1h7" })
788
+ ] });
789
+ var GitBranch = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
790
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
791
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "18", cy: "6", r: "3" }),
792
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "6", cy: "18", r: "3" }),
793
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 9a9 9 0 0 1-9 9" })
794
+ ] });
795
+ var FlaskConical = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
796
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2" }),
797
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8.5 2h7" }),
798
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7 16.5h10" })
799
+ ] });
800
+ var BookOpen = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
801
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 7v14" }),
802
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z" })
803
+ ] });
804
+ var Upload = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [
805
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
806
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "17 8 12 3 7 8" }),
807
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
808
+ ] });
809
+ var Play = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polygon", { points: "6 3 20 12 6 21 6 3" }) });
810
+ var Star = (props) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }) });
780
811
  function getFileIcon(name) {
781
812
  const ext = name.split(".").pop()?.toLowerCase();
782
813
  if (["ts", "tsx", "js", "jsx", "py", "rs", "go", "rb", "sh", "bash"].includes(ext || ""))
@@ -1814,8 +1845,1036 @@ function FileBrowserPanel({ client, sessionId }) {
1814
1845
  function Playground({ client, defaultAgent, className }) {
1815
1846
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PlaygroundProvider, { client, defaultAgent, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PlaygroundInner, { className }) });
1816
1847
  }
1848
+
1849
+ // src/components/AgentConfigEditor.tsx
1850
+ var import_react14 = require("react");
1851
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1852
+ var CONFIG_FIELDS = [
1853
+ { key: "description", label: "Description", type: "text", placeholder: "A brief description of this agent" },
1854
+ { key: "model", label: "Model", type: "text", placeholder: "e.g. claude-sonnet-4-5-20250514" },
1855
+ { key: "systemPrompt", label: "System Prompt", type: "textarea", placeholder: "System prompt for the agent..." },
1856
+ { key: "max_turns", label: "Max Turns", type: "number", placeholder: "e.g. 10" },
1857
+ { key: "permission_mode", label: "Permission Mode", type: "select", placeholder: "Select permission mode", options: ["default", "plan", "bypassPermissions"] }
1858
+ ];
1859
+ function AgentConfigEditor({ client, agentName, className, onSaved }) {
1860
+ const [config, setConfig] = (0, import_react14.useState)({});
1861
+ const [original, setOriginal] = (0, import_react14.useState)({});
1862
+ const [loading, setLoading] = (0, import_react14.useState)(true);
1863
+ const [saving, setSaving] = (0, import_react14.useState)(false);
1864
+ const [error, setError] = (0, import_react14.useState)(null);
1865
+ const [success, setSuccess] = (0, import_react14.useState)(false);
1866
+ const fetchConfig = (0, import_react14.useCallback)(async () => {
1867
+ setLoading(true);
1868
+ setError(null);
1869
+ try {
1870
+ const data = await client.getAgentConfig(agentName);
1871
+ setConfig(data);
1872
+ setOriginal(data);
1873
+ } catch (e) {
1874
+ setError(e instanceof Error ? e.message : "Failed to fetch config");
1875
+ } finally {
1876
+ setLoading(false);
1877
+ }
1878
+ }, [client, agentName]);
1879
+ (0, import_react14.useEffect)(() => {
1880
+ fetchConfig();
1881
+ }, [fetchConfig]);
1882
+ const handleSave = async () => {
1883
+ setSaving(true);
1884
+ setError(null);
1885
+ setSuccess(false);
1886
+ try {
1887
+ const changes = {};
1888
+ for (const field of CONFIG_FIELDS) {
1889
+ if (config[field.key] !== original[field.key]) {
1890
+ changes[field.key] = config[field.key];
1891
+ }
1892
+ }
1893
+ if (Object.keys(changes).length === 0) {
1894
+ setSuccess(true);
1895
+ return;
1896
+ }
1897
+ const updatedAgent = await client.updateAgentConfig(agentName, changes);
1898
+ const data = updatedAgent && typeof updatedAgent === "object" && "config" in updatedAgent && updatedAgent.config ? updatedAgent.config : { ...original, ...changes };
1899
+ setConfig(data);
1900
+ setOriginal(data);
1901
+ setSuccess(true);
1902
+ onSaved?.(data);
1903
+ } catch (e) {
1904
+ setError(e instanceof Error ? e.message : "Failed to save config");
1905
+ } finally {
1906
+ setSaving(false);
1907
+ }
1908
+ };
1909
+ const handleReset = () => {
1910
+ setConfig({ ...original });
1911
+ setError(null);
1912
+ setSuccess(false);
1913
+ };
1914
+ const updateField = (key, value) => {
1915
+ setConfig((prev) => ({ ...prev, [key]: value }));
1916
+ setSuccess(false);
1917
+ };
1918
+ const hasChanges = JSON.stringify(config) !== JSON.stringify(original);
1919
+ if (loading) {
1920
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cn("flex items-center justify-center py-12", className), children: [
1921
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Loader2, { className: "mr-2 h-4 w-4 animate-spin text-white/40" }),
1922
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm text-white/50", children: "Loading config..." })
1923
+ ] });
1924
+ }
1925
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cn("space-y-4", className), children: [
1926
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-end gap-2", children: [
1927
+ hasChanges && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1928
+ "button",
1929
+ {
1930
+ onClick: handleReset,
1931
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg text-white/70 hover:text-white hover:bg-white/10 transition-colors",
1932
+ children: [
1933
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefreshCw, { className: "h-3.5 w-3.5" }),
1934
+ " Reset"
1935
+ ]
1936
+ }
1937
+ ),
1938
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1939
+ "button",
1940
+ {
1941
+ onClick: handleSave,
1942
+ disabled: saving || !hasChanges,
1943
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 disabled:opacity-50 disabled:pointer-events-none transition-colors",
1944
+ children: [
1945
+ saving ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Save, { className: "h-3.5 w-3.5" }),
1946
+ "Save"
1947
+ ]
1948
+ }
1949
+ )
1950
+ ] }),
1951
+ error && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-sm text-red-400 bg-red-500/10 border border-red-500/20 rounded-lg px-4 py-2", children: error }),
1952
+ success && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-sm text-green-400 bg-green-500/10 border border-green-500/20 rounded-lg px-4 py-2", children: "Configuration saved." }),
1953
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "space-y-4 rounded-xl border border-white/10 bg-white/[0.02] p-4", children: CONFIG_FIELDS.map((field) => {
1954
+ const value = config[field.key] ?? "";
1955
+ if (field.type === "textarea") {
1956
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-1.5", children: [
1957
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "block text-sm font-medium text-white/70", children: field.label }),
1958
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1959
+ "textarea",
1960
+ {
1961
+ value: String(value),
1962
+ onChange: (e) => updateField(field.key, e.target.value || void 0),
1963
+ rows: 5,
1964
+ placeholder: field.placeholder,
1965
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50 resize-none"
1966
+ }
1967
+ )
1968
+ ] }, field.key);
1969
+ }
1970
+ if (field.type === "select") {
1971
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-1.5", children: [
1972
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "block text-sm font-medium text-white/70", children: field.label }),
1973
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1974
+ "select",
1975
+ {
1976
+ value: String(value),
1977
+ onChange: (e) => updateField(field.key, e.target.value || void 0),
1978
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white focus-visible:outline-none focus-visible:border-indigo-500/50",
1979
+ children: [
1980
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "", style: { background: "#1c2129" }, children: "Not set" }),
1981
+ field.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: opt, style: { background: "#1c2129" }, children: opt }, opt))
1982
+ ]
1983
+ }
1984
+ )
1985
+ ] }, field.key);
1986
+ }
1987
+ if (field.type === "number") {
1988
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-1.5", children: [
1989
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "block text-sm font-medium text-white/70", children: field.label }),
1990
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1991
+ "input",
1992
+ {
1993
+ type: "number",
1994
+ value: value === void 0 || value === "" ? "" : Number(value),
1995
+ onChange: (e) => updateField(field.key, e.target.value ? Number(e.target.value) : void 0),
1996
+ placeholder: field.placeholder,
1997
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50"
1998
+ }
1999
+ )
2000
+ ] }, field.key);
2001
+ }
2002
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-1.5", children: [
2003
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "block text-sm font-medium text-white/70", children: field.label }),
2004
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2005
+ "input",
2006
+ {
2007
+ type: "text",
2008
+ value: String(value),
2009
+ onChange: (e) => updateField(field.key, e.target.value || void 0),
2010
+ placeholder: field.placeholder,
2011
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50"
2012
+ }
2013
+ )
2014
+ ] }, field.key);
2015
+ }) })
2016
+ ] });
2017
+ }
2018
+
2019
+ // src/components/AgentVersionManager.tsx
2020
+ var import_react15 = require("react");
2021
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2022
+ function AgentVersionManager({ client, agentName, className, onActivated }) {
2023
+ const [versions, setVersions] = (0, import_react15.useState)([]);
2024
+ const [loading, setLoading] = (0, import_react15.useState)(true);
2025
+ const [activating, setActivating] = (0, import_react15.useState)(null);
2026
+ const [showCreate, setShowCreate] = (0, import_react15.useState)(false);
2027
+ const [error, setError] = (0, import_react15.useState)(null);
2028
+ const refresh = (0, import_react15.useCallback)(async () => {
2029
+ try {
2030
+ setLoading(true);
2031
+ const data = await client.listAgentVersions(agentName);
2032
+ setVersions(data);
2033
+ } catch (e) {
2034
+ setError(e instanceof Error ? e.message : "Failed to fetch versions");
2035
+ } finally {
2036
+ setLoading(false);
2037
+ }
2038
+ }, [client, agentName]);
2039
+ (0, import_react15.useEffect)(() => {
2040
+ refresh();
2041
+ }, [refresh]);
2042
+ const handleActivate = async (v) => {
2043
+ setActivating(v.versionNumber);
2044
+ setError(null);
2045
+ try {
2046
+ await client.activateAgentVersion(agentName, v.versionNumber);
2047
+ await refresh();
2048
+ onActivated?.(v);
2049
+ } catch (e) {
2050
+ setError(e instanceof Error ? e.message : "Failed to activate version");
2051
+ } finally {
2052
+ setActivating(null);
2053
+ }
2054
+ };
2055
+ if (loading) {
2056
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cn("flex items-center justify-center py-12", className), children: [
2057
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Loader2, { className: "mr-2 h-4 w-4 animate-spin text-white/40" }),
2058
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-sm text-white/50", children: "Loading versions..." })
2059
+ ] });
2060
+ }
2061
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cn("space-y-4", className), children: [
2062
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between", children: [
2063
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-sm text-white/50", children: [
2064
+ versions.length,
2065
+ " version",
2066
+ versions.length !== 1 ? "s" : ""
2067
+ ] }),
2068
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2069
+ "button",
2070
+ {
2071
+ onClick: () => setShowCreate(true),
2072
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 transition-colors",
2073
+ children: [
2074
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Plus, { className: "h-3.5 w-3.5" }),
2075
+ " Create Version"
2076
+ ]
2077
+ }
2078
+ )
2079
+ ] }),
2080
+ error && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "text-sm text-red-400 bg-red-500/10 border border-red-500/20 rounded-lg px-4 py-2", children: error }),
2081
+ versions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
2082
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(GitBranch, { className: "mb-3 h-10 w-10 text-white/20" }),
2083
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-white/50", children: "No versions yet" }),
2084
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "mt-1 text-xs text-white/40", children: "Create your first version to snapshot the agent config." })
2085
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "space-y-2", children: versions.map((v) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3", children: [
2086
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "min-w-0 flex-1", children: [
2087
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", children: [
2088
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-sm font-semibold text-white", children: [
2089
+ "v",
2090
+ v.versionNumber
2091
+ ] }),
2092
+ v.name && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-sm text-white/50", children: v.name }),
2093
+ v.isActive && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "inline-flex items-center gap-1 rounded-full bg-green-500/10 px-2 py-0.5 text-xs font-medium text-green-400", children: [
2094
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CheckCircle2, { className: "h-3 w-3" }),
2095
+ " Active"
2096
+ ] })
2097
+ ] }),
2098
+ v.releaseNotes && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-white/40 mt-1", children: v.releaseNotes }),
2099
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-3 mt-1", children: [
2100
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-xs text-white/30", children: formatTime(v.createdAt) }),
2101
+ v.systemPrompt && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-xs text-white/30", children: "Has system prompt" }),
2102
+ v.knowledgeFiles && v.knowledgeFiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-xs text-white/30", children: [
2103
+ v.knowledgeFiles.length,
2104
+ " file",
2105
+ v.knowledgeFiles.length !== 1 ? "s" : ""
2106
+ ] })
2107
+ ] })
2108
+ ] }),
2109
+ !v.isActive && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2110
+ "button",
2111
+ {
2112
+ onClick: () => handleActivate(v),
2113
+ disabled: activating === v.versionNumber,
2114
+ className: "inline-flex items-center gap-1 px-2.5 py-1 text-xs font-medium rounded-lg border border-white/20 bg-white/5 text-white hover:bg-white/10 disabled:opacity-50 transition-colors",
2115
+ children: [
2116
+ activating === v.versionNumber ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Loader2, { className: "h-3 w-3 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CheckCircle2, { className: "h-3 w-3" }),
2117
+ "Activate"
2118
+ ]
2119
+ }
2120
+ )
2121
+ ] }, v.id)) }),
2122
+ showCreate && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2123
+ CreateVersionModal,
2124
+ {
2125
+ client,
2126
+ agentName,
2127
+ onClose: () => setShowCreate(false),
2128
+ onCreated: () => {
2129
+ setShowCreate(false);
2130
+ refresh();
2131
+ }
2132
+ }
2133
+ )
2134
+ ] });
2135
+ }
2136
+ function CreateVersionModal({
2137
+ client,
2138
+ agentName,
2139
+ onClose,
2140
+ onCreated
2141
+ }) {
2142
+ const [name, setName] = (0, import_react15.useState)("");
2143
+ const [systemPrompt, setSystemPrompt] = (0, import_react15.useState)("");
2144
+ const [releaseNotes, setReleaseNotes] = (0, import_react15.useState)("");
2145
+ const [creating, setCreating] = (0, import_react15.useState)(false);
2146
+ const [error, setError] = (0, import_react15.useState)(null);
2147
+ const handleCreate = async () => {
2148
+ setCreating(true);
2149
+ setError(null);
2150
+ try {
2151
+ await client.createAgentVersion(agentName, {
2152
+ name: name || void 0,
2153
+ systemPrompt: systemPrompt || void 0,
2154
+ releaseNotes: releaseNotes || void 0
2155
+ });
2156
+ onCreated();
2157
+ } catch (e) {
2158
+ setError(e instanceof Error ? e.message : "Failed to create version");
2159
+ } finally {
2160
+ setCreating(false);
2161
+ }
2162
+ };
2163
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "w-full max-w-lg max-h-[90vh] overflow-auto rounded-xl border border-white/10 bg-[#1c2129] p-6", children: [
2164
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between mb-6", children: [
2165
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { className: "text-lg font-semibold text-white", children: "Create Version" }),
2166
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { onClick: onClose, className: "text-white/40 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(X, { className: "h-5 w-5" }) })
2167
+ ] }),
2168
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-4", children: [
2169
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-1.5", children: [
2170
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Version Name (optional)" }),
2171
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2172
+ "input",
2173
+ {
2174
+ type: "text",
2175
+ value: name,
2176
+ onChange: (e) => setName(e.target.value),
2177
+ placeholder: "e.g. v2 - improved grounding",
2178
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50"
2179
+ }
2180
+ )
2181
+ ] }),
2182
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-1.5", children: [
2183
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "System Prompt (optional)" }),
2184
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2185
+ "textarea",
2186
+ {
2187
+ value: systemPrompt,
2188
+ onChange: (e) => setSystemPrompt(e.target.value),
2189
+ rows: 4,
2190
+ placeholder: "System prompt for this version...",
2191
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50 resize-none"
2192
+ }
2193
+ )
2194
+ ] }),
2195
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-1.5", children: [
2196
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Release Notes (optional)" }),
2197
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2198
+ "textarea",
2199
+ {
2200
+ value: releaseNotes,
2201
+ onChange: (e) => setReleaseNotes(e.target.value),
2202
+ rows: 2,
2203
+ placeholder: "What changed in this version...",
2204
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50 resize-none"
2205
+ }
2206
+ )
2207
+ ] }),
2208
+ error && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm text-red-400", children: error }),
2209
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [
2210
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { onClick: onClose, className: "px-3 py-1.5 text-sm text-white/70 hover:text-white hover:bg-white/10 rounded-lg transition-colors", children: "Cancel" }),
2211
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2212
+ "button",
2213
+ {
2214
+ onClick: handleCreate,
2215
+ disabled: creating,
2216
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 disabled:opacity-50 transition-colors",
2217
+ children: creating ? "Creating..." : "Create Version"
2218
+ }
2219
+ )
2220
+ ] })
2221
+ ] })
2222
+ ] }) });
2223
+ }
2224
+
2225
+ // src/components/AgentKnowledgeBase.tsx
2226
+ var import_react16 = require("react");
2227
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2228
+ function AgentKnowledgeBase({ client, agentName, className }) {
2229
+ const [files, setFiles] = (0, import_react16.useState)([]);
2230
+ const [loading, setLoading] = (0, import_react16.useState)(true);
2231
+ const [expanded, setExpanded] = (0, import_react16.useState)({});
2232
+ const [loadingFile, setLoadingFile] = (0, import_react16.useState)(null);
2233
+ const [deleting, setDeleting] = (0, import_react16.useState)(null);
2234
+ const [uploading, setUploading] = (0, import_react16.useState)(false);
2235
+ const [error, setError] = (0, import_react16.useState)(null);
2236
+ const fileInputRef = (0, import_react16.useRef)(null);
2237
+ const refresh = (0, import_react16.useCallback)(async () => {
2238
+ try {
2239
+ setLoading(true);
2240
+ const data = await client.listAgentFiles(agentName);
2241
+ setFiles(data.files);
2242
+ } catch (e) {
2243
+ setError(e instanceof Error ? e.message : "Failed to fetch files");
2244
+ } finally {
2245
+ setLoading(false);
2246
+ }
2247
+ }, [client, agentName]);
2248
+ (0, import_react16.useEffect)(() => {
2249
+ refresh();
2250
+ }, [refresh]);
2251
+ const handlePreview = async (path) => {
2252
+ if (expanded[path] !== void 0) {
2253
+ setExpanded((prev) => {
2254
+ const next = { ...prev };
2255
+ delete next[path];
2256
+ return next;
2257
+ });
2258
+ return;
2259
+ }
2260
+ setLoadingFile(path);
2261
+ try {
2262
+ const data = await client.getAgentFile(agentName, path);
2263
+ setExpanded((prev) => ({ ...prev, [path]: data.content }));
2264
+ } catch {
2265
+ setExpanded((prev) => ({ ...prev, [path]: "(Failed to load)" }));
2266
+ } finally {
2267
+ setLoadingFile(null);
2268
+ }
2269
+ };
2270
+ const handleDelete = async (path) => {
2271
+ setDeleting(path);
2272
+ setError(null);
2273
+ try {
2274
+ await client.deleteAgentFile(agentName, path);
2275
+ refresh();
2276
+ } catch (e) {
2277
+ setError(e instanceof Error ? e.message : "Failed to delete file");
2278
+ } finally {
2279
+ setDeleting(null);
2280
+ }
2281
+ };
2282
+ const handleUpload = async (fileList) => {
2283
+ setUploading(true);
2284
+ setError(null);
2285
+ try {
2286
+ const uploadFiles = [];
2287
+ for (const file of Array.from(fileList)) {
2288
+ const buffer = await file.arrayBuffer();
2289
+ const base64 = btoa(String.fromCharCode(...new Uint8Array(buffer)));
2290
+ uploadFiles.push({ path: file.name, content: base64 });
2291
+ }
2292
+ await client.uploadAgentFiles(agentName, uploadFiles);
2293
+ refresh();
2294
+ } catch (e) {
2295
+ setError(e instanceof Error ? e.message : "Failed to upload files");
2296
+ } finally {
2297
+ setUploading(false);
2298
+ }
2299
+ };
2300
+ if (loading) {
2301
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn("flex items-center justify-center py-12", className), children: [
2302
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Loader2, { className: "mr-2 h-4 w-4 animate-spin text-white/40" }),
2303
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-sm text-white/50", children: "Loading files..." })
2304
+ ] });
2305
+ }
2306
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cn("space-y-4", className), children: [
2307
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center justify-between", children: [
2308
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-sm text-white/50", children: [
2309
+ files.length,
2310
+ " file",
2311
+ files.length !== 1 ? "s" : ""
2312
+ ] }),
2313
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-2", children: [
2314
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: refresh, className: "p-1.5 text-white/40 hover:text-white rounded transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(RefreshCw, { className: "h-4 w-4" }) }),
2315
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2316
+ "button",
2317
+ {
2318
+ onClick: () => fileInputRef.current?.click(),
2319
+ disabled: uploading,
2320
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 disabled:opacity-50 transition-colors",
2321
+ children: [
2322
+ uploading ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Upload, { className: "h-3.5 w-3.5" }),
2323
+ "Upload"
2324
+ ]
2325
+ }
2326
+ ),
2327
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2328
+ "input",
2329
+ {
2330
+ ref: fileInputRef,
2331
+ type: "file",
2332
+ multiple: true,
2333
+ className: "hidden",
2334
+ onChange: (e) => {
2335
+ if (e.target.files) handleUpload(e.target.files);
2336
+ }
2337
+ }
2338
+ )
2339
+ ] })
2340
+ ] }),
2341
+ error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "text-sm text-red-400 bg-red-500/10 border border-red-500/20 rounded-lg px-4 py-2", children: error }),
2342
+ files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
2343
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BookOpen, { className: "mb-3 h-10 w-10 text-white/20" }),
2344
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium text-white/50", children: "No knowledge files" }),
2345
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "mt-1 text-xs text-white/40", children: "Upload files for this agent's knowledge base." })
2346
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "space-y-1", children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
2347
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.02] px-3 py-2", children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2349
+ "button",
2350
+ {
2351
+ onClick: () => handlePreview(file.path),
2352
+ className: "flex items-center gap-2 min-w-0 flex-1 text-left",
2353
+ children: [
2354
+ loadingFile === file.path ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Loader2, { className: "h-3.5 w-3.5 animate-spin text-white/40 shrink-0" }) : expanded[file.path] !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChevronDown, { className: "h-3.5 w-3.5 text-white/40 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChevronRight, { className: "h-3.5 w-3.5 text-white/40 shrink-0" }),
2355
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FileText, { className: "h-3.5 w-3.5 text-white/40 shrink-0" }),
2356
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-sm text-white truncate", children: file.path }),
2357
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-xs text-white/30 shrink-0", children: formatBytes(file.size) })
2358
+ ]
2359
+ }
2360
+ ),
2361
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2362
+ "button",
2363
+ {
2364
+ onClick: () => handleDelete(file.path),
2365
+ disabled: deleting === file.path,
2366
+ className: "p-1 text-white/30 hover:text-red-400 transition-colors shrink-0 ml-2",
2367
+ children: deleting === file.path ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Trash2, { className: "h-3.5 w-3.5" })
2368
+ }
2369
+ )
2370
+ ] }),
2371
+ expanded[file.path] !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ml-4 mt-1 mb-2 rounded-lg border border-white/5 bg-black/20 p-3", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("pre", { className: "text-xs text-white/70 whitespace-pre-wrap break-words max-h-60 overflow-auto", children: expanded[file.path] }) })
2372
+ ] }, file.path)) })
2373
+ ] });
2374
+ }
2375
+
2376
+ // src/components/AgentEvalRunner.tsx
2377
+ var import_react17 = require("react");
2378
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2379
+ function AgentEvalRunner({ client, agentName, className }) {
2380
+ const [tab, setTab] = (0, import_react17.useState)("cases");
2381
+ const [cases, setCases] = (0, import_react17.useState)([]);
2382
+ const [runs, setRuns] = (0, import_react17.useState)([]);
2383
+ const [loadingCases, setLoadingCases] = (0, import_react17.useState)(true);
2384
+ const [loadingRuns, setLoadingRuns] = (0, import_react17.useState)(true);
2385
+ const [showAddCase, setShowAddCase] = (0, import_react17.useState)(false);
2386
+ const [showRunModal, setShowRunModal] = (0, import_react17.useState)(false);
2387
+ const [error, setError] = (0, import_react17.useState)(null);
2388
+ const refreshCases = (0, import_react17.useCallback)(async () => {
2389
+ try {
2390
+ setLoadingCases(true);
2391
+ const data = await client.listEvalCases(agentName);
2392
+ setCases(data);
2393
+ } catch (e) {
2394
+ setError(e instanceof Error ? e.message : "Failed to fetch eval cases");
2395
+ } finally {
2396
+ setLoadingCases(false);
2397
+ }
2398
+ }, [client, agentName]);
2399
+ const refreshRuns = (0, import_react17.useCallback)(async () => {
2400
+ try {
2401
+ setLoadingRuns(true);
2402
+ const data = await client.listEvalRuns(agentName);
2403
+ setRuns(data);
2404
+ } catch (e) {
2405
+ setError(e instanceof Error ? e.message : "Failed to fetch eval runs");
2406
+ } finally {
2407
+ setLoadingRuns(false);
2408
+ }
2409
+ }, [client, agentName]);
2410
+ (0, import_react17.useEffect)(() => {
2411
+ refreshCases();
2412
+ refreshRuns();
2413
+ }, [refreshCases, refreshRuns]);
2414
+ const intervalRef = (0, import_react17.useRef)(null);
2415
+ (0, import_react17.useEffect)(() => {
2416
+ const hasActive = runs.some((r) => r.status === "pending" || r.status === "running");
2417
+ if (hasActive) {
2418
+ intervalRef.current = setInterval(refreshRuns, 5e3);
2419
+ }
2420
+ return () => {
2421
+ if (intervalRef.current) clearInterval(intervalRef.current);
2422
+ };
2423
+ }, [runs, refreshRuns]);
2424
+ const handleDeleteCase = async (id) => {
2425
+ setError(null);
2426
+ try {
2427
+ await client.deleteEvalCase(agentName, id);
2428
+ refreshCases();
2429
+ } catch (e) {
2430
+ setError(e instanceof Error ? e.message : "Failed to delete case");
2431
+ }
2432
+ };
2433
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cn("space-y-4", className), children: [
2434
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 p-1 bg-white/5 rounded-lg w-fit", children: [
2435
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2436
+ "button",
2437
+ {
2438
+ onClick: () => setTab("cases"),
2439
+ className: cn(
2440
+ "px-3 py-1.5 text-xs font-medium rounded-md transition-colors",
2441
+ tab === "cases" ? "bg-white/10 text-white" : "text-white/50 hover:text-white"
2442
+ ),
2443
+ children: [
2444
+ "Cases (",
2445
+ cases.length,
2446
+ ")"
2447
+ ]
2448
+ }
2449
+ ),
2450
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2451
+ "button",
2452
+ {
2453
+ onClick: () => setTab("runs"),
2454
+ className: cn(
2455
+ "px-3 py-1.5 text-xs font-medium rounded-md transition-colors",
2456
+ tab === "runs" ? "bg-white/10 text-white" : "text-white/50 hover:text-white"
2457
+ ),
2458
+ children: [
2459
+ "Runs (",
2460
+ runs.length,
2461
+ ")"
2462
+ ]
2463
+ }
2464
+ )
2465
+ ] }),
2466
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "text-sm text-red-400 bg-red-500/10 border border-red-500/20 rounded-lg px-4 py-2", children: error }),
2467
+ tab === "cases" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2468
+ CasesTab,
2469
+ {
2470
+ cases,
2471
+ loading: loadingCases,
2472
+ onAdd: () => setShowAddCase(true),
2473
+ onDelete: handleDeleteCase
2474
+ }
2475
+ ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2476
+ RunsTab,
2477
+ {
2478
+ client,
2479
+ agentName,
2480
+ runs,
2481
+ loading: loadingRuns,
2482
+ onRun: () => setShowRunModal(true)
2483
+ }
2484
+ ),
2485
+ showAddCase && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2486
+ AddCaseModal,
2487
+ {
2488
+ client,
2489
+ agentName,
2490
+ onClose: () => setShowAddCase(false),
2491
+ onCreated: () => {
2492
+ setShowAddCase(false);
2493
+ refreshCases();
2494
+ }
2495
+ }
2496
+ ),
2497
+ showRunModal && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2498
+ RunEvalModal,
2499
+ {
2500
+ client,
2501
+ agentName,
2502
+ onClose: () => setShowRunModal(false),
2503
+ onStarted: () => {
2504
+ setShowRunModal(false);
2505
+ refreshRuns();
2506
+ }
2507
+ }
2508
+ )
2509
+ ] });
2510
+ }
2511
+ function CasesTab({
2512
+ cases,
2513
+ loading,
2514
+ onAdd,
2515
+ onDelete
2516
+ }) {
2517
+ const [expanded, setExpanded] = (0, import_react17.useState)(/* @__PURE__ */ new Set());
2518
+ if (loading) {
2519
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-center py-12", children: [
2520
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Loader2, { className: "mr-2 h-4 w-4 animate-spin text-white/40" }),
2521
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm text-white/50", children: "Loading cases..." })
2522
+ ] });
2523
+ }
2524
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-3", children: [
2525
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2526
+ "button",
2527
+ {
2528
+ onClick: onAdd,
2529
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 transition-colors",
2530
+ children: [
2531
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Plus, { className: "h-3.5 w-3.5" }),
2532
+ " Add Case"
2533
+ ]
2534
+ }
2535
+ ) }),
2536
+ cases.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FlaskConical, { className: "mb-3 h-10 w-10 text-white/20" }),
2538
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium text-white/50", children: "No eval cases" }),
2539
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-1 text-xs text-white/40", children: "Add test cases to evaluate your agent." })
2540
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "space-y-1", children: cases.map((c) => {
2541
+ const isExpanded = expanded.has(c.id);
2542
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
2543
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.02] px-3 py-2", children: [
2544
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2545
+ "button",
2546
+ {
2547
+ onClick: () => setExpanded((prev) => {
2548
+ const next = new Set(prev);
2549
+ isExpanded ? next.delete(c.id) : next.add(c.id);
2550
+ return next;
2551
+ }),
2552
+ className: "flex items-center gap-2 min-w-0 flex-1 text-left",
2553
+ children: [
2554
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronDown, { className: "h-3.5 w-3.5 text-white/40 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronRight, { className: "h-3.5 w-3.5 text-white/40 shrink-0" }),
2555
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm text-white truncate", children: c.question }),
2556
+ c.category && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/30 shrink-0", children: c.category })
2557
+ ]
2558
+ }
2559
+ ),
2560
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2561
+ "button",
2562
+ {
2563
+ onClick: () => onDelete(c.id),
2564
+ className: "p-1 text-white/30 hover:text-red-400 transition-colors shrink-0 ml-2",
2565
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(X, { className: "h-3.5 w-3.5" })
2566
+ }
2567
+ )
2568
+ ] }),
2569
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ml-4 mt-1 mb-2 rounded-lg border border-white/5 bg-black/20 p-3 space-y-2", children: [
2570
+ c.expectedTopics && c.expectedTopics.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
2571
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/40", children: "Expected topics: " }),
2572
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/60", children: c.expectedTopics.join(", ") })
2573
+ ] }),
2574
+ c.referenceAnswer && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
2575
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/40", children: "Reference: " }),
2576
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/60", children: c.referenceAnswer })
2577
+ ] }),
2578
+ c.tags && c.tags.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex gap-1", children: c.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs bg-white/5 text-white/50 px-1.5 py-0.5 rounded", children: t }, t)) })
2579
+ ] })
2580
+ ] }, c.id);
2581
+ }) })
2582
+ ] });
2583
+ }
2584
+ function RunsTab({
2585
+ client,
2586
+ agentName,
2587
+ runs,
2588
+ loading,
2589
+ onRun
2590
+ }) {
2591
+ const [expandedRun, setExpandedRun] = (0, import_react17.useState)(null);
2592
+ const [results, setResults] = (0, import_react17.useState)([]);
2593
+ const [loadingResults, setLoadingResults] = (0, import_react17.useState)(false);
2594
+ const handleExpand = async (runId) => {
2595
+ if (expandedRun === runId) {
2596
+ setExpandedRun(null);
2597
+ return;
2598
+ }
2599
+ setExpandedRun(runId);
2600
+ setLoadingResults(true);
2601
+ try {
2602
+ const data = await client.getEvalRunResults(agentName, runId);
2603
+ setResults(data);
2604
+ } catch {
2605
+ setResults([]);
2606
+ } finally {
2607
+ setLoadingResults(false);
2608
+ }
2609
+ };
2610
+ if (loading) {
2611
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-center py-12", children: [
2612
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Loader2, { className: "mr-2 h-4 w-4 animate-spin text-white/40" }),
2613
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm text-white/50", children: "Loading runs..." })
2614
+ ] });
2615
+ }
2616
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-3", children: [
2617
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2618
+ "button",
2619
+ {
2620
+ onClick: onRun,
2621
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 transition-colors",
2622
+ children: [
2623
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Play, { className: "h-3.5 w-3.5" }),
2624
+ " Run Evals"
2625
+ ]
2626
+ }
2627
+ ) }),
2628
+ runs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
2629
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FlaskConical, { className: "mb-3 h-10 w-10 text-white/20" }),
2630
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium text-white/50", children: "No eval runs yet" }),
2631
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-1 text-xs text-white/40", children: "Start a run to evaluate your agent." })
2632
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "space-y-2", children: runs.map((run) => {
2633
+ const statusColor = run.status === "completed" ? "text-green-400" : run.status === "failed" ? "text-red-400" : run.status === "running" ? "text-yellow-400" : "text-white/50";
2634
+ const StatusIcon = run.status === "completed" ? CheckCircle2 : run.status === "failed" ? XCircle : run.status === "running" ? Loader2 : FlaskConical;
2635
+ const isExpanded = expandedRun === run.id;
2636
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
2637
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2638
+ "button",
2639
+ {
2640
+ onClick: () => handleExpand(run.id),
2641
+ className: "flex items-center justify-between w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-left hover:bg-white/[0.04] transition-colors",
2642
+ children: [
2643
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-3 min-w-0", children: [
2644
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatusIcon, { className: cn("h-4 w-4 shrink-0", statusColor, run.status === "running" && "animate-spin") }),
2645
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
2646
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-sm font-medium text-white", children: [
2647
+ run.status,
2648
+ " ",
2649
+ run.versionNumber != null && `(v${run.versionNumber})`
2650
+ ] }),
2651
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [
2652
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/30", children: formatTime(run.createdAt) }),
2653
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-xs text-white/30", children: [
2654
+ run.completedCases ?? 0,
2655
+ "/",
2656
+ run.totalCases ?? 0,
2657
+ " cases"
2658
+ ] })
2659
+ ] })
2660
+ ] })
2661
+ ] }),
2662
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronDown, { className: "h-4 w-4 text-white/30" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChevronRight, { className: "h-4 w-4 text-white/30" })
2663
+ ]
2664
+ }
2665
+ ),
2666
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ml-4 mt-1 mb-2 space-y-1", children: loadingResults ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2 py-4 justify-center", children: [
2667
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Loader2, { className: "h-3 w-3 animate-spin text-white/40" }),
2668
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-xs text-white/40", children: "Loading results..." })
2669
+ ] }) : results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-white/40 py-4 text-center", children: "No results yet." }) : results.map((r) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "rounded-lg border border-white/5 bg-black/20 px-3 py-2", children: [
2670
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between", children: [
2671
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: cn("text-xs font-medium", r.status === "completed" ? "text-green-400" : r.status === "error" ? "text-red-400" : "text-white/50"), children: r.status }),
2672
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
2673
+ r.topicScore != null && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-xs text-white/40", children: [
2674
+ "topic: ",
2675
+ (r.topicScore * 100).toFixed(0),
2676
+ "%"
2677
+ ] }),
2678
+ r.safetyScore != null && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-xs text-white/40", children: [
2679
+ "safety: ",
2680
+ (r.safetyScore * 100).toFixed(0),
2681
+ "%"
2682
+ ] }),
2683
+ r.humanScore != null && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "inline-flex items-center gap-0.5 text-xs text-yellow-400", children: [
2684
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Star, { className: "h-3 w-3" }),
2685
+ " ",
2686
+ r.humanScore
2687
+ ] }),
2688
+ r.latencyMs != null && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "text-xs text-white/30", children: [
2689
+ r.latencyMs,
2690
+ "ms"
2691
+ ] })
2692
+ ] })
2693
+ ] }),
2694
+ r.agentResponse && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-white/50 mt-1 line-clamp-2", children: r.agentResponse }),
2695
+ r.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-red-400/70 mt-1", children: r.error })
2696
+ ] }, r.id)) })
2697
+ ] }, run.id);
2698
+ }) })
2699
+ ] });
2700
+ }
2701
+ function AddCaseModal({
2702
+ client,
2703
+ agentName,
2704
+ onClose,
2705
+ onCreated
2706
+ }) {
2707
+ const [question, setQuestion] = (0, import_react17.useState)("");
2708
+ const [expectedTopics, setExpectedTopics] = (0, import_react17.useState)("");
2709
+ const [referenceAnswer, setReferenceAnswer] = (0, import_react17.useState)("");
2710
+ const [category, setCategory] = (0, import_react17.useState)("");
2711
+ const [creating, setCreating] = (0, import_react17.useState)(false);
2712
+ const [error, setError] = (0, import_react17.useState)(null);
2713
+ const handleCreate = async () => {
2714
+ if (!question.trim()) {
2715
+ setError("Question is required");
2716
+ return;
2717
+ }
2718
+ setCreating(true);
2719
+ setError(null);
2720
+ try {
2721
+ await client.createEvalCase(agentName, {
2722
+ question: question.trim(),
2723
+ expectedTopics: expectedTopics ? expectedTopics.split(",").map((t) => t.trim()).filter(Boolean) : void 0,
2724
+ referenceAnswer: referenceAnswer || void 0,
2725
+ category: category || void 0
2726
+ });
2727
+ onCreated();
2728
+ } catch (e) {
2729
+ setError(e instanceof Error ? e.message : "Failed to create case");
2730
+ } finally {
2731
+ setCreating(false);
2732
+ }
2733
+ };
2734
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "w-full max-w-lg max-h-[90vh] overflow-auto rounded-xl border border-white/10 bg-[#1c2129] p-6", children: [
2735
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between mb-6", children: [
2736
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { className: "text-lg font-semibold text-white", children: "Add Eval Case" }),
2737
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: onClose, className: "text-white/40 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(X, { className: "h-5 w-5" }) })
2738
+ ] }),
2739
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-4", children: [
2740
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1.5", children: [
2741
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Question *" }),
2742
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2743
+ "textarea",
2744
+ {
2745
+ value: question,
2746
+ onChange: (e) => setQuestion(e.target.value),
2747
+ rows: 3,
2748
+ placeholder: "What question should the agent answer?",
2749
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50 resize-none"
2750
+ }
2751
+ )
2752
+ ] }),
2753
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1.5", children: [
2754
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Expected Topics (comma-separated)" }),
2755
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2756
+ "input",
2757
+ {
2758
+ type: "text",
2759
+ value: expectedTopics,
2760
+ onChange: (e) => setExpectedTopics(e.target.value),
2761
+ placeholder: "e.g. pricing, features, support",
2762
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50"
2763
+ }
2764
+ )
2765
+ ] }),
2766
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1.5", children: [
2767
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Reference Answer (optional)" }),
2768
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2769
+ "textarea",
2770
+ {
2771
+ value: referenceAnswer,
2772
+ onChange: (e) => setReferenceAnswer(e.target.value),
2773
+ rows: 2,
2774
+ placeholder: "Ideal answer for comparison...",
2775
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50 resize-none"
2776
+ }
2777
+ )
2778
+ ] }),
2779
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1.5", children: [
2780
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Category (optional)" }),
2781
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2782
+ "input",
2783
+ {
2784
+ type: "text",
2785
+ value: category,
2786
+ onChange: (e) => setCategory(e.target.value),
2787
+ placeholder: "e.g. general, technical, safety",
2788
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50"
2789
+ }
2790
+ )
2791
+ ] }),
2792
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-red-400", children: error }),
2793
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [
2794
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: onClose, className: "px-3 py-1.5 text-sm text-white/70 hover:text-white hover:bg-white/10 rounded-lg transition-colors", children: "Cancel" }),
2795
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2796
+ "button",
2797
+ {
2798
+ onClick: handleCreate,
2799
+ disabled: creating,
2800
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 disabled:opacity-50 transition-colors",
2801
+ children: creating ? "Adding..." : "Add Case"
2802
+ }
2803
+ )
2804
+ ] })
2805
+ ] })
2806
+ ] }) });
2807
+ }
2808
+ function RunEvalModal({
2809
+ client,
2810
+ agentName,
2811
+ onClose,
2812
+ onStarted
2813
+ }) {
2814
+ const [versionNumber, setVersionNumber] = (0, import_react17.useState)("");
2815
+ const [starting, setStarting] = (0, import_react17.useState)(false);
2816
+ const [error, setError] = (0, import_react17.useState)(null);
2817
+ const handleStart = async () => {
2818
+ setStarting(true);
2819
+ setError(null);
2820
+ try {
2821
+ await client.startEvalRun(agentName, {
2822
+ versionNumber: versionNumber ? Number(versionNumber) : void 0
2823
+ });
2824
+ onStarted();
2825
+ } catch (e) {
2826
+ setError(e instanceof Error ? e.message : "Failed to start eval run");
2827
+ } finally {
2828
+ setStarting(false);
2829
+ }
2830
+ };
2831
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "w-full max-w-md rounded-xl border border-white/10 bg-[#1c2129] p-6", children: [
2832
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between mb-6", children: [
2833
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { className: "text-lg font-semibold text-white", children: "Run Evals" }),
2834
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: onClose, className: "text-white/40 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(X, { className: "h-5 w-5" }) })
2835
+ ] }),
2836
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-4", children: [
2837
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1.5", children: [
2838
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "block text-sm font-medium text-white/70", children: "Version Number (optional)" }),
2839
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2840
+ "input",
2841
+ {
2842
+ type: "number",
2843
+ value: versionNumber,
2844
+ onChange: (e) => setVersionNumber(e.target.value),
2845
+ placeholder: "Leave empty for active version",
2846
+ className: "flex w-full rounded-lg border px-3 py-2 text-sm bg-white/5 border-white/10 text-white placeholder:text-white/40 focus-visible:outline-none focus-visible:border-indigo-500/50"
2847
+ }
2848
+ )
2849
+ ] }),
2850
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-red-400", children: error }),
2851
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [
2852
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: onClose, className: "px-3 py-1.5 text-sm text-white/70 hover:text-white hover:bg-white/10 rounded-lg transition-colors", children: "Cancel" }),
2853
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2854
+ "button",
2855
+ {
2856
+ onClick: handleStart,
2857
+ disabled: starting,
2858
+ className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-lg bg-indigo-500 text-white hover:bg-indigo-400 disabled:opacity-50 transition-colors",
2859
+ children: starting ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
2860
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
2861
+ " Starting..."
2862
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
2863
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Play, { className: "h-3.5 w-3.5" }),
2864
+ " Start Run"
2865
+ ] })
2866
+ }
2867
+ )
2868
+ ] })
2869
+ ] })
2870
+ ] }) });
2871
+ }
1817
2872
  // Annotate the CommonJS export names for ESM import in node:
1818
2873
  0 && (module.exports = {
2874
+ AgentConfigEditor,
2875
+ AgentEvalRunner,
2876
+ AgentKnowledgeBase,
2877
+ AgentVersionManager,
1819
2878
  BottomPanels,
1820
2879
  Chat,
1821
2880
  ChatInput,