// Package server 神识 HTTP 服务:数据面(IR 入站 → SSE 出站)与健康面。 package server import ( "encoding/json" "net/http" "hunjing/shenshi/internal/ir" "hunjing/shenshi/internal/relay" "hunjing/shenshi/internal/route" ) // Config 服务配置。 type Config struct { ServiceToken string // 灵台→神识服务令牌;为空时开发档不校验 } // Server 神识 HTTP 服务。 type Server struct { cfg Config routes *route.Registry mux *http.ServeMux } // New 构建服务并注册路由。 func New(cfg Config, routes *route.Registry) *Server { s := &Server{cfg: cfg, routes: routes, mux: http.NewServeMux()} s.mux.HandleFunc("GET /healthz", s.handleHealth) s.mux.HandleFunc("GET /readyz", s.handleHealth) s.mux.Handle("POST /v1/chat/completions", s.auth(http.HandlerFunc(s.handleChat))) return s } // ServeHTTP 实现 http.Handler。 func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.mux.ServeHTTP(w, r) } // auth 服务令牌校验中间件;未配置令牌时放行(本地开发档)。 func (s *Server) auth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if s.cfg.ServiceToken == "" { next.ServeHTTP(w, r) return } credential := r.Header.Get("Authorization") if credential != "Bearer "+s.cfg.ServiceToken { writeError(w, http.StatusUnauthorized, "HJ-2003", "服务令牌无效") return } next.ServeHTTP(w, r) }) } // handleChat 数据面:解析 IR → 路由 → 适配器流出 SSE。 func (s *Server) handleChat(w http.ResponseWriter, r *http.Request) { var req ir.ChatRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "HJ-2002", "IR 请求解析失败: "+err.Error()) return } if err := req.Validate(); err != nil { writeError(w, http.StatusBadRequest, "HJ-2002", err.Error()) return } endpoints, err := s.routes.Resolve(req.Slot) if err != nil { writeError(w, http.StatusServiceUnavailable, "HJ-2001", err.Error()) return } relay.SSEHeaders(w) w.WriteHeader(http.StatusOK) deltas := make(chan ir.Delta, 16) streamErr := make(chan error, 1) go func() { defer close(deltas) streamErr <- endpoints[0].Adaptor.Stream(r.Context(), &req, deltas) }() for d := range deltas { if err := relay.WriteDelta(w, d); err != nil { return // 客户端断开:取消上游由 r.Context() 传播 } } if err := <-streamErr; err != nil { // 流已开始,只能如实中断:写一条错误帧后终止(不伪装 [DONE]) _ = relay.WriteDelta(w, ir.Delta{FinishReason: "error", Delta: ""}) _ = relay.WriteDone(w) return } if err := relay.WriteDone(w); err != nil { return } } // handleHealth 健康面。 func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"status":"ok"}`)) } // writeError 统一错误结构(API 契约 §5)。 func writeError(w http.ResponseWriter, status int, code, message string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) body := map[string]any{ "error": map[string]string{"code": code, "message": message}, } _ = json.NewEncoder(w).Encode(body) }