feat: publish sanitized custom.97 source

This commit is contained in:
cneicy committed 2026-10-27 20:43:39 +08:00
1 parent 8e6ed0317b
commit 86c0276156
1022 files changed
+69903 -19207

No files matched your search

+109 -2
View File
@@ -3,6 +3,7 @@ package service
import (
"fmt"
"os"
"strings"
"testing"
"time"
@@ -56,6 +57,8 @@ func TestGroupDegradationDatabaseMatrix(t *testing.T) {
common.SetDatabaseTypes(oldType, oldLogType)
groupDegradationSnapshot.updated = time.Time{}
groupDegradationSnapshot.latest = nil
groupDegradationSnapshot.vision = nil
groupDegradationSnapshot.ciallo = nil
conn, err := db.DB()
require.NoError(t, err)
require.NoError(t, conn.Close())
@@ -110,15 +113,76 @@ func TestGroupDegradationDatabaseMatrix(t *testing.T) {
require.NoError(t, db.Model(&pelican).Update("quality", "normal").Error)
groupDegradationSnapshot.updated = time.Time{}
assert.False(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"))
vision := model.DetectionRun{ID: "vision-degraded", RequestKey: "vision-degraded", ChannelID: 1, Kind: "vision", CreatedAt: now - 5, Settled: true, Status: "succeeded", Quality: "degraded", Result: `{"closest":"石头"}`}
require.NoError(t, db.Create(&vision).Error)
InvalidateGroupQualityCache()
assert.True(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"), "fingerprint recovery must not clear a failed vision test")
recent, err := RecentDegradedGroups(ctx().Request.Context())
require.NoError(t, err)
assert.True(t, recent["default"])
failedVision := model.DetectionRun{ID: "vision-error", RequestKey: "vision-error", ChannelID: 1, Kind: "vision", CreatedAt: now - 1, Settled: true, Status: "failed", Quality: "normal"}
require.NoError(t, db.Create(&failedVision).Error)
InvalidateGroupQualityCache()
assert.True(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"), "transport errors cannot clear the latest valid vision result")
require.NoError(t, db.Model(&failedVision).Update("quality", "degraded").Error)
require.NoError(t, db.Model(&vision).Updates(map[string]any{"quality": "normal", "result": `{"closest":"这是音箱"}`}).Error)
InvalidateGroupQualityCache()
assert.False(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"))
recent, err = RecentDegradedGroups(ctx().Request.Context())
require.NoError(t, err)
assert.False(t, recent["default"])
require.NoError(t, db.Model(&vision).Updates(map[string]any{"quality": "degraded", "created_at": now - 8*3600, "result": `{"closest":"石头"}`}).Error)
InvalidateGroupQualityCache()
assert.True(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"), "routing keeps the latest valid result")
recent, err = RecentDegradedGroups(ctx().Request.Context())
require.NoError(t, err)
assert.False(t, recent["default"], "recent tag expires after the existing six-hour window")
legacyAnswer := `{"closest":"我这边没收到可查看的图片或文件,暂时无法判断是什么。请重新上传图片"}`
require.NoError(t, db.Model(&vision).Updates(map[string]any{"result": legacyAnswer, "status": "failed", "error": "vision_keyword_missing"}).Error)
InvalidateGroupQualityCache()
unavailable, err := VisionUnavailableGroups(ctx().Request.Context())
require.NoError(t, err)
assert.True(t, unavailable["default"], "legacy answers remain effective beyond the recent window and later transport failures")
assert.False(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"))
recent, err = RecentDegradedGroups(ctx().Request.Context())
require.NoError(t, err)
assert.False(t, recent["default"])
require.NoError(t, db.Model(&vision).Update("created_at", now-2).Error)
summaries, err := GroupDetectionSummaries(ctx().Request.Context(), time.Unix(now, 0), nil, nil)
require.NoError(t, err)
summary := summaries["default"].Vision
require.NotNil(t, summary)
assert.Equal(t, 1, summary.Incomplete)
assert.Equal(t, "incomplete", summary.LatestValid.Quality)
var unchanged model.DetectionRun
require.NoError(t, db.First(&unchanged, "id = ?", vision.ID).Error)
assert.Equal(t, "degraded", unchanged.Quality, "reading history must not rewrite stored results")
ciallo := model.DetectionRun{ID: "ciallo-degraded", RequestKey: "ciallo-degraded", ChannelID: 1, Kind: "ciallo", CreatedAt: now, Settled: true, Status: "succeeded", Quality: "degraded"}
require.NoError(t, db.Create(&ciallo).Error)
InvalidateGroupQualityCache()
assert.True(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"), "incomplete vision must not clear Ciallo degradation")
require.NoError(t, db.Model(&vision).Updates(map[string]any{"status": "succeeded", "result": `{"closest":"这是音箱"}`, "created_at": now}).Error)
InvalidateGroupQualityCache()
unavailable, err = VisionUnavailableGroups(ctx().Request.Context())
require.NoError(t, err)
assert.False(t, unavailable["default"])
assert.True(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"), "vision recovery must not clear Ciallo degradation")
require.NoError(t, db.Model(&ciallo).Update("quality", "normal").Error)
InvalidateGroupQualityCache()
assert.False(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"))
require.NoError(t, db.Delete(&manual).Error)
require.NoError(t, model.SaveStatusPageGroup(ctx().Request.Context(), "default", nil))
groupDegradationSnapshot.updated = time.Time{}
assert.False(t, requestGroupDegraded(ctx(), fingerprint.Model, "default"))
unavailable, err = VisionUnavailableGroups(ctx().Request.Context())
require.NoError(t, err)
assert.False(t, unavailable["default"], "administrator reset removes the vision conclusion")
})
}
}
func TestGroupDegradationUsesLatestValidBeforeHistoryTruncation(t *testing.T) {
func TestGroupDegradationRetainsFullHistoryForNotifications(t *testing.T) {
now := time.Now()
channels := []model.Channel{{Id: 1, Group: "default", Models: fingerprint.Model, Status: 1}}
rounds := []AstraSamplingRound{{ID: "valid", ChannelID: 1, StartedAt: now.Unix() - 100, FinishedAt: now.Unix() - 90, Result: fingerprint.Result{Engine: fingerprint.Version, Status: "mismatch", Closest: "gpt-5.5", ValidSamples: 1}}}
@@ -131,7 +195,7 @@ func TestGroupDegradationUsesLatestValidBeforeHistoryTruncation(t *testing.T) {
summary := AggregateAstraSampling(channels, tasks, now)["default"]
require.NotNil(t, summary.LatestValid)
assert.Equal(t, "gpt-5.5", summary.LatestValid.Closest)
assert.Len(t, summary.History, 12)
assert.Len(t, summary.History, 16)
rounds = append(rounds, AstraSamplingRound{ID: "recovered", ChannelID: 1, StartedAt: now.Unix(), FinishedAt: now.Unix(), Result: fingerprint.Result{Engine: fingerprint.Version, Status: "match", Closest: fingerprint.Model, ValidSamples: 2}})
body, err = common.Marshal(AstraSamplingState{Rounds: rounds})
require.NoError(t, err)
@@ -183,6 +247,15 @@ func TestGroupDegradationOverridesExistingPoolAffinity(t *testing.T) {
RecordPoolAffinity(first)
bound, _ := PreferredPoolChannel(ctx(false), fingerprint.Model)
require.NotNil(t, bound)
image := ctx(false)
image.Request = httptest.NewRequest("POST", "/v1/responses", strings.NewReader(`{"input":[{"role":"user","content":[{"type":"input_image","image_url":"data:image/png;base64,eA=="}]}]}`))
image.Request.Header.Set("Session-Id", "degradation-session")
image.Set("pool_group_visions", map[string]DetectionHistory{"default": {Quality: "incomplete"}})
selected, group, err = SelectChannelForRequest(image, fingerprint.Model, &RetryParam{Ctx: image, TokenGroup: "default", ModelName: fingerprint.Model})
require.Nil(t, err)
require.NotNil(t, selected)
assert.Equal(t, 6401, selected.Id, "incomplete vision must preserve the existing session affinity")
assert.Equal(t, "default", group)
next := ctx(true)
selected, group, err = SelectChannelForRequest(next, fingerprint.Model, &RetryParam{Ctx: next, TokenGroup: "default", ModelName: fingerprint.Model})
require.Nil(t, err)
@@ -191,6 +264,40 @@ func TestGroupDegradationOverridesExistingPoolAffinity(t *testing.T) {
assert.Equal(t, "vip", group)
}
func TestVisionIncompleteRoutingAcrossModelsAndPolicies(t *testing.T) {
db := setupChannelSelectAutoGroupsTest(t)
for i, group := range []string{"default", "vip"} {
createChannelSelectAutoGroupsChannel(t, db, 6601+i, group, fingerprint.Model)
require.NoError(t, db.Model(&model.Channel{}).Where("id = ?", 6601+i).Update("models", fingerprint.Model+",gpt-6-sol").Error)
require.NoError(t, db.Create(&model.Ability{Group: group, Model: "gpt-6-sol", ChannelId: 6601 + i, Enabled: true, Weight: 100}).Error)
}
model.InitChannelCache()
ResetGroupAvailability()
t.Cleanup(ResetGroupAvailability)
for _, mode := range []string{"smart", "custom"} {
for _, allow := range []bool{false, true} {
for _, modelName := range []string{fingerprint.Model, "gpt-6-sol"} {
for _, image := range []bool{false, true} {
c := setupGroupPoolContext(t)
c.Request = httptest.NewRequest("POST", "/v1/responses", nil)
c.Set(model.TokenRoutingContextKey, &model.TokenRoutingPolicy{Version: 1, Mode: mode, AllowDegraded: allow, SkipDegradedGroups: !allow, Groups: []model.TokenGroupEntry{{Group: "default"}, {Group: "vip", Priority: 1}}})
if image {
c.Request = httptest.NewRequest("POST", "/v1/responses", strings.NewReader(`{"input":[{"role":"user","content":[{"type":"input_image","image_url":"data:image/png;base64,eA=="}]}]}`))
}
c.Set("pool_group_fingerprints", map[string]AstraSamplingHistory{})
visions := map[string]DetectionHistory{"default": {Quality: "incomplete"}, "vip": {Quality: "incomplete"}}
c.Set("pool_group_visions", visions)
channel, _, err := selectTokenRoutingPool(&RetryParam{Ctx: c, TokenGroup: "default", ModelName: modelName})
require.NoError(t, err)
require.NotNil(t, channel)
assert.Equal(t, 6601, channel.Id, "mode=%s allow=%v model=%s image=%v", mode, allow, modelName, image)
assert.False(t, poolGroupSkipped(c, modelName, "default"), "incomplete vision must not exclude retries or cooldown recovery")
}
}
}
}
}
func TestGroupDegradationSkipsPoolGroupsAndRespectsUnknownRecoveryAndOptOut(t *testing.T) {
db := setupChannelSelectAutoGroupsTest(t)
createChannelSelectAutoGroupsChannel(t, db, 6301, "default", fingerprint.Model)