feat(*): 插件中心与模型协议 - 完善声明式协议运行时并增加功能开放控制

This commit is contained in:
ddCat
2026-08-23 23:19:27 +08:00
parent 7cc6021f6e
commit 919037e5d9
106 changed files with 8817 additions and 500 deletions

View File

@@ -36,7 +36,7 @@ var (
systemMiniMaxTaskPath = regexp.MustCompile(`^/v2/query/video_generation/[^/]+$`)
openAIPostEndpoints = map[string]bool{
"/responses": true, "/chat/completions": true, "/images/generations": true, "/images/edits": true,
"/audio/speech": true,
"/audio/speech": true, "/messages": true,
}
)
@@ -61,7 +61,7 @@ func authorizeCustomRelay(method string, target *url.URL, apiFormat string, cont
}
apiFormat = strings.ToLower(strings.TrimSpace(apiFormat))
if apiFormat != "openai" && apiFormat != "gemini" {
if apiFormat != "openai" && apiFormat != "gemini" && apiFormat != "claude" {
return errors.New("自定义渠道调用格式无效")
}
if method == http.MethodGet {
@@ -74,7 +74,7 @@ func authorizeCustomRelay(method string, target *url.URL, apiFormat string, cont
allowed := requestPath == "/models" || strings.HasSuffix(requestPath, "/models")
if apiFormat == "openai" {
allowed = allowed || customVideoTaskPath.MatchString(requestPath) || customXAIVideoTaskPath.MatchString(requestPath) || customVideoContentPath.MatchString(requestPath) || customArkVideoTaskPath.MatchString(requestPath) || customMiniMaxTaskPath.MatchString(requestPath)
} else {
} else if apiFormat == "gemini" {
allowed = allowed || customGeminiOperationPath.MatchString(requestPath)
}
if len(query) != 0 || !allowed {
@@ -97,6 +97,12 @@ func authorizeCustomRelay(method string, target *url.URL, apiFormat string, cont
}
return nil
}
if apiFormat == "claude" {
if mediaType != "application/json" || !strings.HasSuffix(requestPath, "/messages") {
return errors.New("Claude 自定义渠道只允许 application/json 的 /messages 请求")
}
return nil
}
if mediaType != "application/json" {
return errors.New("Gemini 自定义渠道生成请求必须使用 application/json")
}
@@ -209,6 +215,8 @@ func interfaceAllowsProxyPath(interfaceType model.ChannelInterfaceType, requestP
return requestPath == "/chat/completions"
case model.ChannelInterfaceOpenAIResponse:
return requestPath == "/responses"
case model.ChannelInterfaceClaudeAPI:
return requestPath == "/messages"
case model.ChannelInterfaceOpenAIImage, model.ChannelInterfaceGrokImage:
return requestPath == "/images/generations" || requestPath == "/images/edits"
case model.ChannelInterfaceVolcengineArkImage: