feat:支持Gemini系列模型的接口
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from langchain_openai import ChatOpenAI, AzureChatOpenAI
|
from langchain_openai import ChatOpenAI, AzureChatOpenAI
|
||||||
|
from google import genai
|
||||||
|
from google.genai import types
|
||||||
|
|
||||||
def ensure_openai_base_url_has_v1(url: str) -> str:
|
def ensure_openai_base_url_has_v1(url: str) -> str:
|
||||||
import re
|
import re
|
||||||
@@ -77,6 +79,38 @@ class OpenAIAdapter(BaseLLMAdapter):
|
|||||||
return ""
|
return ""
|
||||||
return response.content
|
return response.content
|
||||||
|
|
||||||
|
class GeminiAdapter(BaseLLMAdapter):
|
||||||
|
"""
|
||||||
|
适配 Google Gemini 接口
|
||||||
|
"""
|
||||||
|
def __init__(self, api_key: str, model_name: str, max_tokens: int, temperature: float = 0.7, timeout: Optional[int] = 600):
|
||||||
|
self.api_key = api_key
|
||||||
|
self.model_name = model_name
|
||||||
|
self.max_tokens = max_tokens
|
||||||
|
self.temperature = temperature
|
||||||
|
self.timeout = timeout
|
||||||
|
|
||||||
|
self._client = genai.Client(api_key=self.api_key)
|
||||||
|
|
||||||
|
def invoke(self, prompt: str) -> str:
|
||||||
|
try:
|
||||||
|
response = self._client.models.generate_content(
|
||||||
|
model = self.model_name,
|
||||||
|
contents = prompt,
|
||||||
|
config = types.GenerateContentConfig(
|
||||||
|
max_output_tokens=self.max_tokens,
|
||||||
|
temperature=self.temperature,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if response and response.text:
|
||||||
|
return response.text
|
||||||
|
else:
|
||||||
|
logging.warning("No text response from Gemini API.")
|
||||||
|
return ""
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Gemini API 调用失败: {e}")
|
||||||
|
return ""
|
||||||
|
|
||||||
class AzureOpenAIAdapter(BaseLLMAdapter):
|
class AzureOpenAIAdapter(BaseLLMAdapter):
|
||||||
"""
|
"""
|
||||||
适配 Azure OpenAI 接口(使用 langchain.ChatOpenAI)
|
适配 Azure OpenAI 接口(使用 langchain.ChatOpenAI)
|
||||||
@@ -190,5 +224,7 @@ def create_llm_adapter(
|
|||||||
return OllamaAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout)
|
return OllamaAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout)
|
||||||
elif interface_format.lower() == "ml studio":
|
elif interface_format.lower() == "ml studio":
|
||||||
return MLStudioAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout)
|
return MLStudioAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout)
|
||||||
|
elif interface_format.lower() == "gemini":
|
||||||
|
return GeminiAdapter(api_key, model_name, max_tokens, temperature, timeout)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unknown interface_format: {interface_format}")
|
raise ValueError(f"Unknown interface_format: {interface_format}")
|
||||||
|
|||||||
Binary file not shown.
+2
-2
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
tooltips = {
|
tooltips = {
|
||||||
"api_key": "在这里填写你的API Key。如果使用OpenAI官方接口,请在 https://platform.openai.com/account/api-keys 获取。",
|
"api_key": "在这里填写你的API Key。如果使用OpenAI官方接口,请在 https://platform.openai.com/account/api-keys 获取。",
|
||||||
"base_url": "模型的接口地址。若使用OpenAI官方:https://api.openai.com/v1。若使用Ollama本地部署,则类似 http://localhost:11434/v1。",
|
"base_url": "模型的接口地址。若使用OpenAI官方:https://api.openai.com/v1。若使用Ollama本地部署,则类似 http://localhost:11434/v1。调用Gemini模型则无需填写。",
|
||||||
"interface_format": "指定LLM接口兼容格式,可选DeepSeek、OpenAI、Ollama、ML Studio等。\n\n注意:"+
|
"interface_format": "指定LLM接口兼容格式,可选DeepSeek、OpenAI、Ollama、ML Studio、Gemini等。\n\n注意:"+
|
||||||
"OpenAI 兼容是指的可以通过该标准请求的任何接口,不是只允许使用api.openai.com接口\n"+
|
"OpenAI 兼容是指的可以通过该标准请求的任何接口,不是只允许使用api.openai.com接口\n"+
|
||||||
"例如Ollama接口格式也兼容OpenAI,可以无需修改直接使用\n"+
|
"例如Ollama接口格式也兼容OpenAI,可以无需修改直接使用\n"+
|
||||||
"ML Studio接口格式与OpenAI接口格式也一致。",
|
"ML Studio接口格式与OpenAI接口格式也一致。",
|
||||||
|
|||||||
@@ -373,6 +373,8 @@ class NovelGeneratorGUI:
|
|||||||
self.base_url_var.set("https://[az].openai.azure.com/openai/deployments/[model]/chat/completions?api-version=2024-08-01-preview")
|
self.base_url_var.set("https://[az].openai.azure.com/openai/deployments/[model]/chat/completions?api-version=2024-08-01-preview")
|
||||||
elif new_value == "DeepSeek":
|
elif new_value == "DeepSeek":
|
||||||
self.base_url_var.set("https://api.deepseek.com/v1")
|
self.base_url_var.set("https://api.deepseek.com/v1")
|
||||||
|
elif new_value == "Gemini":
|
||||||
|
self.base_url_var.set("") # Gemini 通常不需要 Base URL,可以设置为空
|
||||||
|
|
||||||
for i in range(7):
|
for i in range(7):
|
||||||
self.ai_config_tab.grid_rowconfigure(i, weight=0)
|
self.ai_config_tab.grid_rowconfigure(i, weight=0)
|
||||||
@@ -413,7 +415,7 @@ class NovelGeneratorGUI:
|
|||||||
column=0,
|
column=0,
|
||||||
font=("Microsoft YaHei", 12)
|
font=("Microsoft YaHei", 12)
|
||||||
)
|
)
|
||||||
interface_options = ["DeepSeek", "OpenAI", "Azure OpenAI", "Ollama", "ML Studio"]
|
interface_options = ["DeepSeek", "OpenAI", "Azure OpenAI", "Ollama", "ML Studio", "Gemini"]
|
||||||
interface_dropdown = ctk.CTkOptionMenu(
|
interface_dropdown = ctk.CTkOptionMenu(
|
||||||
self.ai_config_tab,
|
self.ai_config_tab,
|
||||||
values=interface_options,
|
values=interface_options,
|
||||||
|
|||||||
Reference in New Issue
Block a user