response.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. package model
  2. import (
  3. "github.com/labring/aiproxy/core/model"
  4. )
  5. // InputItemType represents the type of an input item
  6. type InputItemType = string
  7. const (
  8. InputItemTypeMessage InputItemType = "message"
  9. InputItemTypeFunctionCall InputItemType = "function_call"
  10. InputItemTypeFunctionCallOutput InputItemType = "function_call_output"
  11. )
  12. // InputContentType represents the type of input content
  13. type InputContentType = string
  14. const (
  15. InputContentTypeInputText InputContentType = "input_text"
  16. InputContentTypeOutputText InputContentType = "output_text"
  17. )
  18. // OutputContentType represents the type of output content
  19. type OutputContentType = string
  20. const (
  21. OutputContentTypeText OutputContentType = "text"
  22. OutputContentTypeOutputText OutputContentType = "output_text"
  23. )
  24. // ResponseStatus represents the status of a response
  25. type ResponseStatus = string
  26. const (
  27. ResponseStatusInProgress ResponseStatus = "in_progress"
  28. ResponseStatusCompleted ResponseStatus = "completed"
  29. ResponseStatusFailed ResponseStatus = "failed"
  30. ResponseStatusIncomplete ResponseStatus = "incomplete"
  31. ResponseStatusCancelled ResponseStatus = "cancelled"
  32. )
  33. // ResponseStreamEventType represents the type of a response stream event
  34. type ResponseStreamEventType = string
  35. const (
  36. // Response lifecycle events
  37. EventResponseCreated ResponseStreamEventType = "response.created"
  38. EventResponseInProgress ResponseStreamEventType = "response.in_progress"
  39. EventResponseCompleted ResponseStreamEventType = "response.completed"
  40. EventResponseFailed ResponseStreamEventType = "response.failed"
  41. EventResponseIncomplete ResponseStreamEventType = "response.incomplete"
  42. EventResponseQueued ResponseStreamEventType = "response.queued"
  43. EventResponseDone ResponseStreamEventType = "response.done" // Legacy/compatibility
  44. // Output item events
  45. EventOutputItemAdded ResponseStreamEventType = "response.output_item.added"
  46. EventOutputItemDone ResponseStreamEventType = "response.output_item.done"
  47. // Content part events
  48. EventContentPartAdded ResponseStreamEventType = "response.content_part.added"
  49. EventContentPartDone ResponseStreamEventType = "response.content_part.done"
  50. // Text output events
  51. EventOutputTextDelta ResponseStreamEventType = "response.output_text.delta"
  52. EventOutputTextDone ResponseStreamEventType = "response.output_text.done"
  53. // Refusal events
  54. EventRefusalDelta ResponseStreamEventType = "response.refusal.delta"
  55. EventRefusalDone ResponseStreamEventType = "response.refusal.done"
  56. // Function call events
  57. EventFunctionCallArgumentsDelta ResponseStreamEventType = "response.function_call_arguments.delta"
  58. EventFunctionCallArgumentsDone ResponseStreamEventType = "response.function_call_arguments.done"
  59. // Reasoning events
  60. EventReasoningSummaryPartAdded ResponseStreamEventType = "response.reasoning_summary_part.added"
  61. EventReasoningSummaryPartDone ResponseStreamEventType = "response.reasoning_summary_part.done"
  62. EventReasoningSummaryTextDelta ResponseStreamEventType = "response.reasoning_summary_text.delta"
  63. EventReasoningSummaryTextDone ResponseStreamEventType = "response.reasoning_summary_text.done"
  64. EventReasoningTextDelta ResponseStreamEventType = "response.reasoning_text.delta"
  65. EventReasoningTextDone ResponseStreamEventType = "response.reasoning_text.done"
  66. // Tool call events
  67. EventFileSearchCallInProgress ResponseStreamEventType = "response.file_search_call.in_progress"
  68. EventFileSearchCallSearching ResponseStreamEventType = "response.file_search_call.searching"
  69. EventFileSearchCallCompleted ResponseStreamEventType = "response.file_search_call.completed"
  70. EventWebSearchCallInProgress ResponseStreamEventType = "response.web_search_call.in_progress"
  71. EventWebSearchCallSearching ResponseStreamEventType = "response.web_search_call.searching"
  72. EventWebSearchCallCompleted ResponseStreamEventType = "response.web_search_call.completed"
  73. EventCodeInterpreterCallInProgress ResponseStreamEventType = "response.code_interpreter_call.in_progress"
  74. EventCodeInterpreterCallInterpreting ResponseStreamEventType = "response.code_interpreter_call.interpreting"
  75. EventCodeInterpreterCallCompleted ResponseStreamEventType = "response.code_interpreter_call.completed"
  76. EventCodeInterpreterCallCodeDelta ResponseStreamEventType = "response.code_interpreter_call_code.delta"
  77. EventCodeInterpreterCallCodeDone ResponseStreamEventType = "response.code_interpreter_call_code.done"
  78. EventImageGenerationCallInProgress ResponseStreamEventType = "response.image_generation_call.in_progress"
  79. EventImageGenerationCallGenerating ResponseStreamEventType = "response.image_generation_call.generating"
  80. EventImageGenerationCallCompleted ResponseStreamEventType = "response.image_generation_call.completed"
  81. EventImageGenerationCallPartialImage ResponseStreamEventType = "response.image_generation_call.partial_image"
  82. EventMCPCallInProgress ResponseStreamEventType = "response.mcp_call.in_progress"
  83. EventMCPCallCompleted ResponseStreamEventType = "response.mcp_call.completed"
  84. EventMCPCallFailed ResponseStreamEventType = "response.mcp_call.failed"
  85. EventMCPCallArgumentsDelta ResponseStreamEventType = "response.mcp_call_arguments.delta"
  86. EventMCPCallArgumentsDone ResponseStreamEventType = "response.mcp_call_arguments.done"
  87. EventMCPListToolsInProgress ResponseStreamEventType = "response.mcp_list_tools.in_progress"
  88. EventMCPListToolsCompleted ResponseStreamEventType = "response.mcp_list_tools.completed"
  89. EventMCPListToolsFailed ResponseStreamEventType = "response.mcp_list_tools.failed"
  90. EventCustomToolCallInputDelta ResponseStreamEventType = "response.custom_tool_call_input.delta"
  91. EventCustomToolCallInputDone ResponseStreamEventType = "response.custom_tool_call_input.done"
  92. // Annotation events
  93. EventOutputTextAnnotationAdded ResponseStreamEventType = "response.output_text.annotation.added"
  94. // Error event
  95. EventError ResponseStreamEventType = "error"
  96. )
  97. // ResponseError represents an error in a response
  98. type ResponseError struct {
  99. Code string `json:"code"`
  100. Message string `json:"message"`
  101. }
  102. // ResponseTool represents a tool in the Responses API format (flattened structure)
  103. type ResponseTool struct {
  104. Type string `json:"type"`
  105. Name string `json:"name,omitempty"`
  106. Description string `json:"description,omitempty"`
  107. Parameters any `json:"parameters,omitempty"`
  108. }
  109. // IncompleteDetails represents details about why a response is incomplete
  110. type IncompleteDetails struct {
  111. Reason string `json:"reason"`
  112. }
  113. // ResponseReasoning represents reasoning information
  114. type ResponseReasoning struct {
  115. Effort *string `json:"effort"`
  116. Summary *string `json:"summary"`
  117. }
  118. // ResponseTextFormat represents text format configuration
  119. type ResponseTextFormat struct {
  120. Type string `json:"type"`
  121. }
  122. // ResponseText represents text configuration
  123. type ResponseText struct {
  124. Format ResponseTextFormat `json:"format"`
  125. }
  126. // OutputContent represents content in an output item
  127. type OutputContent struct {
  128. Type string `json:"type"`
  129. Text string `json:"text,omitempty"`
  130. Annotations []any `json:"annotations,omitempty"`
  131. }
  132. // OutputItem represents an output item in a response
  133. type OutputItem struct {
  134. ID string `json:"id"`
  135. Type string `json:"type"`
  136. Status ResponseStatus `json:"status,omitempty"`
  137. Role string `json:"role,omitempty"`
  138. Content []OutputContent `json:"content,omitempty"`
  139. Arguments string `json:"arguments,omitempty"` // For function_call type
  140. CallID string `json:"call_id,omitempty"` // For function_call type
  141. Name string `json:"name,omitempty"` // For function_call type
  142. Summary []string `json:"summary,omitempty"` // For reasoning type
  143. }
  144. // InputContent represents content in an input item
  145. type InputContent struct {
  146. Type string `json:"type"`
  147. Text string `json:"text,omitempty"`
  148. // Fields for function_call type
  149. ID string `json:"id,omitempty"`
  150. Name string `json:"name,omitempty"`
  151. Arguments string `json:"arguments,omitempty"`
  152. // Fields for function_result type
  153. CallID string `json:"call_id,omitempty"`
  154. Output string `json:"output,omitempty"`
  155. }
  156. // InputItem represents an input item
  157. type InputItem struct {
  158. ID string `json:"id,omitempty"`
  159. Type string `json:"type"`
  160. Role string `json:"role,omitempty"`
  161. Content []InputContent `json:"content,omitempty"`
  162. // Fields for function_call type
  163. Name string `json:"name,omitempty"`
  164. Arguments string `json:"arguments,omitempty"`
  165. // Fields for function_result type
  166. CallID string `json:"call_id,omitempty"`
  167. Output string `json:"output,omitempty"`
  168. }
  169. // ResponseUsageDetails represents detailed token usage information
  170. type ResponseUsageDetails struct {
  171. CachedTokens int64 `json:"cached_tokens,omitempty"`
  172. ReasoningTokens int64 `json:"reasoning_tokens,omitempty"`
  173. }
  174. // ResponseUsage represents usage information for a response
  175. type ResponseUsage struct {
  176. InputTokens int64 `json:"input_tokens"`
  177. OutputTokens int64 `json:"output_tokens"`
  178. TotalTokens int64 `json:"total_tokens"`
  179. InputTokensDetails *ResponseUsageDetails `json:"input_tokens_details,omitempty"`
  180. OutputTokensDetails *ResponseUsageDetails `json:"output_tokens_details,omitempty"`
  181. }
  182. // Response represents an OpenAI response object
  183. type Response struct {
  184. ID string `json:"id"`
  185. Object string `json:"object"`
  186. CreatedAt int64 `json:"created_at"`
  187. Status ResponseStatus `json:"status"`
  188. Error *ResponseError `json:"error"`
  189. IncompleteDetails *IncompleteDetails `json:"incomplete_details"`
  190. Instructions *string `json:"instructions"`
  191. MaxOutputTokens *int `json:"max_output_tokens"`
  192. Model string `json:"model"`
  193. Output []OutputItem `json:"output"`
  194. ParallelToolCalls bool `json:"parallel_tool_calls"`
  195. PreviousResponseID *string `json:"previous_response_id"`
  196. Reasoning ResponseReasoning `json:"reasoning"`
  197. Store bool `json:"store"`
  198. Temperature float64 `json:"temperature"`
  199. Text ResponseText `json:"text"`
  200. ToolChoice any `json:"tool_choice"`
  201. Tools []ResponseTool `json:"tools"`
  202. TopP float64 `json:"top_p"`
  203. Truncation string `json:"truncation"`
  204. Usage *ResponseUsage `json:"usage"`
  205. User *string `json:"user"`
  206. Metadata map[string]any `json:"metadata"`
  207. }
  208. // CreateResponseRequest represents a request to create a response
  209. type CreateResponseRequest struct {
  210. Model string `json:"model"`
  211. Input any `json:"input"`
  212. Background *bool `json:"background,omitempty"`
  213. Conversation any `json:"conversation,omitempty"` // string or object
  214. Include []string `json:"include,omitempty"`
  215. Instructions *string `json:"instructions,omitempty"`
  216. MaxOutputTokens *int `json:"max_output_tokens,omitempty"`
  217. MaxToolCalls *int `json:"max_tool_calls,omitempty"`
  218. Metadata map[string]any `json:"metadata,omitempty"`
  219. ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
  220. PreviousResponseID *string `json:"previous_response_id,omitempty"`
  221. PromptCacheKey *string `json:"prompt_cache_key,omitempty"`
  222. SafetyIdentifier *string `json:"safety_identifier,omitempty"`
  223. ServiceTier *string `json:"service_tier,omitempty"`
  224. Store *bool `json:"store,omitempty"`
  225. Stream bool `json:"stream,omitempty"`
  226. Temperature *float64 `json:"temperature,omitempty"`
  227. Text *ResponseText `json:"text,omitempty"`
  228. ToolChoice any `json:"tool_choice,omitempty"`
  229. Tools []ResponseTool `json:"tools,omitempty"`
  230. TopLogprobs *int `json:"top_logprobs,omitempty"`
  231. TopP *float64 `json:"top_p,omitempty"`
  232. Truncation *string `json:"truncation,omitempty"`
  233. User *string `json:"user,omitempty"` // Deprecated, use prompt_cache_key
  234. }
  235. // InputItemList represents a list of input items
  236. type InputItemList struct {
  237. Object string `json:"object"`
  238. Data []InputItem `json:"data"`
  239. FirstID string `json:"first_id"`
  240. LastID string `json:"last_id"`
  241. HasMore bool `json:"has_more"`
  242. }
  243. // ResponseStreamEvent represents a server-sent event for response streaming
  244. type ResponseStreamEvent struct {
  245. Type string `json:"type"`
  246. Response *Response `json:"response,omitempty"`
  247. OutputIndex *int `json:"output_index,omitempty"`
  248. Item *OutputItem `json:"item,omitempty"`
  249. ItemID string `json:"item_id,omitempty"`
  250. ContentIndex *int `json:"content_index,omitempty"`
  251. Part *OutputContent `json:"part,omitempty"` // For content_part events
  252. Delta string `json:"delta,omitempty"` // For text.delta, function_call_arguments.delta
  253. Text string `json:"text,omitempty"` // For text content
  254. Arguments string `json:"arguments,omitempty"` // For function_call_arguments.done
  255. SequenceNumber int `json:"sequence_number,omitempty"`
  256. }
  257. func (u *ResponseUsage) ToModelUsage() model.Usage {
  258. usage := model.Usage{
  259. InputTokens: model.ZeroNullInt64(u.InputTokens),
  260. OutputTokens: model.ZeroNullInt64(u.OutputTokens),
  261. TotalTokens: model.ZeroNullInt64(u.TotalTokens),
  262. }
  263. if u.InputTokensDetails != nil {
  264. usage.CachedTokens = model.ZeroNullInt64(u.InputTokensDetails.CachedTokens)
  265. }
  266. if u.OutputTokensDetails != nil {
  267. usage.ReasoningTokens = model.ZeroNullInt64(u.OutputTokensDetails.ReasoningTokens)
  268. }
  269. return usage
  270. }
  271. // ToChatUsage converts ResponseUsage to ChatUsage (OpenAI Chat Completions format)
  272. func (u *ResponseUsage) ToChatUsage() ChatUsage {
  273. usage := ChatUsage{
  274. PromptTokens: u.InputTokens,
  275. CompletionTokens: u.OutputTokens,
  276. TotalTokens: u.TotalTokens,
  277. }
  278. if u.InputTokensDetails != nil && u.InputTokensDetails.CachedTokens > 0 {
  279. usage.PromptTokensDetails = &PromptTokensDetails{
  280. CachedTokens: u.InputTokensDetails.CachedTokens,
  281. }
  282. }
  283. if u.OutputTokensDetails != nil && u.OutputTokensDetails.ReasoningTokens > 0 {
  284. usage.CompletionTokensDetails = &CompletionTokensDetails{
  285. ReasoningTokens: u.OutputTokensDetails.ReasoningTokens,
  286. }
  287. }
  288. return usage
  289. }
  290. // ToClaudeUsage converts ResponseUsage to ClaudeUsage (Anthropic Claude format)
  291. func (u *ResponseUsage) ToClaudeUsage() ClaudeUsage {
  292. usage := ClaudeUsage{
  293. InputTokens: u.InputTokens,
  294. OutputTokens: u.OutputTokens,
  295. }
  296. if u.InputTokensDetails != nil && u.InputTokensDetails.CachedTokens > 0 {
  297. usage.CacheReadInputTokens = u.InputTokensDetails.CachedTokens
  298. }
  299. return usage
  300. }
  301. // ToGeminiUsage converts ResponseUsage to GeminiUsageMetadata (Google Gemini format)
  302. func (u *ResponseUsage) ToGeminiUsage() GeminiUsageMetadata {
  303. usage := GeminiUsageMetadata{
  304. PromptTokenCount: u.InputTokens,
  305. CandidatesTokenCount: u.OutputTokens,
  306. TotalTokenCount: u.TotalTokens,
  307. }
  308. if u.InputTokensDetails != nil && u.InputTokensDetails.CachedTokens > 0 {
  309. usage.CachedContentTokenCount = u.InputTokensDetails.CachedTokens
  310. }
  311. if u.OutputTokensDetails != nil && u.OutputTokensDetails.ReasoningTokens > 0 {
  312. usage.ThoughtsTokenCount = u.OutputTokensDetails.ReasoningTokens
  313. }
  314. return usage
  315. }