feat(#93): implement agent spawn via federation
Implements FED-010: Agent Spawn via Federation feature that enables spawning and managing Claude agents on remote federated Mosaic Stack instances via COMMAND message type. Features: - Federation agent command types (spawn, status, kill) - FederationAgentService for handling agent operations - Integration with orchestrator's agent spawner/lifecycle services - API endpoints for spawning, querying status, and killing agents - Full command routing through federation COMMAND infrastructure - Comprehensive test coverage (12/12 tests passing) Architecture: - Hub → Spoke: Spawn agents on remote instances - Command flow: FederationController → FederationAgentService → CommandService → Remote Orchestrator - Response handling: Remote orchestrator returns agent status/results - Security: Connection validation, signature verification Files created: - apps/api/src/federation/types/federation-agent.types.ts - apps/api/src/federation/federation-agent.service.ts - apps/api/src/federation/federation-agent.service.spec.ts Files modified: - apps/api/src/federation/command.service.ts (agent command routing) - apps/api/src/federation/federation.controller.ts (agent endpoints) - apps/api/src/federation/federation.module.ts (service registration) - apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint) - apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration) Testing: - 12/12 tests passing for FederationAgentService - All command service tests passing - TypeScript compilation successful - Linting passed Refs #93 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -65,18 +65,18 @@ DELETE /api/{resource}/:id # Delete resource
|
||||
|
||||
## HTTP Status Codes
|
||||
|
||||
| Code | Meaning | Usage |
|
||||
|------|---------|-------|
|
||||
| 200 | OK | Successful GET, PATCH, PUT |
|
||||
| 201 | Created | Successful POST |
|
||||
| 204 | No Content | Successful DELETE |
|
||||
| 400 | Bad Request | Invalid input |
|
||||
| 401 | Unauthorized | Missing/invalid auth token |
|
||||
| 403 | Forbidden | Valid token, insufficient permissions |
|
||||
| 404 | Not Found | Resource doesn't exist |
|
||||
| 409 | Conflict | Resource already exists |
|
||||
| 422 | Unprocessable Entity | Validation failed |
|
||||
| 500 | Internal Server Error | Server error |
|
||||
| Code | Meaning | Usage |
|
||||
| ---- | --------------------- | ------------------------------------- |
|
||||
| 200 | OK | Successful GET, PATCH, PUT |
|
||||
| 201 | Created | Successful POST |
|
||||
| 204 | No Content | Successful DELETE |
|
||||
| 400 | Bad Request | Invalid input |
|
||||
| 401 | Unauthorized | Missing/invalid auth token |
|
||||
| 403 | Forbidden | Valid token, insufficient permissions |
|
||||
| 404 | Not Found | Resource doesn't exist |
|
||||
| 409 | Conflict | Resource already exists |
|
||||
| 422 | Unprocessable Entity | Validation failed |
|
||||
| 500 | Internal Server Error | Server error |
|
||||
|
||||
## Pagination
|
||||
|
||||
@@ -87,10 +87,12 @@ GET /api/tasks?page=1&limit=20
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `page` — Page number (default: 1)
|
||||
- `limit` — Items per page (default: 10, max: 100)
|
||||
|
||||
**Response includes:**
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [...],
|
||||
@@ -113,6 +115,7 @@ GET /api/events?start_date=2026-01-01&end_date=2026-01-31
|
||||
```
|
||||
|
||||
**Supported operators:**
|
||||
|
||||
- `=` — Equals
|
||||
- `_gt` — Greater than (e.g., `created_at_gt=2026-01-01`)
|
||||
- `_lt` — Less than
|
||||
@@ -139,11 +142,10 @@ GET /api/tasks?fields=id,title,status
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
{ "id": "1", "title": "Task 1", "status": "active" }
|
||||
]
|
||||
"data": [{ "id": "1", "title": "Task 1", "status": "active" }]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -156,6 +158,7 @@ GET /api/tasks?include=assignee,project
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
@@ -186,11 +189,13 @@ See [Authentication Endpoints](../2-authentication/1-endpoints.md) for details.
|
||||
## Request Headers
|
||||
|
||||
**Required:**
|
||||
|
||||
```http
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
**Optional:**
|
||||
|
||||
```http
|
||||
Authorization: Bearer {token}
|
||||
X-Workspace-ID: {workspace-uuid} # For multi-tenant requests
|
||||
@@ -221,6 +226,7 @@ API endpoints are rate-limited:
|
||||
- **Authenticated:** 1000 requests/hour
|
||||
|
||||
**Rate limit headers:**
|
||||
|
||||
```http
|
||||
X-RateLimit-Limit: 1000
|
||||
X-RateLimit-Remaining: 950
|
||||
@@ -235,11 +241,7 @@ CORS is configured for frontend origin:
|
||||
|
||||
```javascript
|
||||
// Allowed origins
|
||||
const origins = [
|
||||
process.env.NEXT_PUBLIC_APP_URL,
|
||||
'http://localhost:3000',
|
||||
'http://localhost:3001'
|
||||
];
|
||||
const origins = [process.env.NEXT_PUBLIC_APP_URL, "http://localhost:3000", "http://localhost:3001"];
|
||||
```
|
||||
|
||||
## Versioning
|
||||
@@ -257,6 +259,7 @@ GET /health
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
@@ -282,6 +285,7 @@ curl -X POST http://localhost:3001/api/tasks \
|
||||
```
|
||||
|
||||
**Response (201):**
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
|
||||
Reference in New Issue
Block a user