mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-11 03:58:28 +08:00
469 lines
15 KiB
Python
469 lines
15 KiB
Python
|
|
"""
|
|||
|
|
Google Gemini API 请求/响应模型
|
|||
|
|
|
|||
|
|
支持 Gemini 3 Pro 及之前版本的 API 格式
|
|||
|
|
参考文档: https://ai.google.dev/gemini-api/docs/gemini-3
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from typing import Any, Dict, List, Literal, Optional, Union
|
|||
|
|
|
|||
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|||
|
|
|
|||
|
|
|
|||
|
|
class BaseModelWithExtras(BaseModel):
|
|||
|
|
"""允许额外字段的基础模型"""
|
|||
|
|
|
|||
|
|
model_config = ConfigDict(extra="allow")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 内容块定义
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiTextPart(BaseModelWithExtras):
|
|||
|
|
"""文本内容块"""
|
|||
|
|
|
|||
|
|
text: str
|
|||
|
|
thought_signature: Optional[str] = Field(
|
|||
|
|
default=None,
|
|||
|
|
alias="thoughtSignature",
|
|||
|
|
description="Gemini 3 思维签名,用于维护多轮对话中的推理上下文",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiInlineData(BaseModelWithExtras):
|
|||
|
|
"""内联数据(图片等)"""
|
|||
|
|
|
|||
|
|
mime_type: str = Field(alias="mimeType")
|
|||
|
|
data: str # base64 encoded
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiMediaResolution(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
媒体分辨率配置 (Gemini 3 新增)
|
|||
|
|
|
|||
|
|
控制图片/视频的处理分辨率:
|
|||
|
|
- media_resolution_low: 图片 280 tokens, 视频 70 tokens/帧
|
|||
|
|
- media_resolution_medium: 图片 560 tokens, 视频 70 tokens/帧
|
|||
|
|
- media_resolution_high: 图片 1120 tokens, 视频 280 tokens/帧
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
level: Literal["media_resolution_low", "media_resolution_medium", "media_resolution_high"]
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiFileData(BaseModelWithExtras):
|
|||
|
|
"""文件引用"""
|
|||
|
|
|
|||
|
|
mime_type: Optional[str] = Field(default=None, alias="mimeType")
|
|||
|
|
file_uri: str = Field(alias="fileUri")
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiFunctionCall(BaseModelWithExtras):
|
|||
|
|
"""函数调用"""
|
|||
|
|
|
|||
|
|
name: str
|
|||
|
|
args: Dict[str, Any]
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiFunctionResponse(BaseModelWithExtras):
|
|||
|
|
"""函数响应"""
|
|||
|
|
|
|||
|
|
name: str
|
|||
|
|
response: Dict[str, Any]
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiPart(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini 内容部分 - 支持多种类型
|
|||
|
|
|
|||
|
|
可以是以下类型之一:
|
|||
|
|
- text: 文本内容
|
|||
|
|
- inline_data: 内联数据(图片等)
|
|||
|
|
- file_data: 文件引用
|
|||
|
|
- function_call: 函数调用
|
|||
|
|
- function_response: 函数响应
|
|||
|
|
|
|||
|
|
Gemini 3 新增:
|
|||
|
|
- thought_signature: 思维签名,用于维护推理上下文
|
|||
|
|
- media_resolution: 媒体分辨率配置
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
text: Optional[str] = None
|
|||
|
|
inline_data: Optional[GeminiInlineData] = Field(default=None, alias="inlineData")
|
|||
|
|
file_data: Optional[GeminiFileData] = Field(default=None, alias="fileData")
|
|||
|
|
function_call: Optional[GeminiFunctionCall] = Field(default=None, alias="functionCall")
|
|||
|
|
function_response: Optional[GeminiFunctionResponse] = Field(
|
|||
|
|
default=None, alias="functionResponse"
|
|||
|
|
)
|
|||
|
|
# Gemini 3 新增
|
|||
|
|
thought_signature: Optional[str] = Field(
|
|||
|
|
default=None,
|
|||
|
|
alias="thoughtSignature",
|
|||
|
|
description="思维签名,用于函数调用和图片生成的上下文保持",
|
|||
|
|
)
|
|||
|
|
media_resolution: Optional[GeminiMediaResolution] = Field(
|
|||
|
|
default=None, alias="mediaResolution", description="媒体分辨率配置"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiContent(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini 消息内容
|
|||
|
|
|
|||
|
|
对应 Gemini API 的 Content 对象
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
role: Optional[Literal["user", "model"]] = None
|
|||
|
|
parts: List[Union[GeminiPart, Dict[str, Any]]]
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 配置定义
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiImageConfig(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
图片生成配置 (Gemini 3 Pro Image)
|
|||
|
|
|
|||
|
|
用于 gemini-3-pro-image-preview 模型
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
aspect_ratio: Optional[str] = Field(
|
|||
|
|
default=None, alias="aspectRatio", description="图片宽高比,如 '16:9', '1:1', '4:3'"
|
|||
|
|
)
|
|||
|
|
image_size: Optional[Literal["2K", "4K"]] = Field(
|
|||
|
|
default=None, alias="imageSize", description="图片尺寸: 2K 或 4K"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiGenerationConfig(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
生成配置
|
|||
|
|
|
|||
|
|
Gemini 3 新增:
|
|||
|
|
- thinking_level: 思考深度 (low/medium/high)
|
|||
|
|
- response_json_schema: 结构化输出的 JSON Schema
|
|||
|
|
- image_config: 图片生成配置
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
temperature: Optional[float] = Field(
|
|||
|
|
default=None, description="采样温度,Gemini 3 建议保持默认值 1.0"
|
|||
|
|
)
|
|||
|
|
top_p: Optional[float] = Field(default=None, alias="topP")
|
|||
|
|
top_k: Optional[int] = Field(default=None, alias="topK")
|
|||
|
|
max_output_tokens: Optional[int] = Field(default=None, alias="maxOutputTokens")
|
|||
|
|
stop_sequences: Optional[List[str]] = Field(default=None, alias="stopSequences")
|
|||
|
|
candidate_count: Optional[int] = Field(default=None, alias="candidateCount")
|
|||
|
|
response_mime_type: Optional[str] = Field(default=None, alias="responseMimeType")
|
|||
|
|
response_schema: Optional[Dict[str, Any]] = Field(default=None, alias="responseSchema")
|
|||
|
|
# Gemini 3 新增
|
|||
|
|
response_json_schema: Optional[Dict[str, Any]] = Field(
|
|||
|
|
default=None, alias="responseJsonSchema", description="结构化输出的 JSON Schema"
|
|||
|
|
)
|
|||
|
|
thinking_level: Optional[Literal["low", "medium", "high"]] = Field(
|
|||
|
|
default=None,
|
|||
|
|
alias="thinkingLevel",
|
|||
|
|
description="Gemini 3 思考深度: low(快速), medium(平衡), high(深度推理,默认)",
|
|||
|
|
)
|
|||
|
|
image_config: Optional[GeminiImageConfig] = Field(
|
|||
|
|
default=None, alias="imageConfig", description="图片生成配置"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiSafetySettings(BaseModelWithExtras):
|
|||
|
|
"""安全设置"""
|
|||
|
|
|
|||
|
|
category: str
|
|||
|
|
threshold: str
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiFunctionDeclaration(BaseModelWithExtras):
|
|||
|
|
"""函数声明"""
|
|||
|
|
|
|||
|
|
name: str
|
|||
|
|
description: Optional[str] = None
|
|||
|
|
parameters: Optional[Dict[str, Any]] = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiGoogleSearchTool(BaseModelWithExtras):
|
|||
|
|
"""Google Search 工具 (Gemini 3)"""
|
|||
|
|
|
|||
|
|
pass # 空对象表示启用
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiUrlContextTool(BaseModelWithExtras):
|
|||
|
|
"""URL Context 工具 (Gemini 3)"""
|
|||
|
|
|
|||
|
|
pass # 空对象表示启用
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiCodeExecutionTool(BaseModelWithExtras):
|
|||
|
|
"""代码执行工具"""
|
|||
|
|
|
|||
|
|
pass # 空对象表示启用
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiTool(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
工具定义
|
|||
|
|
|
|||
|
|
支持的工具类型:
|
|||
|
|
- function_declarations: 自定义函数
|
|||
|
|
- code_execution: 代码执行
|
|||
|
|
- google_search: Google 搜索 (Gemini 3)
|
|||
|
|
- url_context: URL 上下文 (Gemini 3)
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
function_declarations: Optional[List[GeminiFunctionDeclaration]] = Field(
|
|||
|
|
default=None, alias="functionDeclarations"
|
|||
|
|
)
|
|||
|
|
code_execution: Optional[Dict[str, Any]] = Field(default=None, alias="codeExecution")
|
|||
|
|
# Gemini 3 内置工具
|
|||
|
|
google_search: Optional[Dict[str, Any]] = Field(
|
|||
|
|
default=None, alias="googleSearch", description="启用 Google 搜索工具"
|
|||
|
|
)
|
|||
|
|
url_context: Optional[Dict[str, Any]] = Field(
|
|||
|
|
default=None, alias="urlContext", description="启用 URL 上下文工具"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiToolConfig(BaseModelWithExtras):
|
|||
|
|
"""工具配置"""
|
|||
|
|
|
|||
|
|
function_calling_config: Optional[Dict[str, Any]] = Field(
|
|||
|
|
default=None, alias="functionCallingConfig"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiSystemInstruction(BaseModelWithExtras):
|
|||
|
|
"""系统指令"""
|
|||
|
|
|
|||
|
|
parts: List[Union[GeminiPart, Dict[str, Any]]]
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 请求模型
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiGenerateContentRequest(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini generateContent 请求模型
|
|||
|
|
|
|||
|
|
对应 POST /v1beta/models/{model}:generateContent 端点
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
contents: List[GeminiContent]
|
|||
|
|
system_instruction: Optional[GeminiSystemInstruction] = Field(
|
|||
|
|
default=None, alias="systemInstruction"
|
|||
|
|
)
|
|||
|
|
tools: Optional[List[GeminiTool]] = None
|
|||
|
|
tool_config: Optional[GeminiToolConfig] = Field(default=None, alias="toolConfig")
|
|||
|
|
safety_settings: Optional[List[GeminiSafetySettings]] = Field(
|
|||
|
|
default=None, alias="safetySettings"
|
|||
|
|
)
|
|||
|
|
generation_config: Optional[GeminiGenerationConfig] = Field(
|
|||
|
|
default=None, alias="generationConfig"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiStreamGenerateContentRequest(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini streamGenerateContent 请求模型
|
|||
|
|
|
|||
|
|
对应 POST /v1beta/models/{model}:streamGenerateContent 端点
|
|||
|
|
与 generateContent 相同,但返回流式响应
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
contents: List[GeminiContent]
|
|||
|
|
system_instruction: Optional[GeminiSystemInstruction] = Field(
|
|||
|
|
default=None, alias="systemInstruction"
|
|||
|
|
)
|
|||
|
|
tools: Optional[List[GeminiTool]] = None
|
|||
|
|
tool_config: Optional[GeminiToolConfig] = Field(default=None, alias="toolConfig")
|
|||
|
|
safety_settings: Optional[List[GeminiSafetySettings]] = Field(
|
|||
|
|
default=None, alias="safetySettings"
|
|||
|
|
)
|
|||
|
|
generation_config: Optional[GeminiGenerationConfig] = Field(
|
|||
|
|
default=None, alias="generationConfig"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 统一请求模型(用于内部处理)
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiRequest(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini 统一请求模型
|
|||
|
|
|
|||
|
|
内部使用,统一处理 generateContent 和 streamGenerateContent
|
|||
|
|
|
|||
|
|
注意: Gemini API 通过 URL 端点区分流式/非流式请求:
|
|||
|
|
- generateContent - 非流式
|
|||
|
|
- streamGenerateContent - 流式
|
|||
|
|
请求体中不应包含 stream 字段
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
model: Optional[str] = Field(default=None, description="模型名称,从 URL 路径提取(内部使用)")
|
|||
|
|
contents: List[GeminiContent]
|
|||
|
|
system_instruction: Optional[GeminiSystemInstruction] = Field(
|
|||
|
|
default=None, alias="systemInstruction"
|
|||
|
|
)
|
|||
|
|
tools: Optional[List[GeminiTool]] = None
|
|||
|
|
tool_config: Optional[GeminiToolConfig] = Field(default=None, alias="toolConfig")
|
|||
|
|
safety_settings: Optional[List[GeminiSafetySettings]] = Field(
|
|||
|
|
default=None, alias="safetySettings"
|
|||
|
|
)
|
|||
|
|
generation_config: Optional[GeminiGenerationConfig] = Field(
|
|||
|
|
default=None, alias="generationConfig"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 响应模型
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiUsageMetadata(BaseModelWithExtras):
|
|||
|
|
"""Token 使用量"""
|
|||
|
|
|
|||
|
|
prompt_token_count: int = Field(default=0, alias="promptTokenCount")
|
|||
|
|
candidates_token_count: int = Field(default=0, alias="candidatesTokenCount")
|
|||
|
|
total_token_count: int = Field(default=0, alias="totalTokenCount")
|
|||
|
|
cached_content_token_count: Optional[int] = Field(default=None, alias="cachedContentTokenCount")
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiSafetyRating(BaseModelWithExtras):
|
|||
|
|
"""安全评级"""
|
|||
|
|
|
|||
|
|
category: str
|
|||
|
|
probability: str
|
|||
|
|
blocked: Optional[bool] = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiCitationSource(BaseModelWithExtras):
|
|||
|
|
"""引用来源"""
|
|||
|
|
|
|||
|
|
start_index: Optional[int] = Field(default=None, alias="startIndex")
|
|||
|
|
end_index: Optional[int] = Field(default=None, alias="endIndex")
|
|||
|
|
uri: Optional[str] = None
|
|||
|
|
license: Optional[str] = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiCitationMetadata(BaseModelWithExtras):
|
|||
|
|
"""引用元数据"""
|
|||
|
|
|
|||
|
|
citation_sources: Optional[List[GeminiCitationSource]] = Field(
|
|||
|
|
default=None, alias="citationSources"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiGroundingMetadata(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Grounding 元数据 (Gemini 3)
|
|||
|
|
|
|||
|
|
当使用 Google Search 工具时返回
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
search_entry_point: Optional[Dict[str, Any]] = Field(default=None, alias="searchEntryPoint")
|
|||
|
|
grounding_chunks: Optional[List[Dict[str, Any]]] = Field(default=None, alias="groundingChunks")
|
|||
|
|
grounding_supports: Optional[List[Dict[str, Any]]] = Field(
|
|||
|
|
default=None, alias="groundingSupports"
|
|||
|
|
)
|
|||
|
|
web_search_queries: Optional[List[str]] = Field(default=None, alias="webSearchQueries")
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiCandidate(BaseModelWithExtras):
|
|||
|
|
"""候选响应"""
|
|||
|
|
|
|||
|
|
content: Optional[GeminiContent] = None
|
|||
|
|
finish_reason: Optional[str] = Field(default=None, alias="finishReason")
|
|||
|
|
safety_ratings: Optional[List[GeminiSafetyRating]] = Field(default=None, alias="safetyRatings")
|
|||
|
|
citation_metadata: Optional[GeminiCitationMetadata] = Field(
|
|||
|
|
default=None, alias="citationMetadata"
|
|||
|
|
)
|
|||
|
|
grounding_metadata: Optional[GeminiGroundingMetadata] = Field(
|
|||
|
|
default=None, alias="groundingMetadata"
|
|||
|
|
)
|
|||
|
|
token_count: Optional[int] = Field(default=None, alias="tokenCount")
|
|||
|
|
index: Optional[int] = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiPromptFeedback(BaseModelWithExtras):
|
|||
|
|
"""提示反馈"""
|
|||
|
|
|
|||
|
|
block_reason: Optional[str] = Field(default=None, alias="blockReason")
|
|||
|
|
safety_ratings: Optional[List[GeminiSafetyRating]] = Field(default=None, alias="safetyRatings")
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiGenerateContentResponse(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini generateContent 响应模型
|
|||
|
|
|
|||
|
|
对应 generateContent 端点的响应体
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
candidates: Optional[List[GeminiCandidate]] = None
|
|||
|
|
prompt_feedback: Optional[GeminiPromptFeedback] = Field(default=None, alias="promptFeedback")
|
|||
|
|
usage_metadata: Optional[GeminiUsageMetadata] = Field(default=None, alias="usageMetadata")
|
|||
|
|
model_version: Optional[str] = Field(default=None, alias="modelVersion")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 流式响应模型
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiStreamChunk(BaseModelWithExtras):
|
|||
|
|
"""
|
|||
|
|
Gemini 流式响应块
|
|||
|
|
|
|||
|
|
流式响应中的单个数据块,结构与完整响应相同
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
candidates: Optional[List[GeminiCandidate]] = None
|
|||
|
|
prompt_feedback: Optional[GeminiPromptFeedback] = Field(default=None, alias="promptFeedback")
|
|||
|
|
usage_metadata: Optional[GeminiUsageMetadata] = Field(default=None, alias="usageMetadata")
|
|||
|
|
model_version: Optional[str] = Field(default=None, alias="modelVersion")
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# 错误响应
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiErrorDetail(BaseModelWithExtras):
|
|||
|
|
"""错误详情"""
|
|||
|
|
|
|||
|
|
type: Optional[str] = Field(default=None, alias="@type")
|
|||
|
|
reason: Optional[str] = None
|
|||
|
|
domain: Optional[str] = None
|
|||
|
|
metadata: Optional[Dict[str, Any]] = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiError(BaseModelWithExtras):
|
|||
|
|
"""错误信息"""
|
|||
|
|
|
|||
|
|
code: int
|
|||
|
|
message: str
|
|||
|
|
status: str
|
|||
|
|
details: Optional[List[GeminiErrorDetail]] = None
|
|||
|
|
|
|||
|
|
|
|||
|
|
class GeminiErrorResponse(BaseModelWithExtras):
|
|||
|
|
"""错误响应"""
|
|||
|
|
|
|||
|
|
error: GeminiError
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
# Thought Signature 常量
|
|||
|
|
# ---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
# 用于从其他模型迁移对话时绕过签名验证
|
|||
|
|
DUMMY_THOUGHT_SIGNATURE = "context_engineering_is_the_way_to_go"
|