package server import ( "errors" "net/http" "github.com/crypto/byteclaw/internal/providers" "github.com/crypto/byteclaw/internal/store" ) func (s *Server) info(w http.ResponseWriter, _ *http.Request) { in := s.Info if s.Providers != nil { a := s.Providers.Active() in.Provider, in.Model, in.BaseURL = a.Provider, a.Model, s.Providers.BaseURL(a.Provider) } writeJSON(w, 200, in) } func (s *Server) needProviders(w http.ResponseWriter) bool { if s.Providers == nil { writeErr(w, http.StatusNotImplemented, "provider switching not enabled") return false } return true } func providerErr(w http.ResponseWriter, err error) { switch { case errors.Is(err, providers.ErrUnknown): writeErr(w, http.StatusNotFound, err.Error()) default: writeErr(w, http.StatusBadRequest, err.Error()) } } type providerReq struct { Provider string `json:"provider"` Model string `json:"model"` } // GET /api/providers -> {"active":{...},"providers":[...]} (never contains keys). func (s *Server) listProviders(w http.ResponseWriter, _ *http.Request) { if !s.needProviders(w) { return } writeJSON(w, 200, map[string]any{"active": s.Providers.Active(), "providers": s.Providers.List()}) } func (s *Server) setActiveProvider(w http.ResponseWriter, r *http.Request) { if !s.needProviders(w) { return } var b providerReq if !decode(w, r, &b) { return } a, err := s.Providers.SetActive(r.Context(), b.Provider, b.Model) if err != nil { providerErr(w, err) return } writeJSON(w, 200, a) } func (s *Server) listModels(w http.ResponseWriter, r *http.Request) { if !s.needProviders(w) { return } ids, err := s.Providers.Models(r.Context(), r.PathValue("name")) if errors.Is(err, providers.ErrUnknown) { providerErr(w, err) return } if err != nil { s.Log.Warn("list models", "err", err) writeErr(w, http.StatusBadGateway, "provider does not offer a model list") return } writeJSON(w, 200, map[string]any{"models": ids}) } // PUT /api/sessions/{id}/provider: per-session override; empty provider clears it. func (s *Server) setSessionProvider(w http.ResponseWriter, r *http.Request) { if !s.needProviders(w) { return } var b providerReq if !decode(w, r, &b) { return } id := r.PathValue("id") if !s.owns(w, r, id) { return } var a providers.Active if b.Provider != "" { var err error if a, err = s.Providers.Validate(b.Provider, b.Model); err != nil { providerErr(w, err) return } } if err := s.Store.SetSessionProvider(r.Context(), id, a.Provider, a.Model); err != nil { s.storeErr(w, err) return } writeJSON(w, 200, a) } func (s *Server) cancel(w http.ResponseWriter, r *http.Request) { if !s.owns(w, r, r.PathValue("id")) { return } writeJSON(w, 200, map[string]bool{"cancelled": s.Agent.Cancel(r.PathValue("id"))}) } func (s *Server) summarize(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if !s.owns(w, r, id) { return } sm, err := s.Agent.SummarizeNow(r.Context(), id) if err != nil { s.Log.Warn("summarize", "err", err) writeErr(w, http.StatusBadGateway, err.Error()) return } if sm == nil { writeJSON(w, 200, map[string]any{"summary": nil, "note": "nothing to summarize yet"}) return } writeJSON(w, 200, map[string]any{"summary": sm}) } func (s *Server) getSummary(w http.ResponseWriter, r *http.Request) { if !s.owns(w, r, r.PathValue("id")) { return } sm, err := s.Store.LatestSummary(r.Context(), r.PathValue("id")) if err != nil { if errors.Is(err, store.ErrNotFound) { writeErr(w, http.StatusNotFound, "no summary") return } s.storeErr(w, err) return } writeJSON(w, 200, sm) }