Phase 5: multi-host agents (0.5.0)
- stackpilot-agent: slim token-guarded FastAPI (reuses compose_service) exposing stack CRUD/lifecycle/logs + system info; same image, different CMD. agent/ Dockerfile + compose + .env.example. - Central proxy: Agent model, agent_service (httpx ping/proxy + live status: online/offline/unauthorized + hostname/last_seen), routers/agents.py (CRUD + ping + proxied stacks/lifecycle/logs/system). - Frontend: Settings → Remote hosts (add/check/remove, connectivity dot); Stacks grouped by host; remote stack detail with lifecycle, live logs, compose/.env edit. Verified end-to-end: agent+main on a shared network — register (good/bad token), list/create/start/logs/delete remote stacks, offline detection (502). Remote backup destinations (SFTP/S3) deferred. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8d19b09abd
commit
59037f4287
@@ -0,0 +1,30 @@
|
||||
import api from "./client";
|
||||
import type { Agent, StackDetail, StackSummary } from "@/types";
|
||||
|
||||
export type RemoteStackSummary = StackSummary & { agent_id: number; agent_name: string };
|
||||
export type RemoteStackDetail = StackDetail & { agent_id: number; agent_name: string };
|
||||
|
||||
export const agentsApi = {
|
||||
list: (refresh = true) =>
|
||||
api.get<Agent[]>(`/api/agents?refresh=${refresh}`).then((r) => r.data),
|
||||
create: (body: { name: string; url: string; token: string }) =>
|
||||
api.post<Agent>("/api/agents", body).then((r) => r.data),
|
||||
update: (id: number, body: { name?: string; url?: string; token?: string }) =>
|
||||
api.put<Agent>(`/api/agents/${id}`, body).then((r) => r.data),
|
||||
remove: (id: number) => api.delete(`/api/agents/${id}`).then((r) => r.data),
|
||||
ping: (id: number) =>
|
||||
api.post<{ status: string; hostname?: string }>(`/api/agents/${id}/ping`).then((r) => r.data),
|
||||
|
||||
stacks: (id: number) =>
|
||||
api.get<RemoteStackSummary[]>(`/api/agents/${id}/stacks`).then((r) => r.data),
|
||||
stack: (id: number, stackId: string) =>
|
||||
api.get<RemoteStackDetail>(`/api/agents/${id}/stacks/${stackId}`).then((r) => r.data),
|
||||
logs: (id: number, stackId: string, tail = 200) =>
|
||||
api
|
||||
.get<{ logs: string }>(`/api/agents/${id}/stacks/${stackId}/logs?tail=${tail}`)
|
||||
.then((r) => r.data),
|
||||
update_stack: (id: number, stackId: string, body: { yaml?: string; env?: string }) =>
|
||||
api.put(`/api/agents/${id}/stacks/${stackId}`, body).then((r) => r.data),
|
||||
action: (id: number, stackId: string, action: string) =>
|
||||
api.post(`/api/agents/${id}/stacks/${stackId}/${action}`).then((r) => r.data),
|
||||
};
|
||||
Reference in New Issue
Block a user