Merge pull request #170 from capybaraDawn/feature/add-grok-api

feat: add Grok API support in llm_adapters and config_tab UI
This commit is contained in:
IdleCloud
2025-06-30 23:13:04 +08:00
committed by GitHub
3 changed files with 52 additions and 5 deletions
+1
View File
@@ -11,3 +11,4 @@ config.json
config_test.json config_test.json
/novel_generator/__pycache__ /novel_generator/__pycache__
/ui/__pycache__ /ui/__pycache__
.idea/
+45 -2
View File
@@ -3,8 +3,10 @@
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 import genai
from google.genai import types import google.generativeai as genai
# from google.genai import types
from google.generativeai import types
from azure.ai.inference import ChatCompletionsClient from azure.ai.inference import ChatCompletionsClient
from azure.core.credentials import AzureKeyCredential from azure.core.credentials import AzureKeyCredential
from azure.ai.inference.models import SystemMessage, UserMessage from azure.ai.inference.models import SystemMessage, UserMessage
@@ -338,6 +340,45 @@ class SiliconFlowAdapter(BaseLLMAdapter):
except Exception as e: except Exception as e:
logging.error(f"硅基流动API调用超时或失败: {e}") logging.error(f"硅基流动API调用超时或失败: {e}")
return "" 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( def create_llm_adapter(
interface_format: str, interface_format: str,
@@ -372,5 +413,7 @@ def create_llm_adapter(
return VolcanoEngineAIAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout) return VolcanoEngineAIAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout)
elif fmt == "硅基流动": elif fmt == "硅基流动":
return SiliconFlowAdapter(api_key, base_url, model_name, max_tokens, temperature, timeout) 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: else:
raise ValueError(f"Unknown interface_format: {interface_format}") raise ValueError(f"Unknown interface_format: {interface_format}")
+6 -3
View File
@@ -95,6 +95,9 @@ def build_ai_config_tab(self):
elif new_value == "硅基流动": elif new_value == "硅基流动":
self.base_url_var.set("https://api.siliconflow.cn/v1") self.base_url_var.set("https://api.siliconflow.cn/v1")
self.model_name_var.set("deepseek-ai/DeepSeek-V3") 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): for i in range(7):
self.ai_config_tab.grid_rowconfigure(i, weight=0) self.ai_config_tab.grid_rowconfigure(i, weight=0)
@@ -114,8 +117,8 @@ def build_ai_config_tab(self):
# 3) 接口格式 # 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)) 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))
# 在这里的接口选项列表中添加 "硅基流动" # 在接口选项列表中添加 "Grok"
interface_options = ["DeepSeek", "阿里云百炼", "OpenAI", "Azure OpenAI", "Azure AI", "Ollama", "ML Studio", "Gemini", "火山引擎", "硅基流动"] 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 = 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") 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") messagebox.showinfo("提示", "配置已保存至 config.json")
self.log("配置已保存。") self.log("配置已保存。")
else: else:
messagebox.showerror("错误", "保存配置失败。") messagebox.showerror("错误", "保存配置失败。")