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;
|
||||
}
|
||||
|
||||
const messages: Message[] = [
|
||||
const messages: Array<{
|
||||
role: 'user' | 'assistant' | 'system';
|
||||
content: string;
|
||||
}> = [
|
||||
{ role: "system", content: this.getEnhancedPrompt() },
|
||||
{ role: "user", content: userQuestion }
|
||||
];
|
||||
|
@ -34,12 +34,12 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo
|
||||
maxResults,
|
||||
useEnhancedQueries: true,
|
||||
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`);
|
||||
|
||||
|
||||
// If no results, return empty context
|
||||
if (vectorSearchResult.searchResults.length === 0) {
|
||||
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
|
||||
const provider = await providerManager.getPreferredEmbeddingProvider();
|
||||
const providerId = provider?.name || 'default';
|
||||
|
||||
|
||||
const context = await contextFormatter.buildContextFromNotes(
|
||||
vectorSearchResult.searchResults,
|
||||
query,
|
||||
vectorSearchResult.searchResults,
|
||||
query,
|
||||
providerId,
|
||||
messages
|
||||
);
|
||||
@ -64,4 +64,4 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo
|
||||
return { context: "" };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,12 +76,12 @@ export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { re
|
||||
|
||||
// Execute each tool call and add results to messages
|
||||
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 toolResults = await Promise.all(response.tool_calls.map(async (toolCall, index) => {
|
||||
const toolResults = await Promise.all((response.tool_calls || []).map(async (toolCall, index) => {
|
||||
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 parameters
|
||||
|
@ -874,8 +874,8 @@ class RestChatService {
|
||||
if (typeof toolCall.function.arguments === 'string') {
|
||||
try {
|
||||
args = JSON.parse(toolCall.function.arguments);
|
||||
} catch (e) {
|
||||
log.error(`Failed to parse tool arguments: ${e.message}`);
|
||||
} catch (e: unknown) {
|
||||
log.error(`Failed to parse tool arguments: ${e instanceof Error ? e.message : String(e)}`);
|
||||
|
||||
// Try cleanup and retry
|
||||
try {
|
||||
|
@ -116,7 +116,7 @@ export class AttributeManagerTool implements ToolHandler {
|
||||
}
|
||||
|
||||
// Create the attribute
|
||||
await attributes.createAttribute(noteId, attributeName, value);
|
||||
await attributes.createLabel(noteId, attributeName, value);
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
log.info(`Added attribute ${attributeName}=${value || ''} in ${duration}ms`);
|
||||
@ -153,7 +153,18 @@ export class AttributeManagerTool implements ToolHandler {
|
||||
|
||||
// Remove all matching attributes
|
||||
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;
|
||||
@ -195,7 +206,18 @@ export class AttributeManagerTool implements ToolHandler {
|
||||
|
||||
// Update all matching attributes
|
||||
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;
|
||||
|
@ -221,13 +221,14 @@ export class CalendarIntegrationTool implements ToolHandler {
|
||||
|
||||
// Create the new note
|
||||
const createStartTime = Date.now();
|
||||
const noteId = await notes.createNewNote({
|
||||
const result = notes.createNewNote({
|
||||
parentNoteId: parent.noteId,
|
||||
title: title,
|
||||
content: content,
|
||||
type: 'text',
|
||||
type: 'text' as const,
|
||||
mime: 'text/html'
|
||||
});
|
||||
const noteId = result.note.noteId;
|
||||
const createDuration = Date.now() - createStartTime;
|
||||
|
||||
if (!noteId) {
|
||||
|
@ -88,22 +88,22 @@ export class ContentExtractionTool implements ToolHandler {
|
||||
const extractedContent: any = {};
|
||||
|
||||
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`);
|
||||
}
|
||||
|
||||
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`);
|
||||
}
|
||||
|
||||
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`);
|
||||
}
|
||||
|
||||
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`);
|
||||
}
|
||||
|
||||
@ -315,46 +315,42 @@ export class ContentExtractionTool implements ToolHandler {
|
||||
private filterContentByQuery(content: any, query: string): void {
|
||||
const lowerQuery = query.toLowerCase();
|
||||
|
||||
// Filter lists
|
||||
if (content.lists) {
|
||||
content.lists = content.lists.filter(list => {
|
||||
// Keep the list if any item matches the query
|
||||
return list.items.some(item => item.toLowerCase().includes(lowerQuery));
|
||||
content.lists = content.lists.filter((list: { type: string; items: string[] }) => {
|
||||
// Check if any item in the list contains the query
|
||||
return list.items.some((item: string) => item.toLowerCase().includes(lowerQuery));
|
||||
});
|
||||
|
||||
// Also filter individual items in each list
|
||||
content.lists.forEach(list => {
|
||||
list.items = list.items.filter(item => item.toLowerCase().includes(lowerQuery));
|
||||
content.lists.forEach((list: { type: string; items: string[] }) => {
|
||||
list.items = list.items.filter((item: string) => item.toLowerCase().includes(lowerQuery));
|
||||
});
|
||||
}
|
||||
|
||||
// Filter 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)
|
||||
);
|
||||
}
|
||||
|
||||
// Filter tables
|
||||
if (content.tables) {
|
||||
content.tables = content.tables.filter(table => {
|
||||
// Check headers
|
||||
const headerMatch = table.headers.some(header =>
|
||||
content.tables = content.tables.filter((table: { headers: string[]; rows: string[][] }) => {
|
||||
// Check if any header contains the query
|
||||
const headerMatch = table.headers.some((header: string) =>
|
||||
header.toLowerCase().includes(lowerQuery)
|
||||
);
|
||||
|
||||
// Check cells
|
||||
const cellMatch = table.rows.some(row =>
|
||||
row.some(cell => cell.toLowerCase().includes(lowerQuery))
|
||||
// Check if any cell in any row contains the query
|
||||
const cellMatch = table.rows.some((row: string[]) =>
|
||||
row.some((cell: string) => cell.toLowerCase().includes(lowerQuery))
|
||||
);
|
||||
|
||||
return headerMatch || cellMatch;
|
||||
});
|
||||
}
|
||||
|
||||
// Filter code blocks
|
||||
if (content.codeBlocks) {
|
||||
content.codeBlocks = content.codeBlocks.filter(block =>
|
||||
content.codeBlocks = content.codeBlocks.filter((block: { language?: string; code: string }) =>
|
||||
block.code.toLowerCase().includes(lowerQuery)
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import type { Tool, ToolHandler } from './tool_interfaces.js';
|
||||
import log from '../../log.js';
|
||||
import becca from '../../../becca/becca.js';
|
||||
import notes from '../../notes.js';
|
||||
import attributes from '../../attributes.js';
|
||||
|
||||
/**
|
||||
* Definition of the note creation tool
|
||||
@ -43,20 +44,7 @@ export const noteCreationToolDefinition: Tool = {
|
||||
},
|
||||
attributes: {
|
||||
type: 'array',
|
||||
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)'
|
||||
}
|
||||
}
|
||||
}
|
||||
description: 'Array of attributes to set on the note (e.g., [{"name":"#tag"}, {"name":"priority", "value":"high"}])'
|
||||
}
|
||||
},
|
||||
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'}`);
|
||||
|
||||
// Validate parent note exists if specified
|
||||
let parent;
|
||||
let parent = null;
|
||||
if (parentNoteId) {
|
||||
parent = becca.notes[parentNoteId];
|
||||
if (!parent) {
|
||||
@ -98,6 +86,11 @@ export class NoteCreationTool implements ToolHandler {
|
||||
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
|
||||
let noteMime = mime;
|
||||
if (!noteMime) {
|
||||
@ -122,13 +115,14 @@ export class NoteCreationTool implements ToolHandler {
|
||||
|
||||
// Create the note
|
||||
const createStartTime = Date.now();
|
||||
const noteId = await notes.createNewNote({
|
||||
const result = notes.createNewNote({
|
||||
parentNoteId: parent.noteId,
|
||||
title: title,
|
||||
content: content,
|
||||
type: type,
|
||||
type: type as any, // Cast as any since not all string values may match the exact NoteType union
|
||||
mime: noteMime
|
||||
});
|
||||
const noteId = result.note.noteId;
|
||||
const createDuration = Date.now() - createStartTime;
|
||||
|
||||
if (!noteId) {
|
||||
@ -145,7 +139,18 @@ export class NoteCreationTool implements ToolHandler {
|
||||
if (!attr.name) continue;
|
||||
|
||||
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;
|
||||
|
||||
log.info(`Added attribute ${attr.name}=${attr.value || ''} in ${attrDuration}ms`);
|
||||
|
@ -7,6 +7,7 @@
|
||||
import type { Tool, ToolHandler } from './tool_interfaces.js';
|
||||
import log from '../../log.js';
|
||||
import becca from '../../../becca/becca.js';
|
||||
import notes from '../../notes.js';
|
||||
|
||||
/**
|
||||
* Definition of the note update tool
|
||||
@ -79,7 +80,10 @@ export class NoteUpdateTool implements ToolHandler {
|
||||
const titleStartTime = Date.now();
|
||||
|
||||
try {
|
||||
await note.setTitle(title);
|
||||
// Update the note title by setting it and saving
|
||||
note.title = title;
|
||||
note.save();
|
||||
|
||||
const titleDuration = Date.now() - titleStartTime;
|
||||
log.info(`Updated note title to "${title}" in ${titleDuration}ms`);
|
||||
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)
|
||||
const incomingNotes = becca.findNotesWithRelation(sourceNote.noteId);
|
||||
// Since becca.findNotesWithRelation doesn't exist, use attributes to find notes with relation
|
||||
const incomingRelations = [];
|
||||
|
||||
for (const sourceOfRelation of incomingNotes) {
|
||||
const incomingAttributes = sourceOfRelation.getOwnedAttributes()
|
||||
.filter((attr: any) => attr.type === 'relation' && attr.value === sourceNote.noteId);
|
||||
// Find all attributes of type relation that point to this note
|
||||
const relationAttributes = sourceNote.getTargetRelations();
|
||||
|
||||
for (const attr of incomingAttributes) {
|
||||
incomingRelations.push({
|
||||
relationName: attr.name,
|
||||
sourceNoteId: sourceOfRelation.noteId,
|
||||
sourceTitle: sourceOfRelation.title
|
||||
});
|
||||
}
|
||||
for (const attr of relationAttributes) {
|
||||
if (attr.type === 'relation') {
|
||||
const sourceOfRelation = attr.getNote();
|
||||
|
||||
if (incomingRelations.length >= limit) {
|
||||
break;
|
||||
if (sourceOfRelation && !sourceOfRelation.isDeleted) {
|
||||
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