UNPKG

seraph-agent

Version:

An extremely lightweight, SRE autonomous AI agent for seamless integration with common observability tasks.

195 lines (192 loc) 7.33 kB
#!/usr/bin/env node "use strict"; 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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const http = __importStar(require("http")); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const net = __importStar(require("net")); const server_1 = require("./server"); const agent_1 = require("./agent"); const config_1 = require("./config"); const chat_1 = require("./chat"); const mcp_manager_1 = require("./mcp-manager"); const program = new commander_1.Command(); program .name('seraph-agent') .version('1.0.1') .description('A lightweight, autonomous SRE AI agent.'); program.addHelpText('after', ` Dynamic Tool Integration with MCP: Seraph can connect to any server that follows the Model Context Protocol (MCP). This allows the agent to dynamically discover and use external tools to answer your questions and perform tasks. To use this feature, provide the server's URL via the --mcp-server-url option when using the 'chat' command. Example: $ seraph chat "What is the current price of Bitcoin?" --mcp-server-url <some-crypto-mcp-server-url> `); program .command('start') .description('Start the Seraph agent and log ingestion server.') .option('--mcp-server-url <url>', 'Connect to an MCP server to enable dynamic tool usage.') .action(async (options) => { const pidFilePath = path.join(process.cwd(), '.seraph.pid'); try { await fs.promises.access(pidFilePath); console.error('Seraph agent is already running. Please stop it first.'); process.exit(1); } catch (error) { // ENOENT means the file doesn't exist, which is what we want. if (error.code !== 'ENOENT') { console.error('Error checking for existing PID file:', error); process.exit(1); } } console.log('Starting Seraph Agent...'); if (options.mcpServerUrl) { console.log(`MCP server specified. The agent will connect to it when you use the chat command.`); } const config = await (0, config_1.loadConfig)(); const agentManager = new agent_1.AgentManager(config); (0, server_1.startServer)(config, agentManager); await fs.promises.writeFile(pidFilePath, process.pid.toString()); console.log(`Log ingestion server started on port ${config.port}`); console.log(`Agent manager is running with ${config.workers} workers.`); console.log(`PID: ${process.pid}`); }); program .command('status') .description('Check the status of the Seraph agent.') .action(async () => { const config = await (0, config_1.loadConfig)(); let retries = 5; const tryConnect = () => { const options = { hostname: 'localhost', port: config.port, path: '/status', method: 'GET', }; const req = http.request(options, (res) => { if (res.statusCode === 200) { console.log('Seraph agent is running.'); process.exit(0); } else { console.log('Seraph agent is not running.'); process.exit(1); } }); req.on('error', (e) => { if (retries > 0) { retries--; setTimeout(tryConnect, 500); } else { console.error('Error connecting to Seraph agent: Not running'); process.exit(1); } }); req.end(); }; tryConnect(); }); program .command('stop') .description('Stop the Seraph agent.') .action(async () => { const pidFilePath = path.join(process.cwd(), '.seraph.pid'); try { await fs.promises.access(pidFilePath); const pid = parseInt(await fs.promises.readFile(pidFilePath, 'utf-8'), 10); process.kill(pid, 'SIGTERM'); await fs.promises.unlink(pidFilePath); console.log('Seraph agent stopped.'); } catch (error) { if (error.code === 'ENOENT') { console.error('Seraph agent is not running.'); } else if (error.code === 'ESRCH') { // If the process doesn't exist, just remove the pid file. try { await fs.promises.unlink(pidFilePath); console.log('Cleaned up stale PID file.'); } catch (unlinkError) { console.error('Error removing stale PID file:', unlinkError); } } else { console.error('Error stopping agent:', error); } } }); program .command('chat <message>') .description('Chat with the Seraph agent.') .option('-c, --context', 'Include recent logs as context.') .option('--mcp-server-url <url>', 'Dynamically connect to an MCP server to use its tools.') .action(async (message, options) => { console.log("Input received by CLI:", message); const config = await (0, config_1.loadConfig)(); if (options.mcpServerUrl) { await mcp_manager_1.mcpManager.initialize(options.mcpServerUrl); } const tools = mcp_manager_1.mcpManager.getDynamicTools(); if (options.context) { const ipcSocketPath = path.join(process.cwd(), '.seraph.sock'); const client = net.createConnection({ path: ipcSocketPath }, () => { client.write('get_logs'); }); client.on('data', async (data) => { const logs = JSON.parse(data.toString()); const response = await (0, chat_1.chat)(message, config, tools, logs); console.log(response); client.end(); }); client.on('error', (err) => { console.error('Error connecting to Seraph agent IPC server. Is the agent running?'); }); } else { const response = await (0, chat_1.chat)(message, config, tools); console.log(response); } }); program.parse(process.argv);