mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 03:29:02 +01:00 
			
		
		
		
	agentic thinking really works now 🗿
This commit is contained in:
		
							parent
							
								
									90db570e30
								
							
						
					
					
						commit
						4ff3c5abcf
					
				| @ -271,213 +271,142 @@ export class QueryDecompositionTool { | |||||||
|     /** |     /** | ||||||
|      * Generate a unique ID for a sub-query |      * Generate a unique ID for a sub-query | ||||||
|      */ |      */ | ||||||
|     private generateSubQueryId(): string { |     generateSubQueryId(): string { | ||||||
|         return `sq_${Date.now()}_${QueryDecompositionTool.queryCounter++}`; |         return `sq_${Date.now()}_${Math.floor(Math.random() * 10000)}`; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Create sub-queries based on the original query and optional context |      * Create sub-queries based on the original query | ||||||
|      */ |      */ | ||||||
|     private createSubQueries(query: string, context?: string): SubQuery[] { |     createSubQueries(query: string, context?: string): SubQuery[] { | ||||||
|  |         // Simple rules to create sub-queries based on query content
 | ||||||
|         const subQueries: SubQuery[] = []; |         const subQueries: SubQuery[] = []; | ||||||
| 
 | 
 | ||||||
|         // Use context to enhance sub-query generation if available
 |         // Avoid creating subqueries that start with "Provide details about" or similar
 | ||||||
|         if (context) { |         // as these have been causing recursive loops
 | ||||||
|             log.info(`Using context to enhance sub-query generation`); |         if (query.toLowerCase().includes("provide details about") || | ||||||
| 
 |             query.toLowerCase().includes("information related to")) { | ||||||
|             // Add context-specific questions
 |             log.info(`Avoiding recursive subqueries for query "${query.substring(0, 50)}..."`); | ||||||
|             subQueries.push({ |             return [{ | ||||||
|                 id: this.generateSubQueryId(), |                 id: this.generateSubQueryId(), | ||||||
|                 text: `What key information in the current note relates to: "${query}"?`, |                 text: query, | ||||||
|                 reason: 'Identifying directly relevant information in the current context', |                 reason: 'Direct analysis of note details', | ||||||
|                 isAnswered: false |                 isAnswered: false | ||||||
|             }); |             }]; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // 1. Look for multiple question marks
 |         // First, add the original query as a sub-query (always)
 | ||||||
|         const questionSplit = query.split(/\?/).filter(q => q.trim().length > 0); |  | ||||||
| 
 |  | ||||||
|         if (questionSplit.length > 1) { |  | ||||||
|             // Multiple distinct questions detected
 |  | ||||||
|             for (let i = 0; i < questionSplit.length; i++) { |  | ||||||
|                 const text = questionSplit[i].trim() + '?'; |  | ||||||
|                 subQueries.push({ |  | ||||||
|                     id: this.generateSubQueryId(), |  | ||||||
|                     text, |  | ||||||
|                     reason: `Separate question ${i + 1} detected in the original query`, |  | ||||||
|                     isAnswered: false |  | ||||||
|                 }); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Also add a synthesis question
 |  | ||||||
|             subQueries.push({ |  | ||||||
|                 id: this.generateSubQueryId(), |  | ||||||
|                 text: `How do the answers to these questions relate to each other in the context of the original query?`, |  | ||||||
|                 reason: 'Synthesizing information from multiple questions', |  | ||||||
|                 isAnswered: false |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             return subQueries; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // 2. Look for "and", "or", etc. connecting potentially separate questions
 |  | ||||||
|         const conjunctions = [ |  | ||||||
|             { regex: /\b(compare|versus|vs\.?|difference between|similarities between)\b/i, label: 'comparison' }, |  | ||||||
|             { regex: /\b(list|enumerate)\b/i, label: 'listing' }, |  | ||||||
|             { regex: /\b(analyze|examine|investigate|explore)\b/i, label: 'analysis' }, |  | ||||||
|             { regex: /\b(explain|why)\b/i, label: 'explanation' }, |  | ||||||
|             { regex: /\b(how to|steps to|process of)\b/i, label: 'procedure' } |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|         // Check for comparison queries - these often need multiple sub-queries
 |  | ||||||
|         for (const conj of conjunctions) { |  | ||||||
|             if (conj.regex.test(query)) { |  | ||||||
|                 if (conj.label === 'comparison') { |  | ||||||
|                     // For comparisons, we need to research each item, then compare them
 |  | ||||||
|                     const comparisonMatch = query.match(/\b(compare|versus|vs\.?|difference between|similarities between)\s+(.+?)\s+(and|with|to)\s+(.+?)(\?|$)/i); |  | ||||||
| 
 |  | ||||||
|                     if (comparisonMatch) { |  | ||||||
|                         const item1 = comparisonMatch[2].trim(); |  | ||||||
|                         const item2 = comparisonMatch[4].trim(); |  | ||||||
| 
 |  | ||||||
|                         subQueries.push({ |  | ||||||
|                             id: this.generateSubQueryId(), |  | ||||||
|                             text: `What are the key characteristics of ${item1}?`, |  | ||||||
|                             reason: `Need to understand ${item1} for the comparison`, |  | ||||||
|                             isAnswered: false |  | ||||||
|                         }); |  | ||||||
| 
 |  | ||||||
|                         subQueries.push({ |  | ||||||
|                             id: this.generateSubQueryId(), |  | ||||||
|                             text: `What are the key characteristics of ${item2}?`, |  | ||||||
|                             reason: `Need to understand ${item2} for the comparison`, |  | ||||||
|                             isAnswered: false |  | ||||||
|                         }); |  | ||||||
| 
 |  | ||||||
|                         subQueries.push({ |  | ||||||
|                             id: this.generateSubQueryId(), |  | ||||||
|                             text: `What are the main differences between ${item1} and ${item2}?`, |  | ||||||
|                             reason: 'Understanding key differences', |  | ||||||
|                             isAnswered: false |  | ||||||
|                         }); |  | ||||||
| 
 |  | ||||||
|                         subQueries.push({ |  | ||||||
|                             id: this.generateSubQueryId(), |  | ||||||
|                             text: `What are the main similarities between ${item1} and ${item2}?`, |  | ||||||
|                             reason: 'Understanding key similarities', |  | ||||||
|                             isAnswered: false |  | ||||||
|                         }); |  | ||||||
| 
 |  | ||||||
|                         subQueries.push({ |  | ||||||
|                             id: this.generateSubQueryId(), |  | ||||||
|                             text: `What practical implications do these differences and similarities have?`, |  | ||||||
|                             reason: 'Understanding practical significance of the comparison', |  | ||||||
|                             isAnswered: false |  | ||||||
|                         }); |  | ||||||
| 
 |  | ||||||
|                         return subQueries; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // 3. For complex questions without clear separation, create topic-based sub-queries
 |  | ||||||
|         // Lowered the threshold to process more queries this way
 |  | ||||||
|         if (query.length > 50) { |  | ||||||
|             // Extract potential key topics from the query
 |  | ||||||
|             const words = query.toLowerCase().split(/\W+/).filter(w => |  | ||||||
|                 w.length > 3 && |  | ||||||
|                 !['what', 'when', 'where', 'which', 'with', 'would', 'could', 'should', 'have', 'this', 'that', 'there', 'their'].includes(w) |  | ||||||
|             ); |  | ||||||
| 
 |  | ||||||
|             // Count word frequencies
 |  | ||||||
|             const wordFrequency: Record<string, number> = {}; |  | ||||||
|             for (const word of words) { |  | ||||||
|                 wordFrequency[word] = (wordFrequency[word] || 0) + 1; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Get top frequent words
 |  | ||||||
|             const topWords = Object.entries(wordFrequency) |  | ||||||
|                 .sort((a, b) => b[1] - a[1]) |  | ||||||
|                 .slice(0, 4) // Increased from 3 to 4
 |  | ||||||
|                 .map(entry => entry[0]); |  | ||||||
| 
 |  | ||||||
|             if (topWords.length > 0) { |  | ||||||
|                 // Create factual sub-query
 |  | ||||||
|                 subQueries.push({ |  | ||||||
|                     id: this.generateSubQueryId(), |  | ||||||
|                     text: `What are the key facts about ${topWords.join(' and ')} relevant to this question?`, |  | ||||||
|                     reason: 'Gathering basic information about main topics', |  | ||||||
|                     isAnswered: false |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 // Add individual queries for each key topic
 |  | ||||||
|                 topWords.forEach(word => { |  | ||||||
|                     subQueries.push({ |  | ||||||
|                         id: this.generateSubQueryId(), |  | ||||||
|                         text: `What specific details about "${word}" are most relevant to the query?`, |  | ||||||
|                         reason: `Detailed exploration of the "${word}" concept`, |  | ||||||
|                         isAnswered: false |  | ||||||
|                     }); |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 // Create relationship sub-query if multiple top words
 |  | ||||||
|                 if (topWords.length > 1) { |  | ||||||
|                     for (let i = 0; i < topWords.length; i++) { |  | ||||||
|                         for (let j = i + 1; j < topWords.length; j++) { |  | ||||||
|                             subQueries.push({ |  | ||||||
|                                 id: this.generateSubQueryId(), |  | ||||||
|                                 text: `How do ${topWords[i]} and ${topWords[j]} relate to each other?`, |  | ||||||
|                                 reason: `Understanding relationship between ${topWords[i]} and ${topWords[j]}`, |  | ||||||
|                                 isAnswered: false |  | ||||||
|                             }); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 // Add a "what else" query to ensure comprehensive coverage
 |  | ||||||
|                 subQueries.push({ |  | ||||||
|                     id: this.generateSubQueryId(), |  | ||||||
|                     text: `What other important aspects should be considered about this topic that might not be immediately obvious?`, |  | ||||||
|                     reason: 'Exploring non-obvious but relevant information', |  | ||||||
|                     isAnswered: false |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 // Add the original query as the final synthesizing question
 |  | ||||||
|         subQueries.push({ |         subQueries.push({ | ||||||
|             id: this.generateSubQueryId(), |             id: this.generateSubQueryId(), | ||||||
|             text: query, |             text: query, | ||||||
|                     reason: 'Original question to be answered after gathering information', |             reason: 'Original query', | ||||||
|             isAnswered: false |             isAnswered: false | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|                 return subQueries; |         // Check for "compare", "difference", "versus" to identify comparison questions
 | ||||||
|  |         if ( | ||||||
|  |             query.toLowerCase().includes('compare') || | ||||||
|  |             query.toLowerCase().includes('difference between') || | ||||||
|  |             query.toLowerCase().includes(' vs ') || | ||||||
|  |             query.toLowerCase().includes('versus') | ||||||
|  |         ) { | ||||||
|  |             // Extract entities to compare (simplified approach)
 | ||||||
|  |             const entities = this.extractEntitiesForComparison(query); | ||||||
|  | 
 | ||||||
|  |             if (entities.length >= 2) { | ||||||
|  |                 // Add sub-queries for each entity
 | ||||||
|  |                 entities.forEach(entity => { | ||||||
|  |                     subQueries.push({ | ||||||
|  |                         id: this.generateSubQueryId(), | ||||||
|  |                         text: `What are the key characteristics of ${entity}?`, | ||||||
|  |                         reason: `Getting details about "${entity}" for comparison`, | ||||||
|  |                         isAnswered: false | ||||||
|  |                     }); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 // Add explicit comparison sub-query
 | ||||||
|  |                 subQueries.push({ | ||||||
|  |                     id: this.generateSubQueryId(), | ||||||
|  |                     text: `How do ${entities.join(' and ')} compare in terms of their primary features?`, | ||||||
|  |                     reason: 'Direct comparison of the entities', | ||||||
|  |                     isAnswered: false | ||||||
|  |                 }); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         // Check for "how to" questions
 | ||||||
|  |         else if (query.toLowerCase().includes('how to ')) { | ||||||
|  |             const topic = query.replace(/how to /i, '').trim(); | ||||||
| 
 | 
 | ||||||
|         // Fallback: If we can't meaningfully decompose, just use the original query
 |  | ||||||
|         // But also add some generic exploration questions
 |  | ||||||
|             subQueries.push({ |             subQueries.push({ | ||||||
|                 id: this.generateSubQueryId(), |                 id: this.generateSubQueryId(), | ||||||
|             text: query, |                 text: `What are the steps to ${topic}?`, | ||||||
|             reason: 'Primary question', |                 reason: 'Finding procedural information', | ||||||
|             isAnswered: false |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         // Add generic exploration questions even for "simple" queries
 |  | ||||||
|         subQueries.push({ |  | ||||||
|             id: this.generateSubQueryId(), |  | ||||||
|             text: `What background information is helpful to understand this query better?`, |  | ||||||
|             reason: 'Gathering background context', |  | ||||||
|                 isAnswered: false |                 isAnswered: false | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             subQueries.push({ |             subQueries.push({ | ||||||
|                 id: this.generateSubQueryId(), |                 id: this.generateSubQueryId(), | ||||||
|             text: `What related concepts might be important to consider?`, |                 text: `What are common challenges or pitfalls when trying to ${topic}?`, | ||||||
|             reason: 'Exploring related concepts', |                 reason: 'Identifying potential difficulties', | ||||||
|                 isAnswered: false |                 isAnswered: false | ||||||
|             }); |             }); | ||||||
|  |         } | ||||||
|  |         // Check for "why" questions
 | ||||||
|  |         else if (query.toLowerCase().startsWith('why ')) { | ||||||
|  |             const topic = query.replace(/why /i, '').trim(); | ||||||
|  | 
 | ||||||
|  |             subQueries.push({ | ||||||
|  |                 id: this.generateSubQueryId(), | ||||||
|  |                 text: `What are the causes of ${topic}?`, | ||||||
|  |                 reason: 'Identifying causes', | ||||||
|  |                 isAnswered: false | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             subQueries.push({ | ||||||
|  |                 id: this.generateSubQueryId(), | ||||||
|  |                 text: `What evidence supports explanations for ${topic}?`, | ||||||
|  |                 reason: 'Finding supporting evidence', | ||||||
|  |                 isAnswered: false | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |         // Handle "what is" questions
 | ||||||
|  |         else if (query.toLowerCase().startsWith('what is ') || query.toLowerCase().startsWith('what are ')) { | ||||||
|  |             const topic = query.replace(/what (is|are) /i, '').trim().replace(/\?$/, ''); | ||||||
|  | 
 | ||||||
|  |             subQueries.push({ | ||||||
|  |                 id: this.generateSubQueryId(), | ||||||
|  |                 text: `Definition of ${topic}`, | ||||||
|  |                 reason: 'Getting basic definition', | ||||||
|  |                 isAnswered: false | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             subQueries.push({ | ||||||
|  |                 id: this.generateSubQueryId(), | ||||||
|  |                 text: `Examples of ${topic}`, | ||||||
|  |                 reason: 'Finding examples', | ||||||
|  |                 isAnswered: false | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // If no specific sub-queries were added (beyond the original),
 | ||||||
|  |         // generate generic exploratory sub-queries
 | ||||||
|  |         if (subQueries.length <= 1) { | ||||||
|  |             // Extract main entities/concepts from the query
 | ||||||
|  |             const concepts = this.extractMainConcepts(query); | ||||||
|  | 
 | ||||||
|  |             concepts.forEach(concept => { | ||||||
|  |                 // Don't create recursive or self-referential queries
 | ||||||
|  |                 if (!concept.toLowerCase().includes('provide details') && | ||||||
|  |                     !concept.toLowerCase().includes('information related')) { | ||||||
|  |                     subQueries.push({ | ||||||
|  |                         id: this.generateSubQueryId(), | ||||||
|  |                         text: `Key information about ${concept}`, | ||||||
|  |                         reason: `Finding information about "${concept}"`, | ||||||
|  |                         isAnswered: false | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         return subQueries; |         return subQueries; | ||||||
|     } |     } | ||||||
| @ -489,6 +418,104 @@ export class QueryDecompositionTool { | |||||||
|         if (text.length <= maxLength) return text; |         if (text.length <= maxLength) return text; | ||||||
|         return text.substring(0, maxLength - 3) + '...'; |         return text.substring(0, maxLength - 3) + '...'; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Extract entities for comparison from a query | ||||||
|  |      * | ||||||
|  |      * @param query The query to extract entities from | ||||||
|  |      * @returns Array of entity strings | ||||||
|  |      */ | ||||||
|  |     extractEntitiesForComparison(query: string): string[] { | ||||||
|  |         // Try to match patterns like "compare X and Y" or "difference between X and Y"
 | ||||||
|  |         const comparePattern = /\b(?:compare|difference between|similarities between)\s+([^,]+?)\s+(?:and|with|to)\s+([^,\?\.]+)/i; | ||||||
|  |         const vsPattern = /\b([^,]+?)\s+(?:vs\.?|versus)\s+([^,\?\.]+)/i; | ||||||
|  | 
 | ||||||
|  |         let match = query.match(comparePattern) || query.match(vsPattern); | ||||||
|  | 
 | ||||||
|  |         if (match) { | ||||||
|  |             return [match[1].trim(), match[2].trim()]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // If no pattern match, try to extract noun phrases
 | ||||||
|  |         const words = query.split(/\s+/); | ||||||
|  |         const potentialEntities = []; | ||||||
|  |         let currentPhrase = ''; | ||||||
|  | 
 | ||||||
|  |         for (const word of words) { | ||||||
|  |             // Skip common words that are unlikely to be part of entity names
 | ||||||
|  |             if (/^(the|of|and|or|vs|versus|between|comparison|compared|to|with|what|is|are|how|why|when|which)$/i.test(word)) { | ||||||
|  |                 if (currentPhrase.trim()) { | ||||||
|  |                     potentialEntities.push(currentPhrase.trim()); | ||||||
|  |                     currentPhrase = ''; | ||||||
|  |                 } | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             currentPhrase += word + ' '; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (currentPhrase.trim()) { | ||||||
|  |             potentialEntities.push(currentPhrase.trim()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return potentialEntities.slice(0, 2); // Return at most 2 entities
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Extract main concepts from a query | ||||||
|  |      * | ||||||
|  |      * @param query The query to extract concepts from | ||||||
|  |      * @returns Array of concept strings | ||||||
|  |      */ | ||||||
|  |     extractMainConcepts(query: string): string[] { | ||||||
|  |         // Remove question words and common stop words
 | ||||||
|  |         const cleanedQuery = query.replace(/what|is|are|how|why|when|which|the|of|and|or|to|with|in|on|by/gi, ' '); | ||||||
|  | 
 | ||||||
|  |         // Split into words and filter out short words
 | ||||||
|  |         const words = cleanedQuery.split(/\s+/).filter(word => word.length > 3); | ||||||
|  | 
 | ||||||
|  |         // Count word frequency
 | ||||||
|  |         const wordCounts: Record<string, number> = {}; | ||||||
|  |         for (const word of words) { | ||||||
|  |             wordCounts[word.toLowerCase()] = (wordCounts[word.toLowerCase()] || 0) + 1; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Sort by frequency
 | ||||||
|  |         const sortedWords = Object.entries(wordCounts) | ||||||
|  |             .sort((a, b) => b[1] - a[1]) | ||||||
|  |             .map(entry => entry[0]); | ||||||
|  | 
 | ||||||
|  |         // Try to build meaningful phrases around top words
 | ||||||
|  |         const conceptPhrases: string[] = []; | ||||||
|  | 
 | ||||||
|  |         if (sortedWords.length === 0) { | ||||||
|  |             // Fallback if no significant words found
 | ||||||
|  |             return [query.trim()]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Use the top 2-3 words to form concepts
 | ||||||
|  |         for (let i = 0; i < Math.min(sortedWords.length, 3); i++) { | ||||||
|  |             const word = sortedWords[i]; | ||||||
|  | 
 | ||||||
|  |             // Try to find the word in the original query and extract a small phrase around it
 | ||||||
|  |             const wordIndex = query.toLowerCase().indexOf(word); | ||||||
|  |             if (wordIndex >= 0) { | ||||||
|  |                 // Extract a window of text around the word (3 words before and after)
 | ||||||
|  |                 const start = Math.max(0, query.lastIndexOf(' ', wordIndex - 15) + 1); | ||||||
|  |                 const end = Math.min(query.length, query.indexOf(' ', wordIndex + word.length + 15)); | ||||||
|  | 
 | ||||||
|  |                 if (end > start) { | ||||||
|  |                     conceptPhrases.push(query.substring(start, end).trim()); | ||||||
|  |                 } else { | ||||||
|  |                     conceptPhrases.push(word); | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 conceptPhrases.push(word); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return conceptPhrases; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default QueryDecompositionTool; | export default QueryDecompositionTool; | ||||||
|  | |||||||
| @ -111,22 +111,19 @@ export class VectorSearchTool { | |||||||
| 
 | 
 | ||||||
|       // Include more content from each note to provide richer context
 |       // Include more content from each note to provide richer context
 | ||||||
|       if (options.includeContent) { |       if (options.includeContent) { | ||||||
|         // Get full context for each note rather than summaries
 |         // IMPORTANT: Get content directly without recursive processQuery calls
 | ||||||
|  |         // This prevents infinite loops where one search triggers another
 | ||||||
|         for (let i = 0; i < results.length; i++) { |         for (let i = 0; i < results.length; i++) { | ||||||
|           const result = results[i]; |           const result = results[i]; | ||||||
|           try { |           try { | ||||||
|             // Use contextService instead of direct import
 |             // Get content directly from note content service
 | ||||||
|             if (this.contextService && 'processQuery' in this.contextService) { |             if (!result.content) { | ||||||
|               const contextResult = await this.contextService.processQuery( |               const noteContent = await import('../context/note_content.js'); | ||||||
|                 `Provide details about the note: ${result.title}`, |               const content = await noteContent.getNoteContent(result.noteId); | ||||||
|                 null, |               if (content) { | ||||||
|                 result.noteId, |                 // Add content directly without recursive calls
 | ||||||
|                 false |                 result.content = content.substring(0, 2000); // Limit to 2000 chars
 | ||||||
|               ); |                 log.info(`Added direct content for note ${result.noteId}, length: ${result.content.length} chars`); | ||||||
| 
 |  | ||||||
|               if (contextResult && contextResult.context) { |  | ||||||
|                 // Use more of the content, up to 2000 chars
 |  | ||||||
|                 result.content = contextResult.context.substring(0, 2000); |  | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } catch (error) { |           } catch (error) { | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import type { Message, ChatCompletionOptions } from './ai_interface.js'; | import type { Message, ChatCompletionOptions } from './ai_interface.js'; | ||||||
| import aiServiceManager from './ai_service_manager.js'; | import aiServiceManager from './ai_service_manager.js'; | ||||||
| import chatStorageService from './chat_storage_service.js'; | import chatStorageService from './chat_storage_service.js'; | ||||||
|  | import log from '../log.js'; | ||||||
| 
 | 
 | ||||||
| export interface ChatSession { | export interface ChatSession { | ||||||
|     id: string; |     id: string; | ||||||
| @ -247,6 +248,9 @@ export class ChatService { | |||||||
|             // Get showThinking option if it exists
 |             // Get showThinking option if it exists
 | ||||||
|             const showThinking = options?.showThinking === true; |             const showThinking = options?.showThinking === true; | ||||||
| 
 | 
 | ||||||
|  |             log.info(`Processing LLM message: "${content.substring(0, 100)}..."`); | ||||||
|  |             log.info(`Using enhanced context with: noteId=${noteId}, showThinking=${showThinking}`); | ||||||
|  | 
 | ||||||
|             // Get enhanced context for this note and query
 |             // Get enhanced context for this note and query
 | ||||||
|             const enhancedContext = await contextService.getAgentToolsContext( |             const enhancedContext = await contextService.getAgentToolsContext( | ||||||
|                 noteId, |                 noteId, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 perf3ct
						perf3ct