feat(swarm): autonomous agent containers, Swarm Manager with auto-stop, /nodes UI overhaul
## 1. Fix /nodes Swarm Status Display
- Add SwarmStatusBanner component: clear green/red/loading state
- Shows nodeId, managerAddr, isManager badge
- Error state explains what to check (docker.sock mount)
- Header now shows 'swarm unreachable — check gateway' vs 'active'
- swarmOk now checks nodeId presence, not just data existence
## 2. Autonomous Agent Container
- New docker/Dockerfile.agent — builds Go agent binary from gateway/cmd/agent/
- New gateway/cmd/agent/main.go — standalone HTTP microservice:
* GET /health — liveness probe with idle time info
* POST /task — receives task, forwards to Gateway orchestrator
* GET /info — agent metadata (id, hostname, gateway url)
* Idle watchdog: calls /api/swarm/agents/{name}/stop after IdleTimeoutMinutes
* Connects to Swarm overlay network (goclaw-net) → reaches DB/Gateway by DNS
* Env: AGENT_ID, GATEWAY_URL, DATABASE_URL, IDLE_TIMEOUT_MINUTES
## 3. Swarm Manager Agent (auto-stop after 15min idle)
- New gateway/internal/api/swarm_manager.go:
* SwarmManager goroutine checks every 60s
* Scales idle GoClaw agent services to 0 replicas after 15 min
* Tracks lastActivity from task UpdatedAt timestamps
- New REST endpoints in gateway:
* GET /api/swarm/agents — list agents with idleMinutes
* POST /api/swarm/agents/{name}/start — scale up agent
* POST /api/swarm/agents/{name}/stop — scale to 0
* DELETE /api/swarm/services/{id} — remove service permanently
- SwarmManager started as background goroutine in main.go with context cancel
## 4. Docker Client Enhancements
- Added NetworkAttachment type and Networks field to ServiceSpec
- CreateAgentServiceFull(opts) — supports overlay networks, custom labels
- CreateAgentService() delegates to CreateAgentServiceFull for backward compat
- RemoveService(id) — DELETE /v1.44/services/{id}
- GetServiceLastActivity(id) — finds latest task UpdatedAt for idle detection
## 5. tRPC & Gateway Proxy
- New functions: removeSwarmService, listSwarmAgents, startSwarmAgent, stopSwarmAgent
- SwarmAgentInfo type with idleMinutes, lastActivity, desiredReplicas
- createAgentService now accepts networks[] parameter
- New tRPC endpoints: nodes.removeService, nodes.listAgents, nodes.startAgent, nodes.stopAgent
## 6. Nodes.tsx UI Overhaul
- SwarmStatusBanner component at top — no more silent 'connecting…'
- New 'Agents' tab with AgentManagerRow: idle time, auto-stop warning, start/stop/remove buttons
- IdleColor coding: green < 5m, yellow 5-10m, red 10m+ with countdown to auto-stop
- ServiceRow: added Remove button with confirmation dialog
- RemoveConfirmDialog component
- DeployAgentDialog: added overlay networks field, default env includes GATEWAY_URL
- All queries refetch after agent start/stop/remove
This commit is contained in:
53
docker/Dockerfile.agent
Normal file
53
docker/Dockerfile.agent
Normal file
@@ -0,0 +1,53 @@
|
||||
# ── GoClaw Agent Container ────────────────────────────────────────────────────
|
||||
#
|
||||
# Autonomous agent microservice that:
|
||||
# 1. Exposes a lightweight HTTP API (port 8080) for receiving tasks
|
||||
# 2. Has access to the Swarm overlay network (goclaw-net)
|
||||
# 3. Connects to the shared MySQL database for persistence
|
||||
# 4. Calls the LLM API via the GoClaw Gateway
|
||||
# 5. Auto-registers itself with the orchestrator on startup
|
||||
#
|
||||
# Build: docker build -f docker/Dockerfile.agent -t goclaw-agent:latest .
|
||||
# Deploy: docker service create --name goclaw-agent-NAME \
|
||||
# --network goclaw-net \
|
||||
# -e AGENT_ID=NAME \
|
||||
# -e GATEWAY_URL=http://goclaw-gateway:18789 \
|
||||
# -e DATABASE_URL=mysql://... \
|
||||
# goclaw-agent:latest
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ── Stage 1: Build Go agent binary ───────────────────────────────────────────
|
||||
FROM golang:1.23-alpine AS builder
|
||||
WORKDIR /src
|
||||
|
||||
# Copy gateway module (agent reuses gateway internals)
|
||||
COPY gateway/go.mod gateway/go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
COPY gateway/ ./
|
||||
|
||||
# Build the agent server binary
|
||||
RUN go build -o /agent-server ./cmd/agent/...
|
||||
|
||||
# ── Stage 2: Runtime ──────────────────────────────────────────────────────────
|
||||
FROM alpine:3.20
|
||||
RUN apk add --no-cache ca-certificates curl wget tzdata
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /agent-server ./agent-server
|
||||
|
||||
# Default environment (override at deploy time)
|
||||
ENV AGENT_ID=default-agent \
|
||||
AGENT_PORT=8080 \
|
||||
GATEWAY_URL=http://goclaw-gateway:18789 \
|
||||
LLM_BASE_URL=https://ollama.com/v1 \
|
||||
LLM_API_KEY="" \
|
||||
DATABASE_URL="" \
|
||||
IDLE_TIMEOUT_MINUTES=15
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \
|
||||
CMD wget -qO- http://localhost:8080/health || exit 1
|
||||
|
||||
ENTRYPOINT ["/app/agent-server"]
|
||||
Reference in New Issue
Block a user