mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 20:06:08 +01:00 
			
		
		
		
	allow user to select *where* they want to generate embeddings
This commit is contained in:
		@@ -53,3 +53,5 @@ INSERT INTO options (name, value, isSynced, utcDateModified)
 | 
				
			|||||||
VALUES ('embeddingBatchSize', '10', 1, strftime('%Y-%m-%d %H:%M:%f', 'now'));
 | 
					VALUES ('embeddingBatchSize', '10', 1, strftime('%Y-%m-%d %H:%M:%f', 'now'));
 | 
				
			||||||
INSERT INTO options (name, value, isSynced, utcDateModified) 
 | 
					INSERT INTO options (name, value, isSynced, utcDateModified) 
 | 
				
			||||||
VALUES ('embeddingDefaultDimension', '1536', 1, strftime('%Y-%m-%d %H:%M:%f', 'now')); 
 | 
					VALUES ('embeddingDefaultDimension', '1536', 1, strftime('%Y-%m-%d %H:%M:%f', 'now')); 
 | 
				
			||||||
 | 
					INSERT INTO options (name, value, isSynced, utcDateModified) 
 | 
				
			||||||
 | 
					VALUES ('embeddingGenerationLocation', 'client', 1, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')); 
 | 
				
			||||||
@@ -186,6 +186,15 @@ export default class AiSettingsWidget extends OptionsWidget {
 | 
				
			|||||||
                    <div class="help-text">${t("ai_llm.embedding_default_provider_description")}</div>
 | 
					                    <div class="help-text">${t("ai_llm.embedding_default_provider_description")}</div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <div class="form-group">
 | 
				
			||||||
 | 
					                    <label>${t("ai_llm.embedding_generation_location")}</label>
 | 
				
			||||||
 | 
					                    <select class="embedding-generation-location form-control">
 | 
				
			||||||
 | 
					                        <option value="client">${t("ai_llm.embedding_generation_location_client")}</option>
 | 
				
			||||||
 | 
					                        <option value="sync_server">${t("ai_llm.embedding_generation_location_sync_server")}</option>
 | 
				
			||||||
 | 
					                    </select>
 | 
				
			||||||
 | 
					                    <div class="help-text">${t("ai_llm.embedding_generation_location_description")}</div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
                    <label>
 | 
					                    <label>
 | 
				
			||||||
                        <input class="embedding-auto-update-enabled" type="checkbox">
 | 
					                        <input class="embedding-auto-update-enabled" type="checkbox">
 | 
				
			||||||
@@ -446,6 +455,11 @@ export default class AiSettingsWidget extends OptionsWidget {
 | 
				
			|||||||
            await this.updateOption('embeddingsDefaultProvider', $embeddingDefaultProvider.val() as string);
 | 
					            await this.updateOption('embeddingsDefaultProvider', $embeddingDefaultProvider.val() as string);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const $embeddingGenerationLocation = this.$widget.find('.embedding-generation-location');
 | 
				
			||||||
 | 
					        $embeddingGenerationLocation.on('change', async () => {
 | 
				
			||||||
 | 
					            await this.updateOption('embeddingGenerationLocation', $embeddingGenerationLocation.val() as string);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const $embeddingBatchSize = this.$widget.find('.embedding-batch-size');
 | 
					        const $embeddingBatchSize = this.$widget.find('.embedding-batch-size');
 | 
				
			||||||
        $embeddingBatchSize.on('change', async () => {
 | 
					        $embeddingBatchSize.on('change', async () => {
 | 
				
			||||||
            await this.updateOption('embeddingBatchSize', $embeddingBatchSize.val() as string);
 | 
					            await this.updateOption('embeddingBatchSize', $embeddingBatchSize.val() as string);
 | 
				
			||||||
@@ -541,6 +555,7 @@ export default class AiSettingsWidget extends OptionsWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Load embedding options
 | 
					        // Load embedding options
 | 
				
			||||||
        this.$widget.find('.embedding-default-provider').val(options.embeddingsDefaultProvider || 'openai');
 | 
					        this.$widget.find('.embedding-default-provider').val(options.embeddingsDefaultProvider || 'openai');
 | 
				
			||||||
 | 
					        this.$widget.find('.embedding-generation-location').val(options.embeddingGenerationLocation || 'client');
 | 
				
			||||||
        this.setCheckboxState(this.$widget.find('.embedding-auto-update-enabled'), options.embeddingAutoUpdateEnabled || 'true');
 | 
					        this.setCheckboxState(this.$widget.find('.embedding-auto-update-enabled'), options.embeddingAutoUpdateEnabled || 'true');
 | 
				
			||||||
        this.setCheckboxState(this.$widget.find('.enable-automatic-indexing'), options.enableAutomaticIndexing || 'true');
 | 
					        this.setCheckboxState(this.$widget.find('.enable-automatic-indexing'), options.enableAutomaticIndexing || 'true');
 | 
				
			||||||
        this.$widget.find('.embedding-similarity-threshold').val(options.embeddingSimilarityThreshold || '0.65');
 | 
					        this.$widget.find('.embedding-similarity-threshold').val(options.embeddingSimilarityThreshold || '0.65');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1157,6 +1157,10 @@
 | 
				
			|||||||
    "embedding_configuration": "Embeddings Configuration",
 | 
					    "embedding_configuration": "Embeddings Configuration",
 | 
				
			||||||
    "embedding_default_provider": "Default Provider",
 | 
					    "embedding_default_provider": "Default Provider",
 | 
				
			||||||
    "embedding_default_provider_description": "Select the default provider used for generating note embeddings",
 | 
					    "embedding_default_provider_description": "Select the default provider used for generating note embeddings",
 | 
				
			||||||
 | 
					    "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": "Auto-update Embeddings",
 | 
				
			||||||
    "enable_auto_update_embeddings_description": "Automatically update embeddings when notes are modified",
 | 
					    "enable_auto_update_embeddings_description": "Automatically update embeddings when notes are modified",
 | 
				
			||||||
    "auto_update_embeddings": "Auto-update Embeddings",
 | 
					    "auto_update_embeddings": "Auto-update Embeddings",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,6 +157,16 @@ export async function processEmbeddingQueue() {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if this instance should process embeddings
 | 
				
			||||||
 | 
					    const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					    const isSyncServer = await indexService.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					    const shouldProcessEmbeddings = embeddingLocation === 'client' || isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!shouldProcessEmbeddings) {
 | 
				
			||||||
 | 
					        // This instance is not configured to process embeddings
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const batchSize = parseInt(await options.getOption('embeddingBatchSize') || '10', 10);
 | 
					    const batchSize = parseInt(await options.getOption('embeddingBatchSize') || '10', 10);
 | 
				
			||||||
    const enabledProviders = await getEnabledEmbeddingProviders();
 | 
					    const enabledProviders = await getEnabledEmbeddingProviders();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,9 +57,17 @@ class IndexService {
 | 
				
			|||||||
                throw new Error("No embedding providers available");
 | 
					                throw new Error("No embedding providers available");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Setup automatic indexing if enabled
 | 
					            // Check if this instance should process embeddings
 | 
				
			||||||
            if (await options.getOptionBool('embeddingAutoUpdate')) {
 | 
					            const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					            const isSyncServer = await this.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					            const shouldProcessEmbeddings = embeddingLocation === 'client' || isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Setup automatic indexing if enabled and this instance should process embeddings
 | 
				
			||||||
 | 
					            if (await options.getOptionBool('embeddingAutoUpdate') && shouldProcessEmbeddings) {
 | 
				
			||||||
                this.setupAutomaticIndexing();
 | 
					                this.setupAutomaticIndexing();
 | 
				
			||||||
 | 
					                log.info(`Index service: Automatic indexing enabled, processing embeddings ${isSyncServer ? 'as sync server' : 'as client'}`);
 | 
				
			||||||
 | 
					            } else if (await options.getOptionBool('embeddingAutoUpdate')) {
 | 
				
			||||||
 | 
					                log.info("Index service: Automatic indexing enabled, but this instance is not configured to process embeddings");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Listen for note changes to update index
 | 
					            // Listen for note changes to update index
 | 
				
			||||||
@@ -78,32 +86,33 @@ class IndexService {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private setupEventListeners() {
 | 
					    private setupEventListeners() {
 | 
				
			||||||
        // Listen for note content changes
 | 
					        // Listen for note content changes
 | 
				
			||||||
        eventService.subscribe(eventService.NOTE_CONTENT_CHANGE, ({ entity }) => {
 | 
					        eventService.subscribe(eventService.NOTE_CONTENT_CHANGE, async ({ entity }) => {
 | 
				
			||||||
            if (entity && entity.noteId) {
 | 
					            if (entity && entity.noteId) {
 | 
				
			||||||
                this.queueNoteForIndexing(entity.noteId);
 | 
					                // Always queue notes for indexing, but the actual processing will depend on configuration
 | 
				
			||||||
 | 
					                await this.queueNoteForIndexing(entity.noteId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Listen for new notes
 | 
					        // Listen for new notes
 | 
				
			||||||
        eventService.subscribe(eventService.ENTITY_CREATED, ({ entityName, entity }) => {
 | 
					        eventService.subscribe(eventService.ENTITY_CREATED, async ({ entityName, entity }) => {
 | 
				
			||||||
            if (entityName === "notes" && entity && entity.noteId) {
 | 
					            if (entityName === "notes" && entity && entity.noteId) {
 | 
				
			||||||
                this.queueNoteForIndexing(entity.noteId);
 | 
					                await this.queueNoteForIndexing(entity.noteId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Listen for note title changes
 | 
					        // Listen for note title changes
 | 
				
			||||||
        eventService.subscribe(eventService.NOTE_TITLE_CHANGED, ({ noteId }) => {
 | 
					        eventService.subscribe(eventService.NOTE_TITLE_CHANGED, async ({ noteId }) => {
 | 
				
			||||||
            if (noteId) {
 | 
					            if (noteId) {
 | 
				
			||||||
                this.queueNoteForIndexing(noteId);
 | 
					                await this.queueNoteForIndexing(noteId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Listen for changes in AI settings
 | 
					        // Listen for changes in AI settings
 | 
				
			||||||
        eventService.subscribe(eventService.ENTITY_CHANGED, ({ entityName, entity }) => {
 | 
					        eventService.subscribe(eventService.ENTITY_CHANGED, async ({ entityName, entity }) => {
 | 
				
			||||||
            if (entityName === "options" && entity && entity.name) {
 | 
					            if (entityName === "options" && entity && entity.name) {
 | 
				
			||||||
                if (entity.name.startsWith('ai') || entity.name.startsWith('embedding')) {
 | 
					                if (entity.name.startsWith('ai') || entity.name.startsWith('embedding')) {
 | 
				
			||||||
                    log.info("AI settings changed, updating index service configuration");
 | 
					                    log.info("AI settings changed, updating index service configuration");
 | 
				
			||||||
                    this.updateConfiguration();
 | 
					                    await this.updateConfiguration();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
@@ -122,6 +131,16 @@ class IndexService {
 | 
				
			|||||||
        this.automaticIndexingInterval = setInterval(async () => {
 | 
					        this.automaticIndexingInterval = setInterval(async () => {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                if (!this.indexingInProgress) {
 | 
					                if (!this.indexingInProgress) {
 | 
				
			||||||
 | 
					                    // Check if this instance should process embeddings
 | 
				
			||||||
 | 
					                    const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					                    const isSyncServer = await this.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					                    const shouldProcessEmbeddings = embeddingLocation === 'client' || isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (!shouldProcessEmbeddings) {
 | 
				
			||||||
 | 
					                        // This instance is not configured to process embeddings
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const stats = await vectorStore.getEmbeddingStats();
 | 
					                    const stats = await vectorStore.getEmbeddingStats();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // Only run automatic indexing if we're below 95% completion
 | 
					                    // Only run automatic indexing if we're below 95% completion
 | 
				
			||||||
@@ -147,10 +166,20 @@ class IndexService {
 | 
				
			|||||||
            const intervalMs = parseInt(await options.getOption('embeddingUpdateInterval') || '3600000', 10);
 | 
					            const intervalMs = parseInt(await options.getOption('embeddingUpdateInterval') || '3600000', 10);
 | 
				
			||||||
            this.indexUpdateInterval = intervalMs;
 | 
					            this.indexUpdateInterval = intervalMs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Check if this instance should process embeddings
 | 
				
			||||||
 | 
					            const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					            const isSyncServer = await this.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					            const shouldProcessEmbeddings = embeddingLocation === 'client' || isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Update automatic indexing setting
 | 
					            // Update automatic indexing setting
 | 
				
			||||||
            const autoIndexing = await options.getOptionBool('embeddingAutoUpdate');
 | 
					            const autoIndexing = await options.getOptionBool('embeddingAutoUpdate');
 | 
				
			||||||
            if (autoIndexing && !this.automaticIndexingInterval) {
 | 
					            if (autoIndexing && shouldProcessEmbeddings && !this.automaticIndexingInterval) {
 | 
				
			||||||
                this.setupAutomaticIndexing();
 | 
					                this.setupAutomaticIndexing();
 | 
				
			||||||
 | 
					                log.info(`Index service: Automatic indexing enabled, processing embeddings ${isSyncServer ? 'as sync server' : 'as client'}`);
 | 
				
			||||||
 | 
					            } else if (autoIndexing && !shouldProcessEmbeddings && this.automaticIndexingInterval) {
 | 
				
			||||||
 | 
					                clearInterval(this.automaticIndexingInterval);
 | 
				
			||||||
 | 
					                this.automaticIndexingInterval = undefined;
 | 
				
			||||||
 | 
					                log.info("Index service: Automatic indexing disabled for this instance based on configuration");
 | 
				
			||||||
            } else if (!autoIndexing && this.automaticIndexingInterval) {
 | 
					            } else if (!autoIndexing && this.automaticIndexingInterval) {
 | 
				
			||||||
                clearInterval(this.automaticIndexingInterval);
 | 
					                clearInterval(this.automaticIndexingInterval);
 | 
				
			||||||
                this.automaticIndexingInterval = undefined;
 | 
					                this.automaticIndexingInterval = undefined;
 | 
				
			||||||
@@ -179,6 +208,8 @@ class IndexService {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					            // Always queue notes for indexing, regardless of where embedding generation happens
 | 
				
			||||||
 | 
					            // The actual processing will be determined when the queue is processed
 | 
				
			||||||
            await vectorStore.queueNoteForEmbedding(noteId, 'UPDATE');
 | 
					            await vectorStore.queueNoteForEmbedding(noteId, 'UPDATE');
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch (error: any) {
 | 
					        } catch (error: any) {
 | 
				
			||||||
@@ -201,6 +232,17 @@ class IndexService {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					            // Check if this instance should process embeddings
 | 
				
			||||||
 | 
					            const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					            const isSyncServer = await this.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					            const shouldProcessEmbeddings = embeddingLocation === 'client' || isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!shouldProcessEmbeddings) {
 | 
				
			||||||
 | 
					                // This instance is not configured to process embeddings
 | 
				
			||||||
 | 
					                log.info("Skipping full indexing as this instance is not configured to process embeddings");
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.indexingInProgress = true;
 | 
					            this.indexingInProgress = true;
 | 
				
			||||||
            this.indexRebuildInProgress = true;
 | 
					            this.indexRebuildInProgress = true;
 | 
				
			||||||
            this.indexRebuildProgress = 0;
 | 
					            this.indexRebuildProgress = 0;
 | 
				
			||||||
@@ -321,6 +363,17 @@ class IndexService {
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            this.indexingInProgress = true;
 | 
					            this.indexingInProgress = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Check if this instance should process embeddings
 | 
				
			||||||
 | 
					            const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					            const isSyncServer = await this.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					            const shouldProcessEmbeddings = embeddingLocation === 'client' || isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!shouldProcessEmbeddings) {
 | 
				
			||||||
 | 
					                // This instance is not configured to process embeddings
 | 
				
			||||||
 | 
					                log.info("Skipping batch indexing as this instance is not configured to process embeddings");
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Process the embedding queue
 | 
					            // Process the embedding queue
 | 
				
			||||||
            await vectorStore.processEmbeddingQueue();
 | 
					            await vectorStore.processEmbeddingQueue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -618,6 +671,21 @@ class IndexService {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if this instance is a sync server and should generate embeddings
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    async isSyncServerForEmbeddings() {
 | 
				
			||||||
 | 
					        // Check if this is a sync server (no syncServerHost means this is a sync server)
 | 
				
			||||||
 | 
					        const syncServerHost = await options.getOption('syncServerHost');
 | 
				
			||||||
 | 
					        const isSyncServer = !syncServerHost;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check if embedding generation should happen on the sync server
 | 
				
			||||||
 | 
					        const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					        const shouldGenerateOnSyncServer = embeddingLocation === 'sync_server';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return isSyncServer && shouldGenerateOnSyncServer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Generate a comprehensive index entry for a note
 | 
					     * Generate a comprehensive index entry for a note
 | 
				
			||||||
     * This prepares all metadata and contexts for optimal LLM retrieval
 | 
					     * This prepares all metadata and contexts for optimal LLM retrieval
 | 
				
			||||||
@@ -633,6 +701,21 @@ class IndexService {
 | 
				
			|||||||
                throw new Error(`Note ${noteId} not found`);
 | 
					                throw new Error(`Note ${noteId} not found`);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Check where embedding generation should happen
 | 
				
			||||||
 | 
					            const embeddingLocation = await options.getOption('embeddingGenerationLocation') || 'client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If embedding generation should happen on the sync server and we're not the sync server,
 | 
				
			||||||
 | 
					            // just queue the note for embedding but don't generate it
 | 
				
			||||||
 | 
					            const isSyncServer = await this.isSyncServerForEmbeddings();
 | 
				
			||||||
 | 
					            const shouldSkipGeneration = embeddingLocation === 'sync_server' && !isSyncServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (shouldSkipGeneration) {
 | 
				
			||||||
 | 
					                // We're not the sync server, so just queue the note for embedding
 | 
				
			||||||
 | 
					                // The sync server will handle the actual embedding generation
 | 
				
			||||||
 | 
					                log.info(`Note ${noteId} queued for embedding generation on sync server`);
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get complete note context for indexing
 | 
					            // Get complete note context for indexing
 | 
				
			||||||
            const context = await vectorStore.getNoteEmbeddingContext(noteId);
 | 
					            const context = await vectorStore.getNoteEmbeddingContext(noteId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
 | 
				
			|||||||
    enableAutomaticIndexing: boolean;
 | 
					    enableAutomaticIndexing: boolean;
 | 
				
			||||||
    embeddingSimilarityThreshold: string;
 | 
					    embeddingSimilarityThreshold: string;
 | 
				
			||||||
    maxNotesPerLlmQuery: string;
 | 
					    maxNotesPerLlmQuery: string;
 | 
				
			||||||
 | 
					    embeddingGenerationLocation: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lastSyncedPull: number;
 | 
					    lastSyncedPull: number;
 | 
				
			||||||
    lastSyncedPush: number;
 | 
					    lastSyncedPush: number;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user