first commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"agent/internal/agent"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// NewRouter 组装全部路由:静态资源、会话直达、/api/v1 REST、/ws WebSocket。
|
||||
// 返回 (gin.Engine, *Server):*Server 供 main.go 在托管模式下调用 StartBenchmark 自动触发评测。
|
||||
func NewRouter(cfg agent.Config, store *agent.SessionStore, dockerCfg *agent.DockerConfigStore, apiCfg *agent.APIConfigStore) (*gin.Engine, *Server) {
|
||||
s := &Server{
|
||||
cfg: cfg,
|
||||
store: store,
|
||||
agent: agent.NewAgent(cfg, store, dockerCfg, apiCfg),
|
||||
dockerCfg: dockerCfg,
|
||||
apiCfg: apiCfg,
|
||||
}
|
||||
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery(), requestLogger())
|
||||
|
||||
staticDir := filepath.Join(cfg.Workspace, "web", "static")
|
||||
indexFile := filepath.Join(staticDir, "index.html")
|
||||
r.Static("/static", staticDir)
|
||||
r.StaticFile("/", indexFile)
|
||||
|
||||
// 会话直达:/<sessionId> 返回前端页面,由前端 JS 从路径解析会话 ID
|
||||
r.GET("/:sessionId", func(c *gin.Context) {
|
||||
if !sessionIDPattern.MatchString(c.Param("sessionId")) {
|
||||
c.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
c.File(indexFile)
|
||||
})
|
||||
|
||||
v1 := r.Group("/api/v1")
|
||||
v1.GET("/health", s.health)
|
||||
// 授权相关接口始终放行:前端据此判断是否需要授权 / 提交授权码。
|
||||
// 其余 API 与 WebSocket 统一挂 authRequired(未启用授权时自动放行)。
|
||||
auth := v1.Group("/auth")
|
||||
auth.GET("/status", s.authStatus)
|
||||
auth.POST("/login", s.authLogin)
|
||||
|
||||
authed := v1.Group("")
|
||||
authed.Use(s.authRequired)
|
||||
authed.GET("/config", s.config)
|
||||
authed.GET("/docker/config", s.dockerConfig)
|
||||
authed.PUT("/docker/config", s.setDockerConfig)
|
||||
authed.GET("/llm/config", s.llmConfig)
|
||||
authed.PUT("/llm/config", s.setLLMConfig)
|
||||
authed.GET("/sessions", s.listSessions)
|
||||
authed.POST("/sessions", s.createSession)
|
||||
authed.GET("/sessions/:id", s.getSession)
|
||||
authed.GET("/sessions/:id/messages", s.sessionMessages)
|
||||
authed.DELETE("/sessions/:id", s.deleteSession)
|
||||
authed.DELETE("/sessions/:id/messages", s.clearSession)
|
||||
authed.GET("/coop/tasks", s.coopTasks)
|
||||
|
||||
// WebSocket 实时通道:Agent 流式输出 / 状态 / 协作通知(同样受授权保护)
|
||||
r.GET("/ws", s.authRequired, s.ws)
|
||||
|
||||
return r, s
|
||||
}
|
||||
|
||||
// requestLogger 轻量请求日志中间件:统一 [http] 前缀,便于与 [coop] 等日志区分。
|
||||
func requestLogger() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
c.Next()
|
||||
gin.DefaultWriter.Write([]byte(fmt.Sprintf(
|
||||
"[http] %s | %s %s | %s | %d\n",
|
||||
time.Now().Format("2006/01/02 15:04:05"),
|
||||
c.Request.Method,
|
||||
c.Request.URL.Path,
|
||||
time.Since(start).Round(time.Millisecond).String(),
|
||||
c.Writer.Status(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user