From f2af76aa890c453a062b4cdcc2b0f8d19fd29e92 Mon Sep 17 00:00:00 2001 From: Seefs Date: Sun, 19 Jul 2026 22:25:02 +0800 Subject: [PATCH] feat: kimi /v1/responses --- relay/channel/moonshot/adaptor.go | 11 +++++++-- relay/channel/moonshot/adaptor_test.go | 34 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/relay/channel/moonshot/adaptor.go b/relay/channel/moonshot/adaptor.go index c90ae073c744..446ebc50c57a 100644 --- a/relay/channel/moonshot/adaptor.go +++ b/relay/channel/moonshot/adaptor.go @@ -52,6 +52,9 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) { if info.RelayFormat == types.RelayFormatClaude { return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil } + if info.RelayMode == constant.RelayModeResponses { + return fmt.Sprintf("%s/responses", specialPlan.OpenAIBaseURL), nil + } if info.RelayFormat == types.RelayFormatOpenAI { return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil } @@ -69,6 +72,8 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) { return fmt.Sprintf("%s/v1/chat/completions", info.ChannelBaseUrl), nil } else if info.RelayMode == constant.RelayModeCompletions { return fmt.Sprintf("%s/v1/completions", info.ChannelBaseUrl), nil + } else if info.RelayMode == constant.RelayModeResponses { + return fmt.Sprintf("%s/v1/responses", info.ChannelBaseUrl), nil } return fmt.Sprintf("%s/v1/chat/completions", info.ChannelBaseUrl), nil } @@ -99,8 +104,10 @@ func isTemperatureOneOnlyModel(model string) bool { } func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.OpenAIResponsesRequest) (any, error) { - // TODO implement me - return nil, errors.New("not implemented") + if request.Temperature != nil && isTemperatureOneOnlyModel(getUpstreamModelName(info, request.Model)) && *request.Temperature != 1.0 { + request.Temperature = common.GetPointer[float64](1.0) + } + return request, nil } func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, requestBody io.Reader) (any, error) { diff --git a/relay/channel/moonshot/adaptor_test.go b/relay/channel/moonshot/adaptor_test.go index cfa1cb49935b..2b515f53c5fb 100644 --- a/relay/channel/moonshot/adaptor_test.go +++ b/relay/channel/moonshot/adaptor_test.go @@ -6,6 +6,9 @@ import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/dto" relaycommon "github.com/QuantumNous/new-api/relay/common" + relayconstant "github.com/QuantumNous/new-api/relay/constant" + "github.com/QuantumNous/new-api/types" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -66,3 +69,34 @@ func TestConvertOpenAIRequestOtherMoonshotModelKeepsTemperature(t *testing.T) { require.NotNil(t, convertedRequest.Temperature) require.Equal(t, 0.7, *convertedRequest.Temperature) } + +func TestOpenAIResponsesSupport(t *testing.T) { + request := dto.OpenAIResponsesRequest{ + Model: "kimi-k2.6", + Temperature: common.GetPointer[float64](0.7), + } + info := &relaycommon.RelayInfo{ + RelayMode: relayconstant.RelayModeResponses, + RelayFormat: types.RelayFormatOpenAIResponses, + ChannelMeta: &relaycommon.ChannelMeta{ + ChannelBaseUrl: "https://api.moonshot.cn", + UpstreamModelName: "kimi-k2.6", + }, + } + + converted, err := (&Adaptor{}).ConvertOpenAIResponsesRequest(nil, info, request) + require.NoError(t, err) + convertedRequest, ok := converted.(dto.OpenAIResponsesRequest) + require.True(t, ok) + require.NotNil(t, convertedRequest.Temperature) + assert.Equal(t, 1.0, *convertedRequest.Temperature) + + requestURL, err := (&Adaptor{}).GetRequestURL(info) + require.NoError(t, err) + assert.Equal(t, "https://api.moonshot.cn/v1/responses", requestURL) + + info.ChannelBaseUrl = "kimi-coding-plan" + requestURL, err = (&Adaptor{}).GetRequestURL(info) + require.NoError(t, err) + assert.Equal(t, "https://api.kimi.com/coding/v1/responses", requestURL) +}