initial agent-mgr: app builder platform MVP
Go API server + Preact UI + Claude Code adapter. - App-centric model (ideas, not repos) - AgentProvider interface for multi-agent support - K8s pod lifecycle for sandboxed agent sessions - Gitea integration (create repos, push branches) - WebSocket streaming for live session output - Woodpecker CI/CD pipelines (kaniko build + kubectl deploy)
This commit is contained in:
77
internal/api/router.go
Normal file
77
internal/api/router.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/agentsphere/agent-mgr/internal/app"
|
||||
"github.com/agentsphere/agent-mgr/internal/events"
|
||||
"github.com/agentsphere/agent-mgr/internal/provider"
|
||||
"github.com/agentsphere/agent-mgr/internal/store"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
store *store.Store
|
||||
app *app.Service
|
||||
registry *provider.Registry
|
||||
events *events.Bus
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
func NewServer(st *store.Store, appSvc *app.Service, reg *provider.Registry, bus *events.Bus, log *slog.Logger) *Server {
|
||||
return &Server{store: st, app: appSvc, registry: reg, events: bus, log: log}
|
||||
}
|
||||
|
||||
func (s *Server) Handler(staticFS fs.FS) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Compress(5))
|
||||
|
||||
// API routes
|
||||
r.Route("/api/v1", func(r chi.Router) {
|
||||
r.Use(middleware.SetHeader("Content-Type", "application/json"))
|
||||
|
||||
r.Post("/apps", s.createApp)
|
||||
r.Get("/apps", s.listApps)
|
||||
r.Get("/apps/{appID}", s.getApp)
|
||||
r.Delete("/apps/{appID}", s.deleteApp)
|
||||
|
||||
r.Post("/apps/{appID}/sessions", s.createSession)
|
||||
r.Get("/apps/{appID}/sessions", s.listSessions)
|
||||
|
||||
r.Get("/sessions/{sessionID}", s.getSession)
|
||||
r.Post("/sessions/{sessionID}/stop", s.stopSession)
|
||||
r.Post("/sessions/{sessionID}/message", s.sendMessage)
|
||||
r.Get("/sessions/{sessionID}/ws", s.streamSession)
|
||||
|
||||
r.Get("/providers", s.listProviders)
|
||||
|
||||
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
})
|
||||
})
|
||||
|
||||
// Serve SPA for all other routes
|
||||
if staticFS != nil {
|
||||
fileServer := http.FileServer(http.FS(staticFS))
|
||||
r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
|
||||
// Try to serve the file; if not found, serve index.html (SPA routing)
|
||||
path := r.URL.Path
|
||||
f, err := staticFS.Open(path[1:]) // strip leading /
|
||||
if err != nil {
|
||||
// Serve index.html for SPA client-side routing
|
||||
r.URL.Path = "/"
|
||||
} else {
|
||||
f.Close()
|
||||
}
|
||||
fileServer.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
Reference in New Issue
Block a user