mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
33b57ee345
Rename session info endpoint from /sessions/:id/info to /sessions/:id/status and update frontend tab label accordingly. Add /status slash command that displays current session metrics (message count, context usage, cache hit rate, used skills) as formatted text in any channel.
100 lines
2.7 KiB
Go
100 lines
2.7 KiB
Go
package command
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
func (h *Handler) buildStatusGroup() *CommandGroup {
|
|
g := newCommandGroup("status", "View current session status")
|
|
g.DefaultAction = "show"
|
|
g.Register(SubCommand{
|
|
Name: "show",
|
|
Usage: "show - Show current session status",
|
|
Handler: func(cc CommandContext) (string, error) {
|
|
botUUID, err := parseBotUUID(cc.BotID)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
sessionID, err := h.queries.GetLatestSessionIDByBot(cc.Ctx, botUUID)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return "No active session found.", nil
|
|
}
|
|
return "", err
|
|
}
|
|
|
|
msgCount, err := h.queries.CountMessagesBySession(cc.Ctx, sessionID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("count messages: %w", err)
|
|
}
|
|
|
|
var usedTokens int64
|
|
latestUsage, err := h.queries.GetLatestAssistantUsage(cc.Ctx, sessionID)
|
|
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
|
|
return "", fmt.Errorf("get usage: %w", err)
|
|
}
|
|
if err == nil {
|
|
usedTokens = latestUsage
|
|
}
|
|
|
|
cacheRow, err := h.queries.GetSessionCacheStats(cc.Ctx, sessionID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("get cache: %w", err)
|
|
}
|
|
|
|
var contextWindowStr string
|
|
if h.settingsService != nil {
|
|
s, sErr := h.settingsService.GetBot(cc.Ctx, cc.BotID)
|
|
if sErr == nil && s.ChatModelID != "" && h.modelsService != nil {
|
|
m, mErr := h.modelsService.GetByID(cc.Ctx, s.ChatModelID)
|
|
if mErr == nil && m.Config.ContextWindow != nil {
|
|
contextWindowStr = formatTokens(int64(*m.Config.ContextWindow))
|
|
}
|
|
}
|
|
}
|
|
|
|
var cacheHitRate float64
|
|
if cacheRow.TotalInputTokens > 0 {
|
|
cacheHitRate = float64(cacheRow.CacheReadTokens) / float64(cacheRow.TotalInputTokens) * 100
|
|
}
|
|
|
|
skills, _ := h.queries.GetSessionUsedSkills(cc.Ctx, sessionID)
|
|
|
|
var b strings.Builder
|
|
b.WriteString("Session Status:\n\n")
|
|
fmt.Fprintf(&b, "- Messages: %d\n", msgCount)
|
|
if contextWindowStr != "" {
|
|
fmt.Fprintf(&b, "- Context: %s / %s\n", formatTokens(usedTokens), contextWindowStr)
|
|
} else {
|
|
fmt.Fprintf(&b, "- Context: %s\n", formatTokens(usedTokens))
|
|
}
|
|
fmt.Fprintf(&b, "- Cache Hit Rate: %.1f%%\n", cacheHitRate)
|
|
fmt.Fprintf(&b, "- Cache Read: %s\n", formatTokens(cacheRow.CacheReadTokens))
|
|
fmt.Fprintf(&b, "- Cache Write: %s\n", formatTokens(cacheRow.CacheWriteTokens))
|
|
|
|
if len(skills) > 0 {
|
|
fmt.Fprintf(&b, "- Skills: %s\n", strings.Join(skills, ", "))
|
|
}
|
|
|
|
return strings.TrimRight(b.String(), "\n"), nil
|
|
},
|
|
})
|
|
return g
|
|
}
|
|
|
|
func formatTokens(n int64) string {
|
|
if n >= 1_000_000 {
|
|
return fmt.Sprintf("%.1fM", float64(n)/1_000_000)
|
|
}
|
|
if n >= 1_000 {
|
|
return fmt.Sprintf("%.1fK", float64(n)/1_000)
|
|
}
|
|
return strconv.FormatInt(n, 10)
|
|
}
|