From c2e53d58bc14c39249051c8631b3e01279ca9e8b Mon Sep 17 00:00:00 2001 From: Alexander Penzin <58038013+PenzinAlexander@users.noreply.github.com> Date: Fri, 16 Jan 2026 21:28:09 +0200 Subject: [PATCH] fix: Graphiti memory feature on macOS (#1174) Fix two issues preventing Graphiti memory from working on macOS: 1. Replace CommonJS require('https') with ESM import in api-validation-service.ts - The dynamic require() call fails in ESM context with "require is not defined" - Use static import at module level instead 2. Add pandas to requirements.txt - pandas is required by real_ladybug for get_as_df() method in query_memory.py - Without pandas, database connection test fails with "No module named 'pandas'" Fixes #1132 Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com> --- apps/backend/requirements.txt | 3 +++ .../src/main/api-validation-service.ts | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/backend/requirements.txt b/apps/backend/requirements.txt index cd9a8687..ce6f9101 100644 --- a/apps/backend/requirements.txt +++ b/apps/backend/requirements.txt @@ -14,6 +14,9 @@ secretstorage>=3.3.3; sys_platform == "linux" # Requires Python 3.12+ (no Docker required) real_ladybug>=0.13.0; python_version >= "3.12" graphiti-core>=0.5.0; python_version >= "3.12" +# pandas is required by real_ladybug for get_as_df() method +# pandas 2.2.0+ required for pre-built wheels on Python 3.12 +pandas>=2.2.0; python_version >= "3.12" # Windows-specific dependency for LadybugDB/Graphiti # pywin32 provides Windows system bindings required by real_ladybug diff --git a/apps/frontend/src/main/api-validation-service.ts b/apps/frontend/src/main/api-validation-service.ts index 6ef07f07..a2f83549 100644 --- a/apps/frontend/src/main/api-validation-service.ts +++ b/apps/frontend/src/main/api-validation-service.ts @@ -5,6 +5,9 @@ * Used by the Graphiti memory integration for embedding and LLM operations. */ +import https from 'https'; +import type { IncomingMessage } from 'http'; + export interface ApiValidationResult { success: boolean; message: string; @@ -43,8 +46,6 @@ export async function validateOpenAIApiKey( // Use native https module to avoid additional dependencies const result = await new Promise((resolve) => { - const https = require('https'); - const options = { hostname: 'api.openai.com', port: 443, @@ -57,7 +58,7 @@ export async function validateOpenAIApiKey( timeout: 15000, }; - const req = https.request(options, (res: { statusCode: number; on: (event: string, callback: (chunk: Buffer) => void) => void }) => { + const req = https.request(options, (res: IncomingMessage) => { let data = ''; res.on('data', (chunk: Buffer) => { @@ -66,8 +67,9 @@ export async function validateOpenAIApiKey( res.on('end', () => { const latencyMs = Date.now() - startTime; + const statusCode = res.statusCode ?? 0; - if (res.statusCode === 200) { + if (statusCode === 200) { resolve({ success: true, message: 'OpenAI API key is valid', @@ -76,12 +78,12 @@ export async function validateOpenAIApiKey( latencyMs, }, }); - } else if (res.statusCode === 401) { + } else if (statusCode === 401) { resolve({ success: false, message: 'Invalid API key. Please check your OpenAI API key.', }); - } else if (res.statusCode === 429) { + } else if (statusCode === 429) { // Rate limited but key is valid resolve({ success: true, @@ -96,12 +98,12 @@ export async function validateOpenAIApiKey( const errorData = JSON.parse(data); resolve({ success: false, - message: errorData.error?.message || `API error: ${res.statusCode}`, + message: errorData.error?.message || `API error: ${statusCode}`, }); } catch { resolve({ success: false, - message: `API error: ${res.statusCode}`, + message: `API error: ${statusCode}`, }); } }