@tehreet/conduit
Version:
LLM API gateway with intelligent routing, robust process management, and health monitoring
173 lines • 7.01 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.run = run;
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const os_1 = require("os");
const path_1 = require("path");
const utils_1 = require("./utils");
const serverWrapper_1 = require("./serverWrapper");
const router_1 = require("./utils/router");
const pidManager_1 = require("./utils/pidManager");
const constants_1 = require("./constants");
const ConduitServer_1 = require("./server/ConduitServer");
// Export all library functionality
__exportStar(require("./lib"), exports);
// Keep existing exports for backward compatibility (specific exports to avoid conflicts)
__exportStar(require("./core"), exports);
__exportStar(require("./features"), exports);
async function initializeClaudeConfig() {
const homeDir = (0, os_1.homedir)();
const configPath = (0, path_1.join)(homeDir, '.claude.json');
if (!(0, fs_1.existsSync)(configPath)) {
const userID = Array.from({ length: 64 }, () => Math.random().toString(16)[2]).join('');
const configContent = {
numStartups: 184,
autoUpdaterStatus: 'enabled',
userID,
hasCompletedOnboarding: true,
lastOnboardingVersion: '1.0.17',
projects: {},
};
await (0, promises_1.writeFile)(configPath, JSON.stringify(configContent, null, 2));
}
}
async function run(options = {}) {
console.log('[Conduit] run() called with options:', JSON.stringify({
hasConfig: !!options.config,
hasPlugins: !!(options.config && options.config.plugins),
pluginCount: options.config?.plugins?.length || 0,
configKeys: options.config ? Object.keys(options.config) : []
}, null, 2));
// If config with plugins is provided, use the new ConduitServer
if (options.config && options.config.plugins) {
if (!options.silent) {
console.log('🔌 Starting Conduit with enhanced plugin support...');
}
const port = options.port || 3456;
const conduitConfig = {
...options.config,
server: {
port,
host: '127.0.0.1',
...options.config.server
}
};
const server = new ConduitServer_1.ConduitServer(conduitConfig);
await server.start();
if (!options.silent) {
console.log(`🚀 Enhanced Conduit is running on port ${port}`);
console.log(`📍 Health check: http://127.0.0.1:${port}/health`);
console.log(`🔌 Loaded ${server.getPluginManager().getPluginCount()} plugins`);
}
return server;
}
// Legacy mode for backwards compatibility
// Check if service is already running
if (pidManager_1.PidManager.isServiceRunning()) {
console.log('✅ Service is already running in the background.');
return;
}
await initializeClaudeConfig();
await (0, utils_1.initDir)();
const config = await (0, utils_1.initConfig)();
// Check if config has plugins and use enhanced server
if (config.plugins && config.plugins.length > 0) {
console.log('🔌 Config has plugins, switching to enhanced server mode...');
const port = options.port || 3456;
const conduitConfig = {
...config,
// Map legacy provider config format
providers: config.Providers || config.providers,
server: {
port,
host: '127.0.0.1',
...config.server
}
};
const server = new ConduitServer_1.ConduitServer(conduitConfig);
await server.start();
console.log(`🚀 Enhanced Conduit is running on port ${port}`);
console.log(`📍 Health check: http://127.0.0.1:${port}/health`);
return server;
}
// Initialize plugins
await (0, router_1.initializePlugins)(constants_1.PLUGINS_DIR);
const port = options.port || 3456;
// Save the PID of the background process
if (!pidManager_1.PidManager.savePid(process.pid)) {
console.error('Failed to save PID file. Another instance might be starting.');
process.exit(1);
}
// Use port from environment variable if set (for background process)
const servicePort = process.env.SERVICE_PORT
? parseInt(process.env.SERVICE_PORT)
: port;
const server = (0, serverWrapper_1.createConduitServer)({
jsonPath: constants_1.CONFIG_FILE,
initialConfig: {
// ...config,
providers: config.Providers || config.providers,
PORT: servicePort,
LOG_FILE: (0, path_1.join)((0, os_1.homedir)(), '.conduit', 'conduit.log'),
},
gracefulShutdownTimeout: 30000,
onShutdown: async () => {
console.log('Performing custom cleanup...');
// Add any custom cleanup here
},
});
// Add health endpoints BEFORE the main router
// We need to manually add them here since they must come first
const enhancedServer = server;
enhancedServer
.getServer()
.addHook('preHandler', async (req, reply) => {
if (req.url === '/health') {
await reply.status(200).send({
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
pid: process.pid,
});
return;
}
if (req.url === '/ready') {
await reply.status(200).send({
ready: true,
timestamp: new Date().toISOString(),
});
return;
}
if (req.url === '/alive') {
await reply.status(200).send({
alive: true,
pid: process.pid,
memory: process.memoryUsage(),
uptime: process.uptime(),
});
return;
}
});
server.addHook('preHandler', async (req, reply) => (0, router_1.router)(req, reply, config));
await server.start();
console.log(`🚀 Conduit is running on port ${servicePort}`);
console.log(`📍 Health check: http://127.0.0.1:${servicePort}/health`);
console.log(`📝 PID: ${process.pid}`);
}
// run();
//# sourceMappingURL=index.js.map