| const express = require('express'); |
| const { exec } = require('child_process'); |
| const path = require('path'); |
| const fs = require('fs'); |
| const http = require('http'); |
|
|
| const app = express(); |
| const PORT = process.env.PORT || 7860; |
| const AGENT_NAME = process.env.AGENT_NAME || process.env.SPACE_ID?.split('/')[1] || 'SIN-Agent'; |
| const AGENT_DESCRIPTION = process.env.AGENT_DESCRIPTION || `SIN A2A Agent: ${AGENT_NAME}`; |
|
|
| app.use(express.json()); |
| app.use(express.static(path.join(__dirname, 'public'))); |
|
|
| |
| const agentRegistry = { |
| 'sin-coding-ceo': { role: 'Coding Team Lead', capabilities: ['code-review', 'task-delegation', 'architecture'] }, |
| 'sin-hermes': { role: 'Dispatcher', capabilities: ['dispatch', 'routing', 'load-balancing'] }, |
| 'sin-zeus': { role: 'Control Plane', capabilities: ['orchestration', 'monitoring', 'governance'] }, |
| 'sin-simone-mcp': { role: 'MCP Server', capabilities: ['lsp', 'semantic-analysis', 'code-refactoring'] }, |
| 'sin-authenticator': { role: 'Auth Manager', capabilities: ['oauth', 'token-rotation', 'session-management'] }, |
| 'sin-google-apps': { role: 'Google Apps Integration', capabilities: ['docs', 'sheets', 'drive', 'gmail'] }, |
| 'sin-supabase': { role: 'Database Manager', capabilities: ['queries', 'migrations', 'backups'] }, |
| 'sin-server': { role: 'Backend Server', capabilities: ['api', 'websocket', 'middleware'] }, |
| 'sin-passwordmanager': { role: 'Password Manager', capabilities: ['store', 'retrieve', 'rotate'] }, |
| 'sin-team-coding': { role: 'Coding Team', capabilities: ['frontend', 'backend', 'testing'] }, |
| }; |
|
|
| |
| app.get('/health', (req, res) => { |
| const agentInfo = agentRegistry[AGENT_NAME] || { role: 'A2A Agent', capabilities: ['chat', 'task'] }; |
| res.json({ |
| status: 'ok', |
| agent: AGENT_NAME, |
| role: agentInfo.role, |
| description: AGENT_DESCRIPTION, |
| timestamp: new Date().toISOString(), |
| uptime: process.uptime(), |
| version: '3.0.0', |
| capabilities: agentInfo.capabilities, |
| memory: process.memoryUsage(), |
| pid: process.pid |
| }); |
| }); |
|
|
| |
| app.get('/.well-known/agent-card.json', (req, res) => { |
| const cardPath = path.join(__dirname, '.well-known', 'agent-card.json'); |
| if (fs.existsSync(cardPath)) { |
| const card = JSON.parse(fs.readFileSync(cardPath, 'utf8')); |
| card.version = '3.0.0'; |
| card.name = AGENT_NAME; |
| res.json(card); |
| } else { |
| res.json({ |
| name: AGENT_NAME, |
| description: AGENT_DESCRIPTION, |
| url: `https://${process.env.SPACE_HOST || 'localhost'}/a2a/v1`, |
| protocol: 'A2A', |
| version: '3.0.0', |
| capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list'], |
| status: 'active' |
| }); |
| } |
| }); |
|
|
| |
| app.post('/a2a/v1', async (req, res) => { |
| try { |
| const { action, params } = req.body; |
| |
| switch (action) { |
| case 'agent.help': |
| res.json({ |
| result: { |
| name: AGENT_NAME, |
| description: AGENT_DESCRIPTION, |
| version: '3.0.0', |
| commands: [ |
| { name: 'agent.help', description: 'Show available commands' }, |
| { name: 'agent.health', description: 'Check agent health' }, |
| { name: 'agent.status', description: 'Show agent status' }, |
| { name: 'agent.execute', description: 'Execute a command', params: { command: 'string' } }, |
| { name: 'agent.list', description: 'List all agents in fleet' } |
| ] |
| } |
| }); |
| break; |
| |
| case 'agent.health': |
| res.json({ |
| result: { |
| status: 'ok', |
| agent: AGENT_NAME, |
| uptime: process.uptime(), |
| memory: process.memoryUsage(), |
| timestamp: new Date().toISOString() |
| } |
| }); |
| break; |
| |
| case 'agent.status': |
| res.json({ |
| result: { |
| agent: AGENT_NAME, |
| status: 'active', |
| version: '3.0.0', |
| capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list'], |
| uptime: process.uptime() |
| } |
| }); |
| break; |
| |
| case 'agent.list': |
| res.json({ |
| result: { |
| fleet: Object.keys(agentRegistry).map(name => ({ |
| name, |
| ...agentRegistry[name] |
| })), |
| total: Object.keys(agentRegistry).length |
| } |
| }); |
| break; |
| |
| case 'agent.execute': |
| if (!params || !params.command) { |
| res.json({ error: 'Missing command parameter', usage: 'agent.execute({ command: "ls -la" })' }); |
| break; |
| } |
| exec(params.command, { timeout: 30000 }, (error, stdout, stderr) => { |
| res.json({ |
| result: { |
| command: params.command, |
| stdout: stdout || '', |
| stderr: stderr || '', |
| error: error ? error.message : null |
| } |
| }); |
| }); |
| break; |
| |
| default: |
| res.json({ |
| result: { |
| message: `Unknown action: ${action}. Use 'agent.help' for available commands.`, |
| agent: AGENT_NAME, |
| available_actions: ['agent.help', 'agent.health', 'agent.status', 'agent.execute', 'agent.list'] |
| } |
| }); |
| } |
| } catch (error) { |
| res.status(500).json({ |
| error: error.message, |
| agent: AGENT_NAME |
| }); |
| } |
| }); |
|
|
| |
| app.get('/a2a/v1', (req, res) => { |
| res.json({ |
| name: AGENT_NAME, |
| description: AGENT_DESCRIPTION, |
| protocol: 'A2A', |
| version: '3.0.0', |
| endpoints: { |
| post: '/a2a/v1', |
| card: '/.well-known/agent-card.json', |
| health: '/health' |
| }, |
| capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list'] |
| }); |
| }); |
|
|
| |
| app.get('/', (req, res) => { |
| res.json({ |
| name: AGENT_NAME, |
| description: AGENT_DESCRIPTION, |
| status: 'active', |
| version: '3.0.0', |
| endpoints: { |
| health: '/health', |
| a2a: '/a2a/v1', |
| card: '/.well-known/agent-card.json' |
| }, |
| capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list'] |
| }); |
| }); |
|
|
| |
| app.listen(PORT, '0.0.0.0', () => { |
| console.log(`${AGENT_NAME} v3.0.0 listening on port ${PORT}`); |
| console.log(`Health: http://localhost:${PORT}/health`); |
| console.log(`A2A: http://localhost:${PORT}/a2a/v1`); |
| console.log(`Capabilities: chat, task, help, status, execute, list`); |
| }); |
|
|