feat: update chat, settings, prompts and system info modules

This commit is contained in:
2026-06-16 10:33:54 +08:00
parent b86c29c6a4
commit dd13d21c6a
18 changed files with 1362 additions and 43 deletions

View File

@@ -1,9 +1,15 @@
package handlers
import (
"fmt"
"log"
"net/http"
"os"
"os/exec"
"runtime"
"strings"
"sync"
"time"
"github.com/gin-gonic/gin"
"sproutclaw-web/internal/config"
@@ -24,7 +30,33 @@ func RegisterSettings(r *gin.RouterGroup, cfg *config.Config, database *db.DB, p
r.POST("/settings/models-config", handleSetModelsConfig(cfg, piClient))
r.POST("/settings/system-prompt", handleSetSystemPrompt(cfg, piClient))
r.POST("/settings/avatars", handleSetAvatars(database))
r.POST("/settings/restart", handleRestart())
r.GET("/environment", handleEnvironment(cfg))
r.GET("/environment/tools", handleEnvironmentTools())
}
var processStartTime = time.Now()
func handleRestart() gin.HandlerFunc {
return func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"ok": true})
go func() {
time.Sleep(300 * time.Millisecond)
exe, err := os.Executable()
if err != nil {
log.Printf("[restart] get executable: %v", err)
os.Exit(1)
}
cmd := exec.Command(exe, os.Args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
log.Printf("[restart] start new process: %v", err)
os.Exit(1)
}
os.Exit(0)
}()
}
}
func handleGetSettings(cfg *config.Config, database *db.DB) gin.HandlerFunc {
@@ -200,15 +232,70 @@ func handleEnvironment(cfg *config.Config) gin.HandlerFunc {
return func(c *gin.Context) {
hostname, _ := os.Hostname()
cwd, _ := os.Getwd()
exe, _ := os.Executable()
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
goHeapMb := int64(memStats.HeapAlloc / 1024 / 1024)
totalMemMb, freeMemMb := getSysMemMb()
osRelease := getOSRelease()
uptimeSec := int64(time.Since(processStartTime).Seconds())
piCmd := cfg.PiCmd
if len(cfg.PiArgs) > 0 {
piCmd = strings.Join(append([]string{cfg.PiCmd}, cfg.PiArgs...), " ")
}
c.JSON(http.StatusOK, gin.H{
"nodeVersion": runtime.Version(),
"goVersion": runtime.Version(),
"platform": runtime.GOOS,
"arch": runtime.GOARCH,
"osRelease": osRelease,
"hostname": hostname,
"numCPU": runtime.NumCPU(),
"totalMemMb": totalMemMb,
"freeMemMb": freeMemMb,
"pid": os.Getpid(),
"uptime": uptimeSec,
"execPath": exe,
"goroutines": runtime.NumGoroutine(),
"goHeapMb": goHeapMb,
"cwd": cwd,
"port": cfg.Port,
"agentDir": cfg.AgentDir,
"dataDir": cfg.DataDir,
"repoRoot": cfg.RepoRoot,
"piCmd": piCmd,
"memUsagePct": func() string {
if totalMemMb == 0 {
return ""
}
used := totalMemMb - freeMemMb
pct := float64(used) * 100 / float64(totalMemMb)
return fmt.Sprintf("%.1f%%", pct)
}(),
})
}
}
// handleEnvironmentTools detects all agent tools and language runtimes in parallel.
// This is a separate endpoint because version detection involves subprocess calls.
func handleEnvironmentTools() gin.HandlerFunc {
return func(c *gin.Context) {
var (
agentTools []AgentToolInfo
runtimes []RuntimeInfo
wg sync.WaitGroup
)
wg.Add(2)
go func() { defer wg.Done(); agentTools = detectAgentTools() }()
go func() { defer wg.Done(); runtimes = detectRuntimes() }()
wg.Wait()
c.JSON(http.StatusOK, gin.H{
"agentTools": agentTools,
"runtimes": runtimes,
})
}
}