Add token usage stats and consolidate credentials in SQLite
build / build (push) Successful in 2m34s

- New internal/stats (types) and internal/store (SQLite owner: requests + credentials tables, WAL); store implements stats.Recorder.
- Stream (SSE tee) and non-stream chat paths parse upstream usage incl. cached_tokens and record per-request; add /api/stats, /api/stats/reset, /admin/stats HTML with cache hit rate.
- Drop credentials.json: remove auth file I/O and ZHANLU_CREDENTIALS_FILE; credential precedence is env vars > db row.
This commit is contained in:
2026-08-19 15:52:00 +08:00
parent dd5c560b64
commit fa9640d919
15 changed files with 1101 additions and 103 deletions
-30
View File
@@ -1,10 +1,7 @@
package auth
import (
"encoding/json"
"errors"
"os"
"path/filepath"
"strings"
"time"
)
@@ -49,30 +46,3 @@ func (c Credentials) Validate() error {
func (c Credentials) HasAPIKey() bool {
return strings.TrimSpace(c.APIKey) != "" && strings.TrimSpace(c.ModelBaseURL) != ""
}
func LoadCredentials(path string) (Credentials, error) {
b, err := os.ReadFile(path)
if err != nil {
return Credentials{}, err
}
var c Credentials
if err := json.Unmarshal(b, &c); err != nil {
return Credentials{}, err
}
return c, c.Validate()
}
func SaveCredentials(path string, c Credentials) error {
if err := c.Validate(); err != nil {
return err
}
c.SavedAt = time.Now()
b, err := json.MarshalIndent(c, "", " ")
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return err
}
return os.WriteFile(path, b, 0o600)
}