2026-10-15 09:40:30 -07:00
|
|
|
package server
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
2026-10-16 18:11:00 -07:00
|
|
|
"math"
|
2026-10-15 09:40:30 -07:00
|
|
|
"net/http"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"g.fc.run/misc/byre/internal/api"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (s *Server) ListLeadSessions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
sessions, err := s.agents.LeadSessions(r.Context(), actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusOK, sessions)
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-16 18:11:00 -07:00
|
|
|
func (s *Server) ListLeadEvents(w http.ResponseWriter, r *http.Request, params api.ListLeadEventsParams) {
|
|
|
|
|
before := int64(math.MaxInt64)
|
|
|
|
|
if params.Before != nil {
|
|
|
|
|
before = *params.Before
|
|
|
|
|
}
|
|
|
|
|
turns := 50
|
|
|
|
|
if params.Turns != nil {
|
|
|
|
|
turns = *params.Turns
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
page, err := s.store.LeadEventsPage(r.Context(), actor(r), before, turns)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusOK, page)
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-15 09:40:30 -07:00
|
|
|
func (s *Server) MessageLead(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
req := api.MessageCreate{}
|
|
|
|
|
if !readJSON(w, r, &req) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
images, ok := s.images(w, r, req.Images)
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.TrimSpace(req.Text) == "" && len(images) == 0 {
|
|
|
|
|
writeError(w, http.StatusBadRequest, errors.New("text or images are required"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u, err := s.store.GetUser(r.Context(), actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model := ""
|
|
|
|
|
if req.Model != nil {
|
|
|
|
|
model = *req.Model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sess, err := s.agents.MessageLead(r.Context(), u, req.Text, model, images)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeAgentError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusAccepted, sess)
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-16 10:50:29 -07:00
|
|
|
func (s *Server) ListLeadNotes(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
notes, err := s.store.LeadNotes(r.Context(), actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusOK, notes)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) DeleteLeadNote(w http.ResponseWriter, r *http.Request, noteId string) {
|
|
|
|
|
err := s.agents.DeleteLeadNote(r.Context(), actor(r), noteId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeAgentError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-15 09:40:30 -07:00
|
|
|
func (s *Server) GetFocus(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
f, err := s.store.GetFocus(r.Context(), actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusOK, f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) SetFocus(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
f := api.Focus{}
|
|
|
|
|
if !readJSON(w, r, &f) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := s.agents.SetFocus(r.Context(), actor(r), f, actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeAgentError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f, err = s.store.GetFocus(r.Context(), actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusOK, f)
|
|
|
|
|
}
|
2026-10-15 09:59:13 -07:00
|
|
|
|
2026-10-16 11:08:57 -07:00
|
|
|
func (s *Server) GetSummaryReads(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
reads, err := s.store.SummaryReads(r.Context(), actor(r))
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
writeJSON(w, http.StatusOK, reads)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) MarkSummaryRead(w http.ResponseWriter, r *http.Request, taskId string) {
|
|
|
|
|
body := api.SummaryRead{}
|
|
|
|
|
if !readJSON(w, r, &body) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if body.Seq <= 0 {
|
|
|
|
|
writeError(w, http.StatusBadRequest, errors.New("seq must be positive"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err := s.store.MarkSummaryRead(r.Context(), actor(r), taskId, body.Seq)
|
|
|
|
|
if err != nil {
|
|
|
|
|
writeStoreError(w, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-15 09:59:13 -07:00
|
|
|
func (s *Server) SetPaneFocus(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
p := api.PaneFocus{}
|
|
|
|
|
if !readJSON(w, r, &p) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2026-10-16 09:51:32 -07:00
|
|
|
s.agents.SetPaneFocus(actor(r), p)
|
2026-10-15 09:59:13 -07:00
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
|
}
|