relay.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package controller
  2. import (
  3. "fmt"
  4. "net/http"
  5. "one-api/common"
  6. "strings"
  7. "github.com/gin-gonic/gin"
  8. )
  9. type Message struct {
  10. Role string `json:"role"`
  11. Content string `json:"content"`
  12. Name *string `json:"name,omitempty"`
  13. }
  14. const (
  15. RelayModeUnknown = iota
  16. RelayModeChatCompletions
  17. RelayModeCompletions
  18. RelayModeEmbeddings
  19. RelayModeModerations
  20. RelayModeImagesGenerations
  21. RelayModeEdits
  22. )
  23. // https://platform.openai.com/docs/api-reference/chat
  24. type GeneralOpenAIRequest struct {
  25. Model string `json:"model,omitempty"`
  26. Messages []Message `json:"messages,omitempty"`
  27. Prompt any `json:"prompt,omitempty"`
  28. Stream bool `json:"stream,omitempty"`
  29. MaxTokens int `json:"max_tokens,omitempty"`
  30. Temperature float64 `json:"temperature,omitempty"`
  31. TopP float64 `json:"top_p,omitempty"`
  32. N int `json:"n,omitempty"`
  33. Input any `json:"input,omitempty"`
  34. Instruction string `json:"instruction,omitempty"`
  35. }
  36. type ChatRequest struct {
  37. Model string `json:"model"`
  38. Messages []Message `json:"messages"`
  39. MaxTokens int `json:"max_tokens"`
  40. }
  41. type TextRequest struct {
  42. Model string `json:"model"`
  43. Messages []Message `json:"messages"`
  44. Prompt string `json:"prompt"`
  45. MaxTokens int `json:"max_tokens"`
  46. //Stream bool `json:"stream"`
  47. }
  48. type Usage struct {
  49. PromptTokens int `json:"prompt_tokens"`
  50. CompletionTokens int `json:"completion_tokens"`
  51. TotalTokens int `json:"total_tokens"`
  52. }
  53. type OpenAIError struct {
  54. Message string `json:"message"`
  55. Type string `json:"type"`
  56. Param string `json:"param"`
  57. Code any `json:"code"`
  58. }
  59. type OpenAIErrorWithStatusCode struct {
  60. OpenAIError
  61. StatusCode int `json:"status_code"`
  62. }
  63. type TextResponse struct {
  64. Usage `json:"usage"`
  65. Error OpenAIError `json:"error"`
  66. }
  67. type ChatCompletionsStreamResponse struct {
  68. Choices []struct {
  69. Delta struct {
  70. Content string `json:"content"`
  71. } `json:"delta"`
  72. FinishReason string `json:"finish_reason"`
  73. } `json:"choices"`
  74. }
  75. type CompletionsStreamResponse struct {
  76. Choices []struct {
  77. Text string `json:"text"`
  78. FinishReason string `json:"finish_reason"`
  79. } `json:"choices"`
  80. }
  81. func Relay(c *gin.Context) {
  82. relayMode := RelayModeUnknown
  83. if strings.HasPrefix(c.Request.URL.Path, "/v1/chat/completions") {
  84. relayMode = RelayModeChatCompletions
  85. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/completions") {
  86. relayMode = RelayModeCompletions
  87. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/embeddings") {
  88. relayMode = RelayModeEmbeddings
  89. } else if strings.HasSuffix(c.Request.URL.Path, "embeddings") {
  90. relayMode = RelayModeEmbeddings
  91. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/moderations") {
  92. relayMode = RelayModeModerations
  93. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
  94. relayMode = RelayModeImagesGenerations
  95. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/edits") {
  96. relayMode = RelayModeEdits
  97. }
  98. var err *OpenAIErrorWithStatusCode
  99. switch relayMode {
  100. case RelayModeImagesGenerations:
  101. err = relayImageHelper(c, relayMode)
  102. default:
  103. err = relayTextHelper(c, relayMode)
  104. }
  105. if err != nil {
  106. if err.StatusCode == http.StatusTooManyRequests {
  107. err.OpenAIError.Message = "当前分组负载已饱和,请稍后再试,或升级账户以提升服务质量。"
  108. }
  109. c.JSON(err.StatusCode, gin.H{
  110. "error": err.OpenAIError,
  111. })
  112. channelId := c.GetInt("channel_id")
  113. common.SysError(fmt.Sprintf("relay error (channel #%d): %s", channelId, err.Message))
  114. // https://platform.openai.com/docs/guides/error-codes/api-errors
  115. if common.AutomaticDisableChannelEnabled && (err.Type == "insufficient_quota" || err.Code == "invalid_api_key" || err.Code == "account_deactivated") {
  116. channelId := c.GetInt("channel_id")
  117. channelName := c.GetString("channel_name")
  118. disableChannel(channelId, channelName, err.Message)
  119. }
  120. }
  121. }
  122. func RelayNotImplemented(c *gin.Context) {
  123. err := OpenAIError{
  124. Message: "API not implemented",
  125. Type: "one_api_error",
  126. Param: "",
  127. Code: "api_not_implemented",
  128. }
  129. c.JSON(http.StatusNotImplemented, gin.H{
  130. "error": err,
  131. })
  132. }
  133. func RelayNotFound(c *gin.Context) {
  134. err := OpenAIError{
  135. Message: fmt.Sprintf("API not found: %s:%s", c.Request.Method, c.Request.URL.Path),
  136. Type: "one_api_error",
  137. Param: "",
  138. Code: "api_not_found",
  139. }
  140. c.JSON(http.StatusNotFound, gin.H{
  141. "error": err,
  142. })
  143. }