Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

201 linhas
8.0 KiB

  1. package router
  2. import (
  3. "github.com/QuantumNous/new-api/common"
  4. "github.com/QuantumNous/new-api/common/metrics"
  5. "github.com/QuantumNous/new-api/constant"
  6. "github.com/QuantumNous/new-api/controller"
  7. "github.com/QuantumNous/new-api/middleware"
  8. "github.com/QuantumNous/new-api/relay"
  9. "github.com/QuantumNous/new-api/types"
  10. "github.com/gin-gonic/gin"
  11. )
  12. // relayHandler returns a handler that calls controller.Relay with the given format.
  13. func relayHandler(format types.RelayFormat) gin.HandlerFunc {
  14. return func(c *gin.Context) {
  15. controller.Relay(c, format)
  16. }
  17. }
  18. func SetRelayRouter(router *gin.Engine) {
  19. if metrics.IsEnabled() {
  20. metricsPath := common.GetEnvOrDefaultString("METRICS_PATH", "/metrics")
  21. router.GET(metricsPath, gin.WrapH(metrics.NewMetricsHandler()))
  22. }
  23. router.Use(middleware.CORS())
  24. router.Use(middleware.DecompressRequestMiddleware())
  25. router.Use(middleware.BodyStorageCleanup()) // 清理请求体存储
  26. router.Use(middleware.StatsMiddleware())
  27. // https://platform.openai.com/docs/api-reference/introduction
  28. modelsRouter := router.Group("/v1/models")
  29. modelsRouter.Use(middleware.TokenAuth())
  30. {
  31. modelsRouter.GET("", func(c *gin.Context) {
  32. switch {
  33. case c.GetHeader("x-api-key") != "" && c.GetHeader("anthropic-version") != "":
  34. controller.ListModels(c, constant.ChannelTypeAnthropic)
  35. case c.GetHeader("x-goog-api-key") != "" || c.Query("key") != "": // 单独的适配
  36. controller.RetrieveModel(c, constant.ChannelTypeGemini)
  37. default:
  38. controller.ListModels(c, constant.ChannelTypeOpenAI)
  39. }
  40. })
  41. modelsRouter.GET("/:model", func(c *gin.Context) {
  42. switch {
  43. case c.GetHeader("x-api-key") != "" && c.GetHeader("anthropic-version") != "":
  44. controller.RetrieveModel(c, constant.ChannelTypeAnthropic)
  45. default:
  46. controller.RetrieveModel(c, constant.ChannelTypeOpenAI)
  47. }
  48. })
  49. }
  50. geminiRouter := router.Group("/v1beta/models")
  51. geminiRouter.Use(middleware.TokenAuth())
  52. {
  53. geminiRouter.GET("", func(c *gin.Context) {
  54. controller.ListModels(c, constant.ChannelTypeGemini)
  55. })
  56. }
  57. geminiCompatibleRouter := router.Group("/v1beta/openai/models")
  58. geminiCompatibleRouter.Use(middleware.TokenAuth())
  59. {
  60. geminiCompatibleRouter.GET("", func(c *gin.Context) {
  61. controller.ListModels(c, constant.ChannelTypeOpenAI)
  62. })
  63. }
  64. playgroundRouter := router.Group("/pg")
  65. playgroundRouter.Use(middleware.SystemPerformanceCheck())
  66. playgroundRouter.Use(middleware.UserAuth(), middleware.Distribute())
  67. {
  68. playgroundRouter.POST("/chat/completions", controller.Playground)
  69. }
  70. relayV1Router := router.Group("/v1")
  71. relayV1Router.Use(middleware.SystemPerformanceCheck())
  72. relayV1Router.Use(middleware.TokenAuth())
  73. relayV1Router.Use(middleware.ModelRequestRateLimit())
  74. relayV1Router.Use(middleware.RelayCaptureMiddleware())
  75. {
  76. // WebSocket 路由(统一到 Relay)
  77. wsRouter := relayV1Router.Group("")
  78. wsRouter.Use(middleware.Distribute())
  79. wsRouter.Use(middleware.EndpointFormatGuard())
  80. wsRouter.GET("/realtime", relayHandler(types.RelayFormatOpenAIRealtime))
  81. }
  82. {
  83. //http router
  84. httpRouter := relayV1Router.Group("")
  85. httpRouter.Use(middleware.Distribute())
  86. httpRouter.Use(middleware.EndpointFormatGuard())
  87. httpRouter.Use(middleware.UserModelRateLimit())
  88. // claude related routes
  89. httpRouter.POST("/messages", relayHandler(types.RelayFormatClaude))
  90. // chat related routes
  91. httpRouter.POST("/completions", relayHandler(types.RelayFormatOpenAI))
  92. httpRouter.POST("/chat/completions", relayHandler(types.RelayFormatOpenAI))
  93. // response related routes
  94. httpRouter.POST("/responses", relayHandler(types.RelayFormatOpenAIResponses))
  95. httpRouter.POST("/responses/compact", relayHandler(types.RelayFormatOpenAIResponsesCompaction))
  96. // image related routes
  97. httpRouter.POST("/edits", relayHandler(types.RelayFormatOpenAIImage))
  98. httpRouter.POST("/images/generations", relayHandler(types.RelayFormatOpenAIImage))
  99. httpRouter.POST("/images/edits", relayHandler(types.RelayFormatOpenAIImage))
  100. // embedding related routes
  101. httpRouter.POST("/embeddings", relayHandler(types.RelayFormatEmbedding))
  102. // audio related routes
  103. httpRouter.POST("/audio/transcriptions", relayHandler(types.RelayFormatOpenAIAudio))
  104. httpRouter.POST("/audio/translations", relayHandler(types.RelayFormatOpenAIAudio))
  105. httpRouter.POST("/audio/speech", relayHandler(types.RelayFormatOpenAIAudio))
  106. // rerank related routes
  107. httpRouter.POST("/rerank", relayHandler(types.RelayFormatRerank))
  108. // gemini relay routes
  109. httpRouter.POST("/engines/:model/embeddings", relayHandler(types.RelayFormatGemini))
  110. httpRouter.POST("/models/*path", relayHandler(types.RelayFormatGemini))
  111. // other relay routes
  112. httpRouter.POST("/moderations", relayHandler(types.RelayFormatOpenAI))
  113. // not implemented
  114. httpRouter.POST("/images/variations", controller.RelayNotImplemented)
  115. httpRouter.GET("/files", controller.RelayNotImplemented)
  116. httpRouter.POST("/files", controller.RelayNotImplemented)
  117. httpRouter.DELETE("/files/:id", controller.RelayNotImplemented)
  118. httpRouter.GET("/files/:id", controller.RelayNotImplemented)
  119. httpRouter.GET("/files/:id/content", controller.RelayNotImplemented)
  120. httpRouter.POST("/fine-tunes", controller.RelayNotImplemented)
  121. httpRouter.GET("/fine-tunes", controller.RelayNotImplemented)
  122. httpRouter.GET("/fine-tunes/:id", controller.RelayNotImplemented)
  123. httpRouter.POST("/fine-tunes/:id/cancel", controller.RelayNotImplemented)
  124. httpRouter.GET("/fine-tunes/:id/events", controller.RelayNotImplemented)
  125. httpRouter.DELETE("/models/:model", controller.RelayNotImplemented)
  126. }
  127. relayMjRouter := router.Group("/mj")
  128. relayMjRouter.Use(middleware.SystemPerformanceCheck())
  129. registerMjRouterGroup(relayMjRouter)
  130. relayMjModeRouter := router.Group("/:mode/mj")
  131. relayMjModeRouter.Use(middleware.SystemPerformanceCheck())
  132. registerMjRouterGroup(relayMjModeRouter)
  133. //relayMjRouter.Use()
  134. relaySunoRouter := router.Group("/suno")
  135. relaySunoRouter.Use(middleware.SystemPerformanceCheck())
  136. relaySunoRouter.Use(middleware.TokenAuth(), middleware.Distribute())
  137. {
  138. relaySunoRouter.POST("/submit/:action", controller.RelayTask)
  139. relaySunoRouter.POST("/fetch", controller.RelayTaskFetch)
  140. relaySunoRouter.GET("/fetch/:id", controller.RelayTaskFetch)
  141. }
  142. relayGeminiRouter := router.Group("/v1beta")
  143. relayGeminiRouter.Use(middleware.SystemPerformanceCheck())
  144. relayGeminiRouter.Use(middleware.TokenAuth())
  145. relayGeminiRouter.Use(middleware.ModelRequestRateLimit())
  146. relayGeminiRouter.Use(middleware.RelayCaptureMiddleware())
  147. relayGeminiRouter.Use(middleware.Distribute())
  148. relayGeminiRouter.Use(middleware.EndpointFormatGuard())
  149. relayGeminiRouter.Use(middleware.UserModelRateLimit())
  150. {
  151. // Gemini API 路径格式: /v1beta/models/{model_name}:{action}
  152. relayGeminiRouter.POST("/models/*path", relayHandler(types.RelayFormatGemini))
  153. }
  154. }
  155. func registerMjRouterGroup(relayMjRouter *gin.RouterGroup) {
  156. relayMjRouter.GET("/image/:id", relay.RelayMidjourneyImage)
  157. relayMjRouter.Use(middleware.TokenAuth(), middleware.Distribute())
  158. {
  159. relayMjRouter.POST("/submit/action", controller.RelayMidjourney)
  160. relayMjRouter.POST("/submit/shorten", controller.RelayMidjourney)
  161. relayMjRouter.POST("/submit/modal", controller.RelayMidjourney)
  162. relayMjRouter.POST("/submit/imagine", controller.RelayMidjourney)
  163. relayMjRouter.POST("/submit/change", controller.RelayMidjourney)
  164. relayMjRouter.POST("/submit/simple-change", controller.RelayMidjourney)
  165. relayMjRouter.POST("/submit/describe", controller.RelayMidjourney)
  166. relayMjRouter.POST("/submit/blend", controller.RelayMidjourney)
  167. relayMjRouter.POST("/submit/edits", controller.RelayMidjourney)
  168. relayMjRouter.POST("/submit/video", controller.RelayMidjourney)
  169. relayMjRouter.POST("/notify", controller.RelayMidjourney)
  170. relayMjRouter.GET("/task/:id/fetch", controller.RelayMidjourney)
  171. relayMjRouter.GET("/task/:id/image-seed", controller.RelayMidjourney)
  172. relayMjRouter.POST("/task/list-by-condition", controller.RelayMidjourney)
  173. relayMjRouter.POST("/insight-face/swap", controller.RelayMidjourney)
  174. relayMjRouter.POST("/submit/upload-discord-images", controller.RelayMidjourney)
  175. }
  176. }