fix: properly handle API key loading
This commit is contained in:
@@ -11,6 +11,7 @@ import { getDatabase } from '../database';
|
|||||||
|
|
||||||
let chatEngine: ChatEngine | null = null;
|
let chatEngine: ChatEngine | null = null;
|
||||||
let openCodeManager: OpenCodeManager | null = null;
|
let openCodeManager: OpenCodeManager | null = null;
|
||||||
|
let openCodeManagerInitPromise: Promise<void> | null = null;
|
||||||
let mainWindowGetter: (() => BrowserWindow | null) | null = null;
|
let mainWindowGetter: (() => BrowserWindow | null) | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,9 +32,11 @@ function getChatEngine(): ChatEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or create the OpenCodeManager instance
|
* Get or create the OpenCodeManager instance.
|
||||||
|
* Returns a promise that resolves when the manager is fully initialized
|
||||||
|
* (including loading the API key from settings).
|
||||||
*/
|
*/
|
||||||
function getOpenCodeManager(): OpenCodeManager {
|
async function getOpenCodeManager(): Promise<OpenCodeManager> {
|
||||||
if (!openCodeManager) {
|
if (!openCodeManager) {
|
||||||
openCodeManager = new OpenCodeManager(
|
openCodeManager = new OpenCodeManager(
|
||||||
getChatEngine(),
|
getChatEngine(),
|
||||||
@@ -42,14 +45,25 @@ function getOpenCodeManager(): OpenCodeManager {
|
|||||||
() => mainWindowGetter?.() || null
|
() => mainWindowGetter?.() || null
|
||||||
);
|
);
|
||||||
|
|
||||||
// Load API key from settings
|
// Load API key from settings and await it
|
||||||
const engine = getChatEngine();
|
const engine = getChatEngine();
|
||||||
engine.getSetting('opencode_api_key').then(key => {
|
openCodeManagerInitPromise = (async () => {
|
||||||
if (key) {
|
try {
|
||||||
openCodeManager!.setApiKey(key);
|
const key = await engine.getSetting('opencode_api_key');
|
||||||
|
if (key) {
|
||||||
|
openCodeManager!.setApiKey(key);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Silently ignore errors loading the key
|
||||||
}
|
}
|
||||||
}).catch(() => {});
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always wait for initialization to complete before returning
|
||||||
|
if (openCodeManagerInitPromise) {
|
||||||
|
await openCodeManagerInitPromise;
|
||||||
|
}
|
||||||
|
|
||||||
return openCodeManager;
|
return openCodeManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +76,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Check if service is ready
|
// Check if service is ready
|
||||||
ipcMain.handle('chat:checkReady', async () => {
|
ipcMain.handle('chat:checkReady', async () => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
const result = await manager.checkReady();
|
const result = await manager.checkReady();
|
||||||
return {
|
return {
|
||||||
ready: result.ready,
|
ready: result.ready,
|
||||||
@@ -78,7 +92,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Validate API key
|
// Validate API key
|
||||||
ipcMain.handle('chat:validateApiKey', async (_, apiKey: string) => {
|
ipcMain.handle('chat:validateApiKey', async (_, apiKey: string) => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
const result = await manager.validateApiKey(apiKey);
|
const result = await manager.validateApiKey(apiKey);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -90,7 +104,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Set API key
|
// Set API key
|
||||||
ipcMain.handle('chat:setApiKey', async (_, apiKey: string) => {
|
ipcMain.handle('chat:setApiKey', async (_, apiKey: string) => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
manager.setApiKey(apiKey);
|
manager.setApiKey(apiKey);
|
||||||
|
|
||||||
// Persist to settings
|
// Persist to settings
|
||||||
@@ -107,7 +121,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Get API key (masked)
|
// Get API key (masked)
|
||||||
ipcMain.handle('chat:getApiKey', async () => {
|
ipcMain.handle('chat:getApiKey', async () => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
const key = manager.getApiKey();
|
const key = manager.getApiKey();
|
||||||
if (!key) return { hasKey: false, maskedKey: '' };
|
if (!key) return { hasKey: false, maskedKey: '' };
|
||||||
// Mask all but last 4 characters
|
// Mask all but last 4 characters
|
||||||
@@ -124,7 +138,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Get available models
|
// Get available models
|
||||||
ipcMain.handle('chat:getAvailableModels', async () => {
|
ipcMain.handle('chat:getAvailableModels', async () => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
const models = await manager.getAvailableModels();
|
const models = await manager.getAvailableModels();
|
||||||
const engine = getChatEngine();
|
const engine = getChatEngine();
|
||||||
const selectedModel = await engine.getSelectedModel();
|
const selectedModel = await engine.getSelectedModel();
|
||||||
@@ -244,7 +258,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Send a message
|
// Send a message
|
||||||
ipcMain.handle('chat:sendMessage', async (_, conversationId: string, message: string) => {
|
ipcMain.handle('chat:sendMessage', async (_, conversationId: string, message: string) => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
const mainWindow = mainWindowGetter?.();
|
const mainWindow = mainWindowGetter?.();
|
||||||
|
|
||||||
const result = await manager.sendMessage(conversationId, message, {
|
const result = await manager.sendMessage(conversationId, message, {
|
||||||
@@ -275,7 +289,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Abort a running message
|
// Abort a running message
|
||||||
ipcMain.handle('chat:abortMessage', async (_, conversationId: string) => {
|
ipcMain.handle('chat:abortMessage', async (_, conversationId: string) => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
return await manager.abortMessage(conversationId);
|
return await manager.abortMessage(conversationId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Chat IPC] Error aborting message:', error);
|
console.error('[Chat IPC] Error aborting message:', error);
|
||||||
@@ -323,7 +337,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Analyze taxonomy items (tags/categories) and suggest mappings
|
// Analyze taxonomy items (tags/categories) and suggest mappings
|
||||||
ipcMain.handle('chat:analyzeTaxonomy', async (_, categories: Array<{ name: string; slug: string; existsInProject: boolean }>, tags: Array<{ name: string; slug: string; existsInProject: boolean }>, modelId: string) => {
|
ipcMain.handle('chat:analyzeTaxonomy', async (_, categories: Array<{ name: string; slug: string; existsInProject: boolean }>, tags: Array<{ name: string; slug: string; existsInProject: boolean }>, modelId: string) => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
return await manager.analyzeTaxonomy(categories, tags, modelId);
|
return await manager.analyzeTaxonomy(categories, tags, modelId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Chat IPC] Error analyzing taxonomy:', error);
|
console.error('[Chat IPC] Error analyzing taxonomy:', error);
|
||||||
@@ -336,7 +350,7 @@ export function registerChatHandlers(): void {
|
|||||||
// Analyze a media image and generate title, alt text, and caption
|
// Analyze a media image and generate title, alt text, and caption
|
||||||
ipcMain.handle('chat:analyzeMediaImage', async (_, mediaId: string, language?: string) => {
|
ipcMain.handle('chat:analyzeMediaImage', async (_, mediaId: string, language?: string) => {
|
||||||
try {
|
try {
|
||||||
const manager = getOpenCodeManager();
|
const manager = await getOpenCodeManager();
|
||||||
return await manager.analyzeMediaImage(mediaId, language || 'en');
|
return await manager.analyzeMediaImage(mediaId, language || 'en');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Chat IPC] Error analyzing media image:', error);
|
console.error('[Chat IPC] Error analyzing media image:', error);
|
||||||
@@ -353,5 +367,6 @@ export async function cleanupChatHandlers(): Promise<void> {
|
|||||||
await openCodeManager.stop();
|
await openCodeManager.stop();
|
||||||
openCodeManager = null;
|
openCodeManager = null;
|
||||||
}
|
}
|
||||||
|
openCodeManagerInitPromise = null;
|
||||||
chatEngine = null;
|
chatEngine = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user