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>
This commit is contained in:
Alexander Penzin
2026-01-16 21:28:09 +02:00
committed by GitHub
parent 76af0aaabd
commit c2e53d58bc
2 changed files with 13 additions and 8 deletions
+3
View File
@@ -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
@@ -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<ApiValidationResult>((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}`,
});
}
}