fix vector initialisation?

This commit is contained in:
StroepWafel
2026-01-22 11:37:09 +10:30
parent 29cfb4c792
commit b89a6c634c
6 changed files with 174 additions and 14 deletions
+2
View File
@@ -0,0 +1,2 @@
legacy-peer-deps=true
@@ -126,10 +126,16 @@ const globalSearchPlugin: Plugin<typeof settings> = {
initVectorSearch();
// Warm up vector worker in background to improve initial response time
// Warm up vector worker in background to improve initial response time (skip in Firefox)
setTimeout(async () => {
try {
VectorWorkerManager.getInstance();
// Only initialize worker if vector search is supported
const { isVectorSearchSupported } = await import("../utils/browserDetection");
if (isVectorSearchSupported()) {
VectorWorkerManager.getInstance();
} else {
console.debug("[Global Search] Skipping vector worker warm-up (Firefox detected - using text search only)");
}
} catch (error) {
console.warn("[Global Search] Vector worker warm-up failed:", error);
}
@@ -3,9 +3,24 @@ import type { IndexItem } from "../types";
let vectorIndex: EmbeddingIndex | null = null;
let isInitialized = false;
let initializationFailed = false;
let currentAbortController: AbortController | null = null;
let loadedItemIds = new Set<string>();
// Detect Firefox in worker context
function isFirefoxWorker(): boolean {
try {
// Check for Firefox-specific APIs or user agent
if (typeof navigator !== "undefined") {
return navigator.userAgent.toLowerCase().includes("firefox");
}
// In worker context, check for Firefox-specific behavior
return false;
} catch {
return false;
}
}
let streamingSession: {
isActive: boolean;
totalExpected: number;
@@ -21,6 +36,16 @@ async function initWorker() {
console.debug("Vector worker already initialized.");
return;
}
// Skip initialization in Firefox
if (isFirefoxWorker()) {
console.debug("[Vector Worker] Vector search not supported in Firefox - skipping initialization");
isInitialized = true;
initializationFailed = true;
vectorIndex = null;
return;
}
console.debug("Initializing vector worker...");
try {
await initializeModel();
@@ -48,8 +73,9 @@ async function initWorker() {
isInitialized = true;
console.debug("Vector worker initialized successfully.");
} catch (e) {
console.error("Failed to initialize vector worker:", e);
console.warn("[Vector Worker] Failed to initialize vector worker (will use text search only):", e);
isInitialized = true;
initializationFailed = true;
vectorIndex = null;
}
}
@@ -80,18 +106,29 @@ async function startStreamingSession(
totalExpected: number,
batchSize: number = 5,
) {
if (initializationFailed || isFirefoxWorker()) {
self.postMessage({
type: "progress",
data: {
status: "complete",
message: "Vector search not available in Firefox - using text search only",
},
});
return;
}
if (!vectorIndex) {
console.warn(
"Streaming requested but vector index not ready. Attempting init.",
);
await initWorker();
if (!vectorIndex) {
if (!vectorIndex || initializationFailed) {
self.postMessage({
type: "progress",
data: {
status: "error",
status: "complete",
message:
"Vector index not available for streaming after init attempt.",
"Vector index not available - using text search only",
},
});
return;
@@ -306,18 +343,29 @@ async function endStreamingSession() {
async function processItems(items: IndexItem[], signal: AbortSignal) {
console.debug("Worker received process request.");
if (initializationFailed || isFirefoxWorker()) {
self.postMessage({
type: "progress",
data: {
status: "complete",
message: "Vector search not available - using text search only",
},
});
return;
}
if (!vectorIndex) {
console.warn(
"Processing requested but vector index not ready. Attempting init.",
);
await initWorker();
if (!vectorIndex) {
if (!vectorIndex || initializationFailed) {
self.postMessage({
type: "progress",
data: {
status: "error",
status: "complete",
message:
"Vector index not available for processing after init attempt.",
"Vector index not available - using text search only",
},
});
return;
@@ -1,5 +1,6 @@
import { refreshVectorCache } from "../../search/vector/vectorSearch";
import type { IndexItem } from "../types";
import { isVectorSearchSupported } from "../../utils/browserDetection";
import vectorWorker from "./vectorWorker.ts?inlineWorker";
export type ProgressCallback = (data: {
@@ -42,6 +43,13 @@ export class VectorWorkerManager {
}
private async initWorker(): Promise<void> {
// Skip initialization if vector search is not supported (e.g., Firefox)
if (!isVectorSearchSupported()) {
console.debug("[VectorWorkerManager] Vector search not supported - skipping worker initialization");
this.isInitialized = false;
return Promise.resolve();
}
if (this.isInitialized) return Promise.resolve();
if (this.readyPromise) return this.readyPromise;
@@ -234,6 +242,17 @@ export class VectorWorkerManager {
}
async processItems(items: IndexItem[], onProgress?: ProgressCallback) {
// Skip if vector search is not supported
if (!isVectorSearchSupported()) {
if (onProgress) {
onProgress({
status: "complete",
message: "Vector search not available - using text search only"
});
}
return;
}
// Only initialize worker if we actually have items to process
if (items.length === 0) {
if (onProgress) {
@@ -298,6 +317,18 @@ export class VectorWorkerManager {
batchSize: number = 10,
jobId?: string,
): Promise<void> {
// Skip if vector search is not supported
if (!isVectorSearchSupported()) {
console.debug("[VectorWorker] Vector search not supported - skipping streaming session");
if (onProgress) {
onProgress({
status: "complete",
message: "Vector search not available - using text search only",
});
}
return;
}
// Only initialize if we expect items to process
if (totalExpectedItems === 0) {
console.debug("[VectorWorker] No items expected, not starting streaming session");
@@ -1,16 +1,36 @@
import { EmbeddingIndex, getEmbedding, initializeModel } from "embeddia";
import type { IndexItem } from "../../indexing/types";
import type { SearchResult } from "embeddia";
import { isVectorSearchSupported } from "../../utils/browserDetection";
let vectorIndex: EmbeddingIndex | null = null;
let initializationAttempted = false;
let initializationFailed = false;
export async function initVectorSearch() {
// Skip initialization if already attempted and failed, or if not supported
if (initializationFailed || !isVectorSearchSupported()) {
if (!isVectorSearchSupported()) {
console.debug("[Vector Search] Vector search not supported in Firefox - using text search only");
}
return;
}
if (initializationAttempted) {
return;
}
initializationAttempted = true;
try {
await initializeModel();
vectorIndex = new EmbeddingIndex([]);
vectorIndex.preloadIndexedDB();
console.debug("[Vector Search] Initialized successfully");
} catch (e) {
console.error("Error initializing vector search", e);
console.warn("[Vector Search] Failed to initialize vector search (will use text search only):", e);
initializationFailed = true;
vectorIndex = null;
}
}
@@ -44,7 +64,17 @@ export async function searchVectors(
query: string,
topK: number = 20,
): Promise<VectorSearchResult[]> {
if (!vectorIndex) await initVectorSearch();
// Return empty array if vector search is not supported or failed to initialize
if (!isVectorSearchSupported() || initializationFailed) {
return [];
}
if (!vectorIndex) {
await initVectorSearch();
if (!vectorIndex) {
return [];
}
}
// Normalize query for caching
const normalizedQuery = query.trim().toLowerCase().slice(0, 100);
@@ -84,7 +114,20 @@ export async function searchVectors(
}
export async function refreshVectorCache() {
if (!vectorIndex) await initVectorSearch();
vectorIndex!.clearIndexedDBCache();
vectorIndex!.preloadIndexedDB();
if (!isVectorSearchSupported() || initializationFailed) {
return;
}
if (!vectorIndex) {
await initVectorSearch();
}
if (vectorIndex) {
try {
vectorIndex.clearIndexedDBCache();
vectorIndex.preloadIndexedDB();
} catch (e) {
console.warn("[Vector Search] Failed to refresh cache:", e);
}
}
}
@@ -0,0 +1,30 @@
import browser from "webextension-polyfill";
/**
* Detects if the current browser is Firefox
*/
export function isFirefox(): boolean {
try {
// Firefox-specific API
if (typeof (browser.runtime as any).getBrowserInfo === "function") {
return true;
}
// Fallback: check user agent
if (typeof navigator !== "undefined") {
return navigator.userAgent.toLowerCase().includes("firefox");
}
return false;
} catch {
// If we can't detect, assume not Firefox (safer for Chrome/Edge)
return false;
}
}
/**
* Checks if vector search is supported in the current browser
* Currently disabled for Firefox due to security restrictions
*/
export function isVectorSearchSupported(): boolean {
return !isFirefox();
}