Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/api_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func ChannelType2APIType(channelType int) (int, bool) {
return apiType, true
}

func IsResponsesCompactAPIType(apiType int) bool {
func SupportsResponsesCompact(channelType, apiType int) bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enforce the channel/API pair in SupportsResponsesCompact.

channelType is unused. Any supported apiType returns true, including unsupported channel/API combinations. This makes the channel-aware compact gate ineffective.

  • common/api_type.go#L91-L91: return true only for each supported channel/API pair.
  • controller/channel_test_internal_test.go#L105-L111: add mismatched channel/API cases that expect false. The current positive cases also pass with API-type-only logic.
📍 Affects 2 files
  • common/api_type.go#L91-L91 (this comment)
  • controller/channel_test_internal_test.go#L105-L111
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@common/api_type.go` at line 91, Update SupportsResponsesCompact in
common/api_type.go (line 91) to return true only for explicitly supported
channelType/apiType pairs, using both parameters in the gate. Add mismatched
channel/API cases expecting false in controller/channel_test_internal_test.go
(lines 105-111), while retaining the existing valid positive cases.

switch apiType {
case constant.APITypeOpenAI,
constant.APITypeCodex,
Expand Down
26 changes: 3 additions & 23 deletions controller/channel-test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/QuantumNous/new-api/relaykit/types"
"github.com/QuantumNous/new-api/service"
"github.com/QuantumNous/new-api/setting/operation_setting"
"github.com/QuantumNous/new-api/setting/ratio_setting"
hosttypes "github.com/QuantumNous/new-api/types"

"github.com/samber/lo"
Expand All @@ -42,14 +41,11 @@ type testResult struct {
newAPIError *types.NewAPIError
}

func normalizeChannelTestEndpoint(channel *model.Channel, modelName, endpointType string) string {
func normalizeChannelTestEndpoint(channel *model.Channel, endpointType string) string {
normalized := strings.TrimSpace(endpointType)
if normalized != "" {
return normalized
}
if strings.HasSuffix(modelName, ratio_setting.CompactModelSuffix) {
return string(constant.EndpointTypeOpenAIResponseCompact)
}
if channel != nil && channel.Type == constant.ChannelTypeCodex {
return string(constant.EndpointTypeOpenAIResponse)
}
Expand Down Expand Up @@ -111,7 +107,7 @@ func testChannel(ctx context.Context, channel *model.Channel, testUserID int, te
}
}

endpointType = normalizeChannelTestEndpoint(channel, testModel, endpointType)
endpointType = normalizeChannelTestEndpoint(channel, endpointType)

requestPath := "/v1/chat/completions"

Expand Down Expand Up @@ -146,20 +142,12 @@ func testChannel(ctx context.Context, channel *model.Channel, testUserID int, te
requestPath = "/v1/responses"
}

// responses compaction models (must use /v1/responses/compact)
if strings.HasSuffix(testModel, ratio_setting.CompactModelSuffix) {
requestPath = "/v1/responses/compact"
}
}
// Gemini 原生流式通过 URL action(:streamGenerateContent)表达而非请求体字段,
// GeminiChatRequest.IsStream 依据请求 URL 判定,合成请求路径需与生产入口保持一致
if isStream && constant.EndpointType(endpointType) == constant.EndpointTypeGemini {
requestPath = strings.Replace(requestPath, ":generateContent", ":streamGenerateContent", 1)
}
if strings.HasPrefix(requestPath, "/v1/responses/compact") {
testModel = ratio_setting.WithCompactModelSuffix(testModel)
}

c.Request = httptest.NewRequestWithContext(ctx, http.MethodPost, requestPath, nil)

cache, err := model.GetUserCache(testUserID)
Expand Down Expand Up @@ -277,7 +265,7 @@ func testChannel(ctx context.Context, channel *model.Channel, testUserID int, te

apiType, _ := common.ChannelType2APIType(channel.Type)
if info.RelayMode == relayconstant.RelayModeResponsesCompact &&
!common.IsResponsesCompactAPIType(apiType) {
!common.SupportsResponsesCompact(channel.Type, apiType) {
return testResult{
context: c,
localErr: fmt.Errorf("responses compaction test is not supported for api type %d", apiType),
Expand Down Expand Up @@ -806,14 +794,6 @@ func buildTestRequest(model string, endpointType string, channel *model.Channel,
}
}

// Responses compaction models (must use /v1/responses/compact)
if strings.HasSuffix(model, ratio_setting.CompactModelSuffix) {
return &dto.OpenAIResponsesCompactionRequest{
Model: model,
Input: testResponsesInput,
}
}

// Responses-only models (e.g. codex series)
if strings.Contains(strings.ToLower(model), "codex") {
return &dto.OpenAIResponsesRequest{
Expand Down
24 changes: 13 additions & 11 deletions controller/channel_test_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,23 +95,25 @@ func TestNewAPIChannelRegistration(t *testing.T) {
assert.Empty(t, constant.ChannelBaseURLs[constant.ChannelTypeNewAPI])
}

func TestResponsesCompactAPITypeSupport(t *testing.T) {
func TestResponsesCompactChannelSupport(t *testing.T) {
tests := []struct {
name string
apiType int
want bool
name string
channelType int
apiType int
want bool
}{
{name: "OpenAI", apiType: constant.APITypeOpenAI, want: true},
{name: "Codex", apiType: constant.APITypeCodex, want: true},
{name: "Advanced Custom", apiType: constant.APITypeAdvancedCustom, want: true},
{name: "Sub2API", apiType: constant.APITypeSub2API, want: true},
{name: "New API", apiType: constant.APITypeNewAPI, want: true},
{name: "Anthropic", apiType: constant.APITypeAnthropic, want: false},
{name: "OpenAI", channelType: constant.ChannelTypeOpenAI, apiType: constant.APITypeOpenAI, want: true},
{name: "Azure", channelType: constant.ChannelTypeAzure, apiType: constant.APITypeOpenAI, want: true},
{name: "Codex", channelType: constant.ChannelTypeCodex, apiType: constant.APITypeCodex, want: true},
{name: "Advanced Custom", channelType: constant.ChannelTypeAdvancedCustom, apiType: constant.APITypeAdvancedCustom, want: true},
{name: "Sub2API", channelType: constant.ChannelTypeSub2API, apiType: constant.APITypeSub2API, want: true},
{name: "New API", channelType: constant.ChannelTypeNewAPI, apiType: constant.APITypeNewAPI, want: true},
{name: "Anthropic", channelType: constant.ChannelTypeAnthropic, apiType: constant.APITypeAnthropic, want: false},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, test.want, common.IsResponsesCompactAPIType(test.apiType))
assert.Equal(t, test.want, common.SupportsResponsesCompact(test.channelType, test.apiType))
})
}
}
Expand Down
3 changes: 0 additions & 3 deletions middleware/distributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,6 @@ func getModelRequest(c *gin.Context) (*ModelRequest, bool, error) {
common.SetContextKey(c, constant.ContextKeyTokenGroup, modelRequest.Group)
}

if strings.HasPrefix(c.Request.URL.Path, "/v1/responses/compact") && modelRequest.Model != "" {
modelRequest.Model = ratio_setting.WithCompactModelSuffix(modelRequest.Model)
}
return &modelRequest, shouldSelectChannel, nil
}

Expand Down
15 changes: 1 addition & 14 deletions relay/channel/codex/constants.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
package codex

import (
"slices"

"github.com/QuantumNous/new-api/setting/ratio_setting"
)

var baseModelList = []string{
var ModelList = []string{
"gpt-5.6-sol",
"gpt-5.6-terra",
"gpt-5.6-luna",
Expand All @@ -17,11 +11,4 @@ var baseModelList = []string{
"codex-auto-review",
}

var ModelList = slices.DeleteFunc(
ratio_setting.WithCompactModelVariants(baseModelList),
func(modelName string) bool {
return modelName == ratio_setting.WithCompactModelSuffix("codex-auto-review")
},
)

const ChannelName = "codex"
20 changes: 1 addition & 19 deletions relay/helper/model_mapped.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import (
"encoding/json"
"errors"
"fmt"
"strings"

"github.com/QuantumNous/new-api/relay/common"
relayconstant "github.com/QuantumNous/new-api/relay/constant"
"github.com/QuantumNous/new-api/relaykit/dto"
"github.com/QuantumNous/new-api/setting/ratio_setting"
"github.com/gin-gonic/gin"
)

Expand All @@ -18,13 +15,6 @@ func ModelMappedHelper(c *gin.Context, info *common.RelayInfo, request dto.Reque
info.ChannelMeta = &common.ChannelMeta{}
}

isResponsesCompact := info.RelayMode == relayconstant.RelayModeResponsesCompact
originModelName := info.OriginModelName
mappingModelName := originModelName
if isResponsesCompact && strings.HasSuffix(originModelName, ratio_setting.CompactModelSuffix) {
mappingModelName = strings.TrimSuffix(originModelName, ratio_setting.CompactModelSuffix)
}

// map model name
modelMapping := c.GetString("model_mapping")
if modelMapping != "" && modelMapping != "{}" {
Expand All @@ -35,7 +25,7 @@ func ModelMappedHelper(c *gin.Context, info *common.RelayInfo, request dto.Reque
}

// 支持链式模型重定向,最终使用链尾的模型
currentModel := mappingModelName
currentModel := info.OriginModelName
visitedModels := map[string]bool{
currentModel: true,
}
Expand Down Expand Up @@ -66,14 +56,6 @@ func ModelMappedHelper(c *gin.Context, info *common.RelayInfo, request dto.Reque
}
}

if isResponsesCompact {
finalUpstreamModelName := mappingModelName
if info.IsModelMapped && info.UpstreamModelName != "" {
finalUpstreamModelName = info.UpstreamModelName
}
info.UpstreamModelName = finalUpstreamModelName
info.OriginModelName = ratio_setting.WithCompactModelSuffix(finalUpstreamModelName)
}
if request != nil {
request.SetModelName(info.UpstreamModelName)
}
Expand Down
2 changes: 1 addition & 1 deletion relay/responses_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
func ResponsesHelper(c *gin.Context, info *relaycommon.RelayInfo) (newAPIError *types.NewAPIError) {
info.InitChannelMeta(c)
if info.RelayMode == relayconstant.RelayModeResponsesCompact &&
!common.IsResponsesCompactAPIType(info.ApiType) {
!common.SupportsResponsesCompact(info.ChannelType, info.ApiType) {
return types.NewErrorWithStatusCode(
fmt.Errorf("unsupported endpoint %q for api type %d", "/v1/responses/compact", info.ApiType),
types.ErrorCodeInvalidRequest,
Expand Down
11 changes: 1 addition & 10 deletions service/codex_channel_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/model"
"github.com/QuantumNous/new-api/setting/ratio_setting"
)

func FetchCodexChannelModels(channel *model.Channel) ([]string, error) {
Expand Down Expand Up @@ -78,13 +77,5 @@ func fetchCodexChannelModels(
if statusCode < http.StatusOK || statusCode >= http.StatusMultipleChoices {
return nil, fmt.Errorf("upstream status: %d", statusCode)
}
modelVariants := make([]string, 0, len(models)*2)
modelVariants = append(modelVariants, models...)
for _, modelName := range models {
if modelName == "codex-auto-review" {
continue
}
modelVariants = append(modelVariants, ratio_setting.WithCompactModelSuffix(modelName))
}
return modelVariants, nil
return models, nil
}
34 changes: 0 additions & 34 deletions setting/ratio_setting/compact_suffix.go

This file was deleted.

17 changes: 0 additions & 17 deletions setting/ratio_setting/model_ratio.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,17 +364,6 @@ func GetModelPrice(name string, printErr bool) (float64, bool) {
return price, true
}

if strings.HasSuffix(name, CompactModelSuffix) {
price, ok := modelPriceMap.Get(CompactWildcardModelKey)
if !ok {
if printErr {
common.SysError("model price not found: " + name)
}
return -1, false
}
return price, true
}

if printErr {
common.SysError("model price not found: " + name)
}
Expand All @@ -398,12 +387,6 @@ func GetModelRatio(name string) (float64, bool, string) {

ratio, ok := modelRatioMap.Get(name)
if !ok {
if strings.HasSuffix(name, CompactModelSuffix) {
if wildcardRatio, ok := modelRatioMap.Get(CompactWildcardModelKey); ok {
return wildcardRatio, true, name
}
//return 0, true, name
}
return 37.5, operation_setting.SelfUseModeEnabled, name
}
return ratio, true, name
Expand Down
Loading