diff --git a/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js b/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js index 88f5e81f..a7183741 100644 --- a/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js +++ b/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js @@ -4,17 +4,13 @@ import { useState, useEffect, useRef, useCallback } from "react"; import PropTypes from "prop-types"; import { Card, Button, Input, Modal, CardSkeleton, Toggle, ConfirmModal } from "@/shared/components"; import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard"; -import { getCurrentLocale, onLocaleChange } from "@/i18n/runtime"; import { - WENYAN_LOCALES, TUNNEL_BENEFITS, TUNNEL_PING_INTERVAL_MS, TUNNEL_PING_MAX_MS, STATUS_POLL_FAST_MS, REACHABLE_MISS_THRESHOLD, CLIENT_PING_FAST_MS, - CAVEMAN_LEVELS, - PONYTAIL_LEVELS, } from "./endpointConstants"; import { clientPingUrl, clientPingAny } from "./endpointPing"; import EndpointRow from "./components/EndpointRow"; @@ -32,22 +28,9 @@ export default function APIPageClient({ machineId }) { const [requireApiKey, setRequireApiKey] = useState(false); const [requireLogin, setRequireLogin] = useState(true); const [hasPassword, setHasPassword] = useState(true); - const [tunnelDashboardAccess, setTunnelDashboardAccess] = useState(false); - const [rtkEnabled, setRtkEnabledState] = useState(true); - const [headroomEnabled, setHeadroomEnabled] = useState(false); - const [headroomUrl, setHeadroomUrl] = useState("http://localhost:8787"); - const [headroomCompressUserMessages, setHeadroomCompressUserMessages] = useState(false); - const [headroomStatus, setHeadroomStatus] = useState({ installed: false, running: false, python: null, loading: true }); - const [showHeadroomInstallModal, setShowHeadroomInstallModal] = useState(false); - const [headroomActionLoading, setHeadroomActionLoading] = useState(false); - const [headroomActionError, setHeadroomActionError] = useState(""); - const [cavemanEnabled, setCavemanEnabled] = useState(false); - const [cavemanLevel, setCavemanLevel] = useState("full"); - const [ponytailEnabled, setPonytailEnabled] = useState(false); - const [ponytailLevel, setPonytailLevel] = useState("full"); - const [locale, setLocale] = useState("en"); + const [tunnelDashboardAccess, setTunnelDashboardAccess] = useState(false); - // Cloudflare Tunnel state + // Cloudflare Tunnel state const [tunnelChecking, setTunnelChecking] = useState(true); const [tunnelEnabled, setTunnelEnabled] = useState(false); const [tunnelReachable, setTunnelReachable] = useState(false); @@ -101,26 +84,6 @@ export default function APIPageClient({ machineId }) { setIsRemoteHost(!["localhost", "127.0.0.1", "::1"].includes(window.location.hostname)); }, []); - // Track app UI locale to gate wenyan caveman levels - useEffect(() => { - setLocale(getCurrentLocale()); - return onLocaleChange(() => setLocale(getCurrentLocale())); - }, []); - - const isWenyanLocale = WENYAN_LOCALES.includes(locale); - const visibleCavemanLevels = isWenyanLocale - ? CAVEMAN_LEVELS - : CAVEMAN_LEVELS.filter((lvl) => !lvl.wenyan); - - // Reset wenyan level to "ultra" when leaving a Chinese locale - useEffect(() => { - const current = CAVEMAN_LEVELS.find((lvl) => lvl.id === cavemanLevel); - if (current?.wenyan && !isWenyanLocale) { - setCavemanLevel("ultra"); - patchSetting({ cavemanLevel: "ultra" }); - } - }, [isWenyanLocale, cavemanLevel]); - const { copied, copy } = useCopyToClipboard(); // Security gate: block remote exposure while dashboard uses default password or login is off. @@ -241,15 +204,6 @@ export default function APIPageClient({ machineId }) { setRequireLogin(data.requireLogin !== false); setHasPassword(data.hasPassword || false); setTunnelDashboardAccess(data.tunnelDashboardAccess || false); - setRtkEnabledState(data.rtkEnabled !== false); - setHeadroomEnabled(!!data.headroomEnabled); - setHeadroomUrl(data.headroomUrl || "http://localhost:8787"); - setHeadroomCompressUserMessages(!!data.headroomCompressUserMessages); - refreshHeadroomStatus(); - setCavemanEnabled(!!data.cavemanEnabled); - setCavemanLevel(data.cavemanLevel || "full"); - setPonytailEnabled(!!data.ponytailEnabled); - setPonytailLevel(data.ponytailLevel || "full"); } if (statusRes.ok) { const data = await statusRes.json(); @@ -299,106 +253,6 @@ export default function APIPageClient({ machineId }) { } }; - const handleRtkEnabled = async (value) => { - try { - const res = await fetch("/api/settings", { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ rtkEnabled: value }), - }); - if (res.ok) setRtkEnabledState(value); - } catch (error) { - console.log("Error updating rtkEnabled:", error); - } - }; - - const patchSetting = async (patch) => { - try { - await fetch("/api/settings", { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(patch), - }); - } catch (error) { - console.log("Error updating setting:", error); - } - }; - - const handleCavemanEnabled = (value) => { - setCavemanEnabled(value); - patchSetting({ cavemanEnabled: value }); - }; - - const handleHeadroomEnabled = (value) => { - const nextUrl = headroomUrl.trim() || "http://localhost:8787"; - setHeadroomUrl(nextUrl); - setHeadroomEnabled(value); - patchSetting({ headroomEnabled: value, headroomUrl: nextUrl }); - }; - - const handleHeadroomUrlBlur = async () => { - const next = headroomUrl.trim() || "http://localhost:8787"; - setHeadroomUrl(next); - await patchSetting({ headroomUrl: next }); - refreshHeadroomStatus(); - }; - - const handleHeadroomCompressUserMessages = (value) => { - setHeadroomCompressUserMessages(value); - patchSetting({ headroomCompressUserMessages: value }); - }; - - const refreshHeadroomStatus = useCallback(async () => { - setHeadroomStatus((s) => ({ ...s, loading: true })); - try { - const res = await fetch("/api/headroom/status", { headers: { "Cache-Control": "no-store" } }); - const data = await res.json(); - setHeadroomStatus({ ...data, loading: false }); - } catch { - setHeadroomStatus({ installed: false, running: false, python: null, loading: false }); - } - }, []); - - const handleHeadroomStart = useCallback(async () => { - setHeadroomActionError(""); - setHeadroomActionLoading(true); - try { - const res = await fetch("/api/headroom/start", { method: "POST" }); - const data = await res.json().catch(() => ({})); - if (!res.ok) throw new Error(data.error || "Failed to start proxy"); - await refreshHeadroomStatus(); - } catch (e) { - setHeadroomActionError(e.message); - } finally { - setHeadroomActionLoading(false); - } - }, [refreshHeadroomStatus]); - - const handleHeadroomStop = useCallback(async () => { - setHeadroomActionLoading(true); - try { - await fetch("/api/headroom/stop", { method: "POST" }); - await refreshHeadroomStatus(); - } finally { - setHeadroomActionLoading(false); - } - }, [refreshHeadroomStatus]); - - const handleCavemanLevel = (level) => { - setCavemanLevel(level); - patchSetting({ cavemanLevel: level }); - }; - - const handlePonytailEnabled = (value) => { - setPonytailEnabled(value); - patchSetting({ ponytailEnabled: value }); - }; - - const handlePonytailLevel = (level) => { - setPonytailLevel(level); - patchSetting({ ponytailLevel: level }); - }; - const fetchData = async () => { try { const keysRes = await fetch("/api/keys"); @@ -846,19 +700,6 @@ export default function APIPageClient({ machineId }) { } const currentEndpoint = baseUrl; - const headroomRunning = !!headroomStatus.running; - const headroomLocalUrl = headroomStatus.localUrl !== false; - const headroomCanStart = !!headroomStatus.canStart; - const headroomManaged = headroomLocalUrl && !!headroomStatus.managedPid; - const headroomStatusLabel = headroomStatus.loading - ? "Checking…" - : headroomRunning - ? "Running" - : headroomLocalUrl && !headroomStatus.installed - ? "Not installed" - : headroomLocalUrl - ? "Proxy off" - : "Unreachable"; return (
@@ -1220,167 +1061,6 @@ export default function APIPageClient({ machineId }) { )} - {/* Token Saver (RTK + Caveman) */} - -
-

- bolt - Token Saver -

-
-
-
-

- Compress tool output{" "} - - (RTK) - -

-

- git/grep/ls/tree/logs → 60-90% fewer input tokens -

-
- handleRtkEnabled(!rtkEnabled)} - /> -
-
-
-
-

- Compress context{" "} - - (Headroom) - -

- - {headroomStatusLabel} - - -
-

- Compress prompts via /v1/compress before routing to the model -

-
- handleHeadroomEnabled(!headroomEnabled)} - /> -
-
-
-

- Compress LLM output{" "} - - (Caveman) - -

-

- Terse-style system prompt → ~65% fewer output tokens (up to 87%) -

-
-
- {cavemanEnabled && ( -
-
- {visibleCavemanLevels.map((lvl) => ( - - ))} -
-

- {CAVEMAN_LEVELS.find((lvl) => lvl.id === cavemanLevel)?.desc} -

-
- )} - handleCavemanEnabled(!cavemanEnabled)} - /> -
-
-
-
-

- Lazy senior dev{" "} - - (Ponytail) - -

-

- Bias the model toward minimal code: YAGNI, reuse stdlib, deletion over addition -

-
-
- {ponytailEnabled && ( -
-
- {PONYTAIL_LEVELS.map((lvl) => ( - - ))} -
-

- {PONYTAIL_LEVELS.find((lvl) => lvl.id === ponytailLevel)?.desc} -

-
- )} - handlePonytailEnabled(!ponytailEnabled)} - /> -
-
-
- {/* Add Key Modal */} - {/* Headroom Install Guide Modal */} - setShowHeadroomInstallModal(false)} - > -
-
- Status - - {headroomStatusLabel} - -
-
-

Proxy URL

- setHeadroomUrl(e.target.value)} - onBlur={handleHeadroomUrlBlur} - placeholder="http://localhost:8787" - className="font-mono text-sm" - /> -

- Use a local proxy for Start/Stop, or an external Docker sidecar like http://headroom:8787. -

-
- {headroomManaged ? ( - - ) : headroomRunning ? ( -

Headroom proxy is reachable. You can enable the token saver.

- ) : headroomCanStart ? ( - - ) : !headroomLocalUrl ? ( -

Start Headroom separately at the configured URL, then recheck.

- ) : !headroomStatus.python ? ( -

Python ≥ 3.10 required for local managed mode. Install Python first, or use an external proxy URL.

- ) : ( -
-

Install then click Start:

-
-
{`pip install "headroom-ai[proxy]"`}
- -
-
- )} - {headroomActionError && ( -

{headroomActionError}

- )} -
- - -
-
-
- {/* Confirm Modal */} { + setLocale(getCurrentLocale()); + return onLocaleChange(() => setLocale(getCurrentLocale())); + }, []); + + const isWenyanLocale = WENYAN_LOCALES.includes(locale); + const visibleCavemanLevels = isWenyanLocale + ? CAVEMAN_LEVELS + : CAVEMAN_LEVELS.filter((lvl) => !lvl.wenyan); + + useEffect(() => { + const current = CAVEMAN_LEVELS.find((lvl) => lvl.id === cavemanLevel); + if (current?.wenyan && !isWenyanLocale) { + setCavemanLevel("ultra"); + patchSetting({ cavemanLevel: "ultra" }); + } + }, [isWenyanLocale, cavemanLevel]); + + const patchSetting = async (patch) => { + try { + await fetch("/api/settings", { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(patch), + }); + } catch (error) { + console.log("Error updating setting:", error); + } + }; + + const handleRtkEnabled = async (value) => { + try { + const res = await fetch("/api/settings", { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ rtkEnabled: value }), + }); + if (res.ok) setRtkEnabledState(value); + } catch (error) { + console.log("Error updating rtkEnabled:", error); + } + }; + + const handleCavemanEnabled = (value) => { + setCavemanEnabled(value); + patchSetting({ cavemanEnabled: value }); + }; + + const handleHeadroomEnabled = (value) => { + const nextUrl = headroomUrl.trim() || "http://localhost:8787"; + setHeadroomUrl(nextUrl); + setHeadroomEnabled(value); + patchSetting({ headroomEnabled: value, headroomUrl: nextUrl }); + }; + + const handleHeadroomUrlBlur = async () => { + const next = headroomUrl.trim() || "http://localhost:8787"; + setHeadroomUrl(next); + await patchSetting({ headroomUrl: next }); + refreshHeadroomStatus(); + }; + + const refreshHeadroomStatus = useCallback(async () => { + setHeadroomStatus((s) => ({ ...s, loading: true })); + try { + const res = await fetch("/api/headroom/status", { + headers: { "Cache-Control": "no-store" }, + }); + const data = await res.json(); + setHeadroomStatus({ ...data, loading: false }); + } catch { + setHeadroomStatus({ + installed: false, + running: false, + python: null, + loading: false, + }); + } + }, []); + + const handleHeadroomStart = useCallback(async () => { + setHeadroomActionError(""); + setHeadroomActionLoading(true); + try { + const res = await fetch("/api/headroom/start", { method: "POST" }); + const data = await res.json().catch(() => ({})); + if (!res.ok) throw new Error(data.error || "Failed to start proxy"); + await refreshHeadroomStatus(); + } catch (e) { + setHeadroomActionError(e.message); + } finally { + setHeadroomActionLoading(false); + } + }, [refreshHeadroomStatus]); + + const handleHeadroomStop = useCallback(async () => { + setHeadroomActionLoading(true); + try { + await fetch("/api/headroom/stop", { method: "POST" }); + await refreshHeadroomStatus(); + } finally { + setHeadroomActionLoading(false); + } + }, [refreshHeadroomStatus]); + + const handleCavemanLevel = (level) => { + setCavemanLevel(level); + patchSetting({ cavemanLevel: level }); + }; + + const handlePonytailEnabled = (value) => { + setPonytailEnabled(value); + patchSetting({ ponytailEnabled: value }); + }; + + const handlePonytailLevel = (level) => { + setPonytailLevel(level); + patchSetting({ ponytailLevel: level }); + }; + + useEffect(() => { + const loadSettings = async () => { + try { + const res = await fetch("/api/settings"); + if (res.ok) { + const data = await res.json(); + setRtkEnabledState(data.rtkEnabled !== false); + setHeadroomEnabled(!!data.headroomEnabled); + setHeadroomUrl(data.headroomUrl || "http://localhost:8787"); + setCavemanEnabled(!!data.cavemanEnabled); + setCavemanLevel(data.cavemanLevel || "full"); + setPonytailEnabled(!!data.ponytailEnabled); + setPonytailLevel(data.ponytailLevel || "full"); + refreshHeadroomStatus(); + } + } catch {} + }; + loadSettings(); + }, [refreshHeadroomStatus]); + + const headroomRunning = !!headroomStatus.running; + const headroomStatusLabel = headroomStatus.loading + ? "Checking…" + : headroomRunning + ? "Running" + : headroomStatus.localUrl !== false && !headroomStatus.installed + ? "Not installed" + : headroomStatus.localUrl !== false + ? "Stopped" + : "External"; + const headroomLocalUrl = headroomStatus.localUrl !== false; + const headroomCanStart = !!headroomStatus.canStart; + const headroomManaged = + headroomLocalUrl && !!headroomStatus.managedPid; + + return ( +
+ +
+

+ + bolt + + Token Saver +

+
+
+
+

+ Compress tool output{" "} + + (RTK) + +

+

+ git/grep/ls/tree/logs → 60-90% fewer input tokens +

+
+ handleRtkEnabled(!rtkEnabled)} + /> +
+
+
+
+

+ Compress context{" "} + + (Headroom) + +

+ + {headroomStatusLabel} + + +
+

+ Compress prompts via /v1/compress before routing to the model +

+
+ handleHeadroomEnabled(!headroomEnabled)} + /> +
+
+
+

+ Compress LLM output{" "} + + (Caveman) + +

+

+ Terse-style system prompt → ~65% fewer output tokens (up to 87%) +

+
+
+ {cavemanEnabled && ( +
+
+ {visibleCavemanLevels.map((lvl) => ( + + ))} +
+

+ { + CAVEMAN_LEVELS.find((lvl) => lvl.id === cavemanLevel) + ?.desc + } +

+
+ )} + handleCavemanEnabled(!cavemanEnabled)} + /> +
+
+
+
+

+ Lazy senior dev{" "} + + (Ponytail) + +

+

+ Bias the model toward minimal code: YAGNI, reuse stdlib, + deletion over addition +

+
+
+ {ponytailEnabled && ( +
+
+ {PONYTAIL_LEVELS.map((lvl) => ( + + ))} +
+

+ { + PONYTAIL_LEVELS.find((lvl) => lvl.id === ponytailLevel) + ?.desc + } +

+
+ )} + handlePonytailEnabled(!ponytailEnabled)} + /> +
+
+
+ + setShowHeadroomInstallModal(false)} + > +
+
+ Status + + {headroomStatusLabel} + +
+
+

Proxy URL

+ setHeadroomUrl(e.target.value)} + onBlur={handleHeadroomUrlBlur} + placeholder="http://localhost:8787" + className="font-mono text-sm" + /> +

+ Use a local proxy for Start/Stop, or an external Docker sidecar + like http://headroom:8787. +

+
+ {headroomManaged ? ( + + ) : headroomRunning ? ( +

+ Headroom proxy is reachable. You can enable the token saver. +

+ ) : headroomCanStart ? ( + + ) : !headroomLocalUrl ? ( +

+ Start Headroom separately at the configured URL, then recheck. +

+ ) : !headroomStatus.python ? ( +

+ Python ≥ 3.10 required for local managed mode. Install Python + first, or use an external proxy URL. +

+ ) : ( +
+

Install then click Start:

+
+
+                  {`pip install "headroom-ai[proxy]"`}
+                
+ +
+
+ )} + {headroomActionError && ( +

{headroomActionError}

+ )} +
+ + +
+
+
+
+ ); +} diff --git a/src/app/(dashboard)/dashboard/token-saver/page.js b/src/app/(dashboard)/dashboard/token-saver/page.js new file mode 100644 index 00000000..765b51f9 --- /dev/null +++ b/src/app/(dashboard)/dashboard/token-saver/page.js @@ -0,0 +1,5 @@ +import TokenSaverClient from "./TokenSaverClient"; + +export default function TokenSaverPage() { + return ; +} diff --git a/src/shared/components/Header.js b/src/shared/components/Header.js index f8427aa2..ad3c0a03 100644 --- a/src/shared/components/Header.js +++ b/src/shared/components/Header.js @@ -112,6 +112,13 @@ const getPageInfo = (pathname) => { icon: "security", breadcrumbs: [], }; + if (pathname.includes("/token-saver")) + return { + title: "Token Saver", + description: "Compress prompts and outputs to save tokens", + icon: "savings", + breadcrumbs: [], + }; if (pathname.includes("/cli-tools")) return { title: "CLI Tools", diff --git a/src/shared/components/Sidebar.js b/src/shared/components/Sidebar.js index 7d2c43a7..2c1206df 100644 --- a/src/shared/components/Sidebar.js +++ b/src/shared/components/Sidebar.js @@ -24,7 +24,7 @@ const navItems = [ { href: "/dashboard/combos", label: "Combos", icon: "layers" }, { href: "/dashboard/usage", label: "Usage", icon: "bar_chart" }, { href: "/dashboard/quota", label: "Quota Tracker", icon: "data_usage" }, - { href: "/dashboard/mitm", label: "MITM", icon: "security" }, + { href: "/dashboard/token-saver", label: "Token Saver", icon: "savings" }, { href: "/dashboard/cli-tools", label: "CLI Tools", icon: "terminal" }, ];