"use client"; import { useEffect, useMemo, useState } from "react"; import { useTranslations } from "next-intl"; import { SegmentedControl, Collapsible } from "@/shared/components"; import RtkLearnDiscoverCard from "./RtkLearnDiscoverCard"; type RtkFilter = { id: string; name: string; description: string; commandTypes: string[]; category: string; priority: number; }; type RtkConfig = { enabled: boolean; intensity: "minimal" | "standard" | "aggressive"; applyToToolResults: boolean; applyToAssistantMessages: boolean; applyToCodeBlocks: boolean; enabledFilters: string[]; disabledFilters: string[]; maxLinesPerResult: number; maxCharsPerResult: number; deduplicateThreshold: number; customFiltersEnabled: boolean; trustProjectFilters: boolean; rawOutputRetention: "never" | "failures" | "always"; rawOutputMaxBytes: number; }; type AnalyticsSummary = { totalRequests: number; totalTokensSaved: number; avgSavingsPct: number; byEngine?: Record; }; type PreviewResult = { text?: string; compressed?: boolean; originalTokens?: number; compressedTokens?: number; techniquesUsed?: string[]; detection?: { type: string; confidence: number; category: string }; error?: string; }; const SAMPLE_OUTPUT = `$ npm run typecheck src/lib/example.ts:10:15 - error TS2322: Type 'string' is not assignable to type 'number'. 10 const value: number = "bad"; ~~~~~ Found 1 error in src/lib/example.ts:10`; function formatNumber(value: number | undefined): string { return new Intl.NumberFormat().format(value ?? 0); } export default function RtkContextPageClient() { const t = useTranslations("contextRtk"); const [filters, setFilters] = useState([]); const [config, setConfig] = useState(null); const [analytics, setAnalytics] = useState(null); const [sample, setSample] = useState(SAMPLE_OUTPUT); const [preview, setPreview] = useState(null); const [saving, setSaving] = useState(false); const [viewMode, setViewMode] = useState<"simple" | "advanced">("simple"); const [masterEnabled, setMasterEnabled] = useState(null); useEffect(() => { fetch("/api/settings/compression") .then((res) => (res.ok ? res.json() : null)) .then((data) => setMasterEnabled(data?.enabled ?? false)) .catch(() => {}); }, []); useEffect(() => { fetch("/api/context/rtk/filters") .then((res) => (res.ok ? res.json() : null)) .then((data) => setFilters(Array.isArray(data?.filters) ? data.filters : [])) .catch(() => {}); fetch("/api/context/rtk/config") .then((res) => (res.ok ? res.json() : null)) .then((data) => setConfig(data)) .catch(() => {}); fetch("/api/context/analytics?since=7d") .then((res) => (res.ok ? res.json() : null)) .then((data) => setAnalytics(data)) .catch(() => {}); }, []); const groupedFilters = useMemo(() => { return filters.reduce>((groups, filter) => { groups[filter.category] = [...(groups[filter.category] ?? []), filter]; return groups; }, {}); }, [filters]); const activeFilterCount = useMemo(() => { if (!config) return 0; if (config.enabledFilters.length > 0) return config.enabledFilters.length; return filters.filter((filter) => !config.disabledFilters.includes(filter.id)).length; }, [config, filters]); const saveConfig = async (patch: Partial) => { if (!config) return; const nextConfig = { ...config, ...patch }; setConfig(nextConfig); setSaving(true); try { const res = await fetch("/api/context/rtk/config", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(patch), }); if (res.ok) setConfig(await res.json()); } finally { setSaving(false); } }; const toggleFilter = (filterId: string, enabled: boolean) => { if (!config) return; const disabledFilters = enabled ? config.disabledFilters.filter((id) => id !== filterId) : [...new Set([...config.disabledFilters, filterId])]; saveConfig({ disabledFilters }); }; const runPreview = async () => { const res = await fetch("/api/context/rtk/test", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: sample, config: config ?? undefined }), }); setPreview(res.ok ? await res.json() : { error: await res.text() }); }; const rtkStats = analytics?.byEngine?.rtk; const statCards = [ [t("tokensFiltered"), formatNumber(rtkStats?.tokensSaved ?? analytics?.totalTokensSaved)], [t("filtersActive"), formatNumber(activeFilterCount)], [t("requests"), formatNumber(rtkStats?.count ?? analytics?.totalRequests)], [t("avgSavings"), `${rtkStats?.avgSavingsPct ?? analytics?.avgSavingsPct ?? 0}%`], ]; return (
filter_alt

{t("title")}

{t("description")}

setViewMode(v as "simple" | "advanced")} options={[ { value: "simple", label: t("simpleMode") || "Simple" }, { value: "advanced", label: t("advancedMode") || "Advanced" }, ]} />
{statCards.map(([label, value]) => (

{label}

{value}

))}
{masterEnabled === false && (
info

{t("masterSwitchOffAlert")}

)} {config && (
{/* On/off + intensity now live in the panel (/dashboard/context/settings). This page edits RTK's detailed configuration only. */}
{[ ["applyToToolResults", t("toolResults")], ["applyToAssistantMessages", t("assistantMessages")], ["applyToCodeBlocks", t("codeBlocks")], ["customFiltersEnabled", t("customFilters")], ["trustProjectFilters", t("trustProjectFilters")], ].map(([key, label]) => ( ))}
)} {viewMode === "advanced" && (

{t("filterTesting")}