Merge pull request #6444 from Ritel-T/pr/group-free-openai-fast

Add group-level Standard billing for OpenAI Fast requests
This commit is contained in:
Wesley Liddick
2026-09-02 09:23:49 +08:00
committed by GitHub
38 changed files with 481 additions and 25 deletions
@@ -148,6 +148,7 @@ type CreateGroupRequest struct {
AllowMessagesDispatch bool `json:"allow_messages_dispatch"`
AllowLive bool `json:"allow_live"`
ForceOpenAIFast bool `json:"force_openai_fast"`
FreeOpenAIFast bool `json:"free_openai_fast"`
RequireOAuthOnly bool `json:"require_oauth_only"`
RequirePrivacySet bool `json:"require_privacy_set"`
DefaultMappedModel string `json:"default_mapped_model"`
@@ -220,6 +221,7 @@ type UpdateGroupRequest struct {
AllowMessagesDispatch *bool `json:"allow_messages_dispatch"`
AllowLive *bool `json:"allow_live"`
ForceOpenAIFast *bool `json:"force_openai_fast"`
FreeOpenAIFast *bool `json:"free_openai_fast"`
RequireOAuthOnly *bool `json:"require_oauth_only"`
RequirePrivacySet *bool `json:"require_privacy_set"`
DefaultMappedModel *string `json:"default_mapped_model"`
@@ -557,6 +559,7 @@ func (h *GroupHandler) Create(c *gin.Context) {
AllowMessagesDispatch: req.AllowMessagesDispatch,
AllowLive: req.AllowLive,
ForceOpenAIFast: req.ForceOpenAIFast,
FreeOpenAIFast: req.FreeOpenAIFast,
RequireOAuthOnly: req.RequireOAuthOnly,
RequirePrivacySet: req.RequirePrivacySet,
DefaultMappedModel: req.DefaultMappedModel,
@@ -688,6 +691,7 @@ func (h *GroupHandler) Update(c *gin.Context) {
AllowMessagesDispatch: req.AllowMessagesDispatch,
AllowLive: req.AllowLive,
ForceOpenAIFast: req.ForceOpenAIFast,
FreeOpenAIFast: req.FreeOpenAIFast,
RequireOAuthOnly: req.RequireOAuthOnly,
RequirePrivacySet: req.RequirePrivacySet,
DefaultMappedModel: req.DefaultMappedModel,
@@ -9,15 +9,19 @@ import (
func TestGroupRequestsDecodeForceOpenAIFast(t *testing.T) {
var createReq CreateGroupRequest
require.NoError(t, json.Unmarshal([]byte(`{"name":"fast","force_openai_fast":true}`), &createReq))
require.NoError(t, json.Unmarshal([]byte(`{"name":"fast","force_openai_fast":true,"free_openai_fast":true}`), &createReq))
require.True(t, createReq.ForceOpenAIFast)
require.True(t, createReq.FreeOpenAIFast)
var updateReq UpdateGroupRequest
require.NoError(t, json.Unmarshal([]byte(`{"force_openai_fast":false}`), &updateReq))
require.NoError(t, json.Unmarshal([]byte(`{"force_openai_fast":false,"free_openai_fast":false}`), &updateReq))
require.NotNil(t, updateReq.ForceOpenAIFast)
require.False(t, *updateReq.ForceOpenAIFast)
require.NotNil(t, updateReq.FreeOpenAIFast)
require.False(t, *updateReq.FreeOpenAIFast)
var omitted UpdateGroupRequest
require.NoError(t, json.Unmarshal([]byte(`{}`), &omitted))
require.Nil(t, omitted.ForceOpenAIFast)
require.Nil(t, omitted.FreeOpenAIFast)
}
@@ -10,14 +10,16 @@ import (
func TestGroupMapperExposesForceOpenAIFastOnlyToAdmins(t *testing.T) {
group := &service.Group{
ID: 7, Name: "fast", Platform: service.PlatformOpenAI, Status: service.StatusActive, ForceOpenAIFast: true,
ID: 7, Name: "fast", Platform: service.PlatformOpenAI, Status: service.StatusActive, ForceOpenAIFast: true, FreeOpenAIFast: true,
}
userJSON, err := json.Marshal(GroupFromService(group))
require.NoError(t, err)
require.NotContains(t, string(userJSON), "force_openai_fast")
require.NotContains(t, string(userJSON), "free_openai_fast")
adminJSON, err := json.Marshal(GroupFromServiceAdmin(group))
require.NoError(t, err)
require.Contains(t, string(adminJSON), `"force_openai_fast":true`)
require.Contains(t, string(adminJSON), `"free_openai_fast":true`)
}
+1
View File
@@ -149,6 +149,7 @@ func GroupFromServiceAdmin(g *service.Group) *AdminGroup {
out := &AdminGroup{
Group: groupFromServiceBase(g),
ForceOpenAIFast: g.ForceOpenAIFast,
FreeOpenAIFast: g.FreeOpenAIFast,
ProfitControlEnabled: g.ProfitControlEnabled,
ProfitMinMargin: g.ProfitMinMargin,
ProfitSafetyBuffer: g.ProfitSafetyBuffer,
+2
View File
@@ -168,6 +168,8 @@ type AdminGroup struct {
Group
// ForceOpenAIFast 是管理端请求策略,用户侧分组 DTO 无需暴露。
ForceOpenAIFast bool `json:"force_openai_fast"`
// FreeOpenAIFast 是管理端计费策略,用户侧分组 DTO 无需暴露。
FreeOpenAIFast bool `json:"free_openai_fast"`
// 分组利润控制(五个 token 平台分组可启用;margin/buffer 为小数存储)。
// 仅管理员可见:这三个字段与同响应中的 rate_multiplier 相乘即可反推出