diff --git a/apps/webapp/app/components/common/styled-markdown.tsx b/apps/webapp/app/components/common/styled-markdown.tsx
new file mode 100644
index 0000000..b398b26
--- /dev/null
+++ b/apps/webapp/app/components/common/styled-markdown.tsx
@@ -0,0 +1,220 @@
+import ReactMarkdown from "react-markdown";
+import type { Components } from "react-markdown";
+import { cn } from "~/lib/utils";
+
+const markdownComponents: Components = {
+ h1: ({ className, ...props }) => (
+
- {displayText}
+ {displayText.slice(0, 300)}
diff --git a/apps/webapp/app/services/ingestionLogs.server.ts b/apps/webapp/app/services/ingestionLogs.server.ts
index 295b3b1..542e678 100644
--- a/apps/webapp/app/services/ingestionLogs.server.ts
+++ b/apps/webapp/app/services/ingestionLogs.server.ts
@@ -131,7 +131,9 @@ export const getIngestionQueueForFrontend = async (
(log.output as any)?.episodes?.length > 0
) {
// For DOCUMENT type: get episode details and space information for all episodes
- const episodeIds = (log.output as any)?.episodes;
+ const episodeIds = (log.output as any)?.episodes.map(
+ (e: any) => e.episodeUuid,
+ );
// Fetch all episode details in parallel
const episodeDetailsPromises = episodeIds.map((episodeId: string) =>
diff --git a/apps/webapp/app/trigger/spaces/space-summary.ts b/apps/webapp/app/trigger/spaces/space-summary.ts
index dfb62c1..64d3c1c 100644
--- a/apps/webapp/app/trigger/spaces/space-summary.ts
+++ b/apps/webapp/app/trigger/spaces/space-summary.ts
@@ -55,7 +55,7 @@ const SummaryResultSchema = z.object({
const CONFIG = {
maxEpisodesForSummary: 20, // Limit episodes for performance
minEpisodesForSummary: 1, // Minimum episodes to generate summary
- summaryEpisodeThreshold: 10, // Minimum new episodes required to trigger summary (configurable)
+ summaryEpisodeThreshold: 5, // Minimum new episodes required to trigger summary (configurable)
};
export const spaceSummaryQueue = queue({
@@ -85,7 +85,11 @@ export const spaceSummaryTask = task({
});
// Generate summary for the single space
- const summaryResult = await generateSpaceSummary(spaceId, userId, triggerSource);
+ const summaryResult = await generateSpaceSummary(
+ spaceId,
+ userId,
+ triggerSource,
+ );
if (summaryResult) {
// Store the summary
@@ -192,7 +196,10 @@ async function generateSpaceSummary(
const lastSummaryEpisodeCount = space.contextCount || 0;
const episodeDifference = currentEpisodeCount - lastSummaryEpisodeCount;
- if (episodeDifference < CONFIG.summaryEpisodeThreshold) {
+ if (
+ episodeDifference < CONFIG.summaryEpisodeThreshold ||
+ lastSummaryEpisodeCount === 0
+ ) {
logger.info(
`Skipping summary generation for space ${spaceId}: only ${episodeDifference} new episodes (threshold: ${CONFIG.summaryEpisodeThreshold})`,
{
@@ -200,7 +207,7 @@ async function generateSpaceSummary(
lastSummaryEpisodeCount,
episodeDifference,
threshold: CONFIG.summaryEpisodeThreshold,
- }
+ },
);
return null;
}
@@ -211,7 +218,7 @@ async function generateSpaceSummary(
currentEpisodeCount,
lastSummaryEpisodeCount,
episodeDifference,
- }
+ },
);
}
@@ -361,9 +368,15 @@ async function generateUnifiedSummary(
// Space summary generation requires HIGH complexity (creative synthesis, narrative generation)
let responseText = "";
- await makeModelCall(false, prompt, (text: string) => {
- responseText = text;
- }, undefined, 'high');
+ await makeModelCall(
+ false,
+ prompt,
+ (text: string) => {
+ responseText = text;
+ },
+ undefined,
+ "high",
+ );
return parseSummaryResponse(responseText);
} catch (error) {
diff --git a/apps/webapp/prisma/schema.prisma b/apps/webapp/prisma/schema.prisma
index ae4af39..a01752b 100644
--- a/apps/webapp/prisma/schema.prisma
+++ b/apps/webapp/prisma/schema.prisma
@@ -113,10 +113,6 @@ model ConversationHistory {
model IngestionQueue {
id String @id @default(cuid())
- // Relations
- space Space? @relation(fields: [spaceId], references: [id])
- spaceId String?
-
// Queue metadata
data Json // The actual data to be processed
output Json? // The processed output data
@@ -472,29 +468,29 @@ model RecallLog {
}
model Space {
- id String @id @default(cuid())
- name String
- description String?
- autoMode Boolean @default(false)
- summary String?
- themes String[]
- statementCount Int?
+ id String @id @default(cuid())
+ name String
+ description String?
+ autoMode Boolean @default(false)
+ summary String?
+ themes String[]
+ contextCount Int? // Count of context items in this space (episodes, statements, etc.)
status String?
icon String?
- lastPatternTrigger DateTime?
- statementCountAtLastTrigger Int?
+ lastPatternTrigger DateTime?
+ summaryGeneratedAt DateTime?
+ contextCountAtLastTrigger Int? // Context count when pattern was last triggered
// Relations
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- IngestionQueue IngestionQueue[]
- SpacePattern SpacePattern[]
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ SpacePattern SpacePattern[]
}
model SpacePattern {