From 824c6d9133de006092a45f54436274906cae951e Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 12 Jun 2026 17:40:53 +0800 Subject: [PATCH] feat: add Tencent Cloud Coding Plan support and handle coding plan URLs in OpenAI adaptor --- constant/channel.go | 4 ++++ controller/channel_upstream_update.go | 6 +++++- relay/channel/openai/adaptor.go | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/constant/channel.go b/constant/channel.go index 48502bedc..5df81792b 100644 --- a/constant/channel.go +++ b/constant/channel.go @@ -206,4 +206,8 @@ var ChannelSpecialBases = map[string]ChannelSpecialBase{ ClaudeBaseURL: "https://ark.cn-beijing.volces.com/api/coding", OpenAIBaseURL: "https://ark.cn-beijing.volces.com/api/coding/v3", }, + "tencent-coding-plan": { + ClaudeBaseURL: "https://api.lkeap.cloud.tencent.com/coding", + OpenAIBaseURL: "https://api.lkeap.cloud.tencent.com/coding/v3", + }, } diff --git a/controller/channel_upstream_update.go b/controller/channel_upstream_update.go index 77a1e3c81..15de69399 100644 --- a/controller/channel_upstream_update.go +++ b/controller/channel_upstream_update.go @@ -312,7 +312,11 @@ func fetchChannelUpstreamModelIDs(channel *model.Channel) ([]string, error) { url = fmt.Sprintf("%s/v1/models", baseURL) } default: - url = fmt.Sprintf("%s/v1/models", baseURL) + if plan, ok := constant.ChannelSpecialBases[baseURL]; ok && plan.OpenAIBaseURL != "" { + url = fmt.Sprintf("%s/models", plan.OpenAIBaseURL) + } else { + url = fmt.Sprintf("%s/v1/models", baseURL) + } } key, _, apiErr := channel.GetNextEnabledKey() diff --git a/relay/channel/openai/adaptor.go b/relay/channel/openai/adaptor.go index 80dbf4f4c..1ec1b986e 100644 --- a/relay/channel/openai/adaptor.go +++ b/relay/channel/openai/adaptor.go @@ -164,6 +164,20 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) { url = strings.Replace(url, "{model}", info.UpstreamModelName, -1) return url, nil default: + // Handle coding plan special base URLs + if specialPlan, ok := constant.ChannelSpecialBases[info.ChannelBaseUrl]; ok && specialPlan.OpenAIBaseURL != "" { + if info.RelayFormat == types.RelayFormatClaude { + return fmt.Sprintf("%s/v1/messages", specialPlan.ClaudeBaseURL), nil + } + switch info.RelayMode { + case relayconstant.RelayModeEmbeddings: + return fmt.Sprintf("%s/embeddings", specialPlan.OpenAIBaseURL), nil + case relayconstant.RelayModeImagesGenerations: + return fmt.Sprintf("%s/images/generations", specialPlan.OpenAIBaseURL), nil + default: + return fmt.Sprintf("%s/chat/completions", specialPlan.OpenAIBaseURL), nil + } + } if (info.RelayFormat == types.RelayFormatClaude || info.RelayFormat == types.RelayFormatGemini) && info.RelayMode != relayconstant.RelayModeResponses && info.RelayMode != relayconstant.RelayModeResponsesCompact {