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:
@@ -14,6 +14,9 @@ secretstorage>=3.3.3; sys_platform == "linux"
|
|||||||
# Requires Python 3.12+ (no Docker required)
|
# Requires Python 3.12+ (no Docker required)
|
||||||
real_ladybug>=0.13.0; python_version >= "3.12"
|
real_ladybug>=0.13.0; python_version >= "3.12"
|
||||||
graphiti-core>=0.5.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
|
# Windows-specific dependency for LadybugDB/Graphiti
|
||||||
# pywin32 provides Windows system bindings required by real_ladybug
|
# pywin32 provides Windows system bindings required by real_ladybug
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
* Used by the Graphiti memory integration for embedding and LLM operations.
|
* Used by the Graphiti memory integration for embedding and LLM operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import https from 'https';
|
||||||
|
import type { IncomingMessage } from 'http';
|
||||||
|
|
||||||
export interface ApiValidationResult {
|
export interface ApiValidationResult {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
@@ -43,8 +46,6 @@ export async function validateOpenAIApiKey(
|
|||||||
|
|
||||||
// Use native https module to avoid additional dependencies
|
// Use native https module to avoid additional dependencies
|
||||||
const result = await new Promise<ApiValidationResult>((resolve) => {
|
const result = await new Promise<ApiValidationResult>((resolve) => {
|
||||||
const https = require('https');
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
hostname: 'api.openai.com',
|
hostname: 'api.openai.com',
|
||||||
port: 443,
|
port: 443,
|
||||||
@@ -57,7 +58,7 @@ export async function validateOpenAIApiKey(
|
|||||||
timeout: 15000,
|
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 = '';
|
let data = '';
|
||||||
|
|
||||||
res.on('data', (chunk: Buffer) => {
|
res.on('data', (chunk: Buffer) => {
|
||||||
@@ -66,8 +67,9 @@ export async function validateOpenAIApiKey(
|
|||||||
|
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
const latencyMs = Date.now() - startTime;
|
const latencyMs = Date.now() - startTime;
|
||||||
|
const statusCode = res.statusCode ?? 0;
|
||||||
|
|
||||||
if (res.statusCode === 200) {
|
if (statusCode === 200) {
|
||||||
resolve({
|
resolve({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'OpenAI API key is valid',
|
message: 'OpenAI API key is valid',
|
||||||
@@ -76,12 +78,12 @@ export async function validateOpenAIApiKey(
|
|||||||
latencyMs,
|
latencyMs,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (res.statusCode === 401) {
|
} else if (statusCode === 401) {
|
||||||
resolve({
|
resolve({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Invalid API key. Please check your OpenAI API key.',
|
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
|
// Rate limited but key is valid
|
||||||
resolve({
|
resolve({
|
||||||
success: true,
|
success: true,
|
||||||
@@ -96,12 +98,12 @@ export async function validateOpenAIApiKey(
|
|||||||
const errorData = JSON.parse(data);
|
const errorData = JSON.parse(data);
|
||||||
resolve({
|
resolve({
|
||||||
success: false,
|
success: false,
|
||||||
message: errorData.error?.message || `API error: ${res.statusCode}`,
|
message: errorData.error?.message || `API error: ${statusCode}`,
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
resolve({
|
resolve({
|
||||||
success: false,
|
success: false,
|
||||||
message: `API error: ${res.statusCode}`,
|
message: `API error: ${statusCode}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user