mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-20 08:57:57 +00:00
feat: source-model routing disambiguation (source-model/:/ prefix); same-tier round-robin load balancing; public_base_url for copy config; fmtTok(B/M/K) unit scaling; status column reorder (reachability first); drop emoji from seed-warn modal; fix tests for first-run adapter seeding; install lua5.1 dev lib
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@ -17,7 +18,7 @@ import (
|
||||
|
||||
func newTestProvider(t *testing.T, src config.Source) *Provider {
|
||||
t.Helper()
|
||||
vm := lua.NewVM(t.TempDir())
|
||||
vm := lua.NewVM(filepath.Join(t.TempDir(), "adapters"))
|
||||
if err := vm.Start(); err != nil {
|
||||
t.Fatalf("vm: %v", err)
|
||||
}
|
||||
|
||||
@ -125,10 +125,55 @@ func (r *Registry) Resolve(model string) []*Provider {
|
||||
// switch to the owning source but pin the model via request
|
||||
return []*Provider{p}
|
||||
}
|
||||
// "source-model" / "source:model" / "source/model" pinning — disambiguates
|
||||
// duplicate model ids across sources.
|
||||
if p := r.ResolvePinned(model); p != nil {
|
||||
return []*Provider{p}
|
||||
}
|
||||
// unknown model -> fall back to default/AUTO chain
|
||||
return r.AUTOChain()
|
||||
}
|
||||
|
||||
// EffectiveModel strips a "source-model" / "source:model" / "source/model"
|
||||
// pinning prefix and returns the bare model id when that source serves it;
|
||||
// otherwise it returns the input unchanged.
|
||||
func (r *Registry) EffectiveModel(model string) string {
|
||||
sep := strings.IndexAny(model, "-:/")
|
||||
if sep < 1 || sep == len(model)-1 {
|
||||
return model
|
||||
}
|
||||
src, m := model[:sep], model[sep+1:]
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
for _, p := range r.providers {
|
||||
if strings.EqualFold(p.Name(), src) && p.ModelByID(m) != nil {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return model
|
||||
}
|
||||
|
||||
// ResolvePinned resolves "source-model" / "source:model" / "source/model" to
|
||||
// the exact source, or nil if the source does not serve that model.
|
||||
func (r *Registry) ResolvePinned(model string) *Provider {
|
||||
sep := strings.IndexAny(model, "-:/")
|
||||
if sep < 1 || sep == len(model)-1 {
|
||||
return nil
|
||||
}
|
||||
src, m := model[:sep], model[sep+1:]
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
for _, p := range r.providers {
|
||||
if !strings.EqualFold(p.Name(), src) {
|
||||
continue
|
||||
}
|
||||
if p.ModelByID(m) != nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AUTOChain returns the priority-sorted providers for AUTO.
|
||||
func (r *Registry) AUTOChain() []*Provider {
|
||||
return r.Resolve("AUTO")
|
||||
|
||||
Reference in New Issue
Block a user