Skip to content

Commit

Permalink
robot: learn message api
Browse files Browse the repository at this point in the history
Fixes #90.
  • Loading branch information
zephyrtronium committed Dec 13, 2024
1 parent d374d93 commit 4c9186b
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"

"github.com/zephyrtronium/robot/brain"
"github.com/zephyrtronium/robot/userhash"
)

func (robo *Robot) api(ctx context.Context, listen string, mux *http.ServeMux, metrics []prometheus.Collector) error {
Expand All @@ -44,6 +45,7 @@ func (robo *Robot) api(ctx context.Context, listen string, mux *http.ServeMux, m
mux.HandleFunc("GET /debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("GET /debug/pprof/trace", pprof.Trace)
mux.HandleFunc("GET /api/message/{tag...}", robo.apiRecall)
mux.HandleFunc("POST /api/message/{tag...}", robo.apiLearn)
mux.HandleFunc("DELETE /api/message/{tag...}", robo.apiForget)
l, err := net.Listen("tcp", listen)
if err != nil {
Expand Down Expand Up @@ -149,6 +151,58 @@ func (robo *Robot) apiRecall(w http.ResponseWriter, r *http.Request) {
}
}

func (robo *Robot) apiLearn(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := slog.With(slog.String("api", "recall"), slog.Any("trace", uuid.New()))
log.InfoContext(ctx, "handle", slog.String("route", r.Pattern), slog.String("remote", r.RemoteAddr))
defer log.InfoContext(ctx, "done")
tag := r.PathValue("tag")
d := jsontext.NewDecoder(r.Body)
var all error
var msg apiMessage
for {
err := json.UnmarshalDecode(d, &msg)
switch err {
case nil: // do nothing
case io.EOF:
// Done; transmit any learn errors.
if all != nil {
jsonerror(w, http.StatusInternalServerError, all.Error())
return
}
w.WriteHeader(http.StatusNoContent)
return
default:
log.ErrorContext(ctx, "read message", slog.Any("err", err))
jsonerror(w, http.StatusBadRequest, "message read failed")
return
}
m := brain.Message{
ID: msg.ID,
Sender: userhash.Hash{'A', 'P', 'I'},
Text: msg.Text,
}
if m.ID == "" {
m.ID = "API:" + uuid.NewString()
}
if msg.Time == "" {
m.Timestamp = time.Now().UnixMilli()
} else {
t, err := time.Parse(time.RFC3339, msg.Time)
if err != nil {
all = errors.Join(all, err)
continue
}
m.Timestamp = t.UnixMilli()
}
if err := brain.Learn(ctx, robo.brain, tag, &m); err != nil {
log.ErrorContext(ctx, "learn failed", slog.String("tag", tag), slog.String("id", m.ID), slog.Any("err", err))
all = errors.Join(all, err)
// continue on
}
}
}

func (robo *Robot) apiForget(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := slog.With(slog.String("api", "recall"), slog.Any("trace", uuid.New()))
Expand Down

0 comments on commit 4c9186b

Please sign in to comment.