import.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package controller
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/gin-gonic/gin"
  6. "github.com/labring/aiproxy/core/middleware"
  7. "github.com/labring/aiproxy/core/model"
  8. "gorm.io/gorm"
  9. )
  10. type OneAPIChannel struct {
  11. Type int `gorm:"default:0" json:"type"`
  12. Key string `gorm:"type:text" json:"key"`
  13. Status int `gorm:"default:1" json:"status"`
  14. Name string `gorm:"index" json:"name"`
  15. BaseURL string `gorm:"column:base_url;default:''"`
  16. Models string ` json:"models"`
  17. ModelMapping map[string]string `gorm:"type:varchar(1024);serializer:fastjson"`
  18. Priority int32 `gorm:"bigint;default:0"`
  19. Config ChannelConfig `gorm:"serializer:fastjson"`
  20. }
  21. func (c *OneAPIChannel) TableName() string {
  22. return "channels"
  23. }
  24. type ChannelConfig struct {
  25. Region string `json:"region,omitempty"`
  26. SK string `json:"sk,omitempty"`
  27. AK string `json:"ak,omitempty"`
  28. UserID string `json:"user_id,omitempty"`
  29. APIVersion string `json:"api_version,omitempty"`
  30. LibraryID string `json:"library_id,omitempty"`
  31. VertexAIProjectID string `json:"vertex_ai_project_id,omitempty"`
  32. VertexAIADC string `json:"vertex_ai_adc,omitempty"`
  33. }
  34. // https://github.com/songquanpeng/one-api/blob/main/relay/channeltype/define.go
  35. const (
  36. OneAPIOpenAI = iota + 1
  37. OneAPIAPI2D
  38. OneAPIAzure
  39. OneAPICloseAI
  40. OneAPIOpenAISB
  41. OneAPIOpenAIMax
  42. OneAPIOhMyGPT
  43. OneAPICustom
  44. OneAPIAils
  45. OneAPIAIProxy
  46. OneAPIPaLM
  47. OneAPIAPI2GPT
  48. OneAPIAIGC2D
  49. OneAPIAnthropic
  50. OneAPIBaidu
  51. OneAPIZhipu
  52. OneAPIAli
  53. OneAPIXunfei
  54. OneAPIAI360
  55. OneAPIOpenRouter
  56. OneAPIAIProxyLibrary
  57. OneAPIFastGPT
  58. OneAPITencent
  59. OneAPIGemini
  60. OneAPIMoonshot
  61. OneAPIBaichuan
  62. OneAPIMinimax
  63. OneAPIMistral
  64. OneAPIGroq
  65. OneAPIOllama
  66. OneAPILingYiWanWu
  67. OneAPIStepFun
  68. OneAPIAwsClaude
  69. OneAPICoze
  70. OneAPICohere
  71. OneAPIDeepSeek
  72. OneAPICloudflare
  73. OneAPIDeepL
  74. OneAPITogetherAI
  75. OneAPIDoubao
  76. OneAPINovita
  77. OneAPIVertextAI
  78. OneAPIProxy
  79. OneAPISiliconFlow
  80. OneAPIXAI
  81. OneAPIReplicate
  82. OneAPIBaiduV2
  83. OneAPIXunfeiV2
  84. OneAPIAliBailian
  85. OneAPIOpenAICompatible
  86. OneAPIGeminiOpenAICompatible
  87. )
  88. var OneAPIChannelType2AIProxyMap = map[int]model.ChannelType{
  89. OneAPIOpenAI: model.ChannelTypeOpenAI,
  90. OneAPIAzure: model.ChannelTypeAzure,
  91. OneAPIAnthropic: model.ChannelTypeAnthropic,
  92. OneAPIBaidu: model.ChannelTypeBaidu,
  93. OneAPIZhipu: model.ChannelTypeZhipu,
  94. OneAPIAli: model.ChannelTypeAli,
  95. OneAPIAI360: model.ChannelTypeAI360,
  96. OneAPIOpenRouter: model.ChannelTypeOpenRouter,
  97. OneAPITencent: model.ChannelTypeTencent,
  98. OneAPIGemini: model.ChannelTypeGoogleGemini,
  99. OneAPIMoonshot: model.ChannelTypeMoonshot,
  100. OneAPIBaichuan: model.ChannelTypeBaichuan,
  101. OneAPIMinimax: model.ChannelTypeMinimax,
  102. OneAPIMistral: model.ChannelTypeMistral,
  103. OneAPIGroq: model.ChannelTypeGroq,
  104. OneAPIOllama: model.ChannelTypeOllama,
  105. OneAPILingYiWanWu: model.ChannelTypeLingyiwanwu,
  106. OneAPIStepFun: model.ChannelTypeStepfun,
  107. OneAPIAwsClaude: model.ChannelTypeAWS,
  108. OneAPICoze: model.ChannelTypeCoze,
  109. OneAPICohere: model.ChannelTypeCohere,
  110. OneAPIDeepSeek: model.ChannelTypeDeepseek,
  111. OneAPICloudflare: model.ChannelTypeCloudflare,
  112. OneAPIDoubao: model.ChannelTypeDoubao,
  113. OneAPINovita: model.ChannelTypeNovita,
  114. OneAPIVertextAI: model.ChannelTypeVertexAI,
  115. OneAPISiliconFlow: model.ChannelTypeSiliconflow,
  116. OneAPIBaiduV2: model.ChannelTypeBaiduV2,
  117. OneAPIXunfeiV2: model.ChannelTypeXunfei,
  118. OneAPIAliBailian: model.ChannelTypeAli,
  119. OneAPIGeminiOpenAICompatible: model.ChannelTypeGoogleGeminiOpenAI,
  120. OneAPIXAI: model.ChannelTypeXAI,
  121. }
  122. type ImportChannelFromOneAPIRequest struct {
  123. DSN string `json:"dsn"`
  124. }
  125. func AddOneAPIChannel(ch OneAPIChannel) error {
  126. add := AddChannelRequest{
  127. Type: model.ChannelType(ch.Type),
  128. Name: ch.Name,
  129. Key: ch.Key,
  130. BaseURL: ch.BaseURL,
  131. Models: strings.Split(ch.Models, ","),
  132. ModelMapping: ch.ModelMapping,
  133. Priority: ch.Priority,
  134. Status: ch.Status,
  135. }
  136. if t, ok := OneAPIChannelType2AIProxyMap[ch.Type]; ok {
  137. add.Type = t
  138. } else {
  139. add.Type = 1
  140. }
  141. if add.Type == 1 && add.BaseURL != "" {
  142. add.BaseURL += "/v1"
  143. }
  144. chs, err := add.ToChannels()
  145. if err != nil {
  146. return err
  147. }
  148. return model.BatchInsertChannels(chs)
  149. }
  150. // ImportChannelFromOneAPI godoc
  151. //
  152. // @Summary Import channel from OneAPI
  153. // @Description Imports channels from OneAPI
  154. // @Tags channels
  155. // @Produce json
  156. // @Security ApiKeyAuth
  157. // @Param request body ImportChannelFromOneAPIRequest true "Import channel from OneAPI request"
  158. // @Success 200 {object} middleware.APIResponse{data=[]error}
  159. // @Router /api/channels/import/oneapi [post]
  160. func ImportChannelFromOneAPI(c *gin.Context) {
  161. var req ImportChannelFromOneAPIRequest
  162. if err := c.ShouldBindJSON(&req); err != nil {
  163. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  164. return
  165. }
  166. if req.DSN == "" {
  167. middleware.ErrorResponse(c, http.StatusBadRequest, "sql dsn is required")
  168. return
  169. }
  170. var (
  171. db *gorm.DB
  172. err error
  173. )
  174. switch {
  175. case strings.HasPrefix(req.DSN, "mysql"):
  176. db, err = model.OpenMySQL(req.DSN)
  177. case strings.HasPrefix(req.DSN, "postgres"):
  178. db, err = model.OpenPostgreSQL(req.DSN)
  179. default:
  180. middleware.ErrorResponse(
  181. c,
  182. http.StatusBadRequest,
  183. "invalid dsn, only mysql and postgres are supported",
  184. )
  185. return
  186. }
  187. if err != nil {
  188. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  189. return
  190. }
  191. sqlDB, err := db.DB()
  192. if err != nil {
  193. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  194. return
  195. }
  196. defer sqlDB.Close()
  197. allChannels := make([]*OneAPIChannel, 0)
  198. err = db.Model(&OneAPIChannel{}).Find(&allChannels).Error
  199. if err != nil {
  200. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  201. return
  202. }
  203. errs := make([]error, 0)
  204. for _, ch := range allChannels {
  205. err := AddOneAPIChannel(*ch)
  206. if err != nil {
  207. errs = append(errs, err)
  208. }
  209. }
  210. middleware.SuccessResponse(c, errs)
  211. }