mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 19:12:27 +08:00
resolve linter errors
This commit is contained in:
parent
2d745c12c8
commit
c716481ef8
@ -41,7 +41,10 @@ Format your answer as a valid JSON array without markdown code blocks, like this
|
|||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages: Message[] = [
|
const messages: Array<{
|
||||||
|
role: 'user' | 'assistant' | 'system';
|
||||||
|
content: string;
|
||||||
|
}> = [
|
||||||
{ role: "system", content: this.getEnhancedPrompt() },
|
{ role: "system", content: this.getEnhancedPrompt() },
|
||||||
{ role: "user", content: userQuestion }
|
{ role: "user", content: userQuestion }
|
||||||
];
|
];
|
||||||
|
@ -34,12 +34,12 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo
|
|||||||
maxResults,
|
maxResults,
|
||||||
useEnhancedQueries: true,
|
useEnhancedQueries: true,
|
||||||
threshold: 0.6,
|
threshold: 0.6,
|
||||||
llmService: null // Will use default service
|
llmService: undefined // Let the vectorSearchStage use the default service
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info(`Vector search found ${vectorSearchResult.searchResults.length} relevant notes`);
|
log.info(`Vector search found ${vectorSearchResult.searchResults.length} relevant notes`);
|
||||||
|
|
||||||
// If no results, return empty context
|
// If no results, return empty context
|
||||||
if (vectorSearchResult.searchResults.length === 0) {
|
if (vectorSearchResult.searchResults.length === 0) {
|
||||||
log.info(`No relevant notes found for context extraction`);
|
log.info(`No relevant notes found for context extraction`);
|
||||||
@ -49,10 +49,10 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo
|
|||||||
// Step 2: Format search results into a context string
|
// Step 2: Format search results into a context string
|
||||||
const provider = await providerManager.getPreferredEmbeddingProvider();
|
const provider = await providerManager.getPreferredEmbeddingProvider();
|
||||||
const providerId = provider?.name || 'default';
|
const providerId = provider?.name || 'default';
|
||||||
|
|
||||||
const context = await contextFormatter.buildContextFromNotes(
|
const context = await contextFormatter.buildContextFromNotes(
|
||||||
vectorSearchResult.searchResults,
|
vectorSearchResult.searchResults,
|
||||||
query,
|
query,
|
||||||
providerId,
|
providerId,
|
||||||
messages
|
messages
|
||||||
);
|
);
|
||||||
@ -64,4 +64,4 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo
|
|||||||
return { context: "" };
|
return { context: "" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,12 +76,12 @@ export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { re
|
|||||||
|
|
||||||
// Execute each tool call and add results to messages
|
// Execute each tool call and add results to messages
|
||||||
log.info(`========== STARTING TOOL EXECUTION ==========`);
|
log.info(`========== STARTING TOOL EXECUTION ==========`);
|
||||||
log.info(`Executing ${response.tool_calls.length} tool calls in parallel`);
|
log.info(`Executing ${response.tool_calls?.length || 0} tool calls in parallel`);
|
||||||
|
|
||||||
const executionStartTime = Date.now();
|
const executionStartTime = Date.now();
|
||||||
const toolResults = await Promise.all(response.tool_calls.map(async (toolCall, index) => {
|
const toolResults = await Promise.all((response.tool_calls || []).map(async (toolCall, index) => {
|
||||||
try {
|
try {
|
||||||
log.info(`========== TOOL CALL ${index + 1} OF ${response.tool_calls.length} ==========`);
|
log.info(`========== TOOL CALL ${index + 1} OF ${response.tool_calls?.length || 0} ==========`);
|
||||||
log.info(`Tool call ${index + 1} received - Name: ${toolCall.function.name}, ID: ${toolCall.id || 'unknown'}`);
|
log.info(`Tool call ${index + 1} received - Name: ${toolCall.function.name}, ID: ${toolCall.id || 'unknown'}`);
|
||||||
|
|
||||||
// Log parameters
|
// Log parameters
|
||||||
|
@ -874,8 +874,8 @@ class RestChatService {
|
|||||||
if (typeof toolCall.function.arguments === 'string') {
|
if (typeof toolCall.function.arguments === 'string') {
|
||||||
try {
|
try {
|
||||||
args = JSON.parse(toolCall.function.arguments);
|
args = JSON.parse(toolCall.function.arguments);
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
log.error(`Failed to parse tool arguments: ${e.message}`);
|
log.error(`Failed to parse tool arguments: ${e instanceof Error ? e.message : String(e)}`);
|
||||||
|
|
||||||
// Try cleanup and retry
|
// Try cleanup and retry
|
||||||
try {
|
try {
|
||||||
|
@ -116,7 +116,7 @@ export class AttributeManagerTool implements ToolHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the attribute
|
// Create the attribute
|
||||||
await attributes.createAttribute(noteId, attributeName, value);
|
await attributes.createLabel(noteId, attributeName, value);
|
||||||
const duration = Date.now() - startTime;
|
const duration = Date.now() - startTime;
|
||||||
|
|
||||||
log.info(`Added attribute ${attributeName}=${value || ''} in ${duration}ms`);
|
log.info(`Added attribute ${attributeName}=${value || ''} in ${duration}ms`);
|
||||||
@ -153,7 +153,18 @@ export class AttributeManagerTool implements ToolHandler {
|
|||||||
|
|
||||||
// Remove all matching attributes
|
// Remove all matching attributes
|
||||||
for (const attr of attributesToRemove) {
|
for (const attr of attributesToRemove) {
|
||||||
await attributes.deleteAttribute(attr.attributeId);
|
// Delete attribute by recreating it with isDeleted flag
|
||||||
|
const attrToDelete = {
|
||||||
|
attributeId: attr.attributeId,
|
||||||
|
noteId: attr.noteId,
|
||||||
|
type: attr.type,
|
||||||
|
name: attr.name,
|
||||||
|
value: attr.value,
|
||||||
|
isDeleted: true,
|
||||||
|
position: attr.position,
|
||||||
|
utcDateModified: new Date().toISOString()
|
||||||
|
};
|
||||||
|
await attributes.createAttribute(attrToDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
const duration = Date.now() - startTime;
|
const duration = Date.now() - startTime;
|
||||||
@ -195,7 +206,18 @@ export class AttributeManagerTool implements ToolHandler {
|
|||||||
|
|
||||||
// Update all matching attributes
|
// Update all matching attributes
|
||||||
for (const attr of attributesToUpdate) {
|
for (const attr of attributesToUpdate) {
|
||||||
await attributes.updateAttributeValue(attr.attributeId, attributeValue);
|
// Update by recreating with the same ID but new value
|
||||||
|
const attrToUpdate = {
|
||||||
|
attributeId: attr.attributeId,
|
||||||
|
noteId: attr.noteId,
|
||||||
|
type: attr.type,
|
||||||
|
name: attr.name,
|
||||||
|
value: attributeValue,
|
||||||
|
isDeleted: false,
|
||||||
|
position: attr.position,
|
||||||
|
utcDateModified: new Date().toISOString()
|
||||||
|
};
|
||||||
|
await attributes.createAttribute(attrToUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
const duration = Date.now() - startTime;
|
const duration = Date.now() - startTime;
|
||||||
|
@ -221,13 +221,14 @@ export class CalendarIntegrationTool implements ToolHandler {
|
|||||||
|
|
||||||
// Create the new note
|
// Create the new note
|
||||||
const createStartTime = Date.now();
|
const createStartTime = Date.now();
|
||||||
const noteId = await notes.createNewNote({
|
const result = notes.createNewNote({
|
||||||
parentNoteId: parent.noteId,
|
parentNoteId: parent.noteId,
|
||||||
title: title,
|
title: title,
|
||||||
content: content,
|
content: content,
|
||||||
type: 'text',
|
type: 'text' as const,
|
||||||
mime: 'text/html'
|
mime: 'text/html'
|
||||||
});
|
});
|
||||||
|
const noteId = result.note.noteId;
|
||||||
const createDuration = Date.now() - createStartTime;
|
const createDuration = Date.now() - createStartTime;
|
||||||
|
|
||||||
if (!noteId) {
|
if (!noteId) {
|
||||||
|
@ -88,22 +88,22 @@ export class ContentExtractionTool implements ToolHandler {
|
|||||||
const extractedContent: any = {};
|
const extractedContent: any = {};
|
||||||
|
|
||||||
if (extractionType === 'lists' || extractionType === 'all') {
|
if (extractionType === 'lists' || extractionType === 'all') {
|
||||||
extractedContent.lists = this.extractLists(content);
|
extractedContent.lists = this.extractLists(typeof content === 'string' ? content : content.toString());
|
||||||
log.info(`Extracted ${extractedContent.lists.length} lists`);
|
log.info(`Extracted ${extractedContent.lists.length} lists`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extractionType === 'tables' || extractionType === 'all') {
|
if (extractionType === 'tables' || extractionType === 'all') {
|
||||||
extractedContent.tables = this.extractTables(content);
|
extractedContent.tables = this.extractTables(typeof content === 'string' ? content : content.toString());
|
||||||
log.info(`Extracted ${extractedContent.tables.length} tables`);
|
log.info(`Extracted ${extractedContent.tables.length} tables`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extractionType === 'headings' || extractionType === 'all') {
|
if (extractionType === 'headings' || extractionType === 'all') {
|
||||||
extractedContent.headings = this.extractHeadings(content);
|
extractedContent.headings = this.extractHeadings(typeof content === 'string' ? content : content.toString());
|
||||||
log.info(`Extracted ${extractedContent.headings.length} headings`);
|
log.info(`Extracted ${extractedContent.headings.length} headings`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extractionType === 'codeBlocks' || extractionType === 'all') {
|
if (extractionType === 'codeBlocks' || extractionType === 'all') {
|
||||||
extractedContent.codeBlocks = this.extractCodeBlocks(content);
|
extractedContent.codeBlocks = this.extractCodeBlocks(typeof content === 'string' ? content : content.toString());
|
||||||
log.info(`Extracted ${extractedContent.codeBlocks.length} code blocks`);
|
log.info(`Extracted ${extractedContent.codeBlocks.length} code blocks`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,46 +315,42 @@ export class ContentExtractionTool implements ToolHandler {
|
|||||||
private filterContentByQuery(content: any, query: string): void {
|
private filterContentByQuery(content: any, query: string): void {
|
||||||
const lowerQuery = query.toLowerCase();
|
const lowerQuery = query.toLowerCase();
|
||||||
|
|
||||||
// Filter lists
|
|
||||||
if (content.lists) {
|
if (content.lists) {
|
||||||
content.lists = content.lists.filter(list => {
|
content.lists = content.lists.filter((list: { type: string; items: string[] }) => {
|
||||||
// Keep the list if any item matches the query
|
// Check if any item in the list contains the query
|
||||||
return list.items.some(item => item.toLowerCase().includes(lowerQuery));
|
return list.items.some((item: string) => item.toLowerCase().includes(lowerQuery));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Also filter individual items in each list
|
// Also filter individual items in each list
|
||||||
content.lists.forEach(list => {
|
content.lists.forEach((list: { type: string; items: string[] }) => {
|
||||||
list.items = list.items.filter(item => item.toLowerCase().includes(lowerQuery));
|
list.items = list.items.filter((item: string) => item.toLowerCase().includes(lowerQuery));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter headings
|
|
||||||
if (content.headings) {
|
if (content.headings) {
|
||||||
content.headings = content.headings.filter(heading =>
|
content.headings = content.headings.filter((heading: { level: number; text: string }) =>
|
||||||
heading.text.toLowerCase().includes(lowerQuery)
|
heading.text.toLowerCase().includes(lowerQuery)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter tables
|
|
||||||
if (content.tables) {
|
if (content.tables) {
|
||||||
content.tables = content.tables.filter(table => {
|
content.tables = content.tables.filter((table: { headers: string[]; rows: string[][] }) => {
|
||||||
// Check headers
|
// Check if any header contains the query
|
||||||
const headerMatch = table.headers.some(header =>
|
const headerMatch = table.headers.some((header: string) =>
|
||||||
header.toLowerCase().includes(lowerQuery)
|
header.toLowerCase().includes(lowerQuery)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Check cells
|
// Check if any cell in any row contains the query
|
||||||
const cellMatch = table.rows.some(row =>
|
const cellMatch = table.rows.some((row: string[]) =>
|
||||||
row.some(cell => cell.toLowerCase().includes(lowerQuery))
|
row.some((cell: string) => cell.toLowerCase().includes(lowerQuery))
|
||||||
);
|
);
|
||||||
|
|
||||||
return headerMatch || cellMatch;
|
return headerMatch || cellMatch;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter code blocks
|
|
||||||
if (content.codeBlocks) {
|
if (content.codeBlocks) {
|
||||||
content.codeBlocks = content.codeBlocks.filter(block =>
|
content.codeBlocks = content.codeBlocks.filter((block: { language?: string; code: string }) =>
|
||||||
block.code.toLowerCase().includes(lowerQuery)
|
block.code.toLowerCase().includes(lowerQuery)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import type { Tool, ToolHandler } from './tool_interfaces.js';
|
|||||||
import log from '../../log.js';
|
import log from '../../log.js';
|
||||||
import becca from '../../../becca/becca.js';
|
import becca from '../../../becca/becca.js';
|
||||||
import notes from '../../notes.js';
|
import notes from '../../notes.js';
|
||||||
|
import attributes from '../../attributes.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of the note creation tool
|
* Definition of the note creation tool
|
||||||
@ -43,20 +44,7 @@ export const noteCreationToolDefinition: Tool = {
|
|||||||
},
|
},
|
||||||
attributes: {
|
attributes: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
description: 'Array of attributes to set on the note (e.g., [{"name":"#tag"}, {"name":"priority", "value":"high"}])',
|
description: 'Array of attributes to set on the note (e.g., [{"name":"#tag"}, {"name":"priority", "value":"high"}])'
|
||||||
items: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
name: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Name of the attribute'
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Value of the attribute (if applicable)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ['title', 'content']
|
required: ['title', 'content']
|
||||||
@ -87,7 +75,7 @@ export class NoteCreationTool implements ToolHandler {
|
|||||||
log.info(`Executing create_note tool - Title: "${title}", Type: ${type}, ParentNoteId: ${parentNoteId || 'root'}`);
|
log.info(`Executing create_note tool - Title: "${title}", Type: ${type}, ParentNoteId: ${parentNoteId || 'root'}`);
|
||||||
|
|
||||||
// Validate parent note exists if specified
|
// Validate parent note exists if specified
|
||||||
let parent;
|
let parent = null;
|
||||||
if (parentNoteId) {
|
if (parentNoteId) {
|
||||||
parent = becca.notes[parentNoteId];
|
parent = becca.notes[parentNoteId];
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
@ -98,6 +86,11 @@ export class NoteCreationTool implements ToolHandler {
|
|||||||
parent = becca.getNote('root');
|
parent = becca.getNote('root');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we have a valid parent at this point
|
||||||
|
if (!parent) {
|
||||||
|
return 'Error: Failed to get a valid parent note. Root note may not be accessible.';
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the appropriate mime type
|
// Determine the appropriate mime type
|
||||||
let noteMime = mime;
|
let noteMime = mime;
|
||||||
if (!noteMime) {
|
if (!noteMime) {
|
||||||
@ -122,13 +115,14 @@ export class NoteCreationTool implements ToolHandler {
|
|||||||
|
|
||||||
// Create the note
|
// Create the note
|
||||||
const createStartTime = Date.now();
|
const createStartTime = Date.now();
|
||||||
const noteId = await notes.createNewNote({
|
const result = notes.createNewNote({
|
||||||
parentNoteId: parent.noteId,
|
parentNoteId: parent.noteId,
|
||||||
title: title,
|
title: title,
|
||||||
content: content,
|
content: content,
|
||||||
type: type,
|
type: type as any, // Cast as any since not all string values may match the exact NoteType union
|
||||||
mime: noteMime
|
mime: noteMime
|
||||||
});
|
});
|
||||||
|
const noteId = result.note.noteId;
|
||||||
const createDuration = Date.now() - createStartTime;
|
const createDuration = Date.now() - createStartTime;
|
||||||
|
|
||||||
if (!noteId) {
|
if (!noteId) {
|
||||||
@ -145,7 +139,18 @@ export class NoteCreationTool implements ToolHandler {
|
|||||||
if (!attr.name) continue;
|
if (!attr.name) continue;
|
||||||
|
|
||||||
const attrStartTime = Date.now();
|
const attrStartTime = Date.now();
|
||||||
await notes.createAttribute(noteId, attr.name, attr.value || '');
|
// Use createLabel for label attributes
|
||||||
|
if (attr.name.startsWith('#') || attr.name.startsWith('~')) {
|
||||||
|
await attributes.createLabel(noteId, attr.name.substring(1), attr.value || '');
|
||||||
|
} else {
|
||||||
|
// Use createRelation for relation attributes if value looks like a note ID
|
||||||
|
if (attr.value && attr.value.match(/^[a-zA-Z0-9_]{12}$/)) {
|
||||||
|
await attributes.createRelation(noteId, attr.name, attr.value);
|
||||||
|
} else {
|
||||||
|
// Default to label for other attributes
|
||||||
|
await attributes.createLabel(noteId, attr.name, attr.value || '');
|
||||||
|
}
|
||||||
|
}
|
||||||
const attrDuration = Date.now() - attrStartTime;
|
const attrDuration = Date.now() - attrStartTime;
|
||||||
|
|
||||||
log.info(`Added attribute ${attr.name}=${attr.value || ''} in ${attrDuration}ms`);
|
log.info(`Added attribute ${attr.name}=${attr.value || ''} in ${attrDuration}ms`);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import type { Tool, ToolHandler } from './tool_interfaces.js';
|
import type { Tool, ToolHandler } from './tool_interfaces.js';
|
||||||
import log from '../../log.js';
|
import log from '../../log.js';
|
||||||
import becca from '../../../becca/becca.js';
|
import becca from '../../../becca/becca.js';
|
||||||
|
import notes from '../../notes.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of the note update tool
|
* Definition of the note update tool
|
||||||
@ -79,7 +80,10 @@ export class NoteUpdateTool implements ToolHandler {
|
|||||||
const titleStartTime = Date.now();
|
const titleStartTime = Date.now();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await note.setTitle(title);
|
// Update the note title by setting it and saving
|
||||||
|
note.title = title;
|
||||||
|
note.save();
|
||||||
|
|
||||||
const titleDuration = Date.now() - titleStartTime;
|
const titleDuration = Date.now() - titleStartTime;
|
||||||
log.info(`Updated note title to "${title}" in ${titleDuration}ms`);
|
log.info(`Updated note title to "${title}" in ${titleDuration}ms`);
|
||||||
titleUpdateResult = `Title updated from "${note.title}" to "${title}"`;
|
titleUpdateResult = `Title updated from "${note.title}" to "${title}"`;
|
||||||
|
@ -194,23 +194,27 @@ export class RelationshipTool implements ToolHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get incoming relationships (where this note is the target)
|
// Get incoming relationships (where this note is the target)
|
||||||
const incomingNotes = becca.findNotesWithRelation(sourceNote.noteId);
|
// Since becca.findNotesWithRelation doesn't exist, use attributes to find notes with relation
|
||||||
const incomingRelations = [];
|
const incomingRelations = [];
|
||||||
|
|
||||||
for (const sourceOfRelation of incomingNotes) {
|
// Find all attributes of type relation that point to this note
|
||||||
const incomingAttributes = sourceOfRelation.getOwnedAttributes()
|
const relationAttributes = sourceNote.getTargetRelations();
|
||||||
.filter((attr: any) => attr.type === 'relation' && attr.value === sourceNote.noteId);
|
|
||||||
|
|
||||||
for (const attr of incomingAttributes) {
|
for (const attr of relationAttributes) {
|
||||||
incomingRelations.push({
|
if (attr.type === 'relation') {
|
||||||
relationName: attr.name,
|
const sourceOfRelation = attr.getNote();
|
||||||
sourceNoteId: sourceOfRelation.noteId,
|
|
||||||
sourceTitle: sourceOfRelation.title
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (incomingRelations.length >= limit) {
|
if (sourceOfRelation && !sourceOfRelation.isDeleted) {
|
||||||
break;
|
incomingRelations.push({
|
||||||
|
relationName: attr.name,
|
||||||
|
sourceNoteId: sourceOfRelation.noteId,
|
||||||
|
sourceTitle: sourceOfRelation.title
|
||||||
|
});
|
||||||
|
|
||||||
|
if (incomingRelations.length >= limit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user