feat(auto): AUTO-only priority chain with tiered slots + live source probing; CSV export w/ key names; audit persistence; fix prompt token accounting & deepseek thinking

This commit is contained in:
root
2026-08-10 00:10:19 +08:00
parent 859d310ad3
commit d48b993010
10 changed files with 663 additions and 210 deletions

View File

@ -14,6 +14,8 @@ import (
"net/http"
"net/url"
"strings"
"sync"
"time"
"llmsproxy/internal/config"
"llmsproxy/internal/core"
@ -24,9 +26,11 @@ var uiFS embed.FS
// Gateway is the HTTP handler for the OpenAI-compatible endpoint + web UI.
type Gateway struct {
core *core.Core
ui http.Handler
stats *Stats
core *core.Core
ui http.Handler
stats *Stats
probeMu sync.Mutex
lastProbe time.Time
}
func New(c *core.Core, gatewayKeys []string) (*Gateway, error) {
@ -34,10 +38,14 @@ func New(c *core.Core, gatewayKeys []string) (*Gateway, error) {
if err != nil {
return nil, err
}
st := NewStats(3000)
if cfg := c.Config(); cfg != nil && cfg.RuntimeFile != "" {
st.LoadAudit(cfg.RuntimeFile + ".audit.jsonl")
}
return &Gateway{
core: c,
ui: http.FileServer(http.FS(sub)),
stats: NewStats(3000),
stats: st,
}, nil
}
@ -313,7 +321,21 @@ func (g *Gateway) handleModels(w http.ResponseWriter, r *http.Request) {
})
}
// ensureProbe triggers a live source probe at most once every 30s.
func (g *Gateway) ensureProbe(ctx context.Context) {
g.probeMu.Lock()
due := time.Since(g.lastProbe) > 30*time.Second
if due {
g.lastProbe = time.Now()
}
g.probeMu.Unlock()
if due {
g.core.Registry().ProbeAll(ctx)
}
}
func (g *Gateway) handleStatusAPI(w http.ResponseWriter, r *http.Request) {
g.ensureProbe(r.Context())
host := r.Host
if host == "" {
host = g.core.Listen()