chore(server): fix more type errors

This commit is contained in:
Elian Doran 2025-05-28 19:57:55 +03:00
parent ba7c93967e
commit ff106e21cf
No known key found for this signature in database
15 changed files with 99 additions and 43 deletions

View File

@ -51,7 +51,7 @@ export function getLocales(): Locale[] {
}
function getCurrentLanguage(): LOCALE_IDS {
let language: string;
let language: string | null = null;
if (sql_init.isDbInitialized()) {
language = options.getOptionOrNull("locale");
}

View File

@ -84,7 +84,7 @@ async function importOpml(taskContext: TaskContext, fileBuffer: string | Buffer,
}
const outlines = xml.opml.body[0].outline || [];
let returnNote = null;
let returnNote: BNote | null = null;
for (const outline of outlines) {
const note = importOutline(outline, parentNote.noteId);

View File

@ -9,7 +9,7 @@ export interface Message {
content: string;
name?: string;
tool_call_id?: string;
tool_calls?: ToolCall[];
tool_calls?: ToolCall[] | null;
sessionId?: string; // Optional session ID for WebSocket communication
}
@ -210,7 +210,7 @@ export interface ChatResponse {
stream?: (callback: (chunk: StreamChunk) => Promise<void> | void) => Promise<string>;
/** Tool calls from the LLM (if tools were used and the model supports them) */
tool_calls?: ToolCall[];
tool_calls?: ToolCall[] | null;
}
export interface AIService {

View File

@ -22,20 +22,24 @@ export interface NoteEmbeddingContext {
title: string;
mime: string;
}[];
backlinks?: {
sourceNoteId: string;
sourceTitle: string;
relationName: string;
}[];
relatedNotes?: {
targetNoteId: string;
targetTitle: string;
relationName: string;
}[];
backlinks?: Backlink[];
relatedNotes?: RelatedNote[];
labelValues?: Record<string, string>;
templateTitles?: string[];
}
export interface Backlink {
sourceNoteId: string;
sourceTitle: string;
relationName: string;
}
export interface RelatedNote {
targetNoteId: string;
targetTitle: string;
relationName: string;
}
/**
* Information about an embedding model's capabilities
*/

View File

@ -8,6 +8,14 @@ import entityChangesService from "../../../services/entity_changes.js";
import type { EntityChange } from "../../../services/entity_changes_interface.js";
import { EMBEDDING_CONSTANTS } from "../constants/embedding_constants.js";
import { SEARCH_CONSTANTS } from '../constants/search_constants.js';
interface Similarity {
noteId: string;
similarity: number;
contentType: string;
bonuses?: Record<string, number>; // Optional for debugging
}
/**
* Creates or updates an embedding for a note
*/
@ -434,7 +442,7 @@ async function processEmbeddings(queryEmbedding: Float32Array, embeddings: any[]
return { bonuses, totalBonus };
}
const similarities = [];
const similarities: Similarity[] = [];
try {
// Try to extract the original query text if it was added to the metadata

View File

@ -7,6 +7,21 @@ import { getAnthropicOptions } from './providers.js';
import log from '../../log.js';
import Anthropic from '@anthropic-ai/sdk';
import { SEARCH_CONSTANTS } from '../constants/search_constants.js';
import type { ToolCall } from '../tools/tool_interfaces.js';
interface AnthropicMessage extends Omit<Message, "content"> {
content: MessageContent[] | string;
}
interface MessageContent {
type: "text" | "tool_use" | "tool_result";
text?: string;
id?: string;
name?: string;
content?: string;
tool_use_id?: string;
input?: string | Record<string, unknown>;
}
export class AnthropicService extends BaseAIService {
private client: any = null;
@ -130,7 +145,7 @@ export class AnthropicService extends BaseAIService {
.join('');
// Process tool calls if any are present in the response
let toolCalls = null;
let toolCalls: ToolCall[] | null = null;
if (response.content) {
const toolBlocks = response.content.filter((block: any) =>
block.type === 'tool_use' ||
@ -157,7 +172,7 @@ export class AnthropicService extends BaseAIService {
return null;
}).filter(Boolean);
log.info(`Extracted ${toolCalls.length} tool calls from Anthropic response`);
log.info(`Extracted ${toolCalls?.length} tool calls from Anthropic response`);
}
}
@ -406,8 +421,8 @@ export class AnthropicService extends BaseAIService {
/**
* Format messages for the Anthropic API
*/
private formatMessages(messages: Message[]): any[] {
const anthropicMessages: any[] = [];
private formatMessages(messages: Message[]): AnthropicMessage[] {
const anthropicMessages: AnthropicMessage[] = [];
// Process each message
for (const msg of messages) {
@ -424,7 +439,7 @@ export class AnthropicService extends BaseAIService {
// Assistant messages need special handling for tool_calls
if (msg.tool_calls && msg.tool_calls.length > 0) {
// Create content blocks array for tool calls
const content = [];
const content: MessageContent[] = [];
// Add text content if present
if (msg.content) {

View File

@ -181,7 +181,7 @@ export async function updateEmbeddingProviderConfig(
}
// Build update query parts
const updates = [];
const updates: string[] = [];
const params: any[] = [];
if (priority !== undefined) {

View File

@ -8,6 +8,26 @@ import type { Tool, ToolHandler } from './tool_interfaces.js';
import log from '../../log.js';
import becca from '../../../becca/becca.js';
interface CodeBlock {
code: string;
language?: string;
}
interface Heading {
text: string;
level: number; // 1 for H1, 2 for H2, etc.
}
interface List {
type: "unordered" | "ordered";
items: string[];
}
interface Table {
headers: string[];
rows: string[][];
}
/**
* Definition of the content extraction tool
*/
@ -137,8 +157,8 @@ export class ContentExtractionTool implements ToolHandler {
/**
* Extract lists from HTML content
*/
private extractLists(content: string): Array<{ type: string, items: string[] }> {
const lists = [];
private extractLists(content: string): List[] {
const lists: List[] = [];
// Extract unordered lists
const ulRegex = /<ul[^>]*>([\s\S]*?)<\/ul>/gi;
@ -179,7 +199,7 @@ export class ContentExtractionTool implements ToolHandler {
* Extract list items from list content
*/
private extractListItems(listContent: string): string[] {
const items = [];
const items: string[] = [];
const itemRegex = /<li[^>]*>([\s\S]*?)<\/li>/gi;
let itemMatch;
@ -196,15 +216,15 @@ export class ContentExtractionTool implements ToolHandler {
/**
* Extract tables from HTML content
*/
private extractTables(content: string): Array<{ headers: string[], rows: string[][] }> {
const tables = [];
private extractTables(content: string): Table[] {
const tables: Table[] = [];
const tableRegex = /<table[^>]*>([\s\S]*?)<\/table>/gi;
let tableMatch;
let tableMatch: RegExpExecArray | null;
while ((tableMatch = tableRegex.exec(content)) !== null) {
const tableContent = tableMatch[1];
const headers = [];
const rows = [];
const headers: string[] = [];
const rows: string[][] = [];
// Extract table headers
const headerRegex = /<th[^>]*>([\s\S]*?)<\/th>/gi;
@ -218,7 +238,7 @@ export class ContentExtractionTool implements ToolHandler {
let rowMatch;
while ((rowMatch = rowRegex.exec(tableContent)) !== null) {
const rowContent = rowMatch[1];
const cells = [];
const cells: string[] = [];
const cellRegex = /<td[^>]*>([\s\S]*?)<\/td>/gi;
let cellMatch;
@ -246,7 +266,7 @@ export class ContentExtractionTool implements ToolHandler {
* Extract headings from HTML content
*/
private extractHeadings(content: string): Array<{ level: number, text: string }> {
const headings = [];
const headings: Heading[] = [];
for (let i = 1; i <= 6; i++) {
const headingRegex = new RegExp(`<h${i}[^>]*>([\\s\\S]*?)<\/h${i}>`, 'gi');
@ -270,7 +290,7 @@ export class ContentExtractionTool implements ToolHandler {
* Extract code blocks from HTML content
*/
private extractCodeBlocks(content: string): Array<{ language?: string, code: string }> {
const codeBlocks = [];
const codeBlocks: CodeBlock[] = [];
// Look for <pre> and <code> blocks
const preRegex = /<pre[^>]*>([\s\S]*?)<\/pre>/gi;

View File

@ -9,6 +9,7 @@ import log from '../../log.js';
import becca from '../../../becca/becca.js';
import notes from '../../notes.js';
import attributes from '../../attributes.js';
import type { BNote } from '../../backend_script_entrypoint.js';
/**
* Definition of the note creation tool
@ -89,7 +90,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 = null;
let parent: BNote | null = null;
if (parentNoteId) {
parent = becca.notes[parentNoteId];
if (!parent) {

View File

@ -10,6 +10,14 @@ import becca from '../../../becca/becca.js';
import attributes from '../../attributes.js';
import aiServiceManager from '../ai_service_manager.js';
import { SEARCH_CONSTANTS } from '../constants/search_constants.js';
import type { Backlink, RelatedNote } from '../embeddings/embeddings_interface.js';
interface Suggestion {
targetNoteId: string;
targetTitle: string;
similarity: number;
suggestedRelation: string;
}
/**
* Definition of the relationship tool
@ -180,7 +188,7 @@ export class RelationshipTool implements ToolHandler {
.filter((attr: any) => attr.type === 'relation')
.slice(0, limit);
const outgoingRelations = [];
const outgoingRelations: RelatedNote[] = [];
for (const attr of outgoingAttributes) {
const targetNote = becca.notes[attr.value];
@ -196,7 +204,7 @@ export class RelationshipTool implements ToolHandler {
// Get incoming relationships (where this note is the target)
// Since becca.findNotesWithRelation doesn't exist, use attributes to find notes with relation
const incomingRelations = [];
const incomingRelations: Backlink[] = [];
// Find all attributes of type relation that point to this note
const relationAttributes = sourceNote.getTargetRelations();
@ -321,7 +329,7 @@ export class RelationshipTool implements ToolHandler {
const sourceContent = await sourceNote.getContent();
// Prepare suggestions
const suggestions = [];
const suggestions: Suggestion[] = [];
for (const relatedNote of relatedResult.relatedNotes) {
try {

View File

@ -755,7 +755,7 @@ function updateNoteData(noteId: string, content: string, attachments: Attachment
function undeleteNote(noteId: string, taskContext: TaskContext) {
const noteRow = sql.getRow<NoteRow>("SELECT * FROM notes WHERE noteId = ?", [noteId]);
if (!noteRow.isDeleted) {
if (!noteRow.isDeleted || !noteRow.deleteId) {
log.error(`Note '${noteId}' is not deleted and thus cannot be undeleted.`);
return;
}

View File

@ -118,7 +118,7 @@ function getParams(params?: ScriptParams) {
}
function getScriptBundleForFrontend(note: BNote, script?: string, params?: ScriptParams) {
let overrideContent = null;
let overrideContent: string | null = null;
if (script) {
overrideContent = `return (${script}\r\n)(${getParams(params)})`;
@ -170,7 +170,7 @@ function getScriptBundle(note: BNote, root: boolean = true, scriptEnv: string |
includedNoteIds.push(note.noteId);
const modules = [];
const modules: BNote[] = [];
for (const child of note.getChildNotes()) {
const childBundle = getScriptBundle(child, false, scriptEnv, includedNoteIds);

View File

@ -294,11 +294,11 @@ function getExpression(tokens: TokenData[], searchContext: SearchContext, level
valueExtractor: ValueExtractor;
direction: string;
}[] = [];
let limit;
let limit: number | undefined = undefined;
if (tokens[i].token === "orderby") {
do {
const propertyPath = [];
const propertyPath: string[] = [];
let direction = "asc";
do {

View File

@ -36,7 +36,7 @@ function searchFromNote(note: BNote): SearchNoteResult {
const searchScript = note.getRelationValue("searchScript");
const searchString = note.getLabelValue("searchString") || "";
let error = null;
let error: string | null = null;
if (searchScript) {
searchResultNoteIds = searchFromRelation(note, "searchScript");

View File

@ -43,7 +43,7 @@ export default class Shaca {
}
getNotes(noteIds: string[], ignoreMissing = false) {
const filteredNotes = [];
const filteredNotes: SNote[] = [];
for (const noteId of noteIds) {
const note = this.notes[noteId];