You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

194 rivejä
7.7 KiB

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