UI更新、新增本地适配

This commit is contained in:
YILING0013
2025-02-02 19:22:54 +08:00
parent 4b8ceffc01
commit bc6e2ff869
3 changed files with 23 additions and 32 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
# embedding_ollama.py # embedding_ollama.py
import requests import requests
import traceback
from typing import List from typing import List
class OllamaEmbeddings: class OllamaEmbeddings:
@@ -51,4 +52,4 @@ class OllamaEmbeddings:
raise ValueError("No 'embedding' field in Ollama response.") raise ValueError("No 'embedding' field in Ollama response.")
return result["embedding"] return result["embedding"]
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
raise Exception(f"Ollama embeddings request error: {e}") raise Exception(f"Ollama embeddings request error: {e}\n{traceback.format_exc()}")
+5 -16
View File
@@ -3,6 +3,7 @@
import os import os
import logging import logging
import re import re
import traceback
from typing import Dict, List, Optional from typing import Dict, List, Optional
from typing import TypedDict from typing import TypedDict
@@ -59,25 +60,19 @@ def invoke_with_cleaning(model: ChatOpenAI, prompt: str) -> str:
return cleaned_text.strip() return cleaned_text.strip()
# ============ 判断接口格式相关 ============ # ============ 判断接口格式相关 ============
def is_using_ollama_api(interface_format: str, base_url: str) -> bool: def is_using_ollama_api(interface_format: str, base_url: str) -> bool:
""" """
当 interface_format == "Ollama" 时返回 True 当 interface_format == "Ollama" 时返回 True
""" """
if interface_format.lower() == "ollama": return interface_format.lower() == "ollama"
return True
return False
def is_using_ml_studio_api(interface_format: str, base_url: str) -> bool: def is_using_ml_studio_api(interface_format: str, base_url: str) -> bool:
""" """
如果用户在下拉里选择了 ML Studio 如果用户在下拉里选择了 ML Studio
""" """
if interface_format.lower() == "ml studio": return interface_format.lower() == "ml studio"
return True
return False
# ============ 创建 Embeddings 对象 ============ # ============ 创建 Embeddings 对象 ============
def create_embeddings_object( def create_embeddings_object(
api_key: str, api_key: str,
base_url: str, base_url: str,
@@ -106,7 +101,6 @@ def create_embeddings_object(
return OpenAIEmbeddings(openai_api_key=api_key, openai_api_base=base_url) return OpenAIEmbeddings(openai_api_key=api_key, openai_api_base=base_url)
# ============ 向量库相关 ============ # ============ 向量库相关 ============
VECTOR_STORE_DIR = os.path.join(os.getcwd(), "vectorstore") VECTOR_STORE_DIR = os.path.join(os.getcwd(), "vectorstore")
if not os.path.exists(VECTOR_STORE_DIR): if not os.path.exists(VECTOR_STORE_DIR):
os.makedirs(VECTOR_STORE_DIR) os.makedirs(VECTOR_STORE_DIR)
@@ -125,8 +119,8 @@ def clear_vector_store():
elif os.path.isdir(file_path): elif os.path.isdir(file_path):
shutil.rmtree(file_path) shutil.rmtree(file_path)
logging.info("Local vector store has been cleared.") logging.info("Local vector store has been cleared.")
except Exception as e: except Exception:
logging.warning(f"Failed to clear vector store: {e}") logging.warning(f"Failed to clear vector store:\n{traceback.format_exc()}")
else: else:
logging.info("No vector store found to clear.") logging.info("No vector store found to clear.")
@@ -253,7 +247,6 @@ def get_relevant_context_from_vector_store(
return combined return combined
# ============ 多步生成:设置 & 目录 ============ # ============ 多步生成:设置 & 目录 ============
class OverallState(TypedDict): class OverallState(TypedDict):
topic: str topic: str
genre: str genre: str
@@ -383,7 +376,6 @@ def Novel_novel_directory_generate(
logging.info("Novel settings and directory generated successfully.") logging.info("Novel settings and directory generated successfully.")
# ============ 获取最近N章内容,生成短期摘要 ============ # ============ 获取最近N章内容,生成短期摘要 ============
def get_last_n_chapters_text(chapters_dir: str, current_chapter_num: int, n: int = 3) -> List[str]: def get_last_n_chapters_text(chapters_dir: str, current_chapter_num: int, n: int = 3) -> List[str]:
""" """
从指定文件夹中,读取最近 n 章的内容(如果存在),并按从旧到新的顺序返回文本列表。 从指定文件夹中,读取最近 n 章的内容(如果存在),并按从旧到新的顺序返回文本列表。
@@ -436,7 +428,6 @@ def summarize_recent_chapters(
return summary_text return summary_text
# ============ 新增:剧情要点/未解决冲突 ============ # ============ 新增:剧情要点/未解决冲突 ============
PLOT_ARCS_PROMPT = """\ PLOT_ARCS_PROMPT = """\
下面是新生成的章节内容: 下面是新生成的章节内容:
{chapter_text} {chapter_text}
@@ -474,7 +465,6 @@ def update_plot_arcs(
return arcs_text return arcs_text
# ============ 生成章节草稿 & 定稿 ============ # ============ 生成章节草稿 & 定稿 ============
def generate_chapter_draft( def generate_chapter_draft(
novel_settings: str, novel_settings: str,
global_summary: str, global_summary: str,
@@ -707,7 +697,6 @@ def enrich_chapter_text(
return enriched_text if enriched_text else chapter_text return enriched_text if enriched_text else chapter_text
# ============ 导入外部知识文本 ============ # ============ 导入外部知识文本 ============
def import_knowledge_file( def import_knowledge_file(
api_key: str, api_key: str,
base_url: str, base_url: str,
+16 -15
View File
@@ -95,6 +95,12 @@ class NovelGeneratorGUI:
# 全局摘要 Tab # 全局摘要 Tab
self.build_summary_tab() self.build_summary_tab()
# ------------------ 统一异常处理方法 ------------------
def handle_exception(self, context: str):
full_message = f"{context}\n{traceback.format_exc()}"
logging.error(full_message)
self.safe_log(full_message)
# ------------------ 主功能 Tab ------------------ # ------------------ 主功能 Tab ------------------
def build_main_tab(self): def build_main_tab(self):
self.main_tab.rowconfigure(0, weight=1) self.main_tab.rowconfigure(0, weight=1)
@@ -617,9 +623,8 @@ class NovelGeneratorGUI:
temperature=temperature temperature=temperature
) )
self.safe_log("✅ 小说设定和目录生成完成。查看 Novel_setting.txt 和 Novel_directory.txt。") self.safe_log("✅ 小说设定和目录生成完成。查看 Novel_setting.txt 和 Novel_directory.txt。")
except Exception as e: except Exception:
log_error(f"生成小说设定 & 目录时出错: {e}") self.handle_exception("生成小说设定 & 目录时出错")
self.safe_log(f"❌ 生成小说设定 & 目录时出错: {e}")
finally: finally:
self.enable_button_safe(self.btn_generate_full) self.enable_button_safe(self.btn_generate_full)
@@ -695,9 +700,8 @@ class NovelGeneratorGUI:
else: else:
self.safe_log("⚠️ 本章草稿生成失败或无内容。") self.safe_log("⚠️ 本章草稿生成失败或无内容。")
except Exception as e: except Exception:
log_error(f"生成章节草稿时出错: {e}") self.handle_exception("生成章节草稿时出错")
self.safe_log(f"❌ 生成章节草稿时出错: {e}")
finally: finally:
self.enable_button_safe(self.btn_generate_chapter) self.enable_button_safe(self.btn_generate_chapter)
@@ -747,9 +751,8 @@ class NovelGeneratorGUI:
final_text = read_file(chap_file) final_text = read_file(chap_file)
self.master.after(0, lambda: self.show_chapter_in_textbox(final_text)) self.master.after(0, lambda: self.show_chapter_in_textbox(final_text))
except Exception as e: except Exception:
log_error(f"定稿章节时出错: {e}") self.handle_exception("定稿章节时出错")
self.safe_log(f"❌ 定稿章节时出错: {e}")
finally: finally:
self.enable_button_safe(self.btn_finalize_chapter) self.enable_button_safe(self.btn_finalize_chapter)
@@ -803,9 +806,8 @@ class NovelGeneratorGUI:
self.safe_log("审校结果:") self.safe_log("审校结果:")
self.safe_log(result) self.safe_log(result)
except Exception as e: except Exception:
log_error(f"审校时出错: {e}") self.handle_exception("审校时出错")
self.safe_log(f"❌ 审校时出错: {e}")
finally: finally:
self.enable_button_safe(self.btn_check_consistency) self.enable_button_safe(self.btn_check_consistency)
@@ -831,9 +833,8 @@ class NovelGeneratorGUI:
embedding_base_url=self.embedding_url_var.get().strip() embedding_base_url=self.embedding_url_var.get().strip()
) )
self.safe_log("✅ 知识库文件导入完成。") self.safe_log("✅ 知识库文件导入完成。")
except Exception as e: except Exception:
log_error(f"导入知识库时出错: {e}") self.handle_exception("导入知识库时出错")
self.safe_log(f"❌ 导入知识库时出错: {e}")
finally: finally:
self.enable_button_safe(self.btn_import_knowledge) self.enable_button_safe(self.btn_import_knowledge)