diff --git a/apps/webapp/app/components/logo/core.svg b/apps/webapp/app/components/logo/core.svg index eff361b..6242699 100644 --- a/apps/webapp/app/components/logo/core.svg +++ b/apps/webapp/app/components/logo/core.svg @@ -1,42 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/webapp/app/components/logo/logo.tsx b/apps/webapp/app/components/logo/logo.tsx index f94779d..ecf4dd6 100644 --- a/apps/webapp/app/components/logo/logo.tsx +++ b/apps/webapp/app/components/logo/logo.tsx @@ -9,50 +9,6 @@ export interface LogoProps { export default function StaticLogo({ width, height }: LogoProps) { const [theme] = useTheme(); - if (theme === Theme.DARK) { - return ( - - - - - - - - - - - - - ); - } - return ( - - - - - - - - + + + + - + + + + - - - - + + + + diff --git a/apps/webapp/app/components/logs/log-text-collapse.tsx b/apps/webapp/app/components/logs/log-text-collapse.tsx index 7d7cd7f..3880799 100644 --- a/apps/webapp/app/components/logs/log-text-collapse.tsx +++ b/apps/webapp/app/components/logs/log-text-collapse.tsx @@ -99,9 +99,8 @@ export function LogTextCollapse({

- {text} -

+ dangerouslySetInnerHTML={{ __html: text }} + /> diff --git a/apps/webapp/app/routes/api.v1.add.tsx b/apps/webapp/app/routes/api.v1.add.tsx index a86e739..3c27617 100644 --- a/apps/webapp/app/routes/api.v1.add.tsx +++ b/apps/webapp/app/routes/api.v1.add.tsx @@ -1,7 +1,8 @@ import { json } from "@remix-run/node"; import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; -import { addToQueue, IngestBodyRequest } from "~/lib/ingest.server"; +import { addToQueue } from "~/lib/ingest.server"; +import { IngestBodyRequest } from "~/trigger/ingest/ingest"; const { action, loader } = createActionApiRoute( { diff --git a/apps/webapp/app/routes/ingest.tsx b/apps/webapp/app/routes/ingest.tsx deleted file mode 100644 index 80270a5..0000000 --- a/apps/webapp/app/routes/ingest.tsx +++ /dev/null @@ -1,24 +0,0 @@ -// DEPRECATED: This route is deprecated. Please use /api/v1/add instead. -// The API logic has been moved to /api/v1/add. This file is retained for reference only. - -import { json } from "@remix-run/node"; - -import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; -import { addToQueue, IngestBodyRequest } from "~/lib/ingest.server"; - -const { action, loader } = createActionApiRoute( - { - body: IngestBodyRequest, - allowJWT: true, - authorization: { - action: "ingest", - }, - corsStrategy: "all", - }, - async ({ body, authentication }) => { - const response = addToQueue(body, authentication.userId); - return json({ ...response }); - }, -); - -export { action, loader }; diff --git a/apps/webapp/app/routes/reingest.tsx b/apps/webapp/app/routes/reingest.tsx deleted file mode 100644 index a24c841..0000000 --- a/apps/webapp/app/routes/reingest.tsx +++ /dev/null @@ -1,213 +0,0 @@ -// import { json } from "@remix-run/node"; -// import { z } from "zod"; -// import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; -// import { getUserQueue, type IngestBodyRequest } from "~/lib/ingest.server"; -// import { prisma } from "~/db.server"; -// import { logger } from "~/services/logger.service"; -// import { IngestionStatus, type Prisma } from "@core/database"; - -// const ReingestionBodyRequest = z.object({ -// userId: z.string().optional(), -// spaceId: z.string().optional(), -// dryRun: z.boolean().optional().default(false), -// }); - -// type ReingestionRequest = z.infer; - -// async function getCompletedIngestionsByUser(userId?: string, spaceId?: string) { -// const whereClause: Prisma.IngestionQueueWhereInput = { -// status: IngestionStatus.COMPLETED, -// }; - -// if (userId) { -// whereClause.workspace = { -// userId: userId, -// }; -// } - -// if (spaceId) { -// whereClause.spaceId = spaceId; -// } - -// const ingestions = await prisma.ingestionQueue.findMany({ -// where: whereClause, -// include: { -// workspace: { -// include: { -// user: true, -// }, -// }, -// }, -// orderBy: [ -// { createdAt: 'asc' }, // Maintain temporal order -// ], -// }); - -// return ingestions; -// } - -// async function getAllUsers() { -// const users = await prisma.user.findMany({ -// include: { -// Workspace: true, -// }, -// }); -// return users.filter(user => user.Workspace); // Only users with workspaces -// } - -// async function reingestionForUser(userId: string, spaceId?: string, dryRun = false) { -// const ingestions = await getCompletedIngestionsByUser(userId, spaceId); - -// logger.info(`Found ${ingestions.length} completed ingestions for user ${userId}${spaceId ? ` in space ${spaceId}` : ''}`); - -// if (dryRun) { -// return { -// userId, -// ingestionCount: ingestions.length, -// ingestions: ingestions.map(ing => ({ -// id: ing.id, -// createdAt: ing.createdAt, -// spaceId: ing.spaceId, -// data: { -// episodeBody: (ing.data as any)?.episodeBody?.substring(0, 100) + -// ((ing.data as any)?.episodeBody?.length > 100 ? '...' : ''), -// source: (ing.data as any)?.source, -// referenceTime: (ing.data as any)?.referenceTime, -// }, -// })), -// }; -// } - -// // Queue ingestions in temporal order (already sorted by createdAt ASC) -// const queuedJobs = []; -// const ingestionQueue = getUserQueue(userId); -// for (const ingestion of ingestions) { -// try { -// // Parse the original data and add reingestion metadata -// const originalData = ingestion.data as z.infer; - -// const reingestionData = { -// ...originalData, -// source: `reingest-${originalData.source}`, -// metadata: { -// ...originalData.metadata, -// isReingestion: true, -// originalIngestionId: ingestion.id, -// }, -// }; - -// const jobDetails = await ingestionQueue.add( -// `ingest-user-${userId}`, -// { -// queueId: ingestion.id, -// spaceId: ingestion.spaceId, -// userId: userId, -// body: ingestion.data, -// }, -// { -// jobId: `${userId}-${Date.now()}`, -// }, -// ); - -// queuedJobs.push({id: jobDetails.id}); -// } catch (error) { -// logger.error(`Failed to queue ingestion ${ingestion.id} for user ${userId}:`, {error}); -// } -// } - -// return { -// userId, -// ingestionCount: ingestions.length, -// queuedJobsCount: queuedJobs.length, -// queuedJobs, -// }; -// } - -// const { action, loader } = createActionApiRoute( -// { -// body: ReingestionBodyRequest, -// allowJWT: true, -// authorization: { -// action: "reingest", -// }, -// corsStrategy: "all", -// }, -// async ({ body, authentication }) => { -// const { userId, spaceId, dryRun } = body; - -// try { -// // Check if the user is an admin -// const user = await prisma.user.findUnique({ -// where: { id: authentication.userId } -// }); - -// if (!user || user.admin !== true) { -// logger.warn("Unauthorized reingest attempt", { -// requestUserId: authentication.userId, -// }); -// return json( -// { -// success: false, -// error: "Unauthorized: Only admin users can perform reingestion" -// }, -// { status: 403 } -// ); -// } -// if (userId) { -// // Reingest for specific user -// const result = await reingestionForUser(userId, spaceId, dryRun); -// return json({ -// success: true, -// type: "single_user", -// result, -// }); -// } else { -// // Reingest for all users -// const users = await getAllUsers(); -// const results = []; - -// logger.info(`Starting reingestion for ${users.length} users`); - -// for (const user of users) { -// try { -// const result = await reingestionForUser(user.id, spaceId, dryRun); -// results.push(result); - -// if (!dryRun) { -// // Add small delay between users to prevent overwhelming the system -// await new Promise(resolve => setTimeout(resolve, 1000)); -// } -// } catch (error) { -// logger.error(`Failed to reingest for user ${user.id}:`, {error}); -// results.push({ -// userId: user.id, -// error: error instanceof Error ? error.message : "Unknown error", -// }); -// } -// } - -// return json({ -// success: true, -// type: "all_users", -// totalUsers: users.length, -// results, -// summary: { -// totalIngestions: results.reduce((sum, r) => sum, 0), -// totalQueuedJobs: results.reduce((sum, r) => sum, 0), -// }, -// }); -// } -// } catch (error) { -// logger.error("Reingestion failed:", {error}); -// return json( -// { -// success: false, -// error: error instanceof Error ? error.message : "Unknown error", -// }, -// { status: 500 } -// ); -// } -// } -// ); - -// export { action, loader }; diff --git a/apps/webapp/app/routes/search.tsx b/apps/webapp/app/routes/search.tsx deleted file mode 100644 index 981ef17..0000000 --- a/apps/webapp/app/routes/search.tsx +++ /dev/null @@ -1,53 +0,0 @@ -// DEPRECATED: This route is deprecated. Please use /api/v1/search instead. -// The API logic has been moved to /api/v1/search. This file is retained for reference only. - -import { z } from "zod"; -import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server"; -import { SearchService } from "~/services/search.server"; -import { json } from "@remix-run/node"; - -export const SearchBodyRequest = z.object({ - query: z.string(), - startTime: z.string().optional(), - endTime: z.string().optional(), - - // These are not supported yet, but need to support these - spaceId: z.string().optional(), - limit: z.number().optional(), - maxBfsDepth: z.number().optional(), - includeInvalidated: z.boolean().optional(), - entityTypes: z.array(z.string()).optional(), - scoreThreshold: z.number().optional(), - minResults: z.number().optional(), -}); - -const searchService = new SearchService(); -const { action, loader } = createActionApiRoute( - { - body: SearchBodyRequest, - allowJWT: true, - authorization: { - action: "search", - }, - corsStrategy: "all", - }, - async ({ body, authentication }) => { - const results = await searchService.search( - body.query, - authentication.userId, - { - startTime: body.startTime ? new Date(body.startTime) : undefined, - endTime: body.endTime ? new Date(body.endTime) : undefined, - limit: body.limit, - maxBfsDepth: body.maxBfsDepth, - includeInvalidated: body.includeInvalidated, - entityTypes: body.entityTypes, - scoreThreshold: body.scoreThreshold, - minResults: body.minResults, - }, - ); - return json(results); - }, -); - -export { action, loader }; diff --git a/apps/webapp/app/trigger/chat/memory-utils.ts b/apps/webapp/app/trigger/chat/memory-utils.ts index e99b692..afb2791 100644 --- a/apps/webapp/app/trigger/chat/memory-utils.ts +++ b/apps/webapp/app/trigger/chat/memory-utils.ts @@ -20,7 +20,10 @@ export interface AddMemoryParams { export const searchMemory = async (params: SearchMemoryParams) => { try { - const response = await axios.post("https://core::memory/search", params); + const response = await axios.post( + "https://core::memory/api/v1/search", + params, + ); return response.data; } catch (error) { logger.error("Memory search failed", { error, params }); @@ -39,7 +42,7 @@ export const addMemory = async (params: AddMemoryParams) => { }; const response = await axios.post( - "https://core::memory/ingest", + "https://core::memory/api/v1/add", memoryInput, ); return response.data; diff --git a/apps/webapp/app/trigger/utils/utils.ts b/apps/webapp/app/trigger/utils/utils.ts index 1316c15..bc72d91 100644 --- a/apps/webapp/app/trigger/utils/utils.ts +++ b/apps/webapp/app/trigger/utils/utils.ts @@ -37,6 +37,7 @@ type CreatePersonalAccessTokenOptions = { userId: string; }; +// TODO remove from here // Helper functions for token management function createToken() { return `${tokenPrefix}${tokenGenerator()}`; @@ -188,9 +189,9 @@ export const init = async ({ payload }: { payload: InitChatPayload }) => { if (config.url?.startsWith("https://core::memory")) { // Handle both search and ingest endpoints if (config.url.includes("/search")) { - config.url = `${process.env.API_BASE_URL}/search`; - } else if (config.url.includes("/ingest")) { - config.url = `${process.env.API_BASE_URL}/ingest`; + config.url = `${process.env.API_BASE_URL}/api/v1/search`; + } else if (config.url.includes("/add")) { + config.url = `${process.env.API_BASE_URL}/api/v1/add`; } config.headers.Authorization = `Bearer ${pat.token}`; } diff --git a/apps/webapp/public/logo-dark.png b/apps/webapp/public/logo-dark.png index 80b481b..997689a 100644 Binary files a/apps/webapp/public/logo-dark.png and b/apps/webapp/public/logo-dark.png differ diff --git a/apps/webapp/public/logo-dark.svg b/apps/webapp/public/logo-dark.svg index eff361b..6242699 100644 --- a/apps/webapp/public/logo-dark.svg +++ b/apps/webapp/public/logo-dark.svg @@ -1,42 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +