From f6c782816020f43561fb4fd82aa5cb27a4a81943 Mon Sep 17 00:00:00 2001 From: CaIon Date: Fri, 8 Aug 2025 17:28:21 +0800 Subject: [PATCH] feat: implement moonshot adaptor for request handling and response processing --- common/api_type.go | 2 + constant/api_type.go | 3 +- relay/channel/ali/adaptor.go | 16 +---- relay/channel/moonshot/adaptor.go | 111 ++++++++++++++++++++++++++++++ relay/channel/openai/adaptor.go | 5 -- relay/relay_adaptor.go | 3 + 6 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 relay/channel/moonshot/adaptor.go diff --git a/common/api_type.go b/common/api_type.go index f045866a..5ac46c86 100644 --- a/common/api_type.go +++ b/common/api_type.go @@ -65,6 +65,8 @@ func ChannelType2APIType(channelType int) (int, bool) { apiType = constant.APITypeCoze case constant.ChannelTypeJimeng: apiType = constant.APITypeJimeng + case constant.ChannelTypeMoonshot: + apiType = constant.APITypeMoonshot } if apiType == -1 { return constant.APITypeOpenAI, false diff --git a/constant/api_type.go b/constant/api_type.go index 6ba5f257..f62d91d5 100644 --- a/constant/api_type.go +++ b/constant/api_type.go @@ -31,5 +31,6 @@ const ( APITypeXai APITypeCoze APITypeJimeng - APITypeDummy // this one is only for count, do not add any channel after this + APITypeMoonshot // this one is only for count, do not add any channel after this + APITypeDummy // this one is only for count, do not add any channel after this ) diff --git a/relay/channel/ali/adaptor.go b/relay/channel/ali/adaptor.go index f3c5cee6..bfb94008 100644 --- a/relay/channel/ali/adaptor.go +++ b/relay/channel/ali/adaptor.go @@ -125,20 +125,8 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom err, usage = claude.ClaudeHandler(c, resp, info, claude.RequestModeMessage) } default: - switch info.RelayMode { - case constant.RelayModeImagesGenerations: - err, usage = aliImageHandler(c, resp, info) - case constant.RelayModeEmbeddings: - err, usage = aliEmbeddingHandler(c, resp) - case constant.RelayModeRerank: - err, usage = RerankHandler(c, resp, info) - default: - if info.IsStream { - usage, err = openai.OaiStreamHandler(c, info, resp) - } else { - usage, err = openai.OpenaiHandler(c, info, resp) - } - } + adaptor := openai.Adaptor{} + return adaptor.DoResponse(c, resp, info) } return } diff --git a/relay/channel/moonshot/adaptor.go b/relay/channel/moonshot/adaptor.go new file mode 100644 index 00000000..d540388d --- /dev/null +++ b/relay/channel/moonshot/adaptor.go @@ -0,0 +1,111 @@ +package moonshot + +import ( + "errors" + "fmt" + "io" + "net/http" + "one-api/dto" + "one-api/relay/channel" + "one-api/relay/channel/claude" + "one-api/relay/channel/openai" + relaycommon "one-api/relay/common" + "one-api/relay/constant" + "one-api/types" + + "github.com/gin-gonic/gin" +) + +type Adaptor struct { +} + +func (a *Adaptor) ConvertGeminiRequest(*gin.Context, *relaycommon.RelayInfo, *dto.GeminiChatRequest) (any, error) { + //TODO implement me + return nil, errors.New("not implemented") +} + +func (a *Adaptor) ConvertClaudeRequest(c *gin.Context, info *relaycommon.RelayInfo, req *dto.ClaudeRequest) (any, error) { + adaptor := openai.Adaptor{} + return adaptor.ConvertClaudeRequest(c, info, req) +} + +func (a *Adaptor) ConvertAudioRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.AudioRequest) (io.Reader, error) { + //TODO implement me + return nil, errors.New("not supported") +} + +func (a *Adaptor) ConvertImageRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.ImageRequest) (any, error) { + adaptor := openai.Adaptor{} + return adaptor.ConvertImageRequest(c, info, request) +} + +func (a *Adaptor) Init(info *relaycommon.RelayInfo) { +} + +func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) { + switch info.RelayFormat { + case relaycommon.RelayFormatClaude: + return fmt.Sprintf("%s/anthropic/v1/messages", info.BaseUrl), nil + default: + if info.RelayMode == constant.RelayModeRerank { + return fmt.Sprintf("%s/v1/rerank", info.BaseUrl), nil + } else if info.RelayMode == constant.RelayModeEmbeddings { + return fmt.Sprintf("%s/v1/embeddings", info.BaseUrl), nil + } else if info.RelayMode == constant.RelayModeChatCompletions { + return fmt.Sprintf("%s/v1/chat/completions", info.BaseUrl), nil + } else if info.RelayMode == constant.RelayModeCompletions { + return fmt.Sprintf("%s/v1/completions", info.BaseUrl), nil + } + return fmt.Sprintf("%s/v1/chat/completions", info.BaseUrl), nil + } +} + +func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error { + channel.SetupApiRequestHeader(info, c, req) + req.Set("Authorization", fmt.Sprintf("Bearer %s", info.ApiKey)) + return nil +} + +func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayInfo, request *dto.GeneralOpenAIRequest) (any, error) { + return request, nil +} + +func (a *Adaptor) ConvertOpenAIResponsesRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.OpenAIResponsesRequest) (any, error) { + // TODO implement me + return nil, errors.New("not implemented") +} + +func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, requestBody io.Reader) (any, error) { + return channel.DoApiRequest(a, c, info, requestBody) +} + +func (a *Adaptor) ConvertRerankRequest(c *gin.Context, relayMode int, request dto.RerankRequest) (any, error) { + return request, nil +} + +func (a *Adaptor) ConvertEmbeddingRequest(c *gin.Context, info *relaycommon.RelayInfo, request dto.EmbeddingRequest) (any, error) { + return request, nil +} + +func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage any, err *types.NewAPIError) { + switch info.RelayFormat { + case relaycommon.RelayFormatOpenAI: + adaptor := openai.Adaptor{} + return adaptor.DoResponse(c, resp, info) + case relaycommon.RelayFormatClaude: + if info.IsStream { + err, usage = claude.ClaudeStreamHandler(c, resp, info, claude.RequestModeMessage) + } else { + err, usage = claude.ClaudeHandler(c, resp, info, claude.RequestModeMessage) + } + } + return +} + +func (a *Adaptor) GetModelList() []string { + return ModelList +} + +func (a *Adaptor) GetChannelName() string { + return ChannelName +} diff --git a/relay/channel/openai/adaptor.go b/relay/channel/openai/adaptor.go index ed2bea57..c2751c28 100644 --- a/relay/channel/openai/adaptor.go +++ b/relay/channel/openai/adaptor.go @@ -16,7 +16,6 @@ import ( "one-api/relay/channel/ai360" "one-api/relay/channel/lingyiwanwu" "one-api/relay/channel/minimax" - "one-api/relay/channel/moonshot" "one-api/relay/channel/openrouter" "one-api/relay/channel/xinference" relaycommon "one-api/relay/common" @@ -534,8 +533,6 @@ func (a *Adaptor) GetModelList() []string { switch a.ChannelType { case constant.ChannelType360: return ai360.ModelList - case constant.ChannelTypeMoonshot: - return moonshot.ModelList case constant.ChannelTypeLingYiWanWu: return lingyiwanwu.ModelList case constant.ChannelTypeMiniMax: @@ -553,8 +550,6 @@ func (a *Adaptor) GetChannelName() string { switch a.ChannelType { case constant.ChannelType360: return ai360.ChannelName - case constant.ChannelTypeMoonshot: - return moonshot.ChannelName case constant.ChannelTypeLingYiWanWu: return lingyiwanwu.ChannelName case constant.ChannelTypeMiniMax: diff --git a/relay/relay_adaptor.go b/relay/relay_adaptor.go index cc9c5bbb..1ee85986 100644 --- a/relay/relay_adaptor.go +++ b/relay/relay_adaptor.go @@ -19,6 +19,7 @@ import ( "one-api/relay/channel/jina" "one-api/relay/channel/mistral" "one-api/relay/channel/mokaai" + "one-api/relay/channel/moonshot" "one-api/relay/channel/ollama" "one-api/relay/channel/openai" "one-api/relay/channel/palm" @@ -98,6 +99,8 @@ func GetAdaptor(apiType int) channel.Adaptor { return &coze.Adaptor{} case constant.APITypeJimeng: return &jimeng.Adaptor{} + case constant.APITypeMoonshot: + return &moonshot.Adaptor{} // Moonshot uses Claude API } return nil }