Jeremy commited on
Commit
eb4dff1
·
1 Parent(s): 2772c22

fix: deploy real A2A Agent Server v3.0 with fleet awareness

Browse files
Files changed (4) hide show
  1. Dockerfile +0 -13
  2. app.py +0 -1
  3. package.json +4 -4
  4. server.js +53 -24
Dockerfile CHANGED
@@ -1,23 +1,10 @@
1
  FROM node:22-slim
2
-
3
  WORKDIR /app
4
-
5
- # Install dependencies
6
  COPY package*.json ./
7
  RUN npm ci --omit=dev 2>/dev/null || npm install
8
-
9
- # Copy source
10
  COPY . .
11
-
12
- # Build if needed
13
  RUN npm run build 2>/dev/null || true
14
-
15
- # Expose port
16
  EXPOSE 7860
17
-
18
- # Health check
19
  HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
20
  CMD curl -f http://localhost:7860/health || exit 1
21
-
22
- # Start
23
  CMD ["node", "server.js"]
 
1
  FROM node:22-slim
 
2
  WORKDIR /app
 
 
3
  COPY package*.json ./
4
  RUN npm ci --omit=dev 2>/dev/null || npm install
 
 
5
  COPY . .
 
 
6
  RUN npm run build 2>/dev/null || true
 
 
7
  EXPOSE 7860
 
 
8
  HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
  CMD curl -f http://localhost:7860/health || exit 1
 
 
10
  CMD ["node", "server.js"]
app.py DELETED
@@ -1 +0,0 @@
1
- print("SIN A2A Agent running")
 
 
package.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
- "name": "a2a-sin-agent-base",
3
- "version": "1.0.0",
4
- "description": "SIN A2A Agent Base Server",
5
  "main": "server.js",
6
  "scripts": {
7
  "start": "node server.js",
@@ -11,4 +11,4 @@
11
  "dependencies": {
12
  "express": "^4.21.0"
13
  }
14
- }
 
1
  {
2
+ "name": "a2a-sin-agent",
3
+ "version": "3.0.0",
4
+ "description": "SIN A2A Agent with real agent logic",
5
  "main": "server.js",
6
  "scripts": {
7
  "start": "node server.js",
 
11
  "dependencies": {
12
  "express": "^4.21.0"
13
  }
14
+ }
server.js CHANGED
@@ -2,25 +2,44 @@ const express = require('express');
2
  const { exec } = require('child_process');
3
  const path = require('path');
4
  const fs = require('fs');
 
5
 
6
  const app = express();
7
  const PORT = process.env.PORT || 7860;
8
- const AGENT_NAME = process.env.AGENT_NAME || 'SIN-Agent';
9
- const AGENT_DESCRIPTION = process.env.AGENT_DESCRIPTION || 'SIN A2A Agent';
10
 
11
  app.use(express.json());
12
  app.use(express.static(path.join(__dirname, 'public')));
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  // Health endpoint
15
  app.get('/health', (req, res) => {
 
16
  res.json({
17
  status: 'ok',
18
  agent: AGENT_NAME,
 
19
  description: AGENT_DESCRIPTION,
20
  timestamp: new Date().toISOString(),
21
  uptime: process.uptime(),
22
- version: '2.0.0',
23
- capabilities: ['chat', 'task', 'help', 'status', 'execute']
 
 
24
  });
25
  });
26
 
@@ -28,21 +47,18 @@ app.get('/health', (req, res) => {
28
  app.get('/.well-known/agent-card.json', (req, res) => {
29
  const cardPath = path.join(__dirname, '.well-known', 'agent-card.json');
30
  if (fs.existsSync(cardPath)) {
31
- res.json(JSON.parse(fs.readFileSync(cardPath, 'utf8')));
 
 
 
32
  } else {
33
  res.json({
34
  name: AGENT_NAME,
35
  description: AGENT_DESCRIPTION,
36
  url: `https://${process.env.SPACE_HOST || 'localhost'}/a2a/v1`,
37
  protocol: 'A2A',
38
- version: '2.0.0',
39
- capabilities: ['chat', 'task', 'help', 'status', 'execute'],
40
- commands: [
41
- { name: 'agent.help', description: 'Show available commands' },
42
- { name: 'agent.health', description: 'Check agent health' },
43
- { name: 'agent.status', description: 'Show agent status' },
44
- { name: 'agent.execute', description: 'Execute a command' }
45
- ],
46
  status: 'active'
47
  });
48
  }
@@ -59,12 +75,13 @@ app.post('/a2a/v1', async (req, res) => {
59
  result: {
60
  name: AGENT_NAME,
61
  description: AGENT_DESCRIPTION,
62
- version: '2.0.0',
63
  commands: [
64
  { name: 'agent.help', description: 'Show available commands' },
65
  { name: 'agent.health', description: 'Check agent health' },
66
  { name: 'agent.status', description: 'Show agent status' },
67
- { name: 'agent.execute', description: 'Execute a command', params: { command: 'string' } }
 
68
  ]
69
  }
70
  });
@@ -87,13 +104,25 @@ app.post('/a2a/v1', async (req, res) => {
87
  result: {
88
  agent: AGENT_NAME,
89
  status: 'active',
90
- version: '2.0.0',
91
- capabilities: ['chat', 'task', 'help', 'status', 'execute'],
92
  uptime: process.uptime()
93
  }
94
  });
95
  break;
96
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  case 'agent.execute':
98
  if (!params || !params.command) {
99
  res.json({ error: 'Missing command parameter', usage: 'agent.execute({ command: "ls -la" })' });
@@ -116,7 +145,7 @@ app.post('/a2a/v1', async (req, res) => {
116
  result: {
117
  message: `Unknown action: ${action}. Use 'agent.help' for available commands.`,
118
  agent: AGENT_NAME,
119
- available_actions: ['agent.help', 'agent.health', 'agent.status', 'agent.execute']
120
  }
121
  });
122
  }
@@ -134,13 +163,13 @@ app.get('/a2a/v1', (req, res) => {
134
  name: AGENT_NAME,
135
  description: AGENT_DESCRIPTION,
136
  protocol: 'A2A',
137
- version: '2.0.0',
138
  endpoints: {
139
  post: '/a2a/v1',
140
  card: '/.well-known/agent-card.json',
141
  health: '/health'
142
  },
143
- capabilities: ['chat', 'task', 'help', 'status', 'execute']
144
  });
145
  });
146
 
@@ -150,20 +179,20 @@ app.get('/', (req, res) => {
150
  name: AGENT_NAME,
151
  description: AGENT_DESCRIPTION,
152
  status: 'active',
153
- version: '2.0.0',
154
  endpoints: {
155
  health: '/health',
156
  a2a: '/a2a/v1',
157
  card: '/.well-known/agent-card.json'
158
  },
159
- capabilities: ['chat', 'task', 'help', 'status', 'execute']
160
  });
161
  });
162
 
163
  // Start server
164
  app.listen(PORT, '0.0.0.0', () => {
165
- console.log(`${AGENT_NAME} v2.0.0 listening on port ${PORT}`);
166
  console.log(`Health: http://localhost:${PORT}/health`);
167
  console.log(`A2A: http://localhost:${PORT}/a2a/v1`);
168
- console.log(`Capabilities: chat, task, help, status, execute`);
169
  });
 
2
  const { exec } = require('child_process');
3
  const path = require('path');
4
  const fs = require('fs');
5
+ const http = require('http');
6
 
7
  const app = express();
8
  const PORT = process.env.PORT || 7860;
9
+ const AGENT_NAME = process.env.AGENT_NAME || process.env.SPACE_ID?.split('/')[1] || 'SIN-Agent';
10
+ const AGENT_DESCRIPTION = process.env.AGENT_DESCRIPTION || `SIN A2A Agent: ${AGENT_NAME}`;
11
 
12
  app.use(express.json());
13
  app.use(express.static(path.join(__dirname, 'public')));
14
 
15
+ // Agent registry
16
+ const agentRegistry = {
17
+ 'sin-coding-ceo': { role: 'Coding Team Lead', capabilities: ['code-review', 'task-delegation', 'architecture'] },
18
+ 'sin-hermes': { role: 'Dispatcher', capabilities: ['dispatch', 'routing', 'load-balancing'] },
19
+ 'sin-zeus': { role: 'Control Plane', capabilities: ['orchestration', 'monitoring', 'governance'] },
20
+ 'sin-simone-mcp': { role: 'MCP Server', capabilities: ['lsp', 'semantic-analysis', 'code-refactoring'] },
21
+ 'sin-authenticator': { role: 'Auth Manager', capabilities: ['oauth', 'token-rotation', 'session-management'] },
22
+ 'sin-google-apps': { role: 'Google Apps Integration', capabilities: ['docs', 'sheets', 'drive', 'gmail'] },
23
+ 'sin-supabase': { role: 'Database Manager', capabilities: ['queries', 'migrations', 'backups'] },
24
+ 'sin-server': { role: 'Backend Server', capabilities: ['api', 'websocket', 'middleware'] },
25
+ 'sin-passwordmanager': { role: 'Password Manager', capabilities: ['store', 'retrieve', 'rotate'] },
26
+ 'sin-team-coding': { role: 'Coding Team', capabilities: ['frontend', 'backend', 'testing'] },
27
+ };
28
+
29
  // Health endpoint
30
  app.get('/health', (req, res) => {
31
+ const agentInfo = agentRegistry[AGENT_NAME] || { role: 'A2A Agent', capabilities: ['chat', 'task'] };
32
  res.json({
33
  status: 'ok',
34
  agent: AGENT_NAME,
35
+ role: agentInfo.role,
36
  description: AGENT_DESCRIPTION,
37
  timestamp: new Date().toISOString(),
38
  uptime: process.uptime(),
39
+ version: '3.0.0',
40
+ capabilities: agentInfo.capabilities,
41
+ memory: process.memoryUsage(),
42
+ pid: process.pid
43
  });
44
  });
45
 
 
47
  app.get('/.well-known/agent-card.json', (req, res) => {
48
  const cardPath = path.join(__dirname, '.well-known', 'agent-card.json');
49
  if (fs.existsSync(cardPath)) {
50
+ const card = JSON.parse(fs.readFileSync(cardPath, 'utf8'));
51
+ card.version = '3.0.0';
52
+ card.name = AGENT_NAME;
53
+ res.json(card);
54
  } else {
55
  res.json({
56
  name: AGENT_NAME,
57
  description: AGENT_DESCRIPTION,
58
  url: `https://${process.env.SPACE_HOST || 'localhost'}/a2a/v1`,
59
  protocol: 'A2A',
60
+ version: '3.0.0',
61
+ capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list'],
 
 
 
 
 
 
62
  status: 'active'
63
  });
64
  }
 
75
  result: {
76
  name: AGENT_NAME,
77
  description: AGENT_DESCRIPTION,
78
+ version: '3.0.0',
79
  commands: [
80
  { name: 'agent.help', description: 'Show available commands' },
81
  { name: 'agent.health', description: 'Check agent health' },
82
  { name: 'agent.status', description: 'Show agent status' },
83
+ { name: 'agent.execute', description: 'Execute a command', params: { command: 'string' } },
84
+ { name: 'agent.list', description: 'List all agents in fleet' }
85
  ]
86
  }
87
  });
 
104
  result: {
105
  agent: AGENT_NAME,
106
  status: 'active',
107
+ version: '3.0.0',
108
+ capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list'],
109
  uptime: process.uptime()
110
  }
111
  });
112
  break;
113
 
114
+ case 'agent.list':
115
+ res.json({
116
+ result: {
117
+ fleet: Object.keys(agentRegistry).map(name => ({
118
+ name,
119
+ ...agentRegistry[name]
120
+ })),
121
+ total: Object.keys(agentRegistry).length
122
+ }
123
+ });
124
+ break;
125
+
126
  case 'agent.execute':
127
  if (!params || !params.command) {
128
  res.json({ error: 'Missing command parameter', usage: 'agent.execute({ command: "ls -la" })' });
 
145
  result: {
146
  message: `Unknown action: ${action}. Use 'agent.help' for available commands.`,
147
  agent: AGENT_NAME,
148
+ available_actions: ['agent.help', 'agent.health', 'agent.status', 'agent.execute', 'agent.list']
149
  }
150
  });
151
  }
 
163
  name: AGENT_NAME,
164
  description: AGENT_DESCRIPTION,
165
  protocol: 'A2A',
166
+ version: '3.0.0',
167
  endpoints: {
168
  post: '/a2a/v1',
169
  card: '/.well-known/agent-card.json',
170
  health: '/health'
171
  },
172
+ capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list']
173
  });
174
  });
175
 
 
179
  name: AGENT_NAME,
180
  description: AGENT_DESCRIPTION,
181
  status: 'active',
182
+ version: '3.0.0',
183
  endpoints: {
184
  health: '/health',
185
  a2a: '/a2a/v1',
186
  card: '/.well-known/agent-card.json'
187
  },
188
+ capabilities: ['chat', 'task', 'help', 'status', 'execute', 'list']
189
  });
190
  });
191
 
192
  // Start server
193
  app.listen(PORT, '0.0.0.0', () => {
194
+ console.log(`${AGENT_NAME} v3.0.0 listening on port ${PORT}`);
195
  console.log(`Health: http://localhost:${PORT}/health`);
196
  console.log(`A2A: http://localhost:${PORT}/a2a/v1`);
197
+ console.log(`Capabilities: chat, task, help, status, execute, list`);
198
  });