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