88 */
99function formatMarkdown ( markdown ) {
1010 if ( ! markdown ) return '' ;
11-
11+
1212 // Basic markdown formatting (can be enhanced)
1313 let html = markdown
1414 . replace ( / ^ # # # ( .* $ ) / gim, '<h3>$1</h3>' )
@@ -21,7 +21,7 @@ function formatMarkdown(markdown) {
2121 . replace ( / \[ ( .* ?) \] \( ( .* ?) \) / gim, '<a href="$2">$1</a>' )
2222 . replace ( / \n / gim, '<br>' )
2323 . replace ( / ^ - ( .* $ ) / gim, '<li>$1</li>' ) ;
24-
24+
2525 return html ;
2626}
2727
@@ -46,17 +46,41 @@ async function generateIntroduction(topic, format, context = '') {
4646 */
4747async function generateConclusion ( topic , sources , format , context = '' ) {
4848 let conclusion = `## Conclusion\n\n${ topic } is a complex and evolving field with many facets and applications. This document has presented a comprehensive overview based on research from multiple sources.\n\n` ;
49-
49+
5050 // Add sources section
5151 conclusion += `## Sources\n\n` ;
5252 if ( sources && sources . length ) {
5353 sources . forEach ( ( source , index ) => {
54- conclusion += `${ index + 1 } . [${ source } ](${ source } )\n` ;
54+ // Handle different source formats (string or object)
55+ let sourceUrl = '' ;
56+ let sourceTitle = '' ;
57+
58+ if ( typeof source === 'string' ) {
59+ sourceUrl = source ;
60+ sourceTitle = source ;
61+ } else if ( typeof source === 'object' && source !== null ) {
62+ // Extract URL from object
63+ if ( source . url ) {
64+ sourceUrl = source . url ;
65+ sourceTitle = source . title || source . url ;
66+ } else if ( source . href ) {
67+ sourceUrl = source . href ;
68+ sourceTitle = source . title || source . href ;
69+ } else if ( source . toString ) {
70+ sourceUrl = source . toString ( ) ;
71+ sourceTitle = sourceUrl ;
72+ }
73+ }
74+
75+ // Only add valid URLs
76+ if ( sourceUrl ) {
77+ conclusion += `${ index + 1 } . [${ sourceTitle } ](${ sourceUrl } )\n` ;
78+ }
5579 } ) ;
5680 } else {
5781 conclusion += `No sources were available for this document.` ;
5882 }
59-
83+
6084 return conclusion ;
6185}
6286
@@ -73,7 +97,7 @@ async function processSourceContent(source, topic, sectionIndex, totalSections,
7397 if ( ! source || ! source . content ) {
7498 return generateFallbackContent ( topic ) ;
7599 }
76-
100+
77101 try {
78102 // Use the pollinations-text API endpoint for text generation
79103 const response = await fetch ( '/api/pollinations-text' , {
@@ -89,20 +113,35 @@ async function processSourceContent(source, topic, sectionIndex, totalSections,
89113 max_tokens : 2000
90114 } )
91115 } ) ;
92-
116+
93117 const result = await response . json ( ) ;
94-
118+
95119 if ( ! result . success || ! result . text || result . text . trim ( ) . length < 100 ) {
96120 console . log ( 'Failed to generate content from source, using fallback' , result ) ;
97121 return generateFallbackContent ( topic ) ;
98122 }
99-
123+
100124 // Add source attribution
101125 let content = result . text ;
102- if ( ! content . includes ( `Source: ${ source . url } ` ) ) {
103- content += `\n\n*Source: [${ source . url } ](${ source . url } )*\n\n` ;
126+
127+ // Get the source URL in a safe way
128+ let sourceUrl = '' ;
129+ if ( typeof source . url === 'string' ) {
130+ sourceUrl = source . url ;
131+ } else if ( source . url && typeof source . url === 'object' && source . url . href ) {
132+ sourceUrl = source . url . href ;
133+ } else if ( source . url && source . url . toString && source . url . toString ( ) !== '[object Object]' ) {
134+ sourceUrl = source . url . toString ( ) ;
104135 }
105-
136+
137+ // Get the source title
138+ let sourceTitle = source . title || sourceUrl ;
139+
140+ // Add attribution if not already included and we have a valid URL
141+ if ( sourceUrl && ! content . includes ( `Source: ${ sourceUrl } ` ) ) {
142+ content += `\n\n*Source: [${ sourceTitle } ](${ sourceUrl } )*\n\n` ;
143+ }
144+
106145 return content ;
107146 } catch ( error ) {
108147 console . error ( 'Error generating document section:' , error ) ;
@@ -186,9 +225,9 @@ function displayDocument(documentContent, format = 'markdown') {
186225 const documentContainer = document . getElementById ( 'document-container' ) ;
187226 const toggleDocumentBtn = document . getElementById ( 'toggle-document-btn' ) ;
188227 const documentSidebar = document . getElementById ( 'document-sidebar' ) ;
189-
228+
190229 if ( ! documentContainer ) return ;
191-
230+
192231 // Set document content
193232 if ( format === 'markdown' ) {
194233 // For markdown, we need to handle some basic formatting
@@ -198,12 +237,12 @@ function displayDocument(documentContent, format = 'markdown') {
198237 // For HTML, we can set it directly
199238 documentContainer . innerHTML = documentContent ;
200239 }
201-
240+
202241 // Show the document sidebar toggle button
203242 if ( toggleDocumentBtn ) {
204243 toggleDocumentBtn . style . display = 'block' ;
205244 }
206-
245+
207246 // Automatically open the document sidebar
208247 if ( documentSidebar ) {
209248 documentSidebar . classList . add ( 'visible' ) ;
@@ -220,7 +259,7 @@ function downloadDocument(content, filename, format) {
220259 let downloadContent = content ;
221260 let mimeType = 'text/plain' ;
222261 let extension = 'txt' ;
223-
262+
224263 if ( format === 'html' ) {
225264 downloadContent = `<!DOCTYPE html>
226265<html>
@@ -250,7 +289,7 @@ function downloadDocument(content, filename, format) {
250289 mimeType = 'text/markdown' ;
251290 extension = 'md' ;
252291 }
253-
292+
254293 const blob = new Blob ( [ downloadContent ] , { type : mimeType } ) ;
255294 const url = URL . createObjectURL ( blob ) ;
256295 const a = document . createElement ( 'a' ) ;
@@ -288,4 +327,4 @@ export {
288327 displayDocument ,
289328 downloadDocument ,
290329 copyToClipboard
291- } ;
330+ } ;
0 commit comments