gemini.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package model
  2. import "github.com/labring/aiproxy/core/relay/adaptor"
  3. // Gemini API request and response types
  4. // https://ai.google.dev/api/generate-content
  5. type GeminiChatRequest struct {
  6. Contents []*GeminiChatContent `json:"contents"`
  7. SystemInstruction *GeminiChatContent `json:"systemInstruction,omitempty"`
  8. SafetySettings []GeminiChatSafetySettings `json:"safetySettings,omitempty"`
  9. GenerationConfig *GeminiChatGenerationConfig `json:"generationConfig,omitempty"`
  10. Tools []GeminiChatTools `json:"tools,omitempty"`
  11. ToolConfig *GeminiToolConfig `json:"toolConfig,omitempty"`
  12. }
  13. type GeminiChatContent struct {
  14. Role string `json:"role,omitempty"`
  15. Parts []*GeminiPart `json:"parts"`
  16. }
  17. type GeminiPart struct {
  18. InlineData *GeminiInlineData `json:"inlineData,omitempty"`
  19. FunctionCall *GeminiFunctionCall `json:"functionCall,omitempty"`
  20. FunctionResponse *GeminiFunctionResponse `json:"functionResponse,omitempty"`
  21. Text string `json:"text,omitempty"`
  22. Thought bool `json:"thought,omitempty"`
  23. ThoughtSignature string `json:"thoughtSignature,omitempty"`
  24. }
  25. type GeminiInlineData struct {
  26. MimeType string `json:"mimeType"`
  27. Data string `json:"data"`
  28. }
  29. type GeminiFunctionCall struct {
  30. Args map[string]any `json:"args"`
  31. Name string `json:"name"`
  32. }
  33. type GeminiFunctionResponse struct {
  34. Name string `json:"name"`
  35. Response map[string]any `json:"response"`
  36. // vertexai gemini not support `id` filed
  37. ID string `json:"id,omitempty"`
  38. }
  39. type GeminiChatSafetySettings struct {
  40. Category string `json:"category"`
  41. Threshold string `json:"threshold"`
  42. }
  43. type GeminiChatTools struct {
  44. FunctionDeclarations any `json:"functionDeclarations,omitempty"`
  45. }
  46. type GeminiChatGenerationConfig struct {
  47. ResponseSchema map[string]any `json:"responseSchema,omitempty"`
  48. Temperature *float64 `json:"temperature,omitempty"`
  49. TopP *float64 `json:"topP,omitempty"`
  50. ResponseMimeType string `json:"responseMimeType,omitempty"`
  51. StopSequences []string `json:"stopSequences,omitempty"`
  52. TopK float64 `json:"topK,omitempty"`
  53. MaxOutputTokens *int `json:"maxOutputTokens,omitempty"`
  54. CandidateCount int `json:"candidateCount,omitempty"`
  55. ResponseModalities []string `json:"responseModalities,omitempty"`
  56. ThinkingConfig *GeminiThinkingConfig `json:"thinkingConfig,omitempty"`
  57. }
  58. type GeminiThinkingConfig struct {
  59. ThinkingBudget int `json:"thinkingBudget,omitempty"`
  60. IncludeThoughts bool `json:"includeThoughts,omitempty"`
  61. }
  62. type GeminiFunctionCallingConfig struct {
  63. Mode string `json:"mode,omitempty"`
  64. AllowedFunctionNames []string `json:"allowedFunctionNames,omitempty"`
  65. }
  66. type GeminiToolConfig struct {
  67. FunctionCallingConfig GeminiFunctionCallingConfig `json:"functionCallingConfig"`
  68. }
  69. type GeminiChatResponse struct {
  70. Candidates []*GeminiChatCandidate `json:"candidates"`
  71. PromptFeedback *GeminiChatPromptFeedback `json:"promptFeedback,omitempty"`
  72. UsageMetadata *GeminiUsageMetadata `json:"usageMetadata,omitempty"`
  73. ModelVersion string `json:"modelVersion,omitempty"`
  74. }
  75. type GeminiUsageMetadata struct {
  76. PromptTokenCount int64 `json:"promptTokenCount"`
  77. CandidatesTokenCount int64 `json:"candidatesTokenCount"`
  78. TotalTokenCount int64 `json:"totalTokenCount"`
  79. ThoughtsTokenCount int64 `json:"thoughtsTokenCount,omitempty"`
  80. PromptTokensDetails []GeminiPromptTokensDetail `json:"promptTokensDetails"`
  81. CachedContentTokenCount int64 `json:"cachedContentTokenCount,omitempty"`
  82. CacheTokensDetails []GeminiCacheTokensDetail `json:"cacheTokensDetails,omitempty"`
  83. }
  84. type GeminiPromptTokensDetail struct {
  85. Modality string `json:"modality"`
  86. TokenCount int64 `json:"tokenCount"`
  87. }
  88. type GeminiCacheTokensDetail struct {
  89. Modality string `json:"modality"`
  90. TokenCount int64 `json:"tokenCount"`
  91. }
  92. type GeminiChatCandidate struct {
  93. FinishReason string `json:"finishReason,omitempty"`
  94. Content GeminiChatContent `json:"content"`
  95. SafetyRatings []struct {
  96. Category string `json:"category"`
  97. Probability string `json:"probability"`
  98. } `json:"safetyRatings,omitempty"`
  99. Index int64 `json:"index"`
  100. }
  101. type GeminiChatPromptFeedback struct {
  102. SafetyRatings []struct {
  103. Category string `json:"category"`
  104. Probability string `json:"probability"`
  105. } `json:"safetyRatings,omitempty"`
  106. }
  107. // ToUsage converts GeminiUsageMetadata to ChatUsage format
  108. func (u *GeminiUsageMetadata) ToUsage() ChatUsage {
  109. chatUsage := ChatUsage{
  110. PromptTokens: u.PromptTokenCount,
  111. CompletionTokens: u.CandidatesTokenCount +
  112. u.ThoughtsTokenCount,
  113. TotalTokens: u.TotalTokenCount,
  114. PromptTokensDetails: &PromptTokensDetails{
  115. CachedTokens: u.CachedContentTokenCount,
  116. },
  117. CompletionTokensDetails: &CompletionTokensDetails{
  118. ReasoningTokens: u.ThoughtsTokenCount,
  119. },
  120. }
  121. return chatUsage
  122. }
  123. // ToResponseUsage converts GeminiUsageMetadata to ResponseUsage (OpenAI Responses API format)
  124. func (u *GeminiUsageMetadata) ToResponseUsage() ResponseUsage {
  125. usage := ResponseUsage{
  126. InputTokens: u.PromptTokenCount,
  127. OutputTokens: u.CandidatesTokenCount,
  128. TotalTokens: u.TotalTokenCount,
  129. }
  130. if u.CachedContentTokenCount > 0 {
  131. usage.InputTokensDetails = &ResponseUsageDetails{
  132. CachedTokens: u.CachedContentTokenCount,
  133. }
  134. }
  135. if u.ThoughtsTokenCount > 0 {
  136. usage.OutputTokensDetails = &ResponseUsageDetails{
  137. ReasoningTokens: u.ThoughtsTokenCount,
  138. }
  139. }
  140. return usage
  141. }
  142. // ToClaudeUsage converts GeminiUsageMetadata to ClaudeUsage (Anthropic Claude format)
  143. func (u *GeminiUsageMetadata) ToClaudeUsage() ClaudeUsage {
  144. usage := ClaudeUsage{
  145. InputTokens: u.PromptTokenCount,
  146. OutputTokens: u.CandidatesTokenCount,
  147. }
  148. if u.CachedContentTokenCount > 0 {
  149. usage.CacheReadInputTokens = u.CachedContentTokenCount
  150. }
  151. return usage
  152. }
  153. type GeminiError struct {
  154. Message string `json:"message,omitempty"`
  155. Status string `json:"status,omitempty"`
  156. Code int `json:"code,omitempty"`
  157. }
  158. type GeminiErrorResponse struct {
  159. Error GeminiError `json:"error,omitempty"`
  160. }
  161. func NewGeminiError(statusCode int, err GeminiError) adaptor.Error {
  162. return adaptor.NewError(statusCode, GeminiErrorResponse{
  163. Error: err,
  164. })
  165. }
  166. // Gemini Role constants
  167. const (
  168. GeminiRoleModel = "model"
  169. GeminiRoleUser = "user"
  170. )
  171. // Gemini Finish Reason constants
  172. const (
  173. GeminiFinishReasonStop = "STOP"
  174. GeminiFinishReasonMaxTokens = "MAX_TOKENS"
  175. GeminiFinishReasonSafety = "SAFETY"
  176. GeminiFinishReasonRecitation = "RECITATION"
  177. GeminiFinishReasonOther = "OTHER"
  178. GeminiFinishReasonToolCalls = "TOOL_CALLS"
  179. GeminiFinishReasonFunctionCall = "FUNCTION_CALL"
  180. )
  181. // Gemini FunctionCallingConfig Mode constants
  182. const (
  183. GeminiFunctionCallingModeAuto = "AUTO"
  184. GeminiFunctionCallingModeAny = "ANY"
  185. GeminiFunctionCallingModeNone = "NONE"
  186. )
  187. // Gemini Safety Setting Category constants
  188. const (
  189. GeminiSafetyCategoryHarassment = "HARM_CATEGORY_HARASSMENT"
  190. GeminiSafetyCategoryHateSpeech = "HARM_CATEGORY_HATE_SPEECH"
  191. GeminiSafetyCategorySexuallyExplicit = "HARM_CATEGORY_SEXUALLY_EXPLICIT"
  192. GeminiSafetyCategoryDangerousContent = "HARM_CATEGORY_DANGEROUS_CONTENT"
  193. GeminiSafetyCategoryCivicIntegrity = "HARM_CATEGORY_CIVIC_INTEGRITY"
  194. )
  195. // Gemini Safety Setting Threshold constants
  196. const (
  197. GeminiSafetyThresholdBlockNone = "BLOCK_NONE"
  198. GeminiSafetyThresholdBlockLowAndAbove = "BLOCK_LOW_AND_ABOVE"
  199. GeminiSafetyThresholdBlockMediumAndAbove = "BLOCK_MEDIUM_AND_ABOVE"
  200. GeminiSafetyThresholdBlockOnlyHigh = "BLOCK_ONLY_HIGH"
  201. )