From f7b8b2058cdefaa6b5c79ad40cdc3576ea3b6adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CBeeRad=E2=80=9D?= Date: Tue, 13 Jan 2026 11:38:25 +1100 Subject: [PATCH] sync: description generation fix - simplified prompt --- .../[id]/regenerate-description/route.ts | 4 +- app/api/nodes/route.ts | 31 ++++++------ src/services/database/descriptionService.ts | 47 ++++++------------- 3 files changed, 34 insertions(+), 48 deletions(-) diff --git a/app/api/nodes/[id]/regenerate-description/route.ts b/app/api/nodes/[id]/regenerate-description/route.ts index 6c469bb..8ea0415 100644 --- a/app/api/nodes/[id]/regenerate-description/route.ts +++ b/app/api/nodes/[id]/regenerate-description/route.ts @@ -32,8 +32,10 @@ export async function POST( const newDescription = await generateDescription({ title: node.title, content: node.content || undefined, + link: node.link || undefined, metadata: node.metadata as { source?: string; channel_name?: string; author?: string; site_name?: string } | undefined, - type: (node.metadata as { type?: string } | null)?.type + type: (node.metadata as { type?: string } | null)?.type, + dimensions: node.dimensions || [] }); // Update the node with the new description diff --git a/app/api/nodes/route.ts b/app/api/nodes/route.ts index dc48487..ab17cde 100644 --- a/app/api/nodes/route.ts +++ b/app/api/nodes/route.ts @@ -61,26 +61,29 @@ export async function POST(request: NextRequest) { const rawContent = typeof body.content === 'string' ? body.content : null; - // Generate description BEFORE dimension assignment (used as primary context for matching) - let nodeDescription: string | undefined; - try { - nodeDescription = await generateDescription({ - title: body.title, - content: rawContent || undefined, - metadata: body.metadata, - type: body.type - }); - } catch (error) { - console.error('Error generating description:', error); - // Continue without description - dimension assignment will use content as fallback - } - + // Process provided dimensions first (needed for description generation) const providedDimensions = Array.isArray(body.dimensions) ? body.dimensions : []; const trimmedProvidedDimensions = providedDimensions .map((dim: unknown) => typeof dim === 'string' ? dim.trim() : '') .filter(Boolean) .slice(0, 8); + // Generate description with all available context + let nodeDescription: string | undefined; + try { + nodeDescription = await generateDescription({ + title: body.title, + content: rawContent || undefined, + link: body.link || undefined, + metadata: body.metadata, + type: body.type, + dimensions: trimmedProvidedDimensions + }); + } catch (error) { + console.error('Error generating description:', error); + // Continue without description - dimension assignment will use content as fallback + } + // Auto-assign locked dimensions + keyword dimensions for all new nodes const { locked, keywords } = await DimensionService.assignDimensions({ title: body.title, diff --git a/src/services/database/descriptionService.ts b/src/services/database/descriptionService.ts index 637cc7b..a92f1ca 100644 --- a/src/services/database/descriptionService.ts +++ b/src/services/database/descriptionService.ts @@ -4,6 +4,7 @@ import { generateText } from 'ai'; export interface DescriptionInput { title: string; content?: string; + link?: string; metadata?: { source?: string; channel_name?: string; @@ -11,11 +12,12 @@ export interface DescriptionInput { site_name?: string; }; type?: string; + dimensions?: string[]; } /** * Generate a 280-character description for a knowledge node. - * The description starts with "This is a..." and identifies the content type. + * Contextually grounded - adapts to node type (person, concept, article, etc.) */ export async function generateDescription(input: DescriptionInput): Promise { try { @@ -32,7 +34,7 @@ export async function generateDescription(input: DescriptionInput): Promise 800 ? '...' : ''}`); - return `Generate a concise description (max 280 characters) for this knowledge item. + return `Your job is to do your best to answer 'what is this' - the most simple, high level contextual information of what this thing is. Users will be adding a variety of different nodes (ideas, books, podcasts, people, papers etc). Do your best to take the available information and infer what it is - high level. If unsure, that's fine just give your best guess and say you're unsure. Max 280 characters. -CRITICAL REQUIREMENTS: -- Start with "This is a..." -- Identify the content type (article, video, paper, podcast episode, tweet, book, tutorial, etc.) -- Be specific about what the content covers -- Maximum 280 characters total - -=== KNOWLEDGE ITEM === -Title: ${input.title} -${metadataLines.length > 0 ? metadataLines.join('\n') : ''} -${contentPreview ? `\nContent preview: ${contentPreview}${input.content && input.content.length > 500 ? '...' : ''}` : ''} - -=== YOUR RESPONSE === -Write ONLY the description, nothing else. Start with "This is a..."`; +${lines.join('\n')}`; } export const descriptionService = {