relay_info.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package common
  2. import (
  3. "one-api/common"
  4. "one-api/constant"
  5. "one-api/dto"
  6. relayconstant "one-api/relay/constant"
  7. "strings"
  8. "time"
  9. "github.com/gin-gonic/gin"
  10. "github.com/gorilla/websocket"
  11. )
  12. type ThinkingContentInfo struct {
  13. IsFirstThinkingContent bool
  14. SendLastThinkingContent bool
  15. HasSentThinkingContent bool
  16. }
  17. const (
  18. LastMessageTypeNone = "none"
  19. LastMessageTypeText = "text"
  20. LastMessageTypeTools = "tools"
  21. LastMessageTypeThinking = "thinking"
  22. )
  23. type ClaudeConvertInfo struct {
  24. LastMessagesType string
  25. Index int
  26. Usage *dto.Usage
  27. FinishReason string
  28. Done bool
  29. }
  30. const (
  31. RelayFormatOpenAI = "openai"
  32. RelayFormatClaude = "claude"
  33. )
  34. type RerankerInfo struct {
  35. Documents []any
  36. ReturnDocuments bool
  37. }
  38. type RelayInfo struct {
  39. ChannelType int
  40. ChannelId int
  41. TokenId int
  42. TokenKey string
  43. UserId int
  44. Group string
  45. TokenUnlimited bool
  46. StartTime time.Time
  47. FirstResponseTime time.Time
  48. isFirstResponse bool
  49. //SendLastReasoningResponse bool
  50. ApiType int
  51. IsStream bool
  52. IsPlayground bool
  53. UsePrice bool
  54. RelayMode int
  55. UpstreamModelName string
  56. OriginModelName string
  57. //RecodeModelName string
  58. RequestURLPath string
  59. ApiVersion string
  60. PromptTokens int
  61. ApiKey string
  62. Organization string
  63. BaseUrl string
  64. SupportStreamOptions bool
  65. ShouldIncludeUsage bool
  66. IsModelMapped bool
  67. ClientWs *websocket.Conn
  68. TargetWs *websocket.Conn
  69. InputAudioFormat string
  70. OutputAudioFormat string
  71. RealtimeTools []dto.RealTimeTool
  72. IsFirstRequest bool
  73. AudioUsage bool
  74. ReasoningEffort string
  75. ChannelSetting map[string]interface{}
  76. ParamOverride map[string]interface{}
  77. UserSetting map[string]interface{}
  78. UserEmail string
  79. UserQuota int
  80. RelayFormat string
  81. SendResponseCount int
  82. ThinkingContentInfo
  83. *ClaudeConvertInfo
  84. *RerankerInfo
  85. }
  86. // 定义支持流式选项的通道类型
  87. var streamSupportedChannels = map[int]bool{
  88. common.ChannelTypeOpenAI: true,
  89. common.ChannelTypeAnthropic: true,
  90. common.ChannelTypeAws: true,
  91. common.ChannelTypeGemini: true,
  92. common.ChannelCloudflare: true,
  93. common.ChannelTypeAzure: true,
  94. common.ChannelTypeVolcEngine: true,
  95. common.ChannelTypeOllama: true,
  96. common.ChannelTypeXai: true,
  97. }
  98. func GenRelayInfoWs(c *gin.Context, ws *websocket.Conn) *RelayInfo {
  99. info := GenRelayInfo(c)
  100. info.ClientWs = ws
  101. info.InputAudioFormat = "pcm16"
  102. info.OutputAudioFormat = "pcm16"
  103. info.IsFirstRequest = true
  104. return info
  105. }
  106. func GenRelayInfoClaude(c *gin.Context) *RelayInfo {
  107. info := GenRelayInfo(c)
  108. info.RelayFormat = RelayFormatClaude
  109. info.ShouldIncludeUsage = false
  110. info.ClaudeConvertInfo = &ClaudeConvertInfo{
  111. LastMessagesType: LastMessageTypeNone,
  112. }
  113. return info
  114. }
  115. func GenRelayInfoRerank(c *gin.Context, req *dto.RerankRequest) *RelayInfo {
  116. info := GenRelayInfo(c)
  117. info.RelayMode = relayconstant.RelayModeRerank
  118. info.RerankerInfo = &RerankerInfo{
  119. Documents: req.Documents,
  120. ReturnDocuments: req.GetReturnDocuments(),
  121. }
  122. return info
  123. }
  124. func GenRelayInfo(c *gin.Context) *RelayInfo {
  125. channelType := c.GetInt("channel_type")
  126. channelId := c.GetInt("channel_id")
  127. channelSetting := c.GetStringMap("channel_setting")
  128. paramOverride := c.GetStringMap("param_override")
  129. tokenId := c.GetInt("token_id")
  130. tokenKey := c.GetString("token_key")
  131. userId := c.GetInt("id")
  132. group := c.GetString("group")
  133. tokenUnlimited := c.GetBool("token_unlimited_quota")
  134. startTime := c.GetTime(constant.ContextKeyRequestStartTime)
  135. // firstResponseTime = time.Now() - 1 second
  136. apiType, _ := relayconstant.ChannelType2APIType(channelType)
  137. info := &RelayInfo{
  138. UserQuota: c.GetInt(constant.ContextKeyUserQuota),
  139. UserSetting: c.GetStringMap(constant.ContextKeyUserSetting),
  140. UserEmail: c.GetString(constant.ContextKeyUserEmail),
  141. isFirstResponse: true,
  142. RelayMode: relayconstant.Path2RelayMode(c.Request.URL.Path),
  143. BaseUrl: c.GetString("base_url"),
  144. RequestURLPath: c.Request.URL.String(),
  145. ChannelType: channelType,
  146. ChannelId: channelId,
  147. TokenId: tokenId,
  148. TokenKey: tokenKey,
  149. UserId: userId,
  150. Group: group,
  151. TokenUnlimited: tokenUnlimited,
  152. StartTime: startTime,
  153. FirstResponseTime: startTime.Add(-time.Second),
  154. OriginModelName: c.GetString("original_model"),
  155. UpstreamModelName: c.GetString("original_model"),
  156. //RecodeModelName: c.GetString("original_model"),
  157. IsModelMapped: false,
  158. ApiType: apiType,
  159. ApiVersion: c.GetString("api_version"),
  160. ApiKey: strings.TrimPrefix(c.Request.Header.Get("Authorization"), "Bearer "),
  161. Organization: c.GetString("channel_organization"),
  162. ChannelSetting: channelSetting,
  163. ParamOverride: paramOverride,
  164. RelayFormat: RelayFormatOpenAI,
  165. ThinkingContentInfo: ThinkingContentInfo{
  166. IsFirstThinkingContent: true,
  167. SendLastThinkingContent: false,
  168. },
  169. }
  170. if strings.HasPrefix(c.Request.URL.Path, "/pg") {
  171. info.IsPlayground = true
  172. info.RequestURLPath = strings.TrimPrefix(info.RequestURLPath, "/pg")
  173. info.RequestURLPath = "/v1" + info.RequestURLPath
  174. }
  175. if info.BaseUrl == "" {
  176. info.BaseUrl = common.ChannelBaseURLs[channelType]
  177. }
  178. if info.ChannelType == common.ChannelTypeAzure {
  179. info.ApiVersion = GetAPIVersion(c)
  180. }
  181. if info.ChannelType == common.ChannelTypeVertexAi {
  182. info.ApiVersion = c.GetString("region")
  183. }
  184. if streamSupportedChannels[info.ChannelType] {
  185. info.SupportStreamOptions = true
  186. }
  187. // responses 模式不支持 StreamOptions
  188. if relayconstant.RelayModeResponses == info.RelayMode {
  189. info.SupportStreamOptions = false
  190. }
  191. return info
  192. }
  193. func (info *RelayInfo) SetPromptTokens(promptTokens int) {
  194. info.PromptTokens = promptTokens
  195. }
  196. func (info *RelayInfo) SetIsStream(isStream bool) {
  197. info.IsStream = isStream
  198. }
  199. func (info *RelayInfo) SetFirstResponseTime() {
  200. if info.isFirstResponse {
  201. info.FirstResponseTime = time.Now()
  202. info.isFirstResponse = false
  203. }
  204. }
  205. func (info *RelayInfo) HasSendResponse() bool {
  206. return info.FirstResponseTime.After(info.StartTime)
  207. }
  208. type TaskRelayInfo struct {
  209. *RelayInfo
  210. Action string
  211. OriginTaskID string
  212. ConsumeQuota bool
  213. }
  214. func GenTaskRelayInfo(c *gin.Context) *TaskRelayInfo {
  215. info := &TaskRelayInfo{
  216. RelayInfo: GenRelayInfo(c),
  217. }
  218. return info
  219. }