diff --git a/.gitignore b/.gitignore index b239dd5..0242a4c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ config.json config_test.json /novel_generator/__pycache__ /ui/__pycache__ +.idea/ diff --git a/llm_adapters.py b/llm_adapters.py index 141bc53..979d366 100644 --- a/llm_adapters.py +++ b/llm_adapters.py @@ -3,8 +3,10 @@ import logging from typing import Optional from langchain_openai import ChatOpenAI, AzureChatOpenAI -from google import genai -from google.genai import types +# from google import genai +import google.generativeai as genai +# from google.genai import types +from google.generativeai import types from azure.ai.inference import ChatCompletionsClient from azure.core.credentials import AzureKeyCredential from azure.ai.inference.models import SystemMessage, UserMessage @@ -338,6 +340,45 @@ class SiliconFlowAdapter(BaseLLMAdapter): except Exception as e: logging.error(f"硅基流动API调用超时或失败: {e}") return "" +# grok實現 +class GrokAdapter(BaseLLMAdapter): + """ + 适配 xAI Grok API + """ + def __init__(self, api_key: str, base_url: str, model_name: str, max_tokens: int, temperature: float = 0.7, timeout: Optional[int] = 600): + self.base_url = check_base_url(base_url) + self.api_key = api_key + self.model_name = model_name + self.max_tokens = max_tokens + self.temperature = temperature + self.timeout = timeout + + self._client = OpenAI( + base_url=self.base_url, + api_key=self.api_key, + timeout=self.timeout + ) + + def invoke(self, prompt: str) -> str: + try: + response = self._client.chat.completions.create( + model=self.model_name, + messages=[ + {"role": "system", "content": "You are Grok, created by xAI."}, + {"role": "user", "content": prompt}, + ], + max_tokens=self.max_tokens, + temperature=self.temperature, + timeout=self.timeout + ) + if response and response.choices: + return response.choices[0].message.content + else: + logging.warning("No response from GrokAdapter.") + return "" + except Exception as e: + logging.error(f"Grok API 调用失败: {e}") + return "" def create_llm_adapter( interface_format: str, @@ -372,5 +413,7 @@ def create_llm_adapter( return VolcanoEngineAIAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout) elif fmt == "硅基流动": return SiliconFlowAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout) + elif fmt == "grok": + return GrokAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout) else: raise ValueError(f"Unknown interface_format: {interface_format}") diff --git a/ui/config_tab.py b/ui/config_tab.py index 2840679..0a8bfd9 100644 --- a/ui/config_tab.py +++ b/ui/config_tab.py @@ -95,6 +95,9 @@ def build_ai_config_tab(self): elif new_value == "硅基流动": self.base_url_var.set("https://api.siliconflow.cn/v1") self.model_name_var.set("deepseek-ai/DeepSeek-V3") + elif new_value == "Grok": + self.base_url_var.set("https://api.x.ai/v1") + self.model_name_var.set("grok-3") for i in range(7): self.ai_config_tab.grid_rowconfigure(i, weight=0) @@ -114,8 +117,8 @@ def build_ai_config_tab(self): # 3) 接口格式 create_label_with_help(self, parent=self.ai_config_tab, label_text="LLM 接口格式:", tooltip_key="interface_format", row=2, column=0, font=("Microsoft YaHei", 12)) - # 在这里的接口选项列表中添加 "硅基流动" - interface_options = ["DeepSeek", "阿里云百炼", "OpenAI", "Azure OpenAI", "Azure AI", "Ollama", "ML Studio", "Gemini", "火山引擎", "硅基流动"] + # 在接口选项列表中添加 "Grok" + interface_options = ["DeepSeek", "阿里云百炼", "OpenAI", "Azure OpenAI", "Azure AI", "Ollama", "ML Studio", "Gemini", "火山引擎", "硅基流动", "Grok"] interface_dropdown = ctk.CTkOptionMenu(self.ai_config_tab, values=interface_options, variable=self.interface_format_var, command=on_interface_format_changed, font=("Microsoft YaHei", 12)) interface_dropdown.grid(row=2, column=1, padx=5, pady=5, columnspan=2, sticky="nsew") @@ -316,4 +319,4 @@ def save_config_btn(self): messagebox.showinfo("提示", "配置已保存至 config.json") self.log("配置已保存。") else: - messagebox.showerror("错误", "保存配置失败。") + messagebox.showerror("错误", "保存配置失败。") \ No newline at end of file