mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
fix vector initialisation?
This commit is contained in:
@@ -126,10 +126,16 @@ const globalSearchPlugin: Plugin<typeof settings> = {
|
|||||||
|
|
||||||
initVectorSearch();
|
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 () => {
|
setTimeout(async () => {
|
||||||
try {
|
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) {
|
} catch (error) {
|
||||||
console.warn("[Global Search] Vector worker warm-up failed:", 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 vectorIndex: EmbeddingIndex | null = null;
|
||||||
let isInitialized = false;
|
let isInitialized = false;
|
||||||
|
let initializationFailed = false;
|
||||||
let currentAbortController: AbortController | null = null;
|
let currentAbortController: AbortController | null = null;
|
||||||
let loadedItemIds = new Set<string>();
|
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: {
|
let streamingSession: {
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
totalExpected: number;
|
totalExpected: number;
|
||||||
@@ -21,6 +36,16 @@ async function initWorker() {
|
|||||||
console.debug("Vector worker already initialized.");
|
console.debug("Vector worker already initialized.");
|
||||||
return;
|
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...");
|
console.debug("Initializing vector worker...");
|
||||||
try {
|
try {
|
||||||
await initializeModel();
|
await initializeModel();
|
||||||
@@ -48,8 +73,9 @@ async function initWorker() {
|
|||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
console.debug("Vector worker initialized successfully.");
|
console.debug("Vector worker initialized successfully.");
|
||||||
} catch (e) {
|
} 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;
|
isInitialized = true;
|
||||||
|
initializationFailed = true;
|
||||||
vectorIndex = null;
|
vectorIndex = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,18 +106,29 @@ async function startStreamingSession(
|
|||||||
totalExpected: number,
|
totalExpected: number,
|
||||||
batchSize: number = 5,
|
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) {
|
if (!vectorIndex) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Streaming requested but vector index not ready. Attempting init.",
|
"Streaming requested but vector index not ready. Attempting init.",
|
||||||
);
|
);
|
||||||
await initWorker();
|
await initWorker();
|
||||||
if (!vectorIndex) {
|
if (!vectorIndex || initializationFailed) {
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
type: "progress",
|
type: "progress",
|
||||||
data: {
|
data: {
|
||||||
status: "error",
|
status: "complete",
|
||||||
message:
|
message:
|
||||||
"Vector index not available for streaming after init attempt.",
|
"Vector index not available - using text search only",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -306,18 +343,29 @@ async function endStreamingSession() {
|
|||||||
async function processItems(items: IndexItem[], signal: AbortSignal) {
|
async function processItems(items: IndexItem[], signal: AbortSignal) {
|
||||||
console.debug("Worker received process request.");
|
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) {
|
if (!vectorIndex) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Processing requested but vector index not ready. Attempting init.",
|
"Processing requested but vector index not ready. Attempting init.",
|
||||||
);
|
);
|
||||||
await initWorker();
|
await initWorker();
|
||||||
if (!vectorIndex) {
|
if (!vectorIndex || initializationFailed) {
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
type: "progress",
|
type: "progress",
|
||||||
data: {
|
data: {
|
||||||
status: "error",
|
status: "complete",
|
||||||
message:
|
message:
|
||||||
"Vector index not available for processing after init attempt.",
|
"Vector index not available - using text search only",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { refreshVectorCache } from "../../search/vector/vectorSearch";
|
import { refreshVectorCache } from "../../search/vector/vectorSearch";
|
||||||
import type { IndexItem } from "../types";
|
import type { IndexItem } from "../types";
|
||||||
|
import { isVectorSearchSupported } from "../../utils/browserDetection";
|
||||||
import vectorWorker from "./vectorWorker.ts?inlineWorker";
|
import vectorWorker from "./vectorWorker.ts?inlineWorker";
|
||||||
|
|
||||||
export type ProgressCallback = (data: {
|
export type ProgressCallback = (data: {
|
||||||
@@ -42,6 +43,13 @@ export class VectorWorkerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async initWorker(): Promise<void> {
|
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.isInitialized) return Promise.resolve();
|
||||||
if (this.readyPromise) return this.readyPromise;
|
if (this.readyPromise) return this.readyPromise;
|
||||||
|
|
||||||
@@ -234,6 +242,17 @@ export class VectorWorkerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async processItems(items: IndexItem[], onProgress?: ProgressCallback) {
|
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
|
// Only initialize worker if we actually have items to process
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
if (onProgress) {
|
if (onProgress) {
|
||||||
@@ -298,6 +317,18 @@ export class VectorWorkerManager {
|
|||||||
batchSize: number = 10,
|
batchSize: number = 10,
|
||||||
jobId?: string,
|
jobId?: string,
|
||||||
): Promise<void> {
|
): 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
|
// Only initialize if we expect items to process
|
||||||
if (totalExpectedItems === 0) {
|
if (totalExpectedItems === 0) {
|
||||||
console.debug("[VectorWorker] No items expected, not starting streaming session");
|
console.debug("[VectorWorker] No items expected, not starting streaming session");
|
||||||
|
|||||||
@@ -1,16 +1,36 @@
|
|||||||
import { EmbeddingIndex, getEmbedding, initializeModel } from "embeddia";
|
import { EmbeddingIndex, getEmbedding, initializeModel } from "embeddia";
|
||||||
import type { IndexItem } from "../../indexing/types";
|
import type { IndexItem } from "../../indexing/types";
|
||||||
import type { SearchResult } from "embeddia";
|
import type { SearchResult } from "embeddia";
|
||||||
|
import { isVectorSearchSupported } from "../../utils/browserDetection";
|
||||||
|
|
||||||
let vectorIndex: EmbeddingIndex | null = null;
|
let vectorIndex: EmbeddingIndex | null = null;
|
||||||
|
let initializationAttempted = false;
|
||||||
|
let initializationFailed = false;
|
||||||
|
|
||||||
export async function initVectorSearch() {
|
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 {
|
try {
|
||||||
await initializeModel();
|
await initializeModel();
|
||||||
vectorIndex = new EmbeddingIndex([]);
|
vectorIndex = new EmbeddingIndex([]);
|
||||||
vectorIndex.preloadIndexedDB();
|
vectorIndex.preloadIndexedDB();
|
||||||
|
console.debug("[Vector Search] Initialized successfully");
|
||||||
} catch (e) {
|
} 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,
|
query: string,
|
||||||
topK: number = 20,
|
topK: number = 20,
|
||||||
): Promise<VectorSearchResult[]> {
|
): 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
|
// Normalize query for caching
|
||||||
const normalizedQuery = query.trim().toLowerCase().slice(0, 100);
|
const normalizedQuery = query.trim().toLowerCase().slice(0, 100);
|
||||||
@@ -84,7 +114,20 @@ export async function searchVectors(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function refreshVectorCache() {
|
export async function refreshVectorCache() {
|
||||||
if (!vectorIndex) await initVectorSearch();
|
if (!isVectorSearchSupported() || initializationFailed) {
|
||||||
vectorIndex!.clearIndexedDBCache();
|
return;
|
||||||
vectorIndex!.preloadIndexedDB();
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user