From c9fbb0375b414cf4090ce2b00da3867e4ee01cfa Mon Sep 17 00:00:00 2001 From: Harshith Mullapudi Date: Mon, 4 Aug 2025 12:26:26 +0530 Subject: [PATCH] Fix: clustering UI --- apps/init/package.json | 1 - apps/webapp/app/env.server.ts | 1 + apps/webapp/app/routes/api.v1.clusters.tsx | 76 ++++-- apps/webapp/app/routes/home.dashboard.tsx | 45 ++-- apps/webapp/app/routes/onboarding.tsx | 31 ++- .../app/services/authorization.server.ts | 2 +- apps/webapp/app/utils/startup.ts | 4 +- hosting/docker/core/docker-compose.yaml | 9 +- package.json | 2 +- pnpm-lock.yaml | 247 ------------------ 10 files changed, 112 insertions(+), 306 deletions(-) diff --git a/apps/init/package.json b/apps/init/package.json index 7477ad6..b7c2101 100644 --- a/apps/init/package.json +++ b/apps/init/package.json @@ -62,7 +62,6 @@ "clean": "rimraf dist .tshy .tshy-build .turbo", "typecheck": "tsc -p tsconfig.src.json --noEmit", "build": "tshy", - "dev": "tshy --watch", "test": "vitest", "test:e2e": "vitest --run -c ./e2e/vitest.config.ts" }, diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 42aad77..98ef69c 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -9,6 +9,7 @@ const EnvironmentSchema = z.object({ z.literal("production"), z.literal("test"), ]), + POSTGRES_DB: z.string(), DATABASE_URL: z .string() .refine( diff --git a/apps/webapp/app/routes/api.v1.clusters.tsx b/apps/webapp/app/routes/api.v1.clusters.tsx index 7061c2c..e55a37f 100644 --- a/apps/webapp/app/routes/api.v1.clusters.tsx +++ b/apps/webapp/app/routes/api.v1.clusters.tsx @@ -1,17 +1,22 @@ -import { json, type ActionFunctionArgs, type LoaderFunctionArgs } from "@remix-run/node"; +import { json } from "@remix-run/node"; import { z } from "zod"; import { logger } from "~/services/logger.service"; -import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; +import { + createActionApiRoute, + createLoaderApiRoute, +} from "~/services/routeBuilders/apiBuilder.server"; import { ClusteringService } from "~/services/clustering.server"; const clusteringService = new ClusteringService(); - -const { action, loader } = createActionApiRoute( +const { action } = createActionApiRoute( { body: z.object({ - mode: z.enum(['auto', 'incremental', 'complete']).optional().default('auto'), - forceComplete: z.boolean().optional().default(false) + mode: z + .enum(["auto", "incremental", "complete"]) + .optional() + .default("auto"), + forceComplete: z.boolean().optional().default(false), }), allowJWT: true, authorization: { @@ -20,52 +25,73 @@ const { action, loader } = createActionApiRoute( corsStrategy: "all", }, async ({ body, authentication, request }) => { + console.log(request.method, "asd"); try { - if (request.method === "POST") { let result; switch (body.mode) { - case 'incremental': - result = await clusteringService.performIncrementalClustering(authentication.userId); + case "incremental": + result = await clusteringService.performIncrementalClustering( + authentication.userId, + ); break; - case 'complete': - result = await clusteringService.performCompleteClustering(authentication.userId); + case "complete": + result = await clusteringService.performCompleteClustering( + authentication.userId, + ); break; - case 'auto': + case "auto": default: - result = await clusteringService.performClustering(authentication.userId, body.forceComplete); + result = await clusteringService.performClustering( + authentication.userId, + body.forceComplete, + ); break; } - + return json({ success: true, - data: result + data: result, }); } else if (request.method === "GET") { - const clusters = await clusteringService.getClusters(authentication.userId); + const clusters = await clusteringService.getClusters( + authentication.userId, + ); return json({ success: true, - data: clusters + data: clusters, }); } - + return json( { success: false, error: "Method not allowed" }, - { status: 405 } + { status: 405 }, ); - } catch (error) { logger.error("Error in clustering action:", { error }); return json( - { - success: false, - error: error instanceof Error ? error.message : "Unknown error" + { + success: false, + error: error instanceof Error ? error.message : "Unknown error", }, - { status: 500 } + { status: 500 }, ); } }, ); -export { action, loader }; +const loader = createLoaderApiRoute( + { + allowJWT: true, + findResource: async () => 1, + }, + async ({ authentication }) => { + const clusters = await clusteringService.getClusters(authentication.userId); + return json({ + success: true, + data: clusters, + }); + }, +); +export { action, loader }; diff --git a/apps/webapp/app/routes/home.dashboard.tsx b/apps/webapp/app/routes/home.dashboard.tsx index c079ff6..648af22 100644 --- a/apps/webapp/app/routes/home.dashboard.tsx +++ b/apps/webapp/app/routes/home.dashboard.tsx @@ -18,36 +18,31 @@ export default function Dashboard() { // State for nodeLinks and loading const [nodeLinks, setNodeLinks] = useState(null); - const [loading, setLoading] = useState(true); + const [loading, setLoading] = useState(false); useEffect(() => { - let cancelled = false; - async function fetchNodeLinks() { - setLoading(true); - try { - const res = await fetch( - "/node-links?userId=" + - encodeURIComponent("cmc0x85jv0000nu1wiu1yla73"), - ); - if (!res.ok) throw new Error("Failed to fetch node links"); - const data = await res.json(); - if (!cancelled) { - setNodeLinks(data); - setLoading(false); - } - } catch (e) { - if (!cancelled) { - setNodeLinks([]); - setLoading(false); - } - } + if (!loading && userId) { + fetchNodeLinks(); } - fetchNodeLinks(); - return () => { - cancelled = true; - }; }, [userId]); + const fetchNodeLinks = async () => { + setLoading(true); + try { + const res = await fetch( + "/node-links?userId=" + encodeURIComponent(userId), + ); + if (!res.ok) throw new Error("Failed to fetch node links"); + const data = await res.json(); + + setNodeLinks(data); + setLoading(false); + } catch (e) { + setNodeLinks([]); + setLoading(false); + } + }; + return ( <> diff --git a/apps/webapp/app/routes/onboarding.tsx b/apps/webapp/app/routes/onboarding.tsx index ab92979..339d480 100644 --- a/apps/webapp/app/routes/onboarding.tsx +++ b/apps/webapp/app/routes/onboarding.tsx @@ -25,6 +25,7 @@ import { requireUserId } from "~/services/session.server"; import { updateUser } from "~/models/user.server"; import { Copy, Check } from "lucide-react"; import { addToQueue } from "~/lib/ingest.server"; +import { cn } from "~/lib/utils"; const ONBOARDING_STEP_COOKIE = "onboardingStep"; const onboardingStepCookie = createCookie(ONBOARDING_STEP_COOKIE, { @@ -108,6 +109,9 @@ export default function Onboarding() { const navigate = useNavigate(); const [copied, setCopied] = useState(false); + const [selectedSource, setSelectedSource] = useState< + "Claude" | "Cursor" | "Other" + >("Claude"); const [form, fields] = useForm({ lastSubmission: lastSubmission as any, @@ -117,7 +121,12 @@ export default function Onboarding() { }, }); - const memoryUrl = "https://core.heysol.ai/api/v1/mcp/memory"; + const getMemoryUrl = (source: "Claude" | "Cursor" | "Other") => { + const baseUrl = "https://core.heysol.ai/api/v1/mcp/memory"; + return `${baseUrl}?Source=${source}`; + }; + + const memoryUrl = getMemoryUrl(selectedSource); const copyToClipboard = async () => { try { @@ -144,7 +153,25 @@ export default function Onboarding() {
-
+
+
+ {(["Claude", "Cursor", "Other"] as const).map((source) => ( + + ))} +
+