relay.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package controller
  2. import (
  3. "fmt"
  4. "github.com/gin-gonic/gin"
  5. "net/http"
  6. "one-api/common"
  7. "strings"
  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.HasPrefix(c.Request.URL.Path, "/v1/moderations") {
  90. relayMode = RelayModeModerations
  91. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
  92. relayMode = RelayModeImagesGenerations
  93. } else if strings.HasPrefix(c.Request.URL.Path, "/v1/edits") {
  94. relayMode = RelayModeEdits
  95. }
  96. var err *OpenAIErrorWithStatusCode
  97. switch relayMode {
  98. case RelayModeImagesGenerations:
  99. err = relayImageHelper(c, relayMode)
  100. default:
  101. err = relayTextHelper(c, relayMode)
  102. }
  103. if err != nil {
  104. if err.StatusCode == http.StatusTooManyRequests {
  105. err.OpenAIError.Message = "当前分组负载已饱和,请稍后再试,或升级账户以提升服务质量。"
  106. }
  107. c.JSON(err.StatusCode, gin.H{
  108. "error": err.OpenAIError,
  109. })
  110. channelId := c.GetInt("channel_id")
  111. common.SysError(fmt.Sprintf("relay error (channel #%d): %s", channelId, err.Message))
  112. // https://platform.openai.com/docs/guides/error-codes/api-errors
  113. if common.AutomaticDisableChannelEnabled && (err.Type == "insufficient_quota" || err.Code == "invalid_api_key") {
  114. channelId := c.GetInt("channel_id")
  115. channelName := c.GetString("channel_name")
  116. disableChannel(channelId, channelName, err.Message)
  117. }
  118. }
  119. }
  120. func RelayNotImplemented(c *gin.Context) {
  121. err := OpenAIError{
  122. Message: "API not implemented",
  123. Type: "one_api_error",
  124. Param: "",
  125. Code: "api_not_implemented",
  126. }
  127. c.JSON(http.StatusNotImplemented, gin.H{
  128. "error": err,
  129. })
  130. }
  131. func RelayNotFound(c *gin.Context) {
  132. err := OpenAIError{
  133. Message: fmt.Sprintf("API not found: %s:%s", c.Request.Method, c.Request.URL.Path),
  134. Type: "one_api_error",
  135. Param: "",
  136. Code: "api_not_found",
  137. }
  138. c.JSON(http.StatusNotFound, gin.H{
  139. "error": err,
  140. })
  141. }