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