mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-21 00:24:12 +08:00
127 lines
3.5 KiB
Go
127 lines
3.5 KiB
Go
package service
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"math"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
|
)
|
|
|
|
const hermesSessionListLimit = 100
|
|
|
|
func (a AgentService) GetHermesChatSessions(req dto.AgentIDReq) ([]dto.AgentHermesChatSessionItem, error) {
|
|
agent, install, err := a.loadAgentAndInstall(req.AgentID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if agent.AgentType != constant.AppHermesAgent {
|
|
return nil, fmt.Errorf("%s does not support", agent.AgentType)
|
|
}
|
|
return listHermesChatSessionsFromStateDB(filepath.Join(install.GetPath(), "data", "state.db"))
|
|
}
|
|
|
|
func (a AgentService) RenameHermesChatSession(req dto.AgentHermesChatSessionRenameReq) error {
|
|
agent, install, err := a.loadAgentAndInstall(req.AgentID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if agent.AgentType != constant.AppHermesAgent {
|
|
return fmt.Errorf("%s does not support", agent.AgentType)
|
|
}
|
|
|
|
_, err = cmd.NewCommandMgr(cmd.WithTimeout(20*time.Second)).RunWithStdout(
|
|
"docker",
|
|
buildHermesDockerExecArgs(install.ContainerName, "sessions", "rename", req.ID, req.Title)...,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (a AgentService) DeleteHermesChatSession(req dto.AgentHermesChatSessionDeleteReq) error {
|
|
agent, install, err := a.loadAgentAndInstall(req.AgentID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if agent.AgentType != constant.AppHermesAgent {
|
|
return fmt.Errorf("%s does not support", agent.AgentType)
|
|
}
|
|
|
|
_, err = cmd.NewCommandMgr(cmd.WithTimeout(20*time.Second)).RunWithStdout(
|
|
"docker",
|
|
buildHermesDockerExecArgs(install.ContainerName, "sessions", "delete", req.ID, "--yes")...,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func listHermesChatSessionsFromStateDB(stateDBPath string) ([]dto.AgentHermesChatSessionItem, error) {
|
|
if !files.NewFileOp().Stat(stateDBPath) {
|
|
return []dto.AgentHermesChatSessionItem{}, nil
|
|
}
|
|
|
|
db, err := sql.Open("sqlite", stateDBPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer db.Close()
|
|
|
|
rows, err := db.Query(`
|
|
SELECT
|
|
s.id,
|
|
COALESCE(NULLIF(TRIM(s.title), ''), s.id) AS title,
|
|
COALESCE(s.model, '') AS model,
|
|
COALESCE(s.message_count, 0) AS message_count,
|
|
s.started_at,
|
|
COALESCE(MAX(m.timestamp), s.started_at) AS last_active
|
|
FROM sessions s
|
|
LEFT JOIN messages m ON m.session_id = s.id
|
|
WHERE s.source = 'cli'
|
|
GROUP BY s.id, title, model, s.message_count, s.started_at
|
|
ORDER BY last_active DESC
|
|
LIMIT ?
|
|
`, hermesSessionListLimit)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
items := make([]dto.AgentHermesChatSessionItem, 0, 8)
|
|
for rows.Next() {
|
|
var item dto.AgentHermesChatSessionItem
|
|
var title sql.NullString
|
|
var model sql.NullString
|
|
var startedAt sql.NullFloat64
|
|
var lastActive sql.NullFloat64
|
|
if err := rows.Scan(&item.ID, &title, &model, &item.MessageCount, &startedAt, &lastActive); err != nil {
|
|
return nil, err
|
|
}
|
|
item.Title = strings.TrimSpace(title.String)
|
|
if item.Title == "" {
|
|
item.Title = item.ID
|
|
}
|
|
item.Model = strings.TrimSpace(model.String)
|
|
item.StartedAt = formatHermesSessionTimestamp(startedAt)
|
|
item.LastActive = formatHermesSessionTimestamp(lastActive)
|
|
items = append(items, item)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
func formatHermesSessionTimestamp(value sql.NullFloat64) string {
|
|
if !value.Valid || value.Float64 <= 0 {
|
|
return ""
|
|
}
|
|
|
|
seconds, fraction := math.Modf(value.Float64)
|
|
return time.Unix(int64(seconds), int64(fraction*float64(time.Second))).UTC().Format(time.RFC3339)
|
|
}
|