mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-10 18:39:22 +08:00
also extract Note relationships and send as context
This commit is contained in:
parent
915c95f7cb
commit
c9728e70bb
@ -7,6 +7,7 @@ import contextFormatter from './context_formatter.js';
|
|||||||
import aiServiceManager from '../../ai_service_manager.js';
|
import aiServiceManager from '../../ai_service_manager.js';
|
||||||
import { ContextExtractor } from '../index.js';
|
import { ContextExtractor } from '../index.js';
|
||||||
import { CONTEXT_PROMPTS } from '../../prompts/llm_prompt_constants.js';
|
import { CONTEXT_PROMPTS } from '../../prompts/llm_prompt_constants.js';
|
||||||
|
import becca from '../../../../becca/becca.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main context service that integrates all context-related functionality
|
* Main context service that integrates all context-related functionality
|
||||||
@ -455,6 +456,51 @@ export class ContextService {
|
|||||||
for (const note of finalNotes) {
|
for (const note of finalNotes) {
|
||||||
agentContext += `### ${note.title}\n`;
|
agentContext += `### ${note.title}\n`;
|
||||||
|
|
||||||
|
// Add relationship information for the note
|
||||||
|
try {
|
||||||
|
const noteObj = becca.getNote(note.noteId);
|
||||||
|
if (noteObj) {
|
||||||
|
// Get parent notes
|
||||||
|
const parentNotes = noteObj.getParentNotes();
|
||||||
|
if (parentNotes && parentNotes.length > 0) {
|
||||||
|
agentContext += `**Parent notes:** ${parentNotes.map((p: any) => p.title).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get child notes
|
||||||
|
const childNotes = noteObj.getChildNotes();
|
||||||
|
if (childNotes && childNotes.length > 0) {
|
||||||
|
agentContext += `**Child notes:** ${childNotes.map((c: any) => c.title).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get attributes
|
||||||
|
const attributes = noteObj.getAttributes();
|
||||||
|
if (attributes && attributes.length > 0) {
|
||||||
|
const filteredAttrs = attributes.filter((a: any) => !a.name.startsWith('_')); // Filter out system attributes
|
||||||
|
if (filteredAttrs.length > 0) {
|
||||||
|
agentContext += `**Attributes:** ${filteredAttrs.map((a: any) => `${a.name}=${a.value}`).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get backlinks/related notes through relation attributes
|
||||||
|
const relationAttrs = attributes?.filter((a: any) =>
|
||||||
|
a.name.startsWith('relation:') ||
|
||||||
|
a.name.startsWith('label:')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (relationAttrs && relationAttrs.length > 0) {
|
||||||
|
agentContext += `**Relationships:** ${relationAttrs.map((a: any) => {
|
||||||
|
const targetNote = becca.getNote(a.value);
|
||||||
|
const targetTitle = targetNote ? targetNote.title : a.value;
|
||||||
|
return `${a.name.substring(a.name.indexOf(':') + 1)} → ${targetTitle}`;
|
||||||
|
}).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error getting relationship info for note ${note.noteId}: ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
agentContext += '\n';
|
||||||
|
|
||||||
if (note.content) {
|
if (note.content) {
|
||||||
// Extract relevant content instead of just taking first 2000 chars
|
// Extract relevant content instead of just taking first 2000 chars
|
||||||
const relevantContent = await this.extractRelevantContent(note.content, query, 2000);
|
const relevantContent = await this.extractRelevantContent(note.content, query, 2000);
|
||||||
@ -474,6 +520,51 @@ export class ContextService {
|
|||||||
for (const note of finalNotes) {
|
for (const note of finalNotes) {
|
||||||
agentContext += `### ${note.title}\n`;
|
agentContext += `### ${note.title}\n`;
|
||||||
|
|
||||||
|
// Add relationship information for the note
|
||||||
|
try {
|
||||||
|
const noteObj = becca.getNote(note.noteId);
|
||||||
|
if (noteObj) {
|
||||||
|
// Get parent notes
|
||||||
|
const parentNotes = noteObj.getParentNotes();
|
||||||
|
if (parentNotes && parentNotes.length > 0) {
|
||||||
|
agentContext += `**Parent notes:** ${parentNotes.map((p: any) => p.title).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get child notes
|
||||||
|
const childNotes = noteObj.getChildNotes();
|
||||||
|
if (childNotes && childNotes.length > 0) {
|
||||||
|
agentContext += `**Child notes:** ${childNotes.map((c: any) => c.title).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get attributes
|
||||||
|
const attributes = noteObj.getAttributes();
|
||||||
|
if (attributes && attributes.length > 0) {
|
||||||
|
const filteredAttrs = attributes.filter((a: any) => !a.name.startsWith('_')); // Filter out system attributes
|
||||||
|
if (filteredAttrs.length > 0) {
|
||||||
|
agentContext += `**Attributes:** ${filteredAttrs.map((a: any) => `${a.name}=${a.value}`).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get backlinks/related notes through relation attributes
|
||||||
|
const relationAttrs = attributes?.filter((a: any) =>
|
||||||
|
a.name.startsWith('relation:') ||
|
||||||
|
a.name.startsWith('label:')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (relationAttrs && relationAttrs.length > 0) {
|
||||||
|
agentContext += `**Relationships:** ${relationAttrs.map((a: any) => {
|
||||||
|
const targetNote = becca.getNote(a.value);
|
||||||
|
const targetTitle = targetNote ? targetNote.title : a.value;
|
||||||
|
return `${a.name.substring(a.name.indexOf(':') + 1)} → ${targetTitle}`;
|
||||||
|
}).join(', ')}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error getting relationship info for note ${note.noteId}: ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
agentContext += '\n';
|
||||||
|
|
||||||
if (note.content) {
|
if (note.content) {
|
||||||
// Extract relevant content instead of just taking first 2000 chars
|
// Extract relevant content instead of just taking first 2000 chars
|
||||||
const relevantContent = await this.extractRelevantContent(note.content, query, 2000);
|
const relevantContent = await this.extractRelevantContent(note.content, query, 2000);
|
||||||
|
@ -41,6 +41,7 @@ export const CONTEXT_PROMPTS = {
|
|||||||
`You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called TriliumNext Notes to answer the user's question.
|
`You are an AI assistant that decides what information needs to be retrieved from a user's knowledge base called TriliumNext Notes to answer the user's question.
|
||||||
Given the user's question, generate 3-5 specific search queries that would help find relevant information.
|
Given the user's question, generate 3-5 specific search queries that would help find relevant information.
|
||||||
Each query should be focused on a different aspect of the question.
|
Each query should be focused on a different aspect of the question.
|
||||||
|
Avoid generating queries that are too broad, vague, or about a user's entire Note database, and make sure they are relevant to the user's question.
|
||||||
Format your answer as a JSON array of strings, with each string being a search query.
|
Format your answer as a JSON array of strings, with each string being a search query.
|
||||||
Example: ["exact topic mentioned", "related concept 1", "related concept 2"]`,
|
Example: ["exact topic mentioned", "related concept 1", "related concept 2"]`,
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user