completions.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package model
  2. import (
  3. "strings"
  4. )
  5. type ResponseFormat struct {
  6. JSONSchema *JSONSchema `json:"json_schema,omitempty"`
  7. Type string `json:"type,omitempty"`
  8. }
  9. type JSONSchema struct {
  10. Schema map[string]any `json:"schema,omitempty"`
  11. Strict *bool `json:"strict,omitempty"`
  12. Description string `json:"description,omitempty"`
  13. Name string `json:"name"`
  14. }
  15. type Audio struct {
  16. Voice string `json:"voice,omitempty"`
  17. Format string `json:"format,omitempty"`
  18. }
  19. type StreamOptions struct {
  20. IncludeUsage bool `json:"include_usage,omitempty"`
  21. }
  22. type GeneralOpenAIRequest struct {
  23. Prompt any `json:"prompt,omitempty"`
  24. Input any `json:"input,omitempty"`
  25. Metadata any `json:"metadata,omitempty"`
  26. Functions any `json:"functions,omitempty"`
  27. LogitBias any `json:"logit_bias,omitempty"`
  28. FunctionCall any `json:"function_call,omitempty"`
  29. ToolChoice any `json:"tool_choice,omitempty"`
  30. Stop any `json:"stop,omitempty"`
  31. TopLogprobs *int `json:"top_logprobs,omitempty"`
  32. PresencePenalty *float64 `json:"presence_penalty,omitempty"`
  33. ResponseFormat *ResponseFormat `json:"response_format,omitempty"`
  34. FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"`
  35. Logprobs *bool `json:"logprobs,omitempty"`
  36. StreamOptions *StreamOptions `json:"stream_options,omitempty"`
  37. Temperature *float64 `json:"temperature,omitempty"`
  38. TopP *float64 `json:"top_p,omitempty"`
  39. Model string `json:"model,omitempty"`
  40. User string `json:"user,omitempty"`
  41. Size string `json:"size,omitempty"`
  42. Messages []Message `json:"messages,omitempty"`
  43. Tools []Tool `json:"tools,omitempty"`
  44. Seed float64 `json:"seed,omitempty"`
  45. MaxTokens int `json:"max_tokens,omitempty"`
  46. MaxCompletionTokens int `json:"max_completion_tokens,omitempty"`
  47. TopK int `json:"top_k,omitempty"`
  48. NumCtx int `json:"num_ctx,omitempty"`
  49. Stream bool `json:"stream,omitempty"`
  50. // aiproxy control field
  51. Thinking *GeneralThinking `json:"thinking,omitempty"`
  52. }
  53. func (r GeneralOpenAIRequest) ParseInput() []string {
  54. if r.Input == nil {
  55. return nil
  56. }
  57. var input []string
  58. switch v := r.Input.(type) {
  59. case string:
  60. input = []string{v}
  61. case []any:
  62. input = make([]string, 0, len(v))
  63. for _, item := range v {
  64. if str, ok := item.(string); ok {
  65. input = append(input, str)
  66. }
  67. }
  68. }
  69. return input
  70. }
  71. type GeneralThinking = ClaudeThinking
  72. type GeneralOpenAIThinkingRequest struct {
  73. Thinking *GeneralThinking `json:"thinking,omitempty"`
  74. }
  75. type ChatCompletionsStreamResponseChoice struct {
  76. FinishReason FinishReason `json:"finish_reason,omitempty"`
  77. Delta Message `json:"delta"`
  78. Index int `json:"index"`
  79. Text string `json:"text,omitempty"`
  80. }
  81. type ChatCompletionsStreamResponse struct {
  82. Usage *ChatUsage `json:"usage,omitempty"`
  83. ID string `json:"id"`
  84. Object string `json:"object"`
  85. Model string `json:"model"`
  86. Choices []*ChatCompletionsStreamResponseChoice `json:"choices"`
  87. Created int64 `json:"created"`
  88. }
  89. type TextResponseChoice struct {
  90. FinishReason FinishReason `json:"finish_reason"`
  91. Message Message `json:"message"`
  92. Index int `json:"index"`
  93. Text string `json:"text,omitempty"`
  94. }
  95. type TextResponse struct {
  96. ID string `json:"id"`
  97. Model string `json:"model,omitempty"`
  98. Object string `json:"object"`
  99. Choices []*TextResponseChoice `json:"choices"`
  100. Usage ChatUsage `json:"usage"`
  101. Created int64 `json:"created"`
  102. }
  103. type Message struct {
  104. Content any `json:"content,omitempty"`
  105. ReasoningContent string `json:"reasoning_content,omitempty"`
  106. Signature string `json:"signature,omitempty"`
  107. Name *string `json:"name,omitempty"`
  108. Role string `json:"role,omitempty"`
  109. ToolCallID string `json:"tool_call_id,omitempty"`
  110. ToolCalls []ToolCall `json:"tool_calls,omitempty"`
  111. }
  112. func (m *Message) IsStringContent() bool {
  113. _, ok := m.Content.(string)
  114. return ok
  115. }
  116. func (m *Message) ToStringContentMessage() {
  117. if m.IsStringContent() {
  118. return
  119. }
  120. m.Content = m.StringContent()
  121. }
  122. func (m *Message) StringContent() string {
  123. if m.ReasoningContent != "" {
  124. return m.ReasoningContent
  125. }
  126. content, ok := m.Content.(string)
  127. if ok {
  128. return content
  129. }
  130. contentList, ok := m.Content.([]any)
  131. if !ok {
  132. return ""
  133. }
  134. var strBuilder strings.Builder
  135. for _, contentItem := range contentList {
  136. contentMap, ok := contentItem.(map[string]any)
  137. if !ok {
  138. continue
  139. }
  140. if contentMap["type"] == ContentTypeText {
  141. if subStr, ok := contentMap["text"].(string); ok {
  142. strBuilder.WriteString(subStr)
  143. strBuilder.WriteString("\n")
  144. }
  145. }
  146. }
  147. return strBuilder.String()
  148. }
  149. func (m *Message) ParseContent() []MessageContent {
  150. var contentList []MessageContent
  151. switch content := m.Content.(type) {
  152. case string:
  153. contentList = append(contentList, MessageContent{
  154. Type: ContentTypeText,
  155. Text: content,
  156. })
  157. return contentList
  158. case []any:
  159. for _, contentItem := range content {
  160. contentMap, ok := contentItem.(map[string]any)
  161. if !ok {
  162. continue
  163. }
  164. switch contentMap["type"] {
  165. case ContentTypeText:
  166. if subStr, ok := contentMap["text"].(string); ok {
  167. contentList = append(contentList, MessageContent{
  168. Type: ContentTypeText,
  169. Text: subStr,
  170. })
  171. }
  172. case ContentTypeImageURL:
  173. if subObj, ok := contentMap["image_url"].(map[string]any); ok {
  174. url, ok := subObj["url"].(string)
  175. if !ok {
  176. continue
  177. }
  178. contentList = append(contentList, MessageContent{
  179. Type: ContentTypeImageURL,
  180. ImageURL: &ImageURL{
  181. URL: url,
  182. },
  183. })
  184. }
  185. }
  186. }
  187. return contentList
  188. case []MessageContent:
  189. for _, contentItem := range content {
  190. switch contentItem.Type {
  191. case ContentTypeText:
  192. contentList = append(contentList, MessageContent{
  193. Type: ContentTypeText,
  194. Text: contentItem.Text,
  195. })
  196. case ContentTypeImageURL:
  197. imageURL := contentItem.ImageURL
  198. if imageURL == nil {
  199. continue
  200. }
  201. contentList = append(contentList, MessageContent{
  202. Type: ContentTypeImageURL,
  203. ImageURL: &ImageURL{
  204. URL: imageURL.URL,
  205. },
  206. })
  207. }
  208. }
  209. return contentList
  210. default:
  211. return nil
  212. }
  213. }
  214. type ImageURL struct {
  215. URL string `json:"url,omitempty"`
  216. Detail string `json:"detail,omitempty"`
  217. }
  218. type MessageContent struct {
  219. ImageURL *ImageURL `json:"image_url,omitempty"`
  220. Type string `json:"type,omitempty"`
  221. Text string `json:"text,omitempty"`
  222. }