Spaces:
Running
Running
| import gradio as gr | |
| import pandas as pd | |
| from model_handler import ModelHandler | |
| from config import LING_1T | |
| def _format_df_to_string(df: pd.DataFrame, title: str) -> str: | |
| """Formats a pandas DataFrame into a markdown-like string for the prompt.""" | |
| if df is None or df.empty: | |
| return "" | |
| header = f"### {title}\n" | |
| rows = [] | |
| for _, row in df.iterrows(): | |
| if 'Done' in df.columns and 'Task' in df.columns: | |
| status = "[x]" if row['Done'] else "[ ]" | |
| rows.append(f"- {status} {row['Task']}") | |
| elif 'Term' in df.columns and 'Description' in df.columns: | |
| rows.append(f"- **{row['Term']}**: {row['Description']}") | |
| return header + "\n".join(rows) + "\n\n" | |
| def fetch_inspiration_agent(prompt: str, editor_content: str, style: str, kb_df: pd.DataFrame, short_outline_df: pd.DataFrame, long_outline_df: pd.DataFrame): | |
| """ | |
| Agent for fetching inspiration options using a real LLM. | |
| """ | |
| print("\n[Agent][fetch_inspiration_agent] === 推理类型:灵感扩写 ===") | |
| print("【发出的完整上下文】") | |
| print("prompt:", repr(prompt)) | |
| print("editor_content:", repr(editor_content)) | |
| print("style:", repr(style)) | |
| print("kb_df:", repr(kb_df.to_dict("records"))) | |
| print("short_outline_df:", repr(short_outline_df.to_dict("records"))) | |
| print("long_outline_df:", repr(long_outline_df.to_dict("records"))) | |
| try: | |
| # 1. Format context from UI inputs | |
| style_context = f"### 整体章程\n{style}\n\n" | |
| kb_context = _format_df_to_string(kb_df, "知识库") | |
| short_outline_context = _format_df_to_string(short_outline_df, "当前章节大纲") | |
| long_outline_context = _format_df_to_string(long_outline_df, "故事总纲") | |
| # 2. Build System Prompt | |
| system_prompt = ( | |
| "你是一个富有创意的长篇小说家,你的任务是根据提供的背景设定和当前文本,创作三个不同的、有创意的剧情发展方向。\n" | |
| "请严格遵守以下格式:直接开始写第一个选项,然后用 `[END_OF_CHOICE]` 作为分隔符,接着写第二个选项,再用 `[END_OF_CHOICE]` 分隔,最后写第三个选项。不要有任何额外的解释或编号。\n" | |
| "例如:\n" | |
| "剧情发展一的内容...[END_OF_CHOICE]剧情发展二的内容...[END_OF_CHOICE]剧情发展三的内容..." | |
| ) | |
| # 3. Build User Prompt | |
| full_context = style_context + kb_context + long_outline_context + short_outline_context | |
| user_prompt = ( | |
| f"### 背景设定与大纲\n{full_context}\n" | |
| f"### 当前已写内容 (末尾部分)\n{editor_content[-2000:]}\n\n" | |
| f"### 用户指令\n{prompt if prompt else '请基于当前内容,自然地延续剧情。'}" | |
| ) | |
| # 4. Call LLM | |
| model_handler = ModelHandler() | |
| response_generator = model_handler.generate_code( | |
| system_prompt=system_prompt, | |
| user_prompt=user_prompt, | |
| model_choice=LING_1T | |
| ) | |
| full_response = "".join(chunk for chunk in response_generator) | |
| print("【收到的完整上下文】") | |
| print("full_response:", repr(full_response)) | |
| # 5. Parse response and update UI | |
| choices = full_response.split("[END_OF_CHOICE]") | |
| # Ensure we have exactly 3 choices, padding with placeholders if necessary | |
| choices += ["(模型未生成足够选项)"] * (3 - len(choices)) | |
| print(f"[Agent] LLM Choices Received: {len(choices)}") | |
| return gr.update(visible=True), choices[0].strip(), choices[1].strip(), choices[2].strip() | |
| except Exception as e: | |
| print(f"[Agent] Error fetching inspiration: {e}") | |
| error_message = f"获取灵感时出错: {e}" | |
| return gr.update(visible=True), error_message, "请检查日志", "请检查日志" | |
| def fetch_paragraph_continuation_agent(prompt: str, editor_content: str, style: str, kb_df: pd.DataFrame, short_outline_df: pd.DataFrame, long_outline_df: pd.DataFrame): | |
| """ | |
| Agent for fetching a single paragraph continuation (Ribbon UI version). | |
| """ | |
| print("\n[Agent][fetch_paragraph_continuation_agent] === 推理类型:整段续写 (Single) ===") | |
| try: | |
| # 1. Format context | |
| style_context = f"### 整体章程\n{style}\n\n" | |
| kb_context = _format_df_to_string(kb_df, "知识库") | |
| short_outline_context = _format_df_to_string(short_outline_df, "当前章节大纲") | |
| long_outline_context = _format_df_to_string(long_outline_df, "故事总纲") | |
| # 2. Build System Prompt | |
| system_prompt = ( | |
| "你是一个富有创意的长篇小说家。请根据提供的背景设定和当前文本,自然地续写一段高质量的剧情。\n" | |
| "请直接输出续写内容,不要包含任何解释、前缀或后缀。" | |
| ) | |
| # 3. Build User Prompt | |
| full_context = style_context + kb_context + long_outline_context + short_outline_context | |
| user_prompt = ( | |
| f"### 背景设定与大纲\n{full_context}\n" | |
| f"### 当前已写内容 (末尾部分)\n{editor_content[-2000:]}\n\n" | |
| f"### 用户指令\n{prompt if prompt else '请基于当前内容,自然地延续剧情,写一个完整的段落。'}" | |
| ) | |
| # 4. Call LLM | |
| model_handler = ModelHandler() | |
| response_generator = model_handler.generate_code( | |
| system_prompt=system_prompt, | |
| user_prompt=user_prompt, | |
| model_choice=LING_1T | |
| ) | |
| full_response = "".join(chunk for chunk in response_generator) | |
| return full_response.strip() | |
| except Exception as e: | |
| print(f"[Agent] Error fetching paragraph continuation: {e}") | |
| return f"获取续写时出错: {e}" | |
| def apply_inspiration_agent(current_text: str, inspiration_text: str): | |
| """ | |
| Agent for applying selected inspiration to the editor. | |
| """ | |
| print("\n[Agent][apply_inspiration_agent] === 推理类型:应用灵感 ===") | |
| print("【发出的完整上下文】") | |
| print("current_text:", repr(current_text)) | |
| print("inspiration_text:", repr(inspiration_text)) | |
| if not current_text: | |
| new_text = inspiration_text | |
| else: | |
| new_text = current_text + "\n\n" + inspiration_text | |
| print("【收到的完整上下文】") | |
| print("new_text:", repr(new_text)) | |
| # Return a tuple that unpacks into the outputs for the Gradio event handler | |
| return new_text, gr.update(visible=False), "" | |