Skip to main content
Glama

Vibe Coder MCP

by freshtechbro
dependency-container.ts•9.18 kB
/** * Dependency Container - Centralized Dependency Injection * * Manages dependencies between agent modules to prevent circular imports * Implements singleton pattern with lazy loading and safe initialization */ import { ImportCycleBreaker } from '../utils/import-cycle-breaker.js'; import logger from '../logger.js'; // Type definitions for agent classes interface AgentRegistryClass { getInstance(): AgentRegistryInstance; } interface AgentTaskQueueClass { getInstance(): AgentTaskQueueInstance; } interface AgentResponseProcessorClass { getInstance(): AgentResponseProcessorInstance; } interface AgentIntegrationBridgeClass { getInstance(): AgentIntegrationBridgeInstance; } // Instance type definitions interface AgentRegistryInstance { registerAgent(registration: unknown): Promise<void>; getAgent(agentId: string): Promise<unknown>; getAllAgents(): Promise<unknown[]>; } interface AgentTaskQueueInstance { addTask(agentId: string, task: unknown): Promise<string>; getTasks(agentId: string, maxTasks?: number): Promise<unknown[]>; getQueueLength(agentId: string): Promise<number>; } interface AgentResponseProcessorInstance { processResponse(response: unknown): Promise<void>; getResponse(taskId: string): Promise<unknown>; getAllResponses(): Promise<unknown[]>; } interface AgentIntegrationBridgeInstance { bridgeAgentData(agentId: string): Promise<unknown>; syncAgentStatus(agentId: string): Promise<void>; } export interface AgentDependencies { agentRegistry?: AgentRegistryInstance | null; agentTaskQueue?: AgentTaskQueueInstance | null; agentResponseProcessor?: AgentResponseProcessorInstance | null; agentIntegrationBridge?: AgentIntegrationBridgeInstance | null; } /** * Centralized dependency container for agent modules */ export class DependencyContainer { private static instance: DependencyContainer; private static isInitializing = false; private dependencies: AgentDependencies = {}; private initializationPromises = new Map<string, Promise<unknown>>(); static getInstance(): DependencyContainer { if (DependencyContainer.isInitializing) { logger.warn('Circular initialization detected in DependencyContainer, using safe fallback'); return DependencyContainer.createSafeFallback(); } if (!DependencyContainer.instance) { DependencyContainer.isInitializing = true; try { DependencyContainer.instance = new DependencyContainer(); } finally { DependencyContainer.isInitializing = false; } } return DependencyContainer.instance; } private static createSafeFallback(): DependencyContainer { const fallback = Object.create(DependencyContainer.prototype); fallback.dependencies = {}; fallback.initializationPromises = new Map(); // Provide safe no-op methods fallback.getAgentRegistry = async () => null; fallback.getAgentTaskQueue = async () => null; fallback.getAgentResponseProcessor = async () => null; fallback.getAgentIntegrationBridge = async () => null; return fallback; } /** * Get AgentRegistry instance with safe loading */ async getAgentRegistry(): Promise<unknown | null> { if (this.dependencies.agentRegistry) { return this.dependencies.agentRegistry; } // Check if initialization is already in progress if (this.initializationPromises.has('agentRegistry')) { return this.initializationPromises.get('agentRegistry'); } // Start initialization const initPromise = this.initializeAgentRegistry(); this.initializationPromises.set('agentRegistry', initPromise); try { const registry = await initPromise; this.dependencies.agentRegistry = registry; return registry; } finally { this.initializationPromises.delete('agentRegistry'); } } private async initializeAgentRegistry(): Promise<AgentRegistryInstance | null> { try { const registryModule = await ImportCycleBreaker.safeImport<{ AgentRegistry: AgentRegistryClass }>('../tools/agent-registry/index.js'); if (registryModule?.AgentRegistry) { return registryModule.AgentRegistry.getInstance(); } logger.warn('AgentRegistry not available due to circular dependency'); return null; } catch (error) { logger.error('Failed to initialize AgentRegistry:', error); return null; } } /** * Get AgentTaskQueue instance with safe loading */ async getAgentTaskQueue(): Promise<unknown | null> { if (this.dependencies.agentTaskQueue) { return this.dependencies.agentTaskQueue; } if (this.initializationPromises.has('agentTaskQueue')) { return this.initializationPromises.get('agentTaskQueue'); } const initPromise = this.initializeAgentTaskQueue(); this.initializationPromises.set('agentTaskQueue', initPromise); try { const taskQueue = await initPromise; this.dependencies.agentTaskQueue = taskQueue; return taskQueue; } finally { this.initializationPromises.delete('agentTaskQueue'); } } private async initializeAgentTaskQueue(): Promise<AgentTaskQueueInstance | null> { try { const taskQueueModule = await ImportCycleBreaker.safeImport<{ AgentTaskQueue: AgentTaskQueueClass }>('../tools/agent-tasks/index.js'); if (taskQueueModule?.AgentTaskQueue) { return taskQueueModule.AgentTaskQueue.getInstance(); } logger.warn('AgentTaskQueue not available due to circular dependency'); return null; } catch (error) { logger.error('Failed to initialize AgentTaskQueue:', error); return null; } } /** * Get AgentResponseProcessor instance with safe loading */ async getAgentResponseProcessor(): Promise<unknown | null> { if (this.dependencies.agentResponseProcessor) { return this.dependencies.agentResponseProcessor; } if (this.initializationPromises.has('agentResponseProcessor')) { return this.initializationPromises.get('agentResponseProcessor'); } const initPromise = this.initializeAgentResponseProcessor(); this.initializationPromises.set('agentResponseProcessor', initPromise); try { const responseProcessor = await initPromise; this.dependencies.agentResponseProcessor = responseProcessor; return responseProcessor; } finally { this.initializationPromises.delete('agentResponseProcessor'); } } private async initializeAgentResponseProcessor(): Promise<AgentResponseProcessorInstance | null> { try { const responseModule = await ImportCycleBreaker.safeImport<{ AgentResponseProcessor: AgentResponseProcessorClass }>('../tools/agent-response/index.js'); if (responseModule?.AgentResponseProcessor) { return responseModule.AgentResponseProcessor.getInstance(); } logger.warn('AgentResponseProcessor not available due to circular dependency'); return null; } catch (error) { logger.error('Failed to initialize AgentResponseProcessor:', error); return null; } } /** * Get AgentIntegrationBridge instance with safe loading */ async getAgentIntegrationBridge(): Promise<unknown | null> { if (this.dependencies.agentIntegrationBridge) { return this.dependencies.agentIntegrationBridge; } if (this.initializationPromises.has('agentIntegrationBridge')) { return this.initializationPromises.get('agentIntegrationBridge'); } const initPromise = this.initializeAgentIntegrationBridge(); this.initializationPromises.set('agentIntegrationBridge', initPromise); try { const bridge = await initPromise; this.dependencies.agentIntegrationBridge = bridge; return bridge; } finally { this.initializationPromises.delete('agentIntegrationBridge'); } } private async initializeAgentIntegrationBridge(): Promise<AgentIntegrationBridgeInstance | null> { try { const bridgeModule = await ImportCycleBreaker.safeImport<{ AgentIntegrationBridge: AgentIntegrationBridgeClass }>('../tools/vibe-task-manager/services/agent-integration-bridge.js'); if (bridgeModule?.AgentIntegrationBridge) { return bridgeModule.AgentIntegrationBridge.getInstance(); } logger.warn('AgentIntegrationBridge not available due to circular dependency'); return null; } catch (error) { logger.error('Failed to initialize AgentIntegrationBridge:', error); return null; } } /** * Clear all cached dependencies (useful for testing) */ clearCache(): void { this.dependencies = {}; this.initializationPromises.clear(); } /** * Get current dependency status for debugging */ getDependencyStatus(): Record<string, boolean> { return { agentRegistry: !!this.dependencies.agentRegistry, agentTaskQueue: !!this.dependencies.agentTaskQueue, agentResponseProcessor: !!this.dependencies.agentResponseProcessor, agentIntegrationBridge: !!this.dependencies.agentIntegrationBridge }; } } // Export singleton instance export const dependencyContainer = DependencyContainer.getInstance();

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/freshtechbro/vibe-coder-mcp'

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