Skip to main content
Glama
Replicant-Partners

Congo River Compositional Intelligence

python-bridge.ts4.69 kB
/** * Python Service Bridge * Executes Python services and handles JSON communication */ import { spawn } from 'child_process'; import * as path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export interface PythonServiceResult { success: boolean; [key: string]: any; } export class PythonBridge { private pythonExecutable: string; private servicesDir: string; private timeout: number; constructor() { this.pythonExecutable = process.env.PYTHON_EXECUTABLE || 'python3'; this.servicesDir = path.join(__dirname, 'python'); this.timeout = parseInt(process.env.PYTHON_SERVICE_TIMEOUT_MS || '30000'); } /** * Execute a Python service and return JSON result */ async execute( scriptName: string, args: any ): Promise<PythonServiceResult> { const scriptPath = path.join(this.servicesDir, scriptName); const jsonArg = JSON.stringify(args); return new Promise((resolve, reject) => { const childProcess = spawn( this.pythonExecutable, [scriptPath, '--json', jsonArg], { env: { ...process.env, PYTHONPATH: this.servicesDir, }, } ); let stdout = ''; let stderr = ''; childProcess.stdout.on('data', (data: Buffer) => { stdout += data.toString(); }); childProcess.stderr.on('data', (data: Buffer) => { stderr += data.toString(); }); // Timeout handling const timeoutId = setTimeout(() => { childProcess.kill(); reject(new Error(`Python service timed out after ${this.timeout}ms`)); }, this.timeout); childProcess.on('close', (code: number | null) => { clearTimeout(timeoutId); if (code !== 0) { console.error(`[PythonBridge] ${scriptName} failed:`, stderr); reject( new Error( `Python service exited with code ${code}: ${stderr || 'Unknown error'}` ) ); return; } try { const result = JSON.parse(stdout); resolve(result); } catch (error) { console.error(`[PythonBridge] Failed to parse JSON:`, stdout); reject( new Error(`Failed to parse Python output: ${error instanceof Error ? error.message : String(error)}`) ); } }); childProcess.on('error', (error: Error) => { clearTimeout(timeoutId); console.error(`[PythonBridge] Process error:`, error); reject(error); }); }); } /** * Triple Decomposition Service */ async tripleDecomposition(args: { concept: string; context?: string; }): Promise<PythonServiceResult> { return this.execute('triple_decomposer.py', { text: args.concept, context: args.context, }); } /** * Proof Search Service */ async proofSearch(args: { goal: string; premises?: string[]; method?: string; max_depth?: number; }): Promise<PythonServiceResult> { // Convert premises to facts and rules format const facts = args.premises || []; const rules: any[] = []; return this.execute('proof_searcher.py', { goal: args.goal, facts, rules, strategy: args.method || 'auto', max_depth: args.max_depth || 10, }); } /** * Graph Query Service */ async graphQuery(args: { query: string; context?: string; triples?: any[]; }): Promise<PythonServiceResult> { return this.execute('graph_engine.py', { query: args.query, context: args.context, triples: args.triples || [], }); } /** * Neuro-Symbolic Query Service */ async neuroSymbolicQuery(args: { query: string; use_llm?: boolean; llm_provider?: 'anthropic' | 'openai'; include_proof?: boolean; }): Promise<PythonServiceResult> { return this.execute('neuro_symbolic.py', { query: args.query, use_llm: args.use_llm !== false, llm_provider: args.llm_provider || 'anthropic', include_proof: args.include_proof || false, anthropic_api_key: process.env.ANTHROPIC_API_KEY, openai_api_key: process.env.OPENAI_API_KEY, }); } } // Singleton instance let pythonBridge: PythonBridge | null = null; export function getPythonBridge(): PythonBridge { if (!pythonBridge) { pythonBridge = new PythonBridge(); } return pythonBridge; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Replicant-Partners/Congo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server