Add projects
This commit is contained in:
parent
2d3a9ad623
commit
8b607dd700
1802 changed files with 503346 additions and 2 deletions
114
backend/internal/registry/codex_client_models_updater.go
Normal file
114
backend/internal/registry/codex_client_models_updater.go
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const maxCodexClientModelsSize = 8 << 20
|
||||
|
||||
var codexClientModelsURLs = []string{
|
||||
"https://raw.githubusercontent.com/router-for-me/models/refs/heads/main/codex_client_models.json",
|
||||
"https://models.router-for.me/codex_client_models.json",
|
||||
}
|
||||
|
||||
var codexClientModelsUpdaterOnce sync.Once
|
||||
|
||||
// StartCodexClientModelsUpdater starts a background updater that fetches the
|
||||
// Codex client model catalog immediately and then refreshes it every 3 hours.
|
||||
// Safe to call multiple times; only one updater will run.
|
||||
func StartCodexClientModelsUpdater(ctx context.Context) {
|
||||
codexClientModelsUpdaterOnce.Do(func() {
|
||||
go runCodexClientModelsUpdater(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func runCodexClientModelsUpdater(ctx context.Context) {
|
||||
tryRefreshCodexClientModels(ctx, "startup Codex client model refresh")
|
||||
|
||||
ticker := time.NewTicker(modelsRefreshInterval)
|
||||
defer ticker.Stop()
|
||||
log.Infof("periodic Codex client model refresh started (interval=%s)", modelsRefreshInterval)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
tryRefreshCodexClientModels(ctx, "periodic Codex client model refresh")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func tryRefreshCodexClientModels(ctx context.Context, label string) {
|
||||
data, sourceURL := fetchCodexClientModelsFromRemote(ctx)
|
||||
if data == nil {
|
||||
log.Warnf("%s: fetch failed from all URLs, keeping current data", label)
|
||||
return
|
||||
}
|
||||
|
||||
changed, err := loadCodexClientModelsFromBytes(data, sourceURL)
|
||||
if err != nil {
|
||||
log.Warnf("%s: fetched catalog rejected, keeping current data: %v", label, err)
|
||||
return
|
||||
}
|
||||
if !changed {
|
||||
log.Infof("%s completed from %s, no changes detected", label, sourceURL)
|
||||
return
|
||||
}
|
||||
log.Infof("%s completed from %s, catalog updated", label, sourceURL)
|
||||
}
|
||||
|
||||
func fetchCodexClientModelsFromRemote(ctx context.Context) ([]byte, string) {
|
||||
client := &http.Client{Timeout: modelsFetchTimeout}
|
||||
for _, sourceURL := range codexClientModelsURLs {
|
||||
reqCtx, cancel := context.WithTimeout(ctx, modelsFetchTimeout)
|
||||
req, err := http.NewRequestWithContext(reqCtx, http.MethodGet, sourceURL, nil)
|
||||
if err != nil {
|
||||
cancel()
|
||||
log.Debugf("Codex client models fetch request creation failed for %s: %v", sourceURL, err)
|
||||
continue
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
cancel()
|
||||
log.Debugf("Codex client models fetch failed from %s: %v", sourceURL, err)
|
||||
continue
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if errClose := resp.Body.Close(); errClose != nil {
|
||||
log.Debugf("Codex client models response close failed for %s: %v", sourceURL, errClose)
|
||||
}
|
||||
cancel()
|
||||
log.Debugf("Codex client models fetch returned %d from %s", resp.StatusCode, sourceURL)
|
||||
continue
|
||||
}
|
||||
|
||||
data, errRead := io.ReadAll(io.LimitReader(resp.Body, maxCodexClientModelsSize+1))
|
||||
errClose := resp.Body.Close()
|
||||
cancel()
|
||||
if errRead != nil {
|
||||
log.Debugf("Codex client models fetch read error from %s: %v", sourceURL, errRead)
|
||||
continue
|
||||
}
|
||||
if errClose != nil {
|
||||
log.Debugf("Codex client models response close failed for %s: %v", sourceURL, errClose)
|
||||
continue
|
||||
}
|
||||
if len(data) > maxCodexClientModelsSize {
|
||||
log.Warnf("Codex client models fetch from %s exceeded %d bytes", sourceURL, maxCodexClientModelsSize)
|
||||
continue
|
||||
}
|
||||
if err := ValidateCodexClientModelsJSON(data); err != nil {
|
||||
log.Warnf("Codex client models validate failed from %s: %v", sourceURL, err)
|
||||
continue
|
||||
}
|
||||
return data, sourceURL
|
||||
}
|
||||
return nil, ""
|
||||
}
|
||||
Loading…
Reference in a new issue