Skip to content
This repository was archived by the owner on Jun 24, 2025. It is now read-only.

Remove Embeddings from LLM feature #2205

Merged
merged 5 commits into from
Jun 7, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/client/src/server_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ export interface EntityChange {
instanceId?: string | null;
}

export type EntityType = "notes" | "branches" | "attributes" | "note_reordering" | "revisions" | "options" | "attachments" | "blobs" | "etapi_tokens" | "note_embeddings";
export type EntityType = "notes" | "branches" | "attributes" | "note_reordering" | "revisions" | "options" | "attachments" | "blobs" | "etapi_tokens";
2 changes: 1 addition & 1 deletion apps/client/src/services/froca_updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async function processEntityChanges(entityChanges: EntityChange[]) {
loadResults.addOption(attributeEntity.name);
} else if (ec.entityName === "attachments") {
processAttachment(loadResults, ec);
} else if (ec.entityName === "blobs" || ec.entityName === "etapi_tokens" || ec.entityName === "note_embeddings") {
} else if (ec.entityName === "blobs" || ec.entityName === "etapi_tokens") {
// NOOP - these entities are handled at the backend level and don't require frontend processing
} else {
throw new Error(`Unknown entityName '${ec.entityName}'`);
Expand Down
14 changes: 1 addition & 13 deletions apps/client/src/services/load_results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,7 @@ interface OptionRow {}

interface NoteReorderingRow {}

interface NoteEmbeddingRow {
embedId: string;
noteId: string;
providerId: string;
modelId: string;
dimension: number;
version: number;
dateCreated: string;
utcDateCreated: string;
dateModified: string;
utcDateModified: string;
}


type EntityRowMappings = {
notes: NoteRow;
Expand All @@ -64,7 +53,6 @@ type EntityRowMappings = {
options: OptionRow;
revisions: RevisionRow;
note_reordering: NoteReorderingRow;
note_embeddings: NoteEmbeddingRow;
};

export type EntityRowNames = keyof EntityRowMappings;
Expand Down
75 changes: 3 additions & 72 deletions apps/client/src/translations/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1124,18 +1124,15 @@
"layout-horizontal-description": "launcher bar is underneath the tab bar, the tab bar is now full width."
},
"ai_llm": {
"embeddings_configuration": "Embeddings Configuration",
"not_started": "Not started",
"title": "AI & Embedding Settings",
"embedding_statistics": "Embedding Statistics",
"title": "AI Settings",
"processed_notes": "Processed Notes",
"total_notes": "Total Notes",
"progress": "Progress",
"queued_notes": "Queued Notes",
"failed_notes": "Failed Notes",
"last_processed": "Last Processed",
"refresh_stats": "Refresh Statistics",
"no_failed_embeddings": "No failed embeddings found.",
"enable_ai_features": "Enable AI/LLM features",
"enable_ai_description": "Enable AI features like note summarization, content generation, and other LLM capabilities",
"openai_tab": "OpenAI",
Expand All @@ -1160,49 +1157,27 @@
"anthropic_api_key_description": "Your Anthropic API key for accessing Claude models",
"default_model": "Default Model",
"openai_model_description": "Examples: gpt-4o, gpt-4-turbo, gpt-3.5-turbo",
"embedding_model": "Embedding Model",
"openai_embedding_model_description": "Model used for generating embeddings (text-embedding-3-small recommended)",
"base_url": "Base URL",
"openai_url_description": "Default: https://api.openai.com/v1",
"anthropic_settings": "Anthropic Settings",
"anthropic_url_description": "Base URL for the Anthropic API (default: https://api.anthropic.com)",
"anthropic_model_description": "Anthropic Claude models for chat completion",
"voyage_settings": "Voyage AI Settings",
"voyage_api_key_description": "Your Voyage AI API key for accessing embeddings services",
"ollama_settings": "Ollama Settings",
"ollama_url_description": "URL for the Ollama API (default: http://localhost:11434)",
"ollama_model_description": "Ollama model to use for chat completion",
"anthropic_configuration": "Anthropic Configuration",
"voyage_embedding_model_description": "Voyage AI embedding models for text embeddings (voyage-2 recommended)",
"voyage_configuration": "Voyage AI Configuration",
"voyage_url_description": "Default: https://api.voyageai.com/v1",
"ollama_configuration": "Ollama Configuration",
"enable_ollama": "Enable Ollama",
"enable_ollama_description": "Enable Ollama for local AI model usage",
"ollama_url": "Ollama URL",
"ollama_model": "Ollama Model",
"ollama_embedding_model": "Embedding Model",
"ollama_embedding_model_description": "Specialized model for generating embeddings (vector representations)",
"refresh_models": "Refresh Models",
"refreshing_models": "Refreshing...",
"embedding_configuration": "Embeddings Configuration",
"embedding_default_provider": "Default Provider",
"embedding_default_provider_description": "Select the default provider used for generating note embeddings",
"embedding_provider_precedence": "Embedding Provider Precedence",
"embedding_providers_order": "Embedding Provider Order",
"embedding_providers_order_description": "Set the order of embedding providers in comma-separated format (e.g., \"openai,voyage,ollama,local\")",
"enable_automatic_indexing": "Enable Automatic Indexing",
"enable_automatic_indexing_description": "Automatically generate embeddings for new and updated notes",
"embedding_auto_update_enabled": "Auto-update Embeddings",
"embedding_auto_update_enabled_description": "Automatically update embeddings when notes are modified",
"recreate_embeddings": "Recreate All Embeddings",
"recreate_embeddings_description": "Regenerate all note embeddings from scratch (may take a long time for large note collections)",
"recreate_embeddings_started": "Embeddings regeneration started. This may take a long time for large note collections.",
"recreate_embeddings_error": "Error starting embeddings regeneration. Check logs for details.",
"recreate_embeddings_confirm": "Are you sure you want to recreate all embeddings? This may take a long time for large note collections.",
"rebuild_index": "Rebuild Index",
"rebuild_index_description": "Rebuild the vector search index for better performance (much faster than recreating embeddings)",
"rebuild_index_started": "Embedding index rebuild started. This may take several minutes.",
"rebuild_index_error": "Error starting index rebuild. Check logs for details.",
"note_title": "Note Title",
"error": "Error",
Expand All @@ -1212,43 +1187,16 @@
"partial": "{{ percentage }}% completed",
"retry_queued": "Note queued for retry",
"retry_failed": "Failed to queue note for retry",
"embedding_provider_precedence_description": "Comma-separated list of providers in order of precedence for embeddings search (e.g., 'openai,ollama,anthropic')",
"embedding_dimension_strategy": "Embedding Dimension Strategy",
"embedding_dimension_auto": "Auto (Recommended)",
"embedding_dimension_fixed": "Fixed",
"embedding_similarity_threshold": "Similarity Threshold",
"embedding_similarity_threshold_description": "Minimum similarity score for notes to be included in search results (0-1)",
"max_notes_per_llm_query": "Max Notes Per Query",
"max_notes_per_llm_query_description": "Maximum number of similar notes to include in AI context",
"embedding_dimension_strategy_description": "Choose how embeddings are handled. 'Native' preserves maximum information by adapting smaller vectors to match larger ones (recommended). 'Regenerate' creates new embeddings with the target model for specific search needs.",
"drag_providers_to_reorder": "Drag providers up or down to set your preferred order for embedding searches",
"active_providers": "Active Providers",
"disabled_providers": "Disabled Providers",
"remove_provider": "Remove provider from search",
"restore_provider": "Restore provider to search",
"embedding_generation_location": "Generation Location",
"embedding_generation_location_description": "Select where embedding generation should happen",
"embedding_generation_location_client": "Client/Server",
"embedding_generation_location_sync_server": "Sync Server",
"enable_auto_update_embeddings": "Auto-update Embeddings",
"enable_auto_update_embeddings_description": "Automatically update embeddings when notes are modified",
"auto_update_embeddings": "Auto-update Embeddings",
"auto_update_embeddings_desc": "Automatically update embeddings when notes are modified",
"similarity_threshold": "Similarity Threshold",
"similarity_threshold_description": "Minimum similarity score (0-1) for notes to be included in context for LLM queries",
"embedding_batch_size": "Batch Size",
"embedding_batch_size_description": "Number of notes to process in a single batch (1-50)",
"embedding_update_interval": "Update Interval (ms)",
"embedding_update_interval_description": "Time between processing batches of embeddings (in milliseconds)",
"embedding_default_dimension": "Default Dimension",
"embedding_default_dimension_description": "Default embedding vector dimension when creating new embeddings",
"reprocess_all_embeddings": "Reprocess All Embeddings",
"reprocess_all_embeddings_description": "Queue all notes for embedding processing. This may take some time depending on your number of notes.",
"reprocessing_embeddings": "Reprocessing...",
"reprocess_started": "Embedding reprocessing started in the background",
"reprocess_error": "Error starting embedding reprocessing",

"reprocess_index": "Rebuild Search Index",
"reprocess_index_description": "Optimize the search index for better performance. This uses existing embeddings without regenerating them (much faster than reprocessing all embeddings).",
"reprocessing_index": "Rebuilding...",
"reprocess_index_started": "Search index optimization started in the background",
"reprocess_index_error": "Error rebuilding search index",
Expand All @@ -1261,15 +1209,13 @@
"incomplete": "Incomplete ({{percentage}}%)",
"complete": "Complete (100%)",
"refreshing": "Refreshing...",
"stats_error": "Error fetching embedding statistics",
"auto_refresh_notice": "Auto-refreshes every {{seconds}} seconds",
"note_queued_for_retry": "Note queued for retry",
"failed_to_retry_note": "Failed to retry note",
"all_notes_queued_for_retry": "All failed notes queued for retry",
"failed_to_retry_all": "Failed to retry notes",
"ai_settings": "AI Settings",
"api_key_tooltip": "API key for accessing the service",
"confirm_delete_embeddings": "Are you sure you want to delete all AI embeddings? This will remove all semantic search capabilities until notes are reindexed, which can take a significant amount of time.",
"empty_key_warning": {
"anthropic": "Anthropic API key is empty. Please enter a valid API key.",
"openai": "OpenAI API key is empty. Please enter a valid API key.",
Expand Down Expand Up @@ -1302,7 +1248,6 @@
"note_chat": "Note Chat",
"notes_indexed": "{{ count }} note indexed",
"notes_indexed_plural": "{{ count }} notes indexed",
"reset_embeddings": "Reset Embeddings",
"sources": "Sources",
"start_indexing": "Start Indexing",
"use_advanced_context": "Use Advanced Context",
Expand All @@ -1315,24 +1260,10 @@
},
"create_new_ai_chat": "Create new AI Chat",
"configuration_warnings": "There are some issues with your AI configuration. Please check your settings.",
"embeddings_started": "Embedding generation started",
"embeddings_stopped": "Embedding generation stopped",
"embeddings_toggle_error": "Error toggling embeddings",
"local_embedding_description": "Uses local embedding models for offline text embedding generation",
"local_embedding_settings": "Local Embedding Settings",
"ollama_embedding_settings": "Ollama Embedding Settings",
"ollama_embedding_url_description": "URL for the Ollama API for embedding generation (default: http://localhost:11434)",
"openai_embedding_api_key_description": "Your OpenAI API key for embedding generation (can be different from chat API key)",
"openai_embedding_settings": "OpenAI Embedding Settings",
"openai_embedding_url_description": "Base URL for OpenAI embedding API (default: https://api.openai.com/v1)",
"selected_embedding_provider": "Selected Embedding Provider",
"selected_embedding_provider_description": "Choose the provider for generating note embeddings",
"selected_provider": "Selected Provider",
"selected_provider_description": "Choose the AI provider for chat and completion features",
"select_embedding_provider": "Select embedding provider...",
"select_model": "Select model...",
"select_provider": "Select provider...",
"voyage_embedding_url_description": "Base URL for the Voyage AI embedding API (default: https://api.voyageai.com/v1)"
"select_provider": "Select provider..."
},
"zoom_factor": {
"title": "Zoom Factor (desktop build only)",
Expand Down
6 changes: 0 additions & 6 deletions apps/client/src/widgets/llm_chat/communication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,3 @@ export async function getDirectResponse(noteId: string, messageParams: any): Pro
}
}

/**
* Get embedding statistics
*/
export async function getEmbeddingStats(): Promise<any> {
return server.get('llm/embeddings/stats');
}
6 changes: 3 additions & 3 deletions apps/client/src/widgets/llm_chat/llm_chat_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { TPL, addMessageToChat, showSources, hideSources, showLoadingIndicator,
import { formatMarkdown } from "./utils.js";
import { createChatSession, checkSessionExists, setupStreamingResponse, getDirectResponse } from "./communication.js";
import { extractInChatToolSteps } from "./message_processor.js";
import { validateEmbeddingProviders } from "./validation.js";
import { validateProviders } from "./validation.js";
import type { MessageData, ToolExecutionStep, ChatData } from "./types.js";
import { formatCodeBlocks } from "../../services/syntax_highlight.js";
import { ClassicEditor, type CKTextEditor, type MentionFeed } from "@triliumnext/ckeditor5";
Expand Down Expand Up @@ -616,7 +616,7 @@ export default class LlmChatPanel extends BasicWidget {
}

// Check for any provider validation issues when refreshing
await validateEmbeddingProviders(this.validationWarning);
await validateProviders(this.validationWarning);

// Get current note context if needed
const currentActiveNoteId = appContext.tabManager.getActiveContext()?.note?.noteId || null;
Expand Down Expand Up @@ -767,7 +767,7 @@ export default class LlmChatPanel extends BasicWidget {
*/
private async processUserMessage(content: string) {
// Check for validation issues first
await validateEmbeddingProviders(this.validationWarning);
await validateProviders(this.validationWarning);

// Make sure we have a valid session
if (!this.noteId) {
Expand Down
31 changes: 5 additions & 26 deletions apps/client/src/widgets/llm_chat/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
* Validation functions for LLM Chat
*/
import options from "../../services/options.js";
import { getEmbeddingStats } from "./communication.js";

/**
* Validate embedding providers configuration
* Validate providers configuration
*/
export async function validateEmbeddingProviders(validationWarning: HTMLElement): Promise<void> {
export async function validateProviders(validationWarning: HTMLElement): Promise<void> {
try {
// Check if AI is enabled
const aiEnabled = options.is('aiEnabled');
Expand Down Expand Up @@ -62,23 +61,8 @@ export async function validateEmbeddingProviders(validationWarning: HTMLElement)
// Add checks for other providers as needed
}

// Fetch embedding stats to check if there are any notes being processed
const embeddingStats = await getEmbeddingStats() as {
success: boolean,
stats: {
totalNotesCount: number;
embeddedNotesCount: number;
queuedNotesCount: number;
failedNotesCount: number;
lastProcessedDate: string | null;
percentComplete: number;
}
};
const queuedNotes = embeddingStats?.stats?.queuedNotesCount || 0;
const hasEmbeddingsInQueue = queuedNotes > 0;

// Show warning if there are configuration issues or embeddings in queue
if (configIssues.length > 0 || hasEmbeddingsInQueue) {
// Show warning if there are configuration issues
if (configIssues.length > 0) {
let message = '<i class="bx bx-error-circle me-2"></i><strong>AI Provider Configuration Issues</strong>';

message += '<ul class="mb-1 ps-4">';
Expand All @@ -87,11 +71,6 @@ export async function validateEmbeddingProviders(validationWarning: HTMLElement)
for (const issue of configIssues) {
message += `<li>${issue}</li>`;
}

// Show warning about embeddings queue if applicable
if (hasEmbeddingsInQueue) {
message += `<li>Currently processing embeddings for ${queuedNotes} notes. Some AI features may produce incomplete results until processing completes.</li>`;
}

message += '</ul>';
message += '<div class="mt-2"><a href="javascript:" class="settings-link btn btn-sm btn-outline-secondary"><i class="bx bx-cog me-1"></i>Open AI Settings</a></div>';
Expand All @@ -103,7 +82,7 @@ export async function validateEmbeddingProviders(validationWarning: HTMLElement)
validationWarning.style.display = 'none';
}
} catch (error) {
console.error('Error validating embedding providers:', error);
console.error('Error validating providers:', error);
validationWarning.style.display = 'none';
}
}
Loading