fix(grok): 运行时映射设置即时失效账号缓存

This commit is contained in:
IanShaw027
2026-08-07 13:59:32 +08:00
parent ec9e733606
commit cda6de44da
3 changed files with 37 additions and 1 deletions
+9
View File
@@ -8,15 +8,24 @@ import (
// runtimeMappingOpts holds operator-configured defaults applied when Grok
// accounts leave credentials.model_mapping empty. Updated from settings.
var runtimeMappingOpts atomic.Value // ModelMappingOptions
var runtimeMappingVersion atomic.Uint64
func init() {
runtimeMappingOpts.Store(ModelMappingOptions{})
runtimeMappingVersion.Store(1)
}
// SetRuntimeModelMappingOptions updates process-wide defaults used by
// DefaultModelMapping (e.g. after settings load). Safe for concurrent use.
func SetRuntimeModelMappingOptions(opts ModelMappingOptions) {
runtimeMappingOpts.Store(opts)
runtimeMappingVersion.Add(1)
}
// RuntimeModelMappingVersion changes whenever runtime mapping options change.
// Account-level caches include it so settings updates take effect without a restart.
func RuntimeModelMappingVersion() uint64 {
return runtimeMappingVersion.Load()
}
// RuntimeModelMappingOptions returns the last options set via SetRuntimeModelMappingOptions.
+5 -1
View File
@@ -71,6 +71,7 @@ type Account struct {
modelMappingCacheRawPtr uintptr
modelMappingCacheRawLen int
modelMappingCacheRawSig uint64
modelMappingCacheRuntimeVersion uint64
// header_overrides 热路径缓存(非持久化字段,同 model_mapping 缓存先例)
headerOverrideCache map[string]string
@@ -553,6 +554,7 @@ func stringMappingFromRaw(raw any) map[string]string {
}
func (a *Account) GetModelMapping() map[string]string {
runtimeVersion := xai.RuntimeModelMappingVersion()
credentialsPtr := mapPtr(a.Credentials)
rawMapping, _ := a.Credentials["model_mapping"].(map[string]any)
rawPtr := mapPtr(rawMapping)
@@ -563,7 +565,8 @@ func (a *Account) GetModelMapping() map[string]string {
if a.modelMappingCacheReady &&
a.modelMappingCacheCredentialsPtr == credentialsPtr &&
a.modelMappingCacheRawPtr == rawPtr &&
a.modelMappingCacheRawLen == rawLen {
a.modelMappingCacheRawLen == rawLen &&
a.modelMappingCacheRuntimeVersion == runtimeVersion {
rawSig = modelMappingSignature(rawMapping)
rawSigReady = true
if a.modelMappingCacheRawSig == rawSig {
@@ -582,6 +585,7 @@ func (a *Account) GetModelMapping() map[string]string {
a.modelMappingCacheRawPtr = rawPtr
a.modelMappingCacheRawLen = rawLen
a.modelMappingCacheRawSig = rawSig
a.modelMappingCacheRuntimeVersion = runtimeVersion
return mapping
}
@@ -6,8 +6,31 @@ import (
"testing"
"github.com/Wei-Shaw/sub2api/internal/domain"
"github.com/Wei-Shaw/sub2api/internal/pkg/xai"
)
func TestGrokAccountModelMappingCacheInvalidatesWithRuntimeSettings(t *testing.T) {
original := xai.RuntimeModelMappingOptions()
t.Cleanup(func() { xai.SetRuntimeModelMappingOptions(original) })
account := &Account{Platform: PlatformGrok, Credentials: map[string]any{}}
xai.SetRuntimeModelMappingOptions(xai.ModelMappingOptions{})
requireMappedModel(t, account, "claude-sonnet-4-5", "claude-sonnet-4-5")
xai.SetRuntimeModelMappingOptions(xai.ModelMappingOptions{
DefaultText: "grok-build-0.1",
EnableCrossClientMap: true,
})
requireMappedModel(t, account, "claude-sonnet-4-5", "grok-build-0.1")
}
func requireMappedModel(t *testing.T, account *Account, requested, expected string) {
t.Helper()
if actual := account.GetMappedModel(requested); actual != expected {
t.Fatalf("GetMappedModel(%q) = %q, want %q", requested, actual, expected)
}
}
func TestMatchWildcard(t *testing.T) {
tests := []struct {
name string