mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 02:25:00 +00:00
feat: openai response /v1/response/compact (#2644)
* feat: openai response /v1/response/compact * feat: /v1/response/compact bill * feat: /v1/response/compact * feat: /v1/responses/compact -> codex channel * feat: /v1/responses/compact -> codex channel * feat: /v1/responses/compact -> codex channel * feat: codex channel default models * feat: compact model price * feat: /v1/responses/comapct test
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/QuantumNous/new-api/relay/helper"
|
||||
"github.com/QuantumNous/new-api/service"
|
||||
"github.com/QuantumNous/new-api/setting/operation_setting"
|
||||
"github.com/QuantumNous/new-api/setting/ratio_setting"
|
||||
"github.com/QuantumNous/new-api/types"
|
||||
|
||||
"github.com/bytedance/gopkg/util/gopool"
|
||||
@@ -107,6 +108,14 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
|
||||
if strings.Contains(strings.ToLower(testModel), "codex") {
|
||||
requestPath = "/v1/responses"
|
||||
}
|
||||
|
||||
// responses compaction models (must use /v1/responses/compact)
|
||||
if strings.HasSuffix(testModel, ratio_setting.CompactModelSuffix) {
|
||||
requestPath = "/v1/responses/compact"
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(requestPath, "/v1/responses/compact") {
|
||||
testModel = ratio_setting.WithCompactModelSuffix(testModel)
|
||||
}
|
||||
|
||||
c.Request = &http.Request{
|
||||
@@ -150,6 +159,8 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
|
||||
relayFormat = types.RelayFormatOpenAI
|
||||
case constant.EndpointTypeOpenAIResponse:
|
||||
relayFormat = types.RelayFormatOpenAIResponses
|
||||
case constant.EndpointTypeOpenAIResponseCompact:
|
||||
relayFormat = types.RelayFormatOpenAIResponsesCompaction
|
||||
case constant.EndpointTypeAnthropic:
|
||||
relayFormat = types.RelayFormatClaude
|
||||
case constant.EndpointTypeGemini:
|
||||
@@ -184,6 +195,9 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
|
||||
if c.Request.URL.Path == "/v1/responses" {
|
||||
relayFormat = types.RelayFormatOpenAIResponses
|
||||
}
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/v1/responses/compact") {
|
||||
relayFormat = types.RelayFormatOpenAIResponsesCompaction
|
||||
}
|
||||
}
|
||||
|
||||
request := buildTestRequest(testModel, endpointType, channel)
|
||||
@@ -215,6 +229,15 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
|
||||
request.SetModelName(testModel)
|
||||
|
||||
apiType, _ := common.ChannelType2APIType(channel.Type)
|
||||
if info.RelayMode == relayconstant.RelayModeResponsesCompact &&
|
||||
apiType != constant.APITypeOpenAI &&
|
||||
apiType != constant.APITypeCodex {
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: fmt.Errorf("responses compaction test only supports openai/codex channels, got api type %d", apiType),
|
||||
newAPIError: types.NewError(fmt.Errorf("unsupported api type: %d", apiType), types.ErrorCodeInvalidApiType),
|
||||
}
|
||||
}
|
||||
adaptor := relay.GetAdaptor(apiType)
|
||||
if adaptor == nil {
|
||||
return testResult{
|
||||
@@ -287,6 +310,25 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
|
||||
newAPIError: types.NewError(errors.New("invalid response request type"), types.ErrorCodeConvertRequestFailed),
|
||||
}
|
||||
}
|
||||
case relayconstant.RelayModeResponsesCompact:
|
||||
// Response compaction request - convert to OpenAIResponsesRequest before adapting
|
||||
switch req := request.(type) {
|
||||
case *dto.OpenAIResponsesCompactionRequest:
|
||||
convertedRequest, err = adaptor.ConvertOpenAIResponsesRequest(c, info, dto.OpenAIResponsesRequest{
|
||||
Model: req.Model,
|
||||
Input: req.Input,
|
||||
Instructions: req.Instructions,
|
||||
PreviousResponseID: req.PreviousResponseID,
|
||||
})
|
||||
case *dto.OpenAIResponsesRequest:
|
||||
convertedRequest, err = adaptor.ConvertOpenAIResponsesRequest(c, info, *req)
|
||||
default:
|
||||
return testResult{
|
||||
context: c,
|
||||
localErr: errors.New("invalid response compaction request type"),
|
||||
newAPIError: types.NewError(errors.New("invalid response compaction request type"), types.ErrorCodeConvertRequestFailed),
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Chat/Completion 等其他请求类型
|
||||
if generalReq, ok := request.(*dto.GeneralOpenAIRequest); ok {
|
||||
@@ -432,6 +474,8 @@ func testChannel(channel *model.Channel, testModel string, endpointType string)
|
||||
}
|
||||
|
||||
func buildTestRequest(model string, endpointType string, channel *model.Channel) dto.Request {
|
||||
testResponsesInput := json.RawMessage(`[{"role":"user","content":"hi"}]`)
|
||||
|
||||
// 根据端点类型构建不同的测试请求
|
||||
if endpointType != "" {
|
||||
switch constant.EndpointType(endpointType) {
|
||||
@@ -463,6 +507,12 @@ func buildTestRequest(model string, endpointType string, channel *model.Channel)
|
||||
Model: model,
|
||||
Input: json.RawMessage(`[{"role":"user","content":"hi"}]`),
|
||||
}
|
||||
case constant.EndpointTypeOpenAIResponseCompact:
|
||||
// 返回 OpenAIResponsesCompactionRequest
|
||||
return &dto.OpenAIResponsesCompactionRequest{
|
||||
Model: model,
|
||||
Input: testResponsesInput,
|
||||
}
|
||||
case constant.EndpointTypeAnthropic, constant.EndpointTypeGemini, constant.EndpointTypeOpenAI:
|
||||
// 返回 GeneralOpenAIRequest
|
||||
maxTokens := uint(16)
|
||||
@@ -504,6 +554,14 @@ 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{
|
||||
|
||||
Reference in New Issue
Block a user