relay-router.go 8.2 KB

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