fix(llm): try to resolve initialization issue, part 1

This commit is contained in:
perf3ct 2025-06-03 20:36:46 +00:00
parent 307af229ae
commit 445ae312ef
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232
2 changed files with 117 additions and 19 deletions

View File

@ -21,6 +21,60 @@ import "./services/handlers.js";
import "./becca/becca_loader.js"; import "./becca/becca_loader.js";
import { RESOURCE_DIR } from "./services/resource_dir.js"; import { RESOURCE_DIR } from "./services/resource_dir.js";
/**
* Initialize or shutdown LLM features based on settings
*/
async function manageLLMFeatures(enabled: boolean) {
if (enabled) {
log.info("LLM features enabled in settings, initializing...");
try {
// Initialize embedding providers
log.info("Initializing embedding providers...");
const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js");
await initializeEmbeddings();
log.info("Embedding providers initialized");
// Initialize the index service for LLM functionality
log.info("Initializing index service...");
const { default: indexService } = await import("./services/llm/index_service.js");
await indexService.initialize()
.then(() => log.info("Index service initialized successfully"))
.catch((error) => {
const errorMsg = error instanceof Error ? error.message : String(error);
log.error(`Failed to initialize index service: ${errorMsg}`);
console.error("Failed to initialize index service:", error);
});
log.info("LLM features initialization completed");
} catch (error: unknown) {
const errorMsg = error instanceof Error ? error.message : String(error);
log.error(`Error initializing LLM features: ${errorMsg}`);
console.error("Error initializing LLM features:", error);
}
} else {
log.info("LLM features disabled in settings, shutting down...");
try {
// Get index service and shut it down if it exists
try {
const { default: indexService } = await import("./services/llm/index_service.js");
if (indexService && typeof indexService.shutdown === 'function') {
await indexService.shutdown();
log.info("Index service shut down successfully");
}
} catch (error) {
// Skip if index service can't be loaded
log.info(`Index service not available for shutdown: ${error}`);
}
log.info("LLM features shutdown completed");
} catch (error: unknown) {
const errorMsg = error instanceof Error ? error.message : String(error);
log.error(`Error shutting down LLM features: ${errorMsg}`);
console.error("Error shutting down LLM features:", error);
}
}
}
export default async function buildApp() { export default async function buildApp() {
const app = express(); const app = express();
@ -30,18 +84,22 @@ export default async function buildApp() {
// Listen for database initialization event // Listen for database initialization event
eventService.subscribe(eventService.DB_INITIALIZED, async () => { eventService.subscribe(eventService.DB_INITIALIZED, async () => {
try { try {
log.info("Database initialized, setting up LLM features"); log.info("Database initialized, setting up LLM features with delay to ensure all services are ready");
// Initialize embedding providers // Add a small delay to ensure all services are completely initialized
const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js"); // This helps prevent race conditions where the database is marked as initialized
await initializeEmbeddings(); // but other dependent services haven't fully loaded
await new Promise(resolve => setTimeout(resolve, 1000));
// Initialize the index service for LLM functionality
const { default: indexService } = await import("./services/llm/index_service.js"); // Check if AI features are enabled
await indexService.initialize().catch(e => console.error("Failed to initialize index service:", e)); const aiEnabled = await (await import("./services/options.js")).default.getOptionBool('aiEnabled');
if (aiEnabled) {
log.info("LLM features initialized successfully"); await manageLLMFeatures(true);
} else {
log.info("LLM features disabled in settings, skipping initialization");
}
} catch (error) { } catch (error) {
log.error("Error initializing LLM features:", error);
console.error("Error initializing LLM features:", error); console.error("Error initializing LLM features:", error);
} }
}); });
@ -49,19 +107,29 @@ export default async function buildApp() {
// Initialize LLM features only if database is already initialized // Initialize LLM features only if database is already initialized
if (sql_init.isDbInitialized()) { if (sql_init.isDbInitialized()) {
try { try {
// Initialize embedding providers // Check if AI features are enabled
const { initializeEmbeddings } = await import("./services/llm/embeddings/init.js"); const aiEnabled = await (await import("./services/options.js")).default.getOptionBool('aiEnabled');
await initializeEmbeddings(); if (aiEnabled) {
await manageLLMFeatures(true);
// Initialize the index service for LLM functionality } else {
const { default: indexService } = await import("./services/llm/index_service.js"); log.info("LLM features disabled in settings, skipping initialization");
await indexService.initialize().catch(e => console.error("Failed to initialize index service:", e)); }
} catch (error) { } catch (error) {
console.error("Error initializing LLM features:", error); console.error("Error initializing LLM features:", error);
log.error(`Error initializing LLM features: ${error}`);
} }
} else { } else {
console.log("Database not initialized yet. LLM features will be initialized after setup."); log.info("Database not initialized yet. LLM features will be initialized after setup.");
} }
// Listen for changes to the aiEnabled option
eventService.subscribe(eventService.ENTITY_CHANGED, async ({ entityName, entity }) => {
if (entityName === "options" && entity && entity.name === 'aiEnabled' && sql_init.isDbInitialized()) {
const enabled = entity.value === "true";
log.info(`AI features ${enabled ? 'enabled' : 'disabled'} in settings`);
await manageLLMFeatures(enabled);
}
});
const publicDir = isDev ? path.join(getResourceDir(), "../dist/public") : path.join(getResourceDir(), "public"); const publicDir = isDev ? path.join(getResourceDir(), "../dist/public") : path.join(getResourceDir(), "public");
const publicAssetsDir = path.join(publicDir, "assets"); const publicAssetsDir = path.join(publicDir, "assets");

View File

@ -40,6 +40,36 @@ export class IndexService {
private defaultSimilarityThreshold = SEARCH_CONSTANTS.VECTOR_SEARCH.EXACT_MATCH_THRESHOLD; private defaultSimilarityThreshold = SEARCH_CONSTANTS.VECTOR_SEARCH.EXACT_MATCH_THRESHOLD;
private indexUpdateInterval = 3600000; // 1 hour in milliseconds private indexUpdateInterval = 3600000; // 1 hour in milliseconds
/**
* Shutdown the index service and free resources
*/
async shutdown(): Promise<void> {
if (!this.initialized) {
log.info('Index service not initialized, nothing to shut down');
return;
}
try {
// Clear any automatic indexing tasks
if (this.automaticIndexingInterval) {
clearInterval(this.automaticIndexingInterval);
this.automaticIndexingInterval = undefined;
}
// Cancel any ongoing indexing operations
this.indexingInProgress = false;
this.indexRebuildInProgress = false;
// Release resources and signal that the service is no longer initialized
this.initialized = false;
log.info('Index service shut down successfully');
} catch (error: unknown) {
const errorMsg = error instanceof Error ? error.message : String(error);
log.error(`Error shutting down index service: ${errorMsg}`);
throw error;
}
}
/** /**
* Initialize the index service * Initialize the index service
*/ */