140 lines
3.4 KiB
Go
140 lines
3.4 KiB
Go
package jlog
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"slices"
|
|
"time"
|
|
|
|
"github.com/d1nch8g/jules/chat"
|
|
"github.com/d1nch8g/jules/database"
|
|
"github.com/d1nch8g/jules/engine/prompt"
|
|
)
|
|
|
|
type Event struct {
|
|
ctx context.Context
|
|
attrs []slog.Attr
|
|
start time.Time
|
|
}
|
|
|
|
func FromMessage(ctx context.Context, msg chat.Message) *Event {
|
|
e := &Event{start: time.Now(), ctx: ctx}
|
|
e.attrs = append(e.attrs,
|
|
slog.String("type", "message_processing"),
|
|
slog.String("platform", msg.Chat),
|
|
slog.String("platform_user_id", msg.ID),
|
|
slog.String("message", msg.Text),
|
|
)
|
|
return e
|
|
}
|
|
|
|
func FromNotification(ctx context.Context, notif database.Notification) *Event {
|
|
e := &Event{start: time.Now(), ctx: ctx}
|
|
e.attrs = append(e.attrs,
|
|
slog.String("type", "notification_processing"),
|
|
slog.String("notification_id", notif.ID.String()),
|
|
slog.String("user_id", notif.UserID.String()),
|
|
slog.String("initiator_id", notif.InitiatorID.String()),
|
|
slog.String("content", notif.Content),
|
|
)
|
|
return e
|
|
}
|
|
|
|
func (e *Event) User(u *database.User) *Event {
|
|
e.attrs = append(e.attrs,
|
|
slog.String("user_id", u.ID.String()),
|
|
slog.String("user_lang", u.Language),
|
|
slog.String("user_tz", u.Timezone),
|
|
slog.String("user_chat", u.PreferredChat),
|
|
slog.String("user_role", u.Role),
|
|
)
|
|
return e
|
|
}
|
|
|
|
func (e *Event) Context(ctx *prompt.Context) *Event {
|
|
if ctx == nil {
|
|
return e
|
|
}
|
|
|
|
e.attrs = append(e.attrs,
|
|
slog.String("user_lang", ctx.UserLanguage),
|
|
slog.String("user_tz", ctx.UserTimezone),
|
|
slog.String("user_chat", ctx.UserPreferredChat),
|
|
slog.String("user_bind_code", ctx.UserBindCode.String()),
|
|
slog.String("user_contact_code", ctx.UserContactCode.String()),
|
|
)
|
|
|
|
for _, chat := range ctx.Chats {
|
|
e.attrs = append(e.attrs, slog.String("chat", chat.Platform))
|
|
}
|
|
|
|
for _, fact := range ctx.Facts {
|
|
e.attrs = append(e.attrs, slog.String("fact", fact.Value))
|
|
}
|
|
|
|
for _, contact := range ctx.Contacts {
|
|
e.attrs = append(e.attrs, slog.String("contact", contact.Name))
|
|
}
|
|
|
|
for _, n := range ctx.IncomingNotifications {
|
|
e.attrs = append(e.attrs, slog.String("incoming_notif", n.Content))
|
|
}
|
|
|
|
for _, n := range ctx.OutgoingNotificaions {
|
|
e.attrs = append(e.attrs, slog.String("outgoing_notif", n.Content))
|
|
}
|
|
|
|
for _, a := range ctx.RecentActions {
|
|
e.attrs = append(e.attrs, slog.String("action", string(a.Payload)))
|
|
}
|
|
|
|
return e
|
|
}
|
|
|
|
func (e *Event) LLMResponse(content string) *Event {
|
|
for i, attr := range e.attrs {
|
|
if attr.Key == "llm_response" {
|
|
e.attrs[i] = slog.String("llm_response", content)
|
|
return e
|
|
}
|
|
}
|
|
e.attrs = append(e.attrs, slog.String("llm_response", content))
|
|
return e
|
|
}
|
|
|
|
func (e *Event) Actions(actions []any) *Event {
|
|
e.attrs = slices.DeleteFunc(e.attrs, func(a slog.Attr) bool {
|
|
return a.Key == "action"
|
|
})
|
|
for _, action := range actions {
|
|
e.attrs = append(e.attrs, slog.Any("action", action))
|
|
}
|
|
return e
|
|
}
|
|
|
|
func (e *Event) Info(msg string) {
|
|
e.log(slog.LevelInfo, msg)
|
|
}
|
|
|
|
func (e *Event) Warn(msg string, errs ...error) {
|
|
if len(errs) > 0 {
|
|
for _, err := range errs {
|
|
e.attrs = append(e.attrs, slog.Any("error", err))
|
|
}
|
|
}
|
|
e.log(slog.LevelWarn, msg)
|
|
}
|
|
|
|
func (e *Event) Error(msg string, err error) {
|
|
e.attrs = append(e.attrs, slog.String("error", err.Error()))
|
|
e.log(slog.LevelError, msg)
|
|
}
|
|
|
|
func (e *Event) log(level slog.Level, msg string) {
|
|
if e.ctx == nil {
|
|
e.ctx = context.Background()
|
|
}
|
|
attrs := append(e.attrs, slog.String("duration", time.Since(e.start).String()))
|
|
slog.LogAttrs(e.ctx, level, msg, attrs...)
|
|
}
|