Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

207 wiersze
8.2 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. if metrics.IsEnabled() {
  74. relayV1Router.Use(metrics.MetricsMiddleware(metrics.GetMetrics()))
  75. }
  76. relayV1Router.Use(middleware.ModelRequestRateLimit())
  77. relayV1Router.Use(middleware.RelayCaptureMiddleware())
  78. {
  79. // WebSocket 路由(统一到 Relay)
  80. wsRouter := relayV1Router.Group("")
  81. wsRouter.Use(middleware.Distribute())
  82. wsRouter.Use(middleware.EndpointFormatGuard())
  83. wsRouter.GET("/realtime", relayHandler(types.RelayFormatOpenAIRealtime))
  84. }
  85. {
  86. //http router
  87. httpRouter := relayV1Router.Group("")
  88. httpRouter.Use(middleware.Distribute())
  89. httpRouter.Use(middleware.EndpointFormatGuard())
  90. httpRouter.Use(middleware.UserModelRateLimit())
  91. // claude related routes
  92. httpRouter.POST("/messages", relayHandler(types.RelayFormatClaude))
  93. // chat related routes
  94. httpRouter.POST("/completions", relayHandler(types.RelayFormatOpenAI))
  95. httpRouter.POST("/chat/completions", relayHandler(types.RelayFormatOpenAI))
  96. // response related routes
  97. httpRouter.POST("/responses", relayHandler(types.RelayFormatOpenAIResponses))
  98. httpRouter.POST("/responses/compact", relayHandler(types.RelayFormatOpenAIResponsesCompaction))
  99. // image related routes
  100. httpRouter.POST("/edits", relayHandler(types.RelayFormatOpenAIImage))
  101. httpRouter.POST("/images/generations", relayHandler(types.RelayFormatOpenAIImage))
  102. httpRouter.POST("/images/edits", relayHandler(types.RelayFormatOpenAIImage))
  103. // embedding related routes
  104. httpRouter.POST("/embeddings", relayHandler(types.RelayFormatEmbedding))
  105. // audio related routes
  106. httpRouter.POST("/audio/transcriptions", relayHandler(types.RelayFormatOpenAIAudio))
  107. httpRouter.POST("/audio/translations", relayHandler(types.RelayFormatOpenAIAudio))
  108. httpRouter.POST("/audio/speech", relayHandler(types.RelayFormatOpenAIAudio))
  109. // rerank related routes
  110. httpRouter.POST("/rerank", relayHandler(types.RelayFormatRerank))
  111. // gemini relay routes
  112. httpRouter.POST("/engines/:model/embeddings", relayHandler(types.RelayFormatGemini))
  113. httpRouter.POST("/models/*path", relayHandler(types.RelayFormatGemini))
  114. // other relay routes
  115. httpRouter.POST("/moderations", relayHandler(types.RelayFormatOpenAI))
  116. // not implemented
  117. httpRouter.POST("/images/variations", controller.RelayNotImplemented)
  118. httpRouter.GET("/files", controller.RelayNotImplemented)
  119. httpRouter.POST("/files", controller.RelayNotImplemented)
  120. httpRouter.DELETE("/files/:id", controller.RelayNotImplemented)
  121. httpRouter.GET("/files/:id", controller.RelayNotImplemented)
  122. httpRouter.GET("/files/:id/content", controller.RelayNotImplemented)
  123. httpRouter.POST("/fine-tunes", controller.RelayNotImplemented)
  124. httpRouter.GET("/fine-tunes", controller.RelayNotImplemented)
  125. httpRouter.GET("/fine-tunes/:id", controller.RelayNotImplemented)
  126. httpRouter.POST("/fine-tunes/:id/cancel", controller.RelayNotImplemented)
  127. httpRouter.GET("/fine-tunes/:id/events", controller.RelayNotImplemented)
  128. httpRouter.DELETE("/models/:model", controller.RelayNotImplemented)
  129. }
  130. relayMjRouter := router.Group("/mj")
  131. relayMjRouter.Use(middleware.SystemPerformanceCheck())
  132. registerMjRouterGroup(relayMjRouter)
  133. relayMjModeRouter := router.Group("/:mode/mj")
  134. relayMjModeRouter.Use(middleware.SystemPerformanceCheck())
  135. registerMjRouterGroup(relayMjModeRouter)
  136. //relayMjRouter.Use()
  137. relaySunoRouter := router.Group("/suno")
  138. relaySunoRouter.Use(middleware.SystemPerformanceCheck())
  139. relaySunoRouter.Use(middleware.TokenAuth(), middleware.Distribute())
  140. {
  141. relaySunoRouter.POST("/submit/:action", controller.RelayTask)
  142. relaySunoRouter.POST("/fetch", controller.RelayTaskFetch)
  143. relaySunoRouter.GET("/fetch/:id", controller.RelayTaskFetch)
  144. }
  145. relayGeminiRouter := router.Group("/v1beta")
  146. relayGeminiRouter.Use(middleware.SystemPerformanceCheck())
  147. relayGeminiRouter.Use(middleware.TokenAuth())
  148. if metrics.IsEnabled() {
  149. relayGeminiRouter.Use(metrics.MetricsMiddleware(metrics.GetMetrics()))
  150. }
  151. relayGeminiRouter.Use(middleware.ModelRequestRateLimit())
  152. relayGeminiRouter.Use(middleware.RelayCaptureMiddleware())
  153. relayGeminiRouter.Use(middleware.Distribute())
  154. relayGeminiRouter.Use(middleware.EndpointFormatGuard())
  155. relayGeminiRouter.Use(middleware.UserModelRateLimit())
  156. {
  157. // Gemini API 路径格式: /v1beta/models/{model_name}:{action}
  158. relayGeminiRouter.POST("/models/*path", relayHandler(types.RelayFormatGemini))
  159. }
  160. }
  161. func registerMjRouterGroup(relayMjRouter *gin.RouterGroup) {
  162. relayMjRouter.GET("/image/:id", relay.RelayMidjourneyImage)
  163. relayMjRouter.Use(middleware.TokenAuth(), middleware.Distribute())
  164. {
  165. relayMjRouter.POST("/submit/action", controller.RelayMidjourney)
  166. relayMjRouter.POST("/submit/shorten", controller.RelayMidjourney)
  167. relayMjRouter.POST("/submit/modal", controller.RelayMidjourney)
  168. relayMjRouter.POST("/submit/imagine", controller.RelayMidjourney)
  169. relayMjRouter.POST("/submit/change", controller.RelayMidjourney)
  170. relayMjRouter.POST("/submit/simple-change", controller.RelayMidjourney)
  171. relayMjRouter.POST("/submit/describe", controller.RelayMidjourney)
  172. relayMjRouter.POST("/submit/blend", controller.RelayMidjourney)
  173. relayMjRouter.POST("/submit/edits", controller.RelayMidjourney)
  174. relayMjRouter.POST("/submit/video", controller.RelayMidjourney)
  175. relayMjRouter.POST("/notify", controller.RelayMidjourney)
  176. relayMjRouter.GET("/task/:id/fetch", controller.RelayMidjourney)
  177. relayMjRouter.GET("/task/:id/image-seed", controller.RelayMidjourney)
  178. relayMjRouter.POST("/task/list-by-condition", controller.RelayMidjourney)
  179. relayMjRouter.POST("/insight-face/swap", controller.RelayMidjourney)
  180. relayMjRouter.POST("/submit/upload-discord-images", controller.RelayMidjourney)
  181. }
  182. }