feat: add Grok API support in llm_adapters and config_tab UI
This commit is contained in:
@@ -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
@@ -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
@@ -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("错误", "保存配置失败。")
|
||||||
Reference in New Issue
Block a user