Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,556 +1,556 @@
|
|
1 |
-
import random
|
2 |
-
import threading
|
3 |
-
import time
|
4 |
-
import requests
|
5 |
-
import json
|
6 |
-
import base64
|
7 |
-
import os
|
8 |
-
import gradio as gr
|
9 |
-
import re
|
10 |
-
|
11 |
-
from AIGN import AIGN
|
12 |
-
from openAI import openAIChatLLM
|
13 |
-
|
14 |
-
chatLLM = openAIChatLLM()
|
15 |
-
|
16 |
-
STREAM_INTERVAL = 0.2
|
17 |
-
CURRENT_MODEL = "gpt-4o-mini" # 默认模型
|
18 |
-
|
19 |
-
# 在文件开头添加以下函数
|
20 |
-
def clear_console():
|
21 |
-
# 根据操作系统类型选择清屏命令
|
22 |
-
if os.name == 'nt': # Windows
|
23 |
-
os.system('cls')
|
24 |
-
else: # Mac and Linux
|
25 |
-
os.system('clear')
|
26 |
-
|
27 |
-
def get_model_options():
|
28 |
-
try:
|
29 |
-
response = requests.get("https://api.deem.love/v1/models")
|
30 |
-
data = response.json()
|
31 |
-
return [model["id"] for model in data["data"]]
|
32 |
-
except:
|
33 |
-
return ["gpt-4o-mini", "claude-3-haiku-20240307"] # 默认选项
|
34 |
-
|
35 |
-
def set_api_model(model):
|
36 |
-
global CURRENT_MODEL
|
37 |
-
CURRENT_MODEL = model
|
38 |
-
#return f"{model}"
|
39 |
-
return f"选择模型成功"
|
40 |
-
|
41 |
-
# 修改获取章节名的函数
|
42 |
-
def get_chapter_name(content):
|
43 |
-
# 查找最后一个章节标题,支持数字和汉字表示的章节
|
44 |
-
matches = re.findall(r'(?:##?|)?\s*第([一二三四五六七八九十百千万亿\d]+)章[::]?\s*(.+)', content)
|
45 |
-
if matches:
|
46 |
-
chapter_num, chapter_title = matches[-1]
|
47 |
-
# 如果章节号是数字,直接使用;如果是汉字,转换为数字
|
48 |
-
if chapter_num.isdigit():
|
49 |
-
return f"第{chapter_num}章:{chapter_title.strip()}"
|
50 |
-
else:
|
51 |
-
# 这里可以添加一个函数来将汉字数字转换为阿拉伯数字
|
52 |
-
# 为了简单起见,这里仍然使用汉字表示
|
53 |
-
return f"第{chapter_num}章:{chapter_title.strip()}"
|
54 |
-
return "未知章节"
|
55 |
-
|
56 |
-
# 修改保存进度函数
|
57 |
-
def save_progress(aign):
|
58 |
-
chapter_name = get_chapter_name(aign.novel_content)
|
59 |
-
# 移除文件名中的非法字符
|
60 |
-
filename = re.sub(r'[\\/*?:"<>|]', '', chapter_name)
|
61 |
-
filename = f"{filename}.json"
|
62 |
-
|
63 |
-
data = {
|
64 |
-
"novel_outline": aign.novel_outline,
|
65 |
-
"paragraph_list": aign.paragraph_list,
|
66 |
-
"novel_content": aign.novel_content,
|
67 |
-
"writing_plan": aign.writing_plan,
|
68 |
-
"temp_setting": aign.temp_setting,
|
69 |
-
"writing_memory": aign.writing_memory,
|
70 |
-
"user_idea": aign.user_idea,
|
71 |
-
"user_requriments": aign.user_requriments,
|
72 |
-
}
|
73 |
-
|
74 |
-
json_str = json.dumps(data, ensure_ascii=False, indent=2)
|
75 |
-
b64 = base64.b64encode(json_str.encode()).decode()
|
76 |
-
href = f"data:application/json;base64,{b64}"
|
77 |
-
download_link = f'<a href="{href}" download="{filename}">点击下载进度文件</a>'
|
78 |
-
return download_link
|
79 |
-
|
80 |
-
# 修改加载函数
|
81 |
-
def load_progress(aign, file):
|
82 |
-
try:
|
83 |
-
if file is None:
|
84 |
-
return aign, "请选择要加载的文件", None, None, None, None, None, None, None, None
|
85 |
-
|
86 |
-
# 检查 file 是否为字符串(文件路径)
|
87 |
-
if isinstance(file, str):
|
88 |
-
with open(file, 'r', encoding='utf-8') as f:
|
89 |
-
content = f.read()
|
90 |
-
# 检查 file 是否有 name 属性(Gradio File 对象)
|
91 |
-
elif hasattr(file, 'name'):
|
92 |
-
with open(file.name, 'r', encoding='utf-8') as f:
|
93 |
-
content = f.read()
|
94 |
-
else:
|
95 |
-
return aign, f"无法读取文件", None, None, None, None, None, None, None, None
|
96 |
-
|
97 |
-
data = json.loads(content)
|
98 |
-
|
99 |
-
aign.novel_outline = data["novel_outline"]
|
100 |
-
aign.paragraph_list = data["paragraph_list"]
|
101 |
-
aign.novel_content = data["novel_content"]
|
102 |
-
aign.writing_plan = data["writing_plan"]
|
103 |
-
aign.temp_setting = data["temp_setting"]
|
104 |
-
aign.writing_memory = data["writing_memory"]
|
105 |
-
aign.user_idea = data["user_idea"]
|
106 |
-
aign.user_requriments = data["user_requriments"]
|
107 |
-
#aign.embellishment_idea = data["embellishment_idea"]
|
108 |
-
aign.update_chapter_list()
|
109 |
-
chapter_choices = [title for title, _ in aign.chapter_list]
|
110 |
-
|
111 |
-
return aign, f"进度已加载", data["novel_outline"], data["novel_content"], data["writing_plan"], data["temp_setting"], data["writing_memory"], data["user_idea"], data["user_requriments"], gr.Dropdown(choices=chapter_choices, value=chapter_choices[-1] if chapter_choices else None)
|
112 |
-
except Exception as e:
|
113 |
-
return aign, f"加载失败: {str(e)}", None, None, None, None, None, None, None, None
|
114 |
-
|
115 |
-
# 新增保存正文函数
|
116 |
-
def save_content(content):
|
117 |
-
if not content:
|
118 |
-
return "正文为空,无需保存"
|
119 |
-
|
120 |
-
b64 = base64.b64encode(content.encode()).decode()
|
121 |
-
href = f"data:text/plain;base64,{b64}"
|
122 |
-
download_link = f'<a href="{href}" download="novel_content.txt">点击下载正文</a>'
|
123 |
-
return download_link
|
124 |
-
|
125 |
-
# 添加撤销功能的事件处理
|
126 |
-
def undo_generation(aign, history):
|
127 |
-
if aign.undo():
|
128 |
-
return [
|
129 |
-
aign,
|
130 |
-
history,
|
131 |
-
aign.writing_plan,
|
132 |
-
aign.temp_setting,
|
133 |
-
aign.writing_memory,
|
134 |
-
aign.novel_content,
|
135 |
-
gr.Button(visible=True),
|
136 |
-
]
|
137 |
-
else:
|
138 |
-
return [
|
139 |
-
aign,
|
140 |
-
history + [["系统", "无法撤销,已经是最初状态"]],
|
141 |
-
aign.writing_plan,
|
142 |
-
aign.temp_setting,
|
143 |
-
aign.writing_memory,
|
144 |
-
aign.novel_content,
|
145 |
-
gr.Button(visible=True),
|
146 |
-
]
|
147 |
-
|
148 |
-
def display_chapter(chapters, page_num):
|
149 |
-
if 1 <= page_num <= len(chapters):
|
150 |
-
chapter_title, chapter_content = chapters[page_num - 1]
|
151 |
-
return f"{chapter_title}\n\n{chapter_content}"
|
152 |
-
else:
|
153 |
-
return "没有更多章节了。"
|
154 |
-
|
155 |
-
def prev_page(aign, current_page):
|
156 |
-
chapters = aign.chapter_list
|
157 |
-
if current_page > 1:
|
158 |
-
current_page -= 1
|
159 |
-
return current_page, display_chapter(chapters, current_page)
|
160 |
-
|
161 |
-
def next_page(aign, current_page):
|
162 |
-
chapters = aign.chapter_list
|
163 |
-
if current_page < len(chapters):
|
164 |
-
current_page += 1
|
165 |
-
return current_page, display_chapter(chapters, current_page)
|
166 |
-
|
167 |
-
def select_chapter(aign, chapter_title):
|
168 |
-
chapters = aign.chapter_list
|
169 |
-
for i, (title, _) in enumerate(chapters, start=1):
|
170 |
-
if title == chapter_title:
|
171 |
-
return i, display_chapter(chapters, i)
|
172 |
-
return 1, "章节未找到。"
|
173 |
-
|
174 |
-
|
175 |
-
def make_middle_chat():
|
176 |
-
carrier = threading.Event()
|
177 |
-
carrier.history = []
|
178 |
-
|
179 |
-
def middle_chat(messages, temperature=None, top_p=None):
|
180 |
-
nonlocal carrier
|
181 |
-
carrier.history.append([None, ""])
|
182 |
-
if len(carrier.history) > 20:
|
183 |
-
carrier.history = carrier.history[-16:]
|
184 |
-
try:
|
185 |
-
for resp in chatLLM(
|
186 |
-
messages, temperature=temperature, top_p=top_p, stream=True, model=CURRENT_MODEL
|
187 |
-
):
|
188 |
-
output_text = resp["content"]
|
189 |
-
total_tokens = resp["total_tokens"]
|
190 |
-
|
191 |
-
carrier.history[-1][1] = f"total_tokens: {total_tokens}\n{output_text}"
|
192 |
-
return {
|
193 |
-
"content": output_text,
|
194 |
-
"total_tokens": total_tokens,
|
195 |
-
}
|
196 |
-
except Exception as e:
|
197 |
-
carrier.history[-1][1] = f"Error: {e}"
|
198 |
-
raise e
|
199 |
-
|
200 |
-
return carrier, middle_chat
|
201 |
-
|
202 |
-
|
203 |
-
def gen_ouline_button_clicked(aign, user_idea, history):
|
204 |
-
clear_console() # 清空命令行
|
205 |
-
aign.user_idea = user_idea
|
206 |
-
|
207 |
-
carrier, middle_chat = make_middle_chat()
|
208 |
-
carrier.history = [] # 清空历史记录
|
209 |
-
aign.novel_outline_writer.chatLLM = middle_chat
|
210 |
-
|
211 |
-
gen_ouline_thread = threading.Thread(target=aign.
|
212 |
-
gen_ouline_thread.start()
|
213 |
-
|
214 |
-
while gen_ouline_thread.is_alive():
|
215 |
-
yield [
|
216 |
-
aign,
|
217 |
-
carrier.history,
|
218 |
-
aign.novel_outline,
|
219 |
-
gr.Button(visible=False),
|
220 |
-
]
|
221 |
-
time.sleep(STREAM_INTERVAL)
|
222 |
-
yield [
|
223 |
-
aign,
|
224 |
-
carrier.history,
|
225 |
-
aign.novel_outline,
|
226 |
-
gr.Button(visible=True),
|
227 |
-
]
|
228 |
-
|
229 |
-
|
230 |
-
def gen_beginning_button_clicked(
|
231 |
-
aign, history, novel_outline, user_requriments#, embellishment_idea
|
232 |
-
):
|
233 |
-
clear_console() # 清空命令行
|
234 |
-
aign.novel_outline = novel_outline
|
235 |
-
aign.user_requriments = user_requriments
|
236 |
-
#aign.embellishment_idea = embellishment_idea
|
237 |
-
|
238 |
-
carrier, middle_chat = make_middle_chat()
|
239 |
-
carrier.history = [] # 清空历史记录
|
240 |
-
aign.novel_beginning_writer.chatLLM = middle_chat
|
241 |
-
#aign.novel_embellisher.chatLLM = middle_chat
|
242 |
-
|
243 |
-
gen_beginning_thread = threading.Thread(target=aign.genBeginning)
|
244 |
-
gen_beginning_thread.start()
|
245 |
-
|
246 |
-
while gen_beginning_thread.is_alive():
|
247 |
-
yield [
|
248 |
-
aign,
|
249 |
-
carrier.history,
|
250 |
-
aign.writing_plan,
|
251 |
-
aign.temp_setting,
|
252 |
-
aign.novel_content,
|
253 |
-
gr.Button(visible=False),
|
254 |
-
]
|
255 |
-
time.sleep(STREAM_INTERVAL)
|
256 |
-
yield [
|
257 |
-
aign,
|
258 |
-
carrier.history,
|
259 |
-
aign.writing_plan,
|
260 |
-
aign.temp_setting,
|
261 |
-
aign.novel_content,
|
262 |
-
gr.Button(visible=True),
|
263 |
-
]
|
264 |
-
|
265 |
-
|
266 |
-
def gen_next_paragraph_button_clicked(
|
267 |
-
aign,
|
268 |
-
history,
|
269 |
-
user_idea,
|
270 |
-
novel_outline,
|
271 |
-
writing_memory,
|
272 |
-
temp_setting,
|
273 |
-
writing_plan,
|
274 |
-
user_requriments,
|
275 |
-
#embellishment_idea,
|
276 |
-
):
|
277 |
-
# 生成保存进度链接
|
278 |
-
save_link = save_progress(aign) # 在函数开头定义保存进度链接
|
279 |
-
|
280 |
-
# 清空命令行
|
281 |
-
clear_console()
|
282 |
-
|
283 |
-
# 更新 AIGN 对象的各个字段
|
284 |
-
aign.user_idea = user_idea
|
285 |
-
aign.novel_outline = novel_outline
|
286 |
-
aign.writing_memory = writing_memory
|
287 |
-
aign.temp_setting = temp_setting
|
288 |
-
aign.writing_plan = writing_plan
|
289 |
-
aign.user_requriments = user_requriments
|
290 |
-
#aign.embellishment_idea = embellishment_idea
|
291 |
-
|
292 |
-
carrier, middle_chat = make_middle_chat()
|
293 |
-
carrier.history = [] # 清空历史记录
|
294 |
-
aign.novel_writer.chatLLM = middle_chat
|
295 |
-
#aign.novel_embellisher.chatLLM = middle_chat
|
296 |
-
aign.memory_maker.chatLLM = middle_chat
|
297 |
-
|
298 |
-
gen_next_paragraph_thread = threading.Thread(target=aign.genNextParagraph)
|
299 |
-
gen_next_paragraph_thread.start()
|
300 |
-
|
301 |
-
while gen_next_paragraph_thread.is_alive():
|
302 |
-
# 生成保存进度链接
|
303 |
-
save_link = save_progress(aign)
|
304 |
-
|
305 |
-
aign.update_chapter_list()
|
306 |
-
# 获取当前章节内容
|
307 |
-
current_chapter_content = display_chapter(aign.chapter_list, len(aign.chapter_list))
|
308 |
-
chapter_choices = [title for title, _ in aign.chapter_list]
|
309 |
-
yield [
|
310 |
-
aign,
|
311 |
-
carrier.history,
|
312 |
-
aign.writing_plan,
|
313 |
-
aign.temp_setting,
|
314 |
-
aign.writing_memory,
|
315 |
-
#aign.novel_content,#全部章节内容
|
316 |
-
current_chapter_content, # 只更新当前章节内容
|
317 |
-
gr.Button(visible=False),
|
318 |
-
save_link, # 返回生成的保存进度链接
|
319 |
-
gr.Dropdown(choices=chapter_choices, value=chapter_choices[-1] if chapter_choices else None),
|
320 |
-
]
|
321 |
-
time.sleep(STREAM_INTERVAL)
|
322 |
-
|
323 |
-
# 生成保存进度链接
|
324 |
-
save_link = save_progress(aign)
|
325 |
-
|
326 |
-
aign.update_chapter_list()
|
327 |
-
# 获取最终的当前章节内容
|
328 |
-
current_chapter_content = display_chapter(aign.chapter_list, len(aign.chapter_list))
|
329 |
-
chapter_choices = [title for title, _ in aign.chapter_list]
|
330 |
-
yield [
|
331 |
-
aign,
|
332 |
-
carrier.history,
|
333 |
-
aign.writing_plan,
|
334 |
-
aign.temp_setting,
|
335 |
-
aign.writing_memory,
|
336 |
-
#aign.novel_content, #全部章节内容
|
337 |
-
current_chapter_content, # 只更新当前章节内容
|
338 |
-
gr.Button(visible=True),
|
339 |
-
save_link, # 返回生成的保存进度链接
|
340 |
-
gr.Dropdown(choices=chapter_choices, value=chapter_choices[-1] if chapter_choices else None),
|
341 |
-
]
|
342 |
-
|
343 |
-
|
344 |
-
css = """
|
345 |
-
#row1 {
|
346 |
-
min-width: 200px;
|
347 |
-
height: calc(100vh - 180px);
|
348 |
-
overflow: auto;
|
349 |
-
}
|
350 |
-
#row2 {
|
351 |
-
min-width: 300px;
|
352 |
-
height: calc(100vh - 180px);
|
353 |
-
overflow: auto;
|
354 |
-
}
|
355 |
-
#row3 {
|
356 |
-
min-width: 200px;
|
357 |
-
height: calc(100vh - 180px);
|
358 |
-
overflow: auto;
|
359 |
-
}
|
360 |
-
"""
|
361 |
-
|
362 |
-
with gr.Blocks(css=css) as demo:
|
363 |
-
aign = gr.State(AIGN(chatLLM))
|
364 |
-
gr.
|
365 |
-
|
366 |
-
#gr.
|
367 |
-
|
368 |
-
# 添加模型选择下拉框
|
369 |
-
# with gr.Row(): 同一行
|
370 |
-
with gr.Row():
|
371 |
-
with gr.Column(scale=0, elem_id="row1"):
|
372 |
-
with gr.Tab("⚙"):
|
373 |
-
model_dropdown = gr.Dropdown(
|
374 |
-
choices=get_model_options(),
|
375 |
-
label="选择模型",
|
376 |
-
interactive=True,
|
377 |
-
value=CURRENT_MODEL
|
378 |
-
)
|
379 |
-
model_output = gr.Textbox(label="模型设置结果", interactive=False)
|
380 |
-
load_status = gr.Textbox(label="加载状态", interactive=False)
|
381 |
-
load_file = gr.File(label="选择加载文件", file_count="single", file_types=[".json"])
|
382 |
-
load_button = gr.Button("加载进度")
|
383 |
-
with gr.Tab("开始"):
|
384 |
-
gr.
|
385 |
-
user_idea_text = gr.Textbox(
|
386 |
-
"架空历史:\n\n1. 选择关键历史节点并改变\n2. 描述由此引发的历史走向变化\n3. 塑造新兴历史人物(可改编或原创)\n4. 构建独特社会结构、文化和思潮\n5. 想象可能出现的科技创新\n6. 概述世界格局重塑(国界、政体、国际关系)\n7. 用生动叙事呈现,让读者身临其境\n\n目标:创造合理又富想象力的平行宇宙,既有趣又引人深思。",
|
387 |
-
label="想法",
|
388 |
-
lines=16,
|
389 |
-
interactive=True,
|
390 |
-
)
|
391 |
-
user_requriments_text = gr.Textbox(
|
392 |
-
"1. 语言要求:\n - 不直白\n - 句式多变\n - 避免陈词滥调\n - 使用不寻常的词句\n - 运用隐喻和象征\n2. 创作风格:\n - 抽象\n - 富有意境和想象力\n - 具创意个性\n - 有力度\n - 画面感强\n - 音乐感佳\n - 浪漫气息浓厚\n - 语言深邃\n3. 表达目标:\n - 传达独特的神秘和魔幻感\n - 探索和反思自我与世界\n - 表达对自己和社会的孤独与关注\n4. 读者体验:有趣、惊奇、新鲜",
|
393 |
-
label="写作要求",
|
394 |
-
lines=6,
|
395 |
-
interactive=True,
|
396 |
-
)
|
397 |
-
gen_ouline_button = gr.Button("生成大纲")
|
398 |
-
with gr.Tab("大纲"):
|
399 |
-
novel_outline_text = gr.Textbox(
|
400 |
-
label="大纲", lines=33, interactive=True
|
401 |
-
)
|
402 |
-
#gen_beginning_button = gr.Button("生成开头")
|
403 |
-
#gen_next_paragraph_button = gr.Button("生成开头")
|
404 |
-
with gr.Tab("状态"):
|
405 |
-
writing_memory_text = gr.Textbox(
|
406 |
-
label="记忆",
|
407 |
-
lines=8,
|
408 |
-
interactive=True,
|
409 |
-
max_lines=8,
|
410 |
-
)
|
411 |
-
writing_plan_text = gr.Textbox(label="计划", lines=6, interactive=True, max_lines=6)
|
412 |
-
temp_setting_text = gr.Textbox(
|
413 |
-
label="临时设定", lines=5, interactive=True, max_lines=5
|
414 |
-
)
|
415 |
-
gen_next_paragraph_button = gr.Button("生成章节")
|
416 |
-
download_link = gr.HTML()
|
417 |
-
save_button = gr.Button("保存进度")
|
418 |
-
with gr.Tab("导航"):
|
419 |
-
save_content_button = gr.Button("保存正文")
|
420 |
-
current_page = gr.Number(value=1, label="当前页码", interactive=False)
|
421 |
-
prev_button = gr.Button("上一页")
|
422 |
-
next_button = gr.Button("下一页")
|
423 |
-
|
424 |
-
# 添加章节导航下拉列表
|
425 |
-
chapter_dropdown = gr.Dropdown(label="章节导航", choices=[], interactive=True)
|
426 |
-
|
427 |
-
# TODO
|
428 |
-
# gen_next_paragraph_button = gr.Button("撤销生成")
|
429 |
-
#undo_button = gr.Button("撤销生成")
|
430 |
-
# TODO
|
431 |
-
# auto_gen_next_checkbox = gr.Checkbox(
|
432 |
-
# label="自动生成下一段", checked=False, interactive=True
|
433 |
-
# )
|
434 |
-
|
435 |
-
with gr.Column(scale=3, elem_id="row2"):
|
436 |
-
chatBox = gr.Chatbot(height=f"80vh", label="输出")
|
437 |
-
with gr.Column(scale=0, elem_id="row3"):
|
438 |
-
novel_content_text = gr.Textbox(
|
439 |
-
label="小说正文", lines=35, interactive=True, show_copy_button=True
|
440 |
-
)
|
441 |
-
# TODO
|
442 |
-
# download_novel_button = gr.Button("下载小说")
|
443 |
-
|
444 |
-
#gr.
|
445 |
-
|
446 |
-
prev_button.click(
|
447 |
-
prev_page,
|
448 |
-
inputs=[aign, current_page],
|
449 |
-
outputs=[current_page, novel_content_text],
|
450 |
-
queue=False
|
451 |
-
)
|
452 |
-
|
453 |
-
next_button.click(
|
454 |
-
next_page,
|
455 |
-
inputs=[aign, current_page],
|
456 |
-
outputs=[current_page, novel_content_text],
|
457 |
-
queue=False
|
458 |
-
)
|
459 |
-
|
460 |
-
# 添加章节下拉列表的事件处理
|
461 |
-
chapter_dropdown.change(
|
462 |
-
select_chapter,
|
463 |
-
inputs=[aign, chapter_dropdown],
|
464 |
-
outputs=[current_page, novel_content_text],
|
465 |
-
queue=False
|
466 |
-
)
|
467 |
-
|
468 |
-
# 添加模型选择的事件处理
|
469 |
-
model_dropdown.change(
|
470 |
-
set_api_model,
|
471 |
-
inputs=[model_dropdown],
|
472 |
-
outputs=[model_output]
|
473 |
-
)
|
474 |
-
|
475 |
-
# 修改按钮事件
|
476 |
-
save_button.click(
|
477 |
-
save_progress,
|
478 |
-
inputs=[aign],
|
479 |
-
outputs=[download_link]
|
480 |
-
)
|
481 |
-
|
482 |
-
# 修改加载按钮事件,包含章节下拉列表的更新
|
483 |
-
load_button.click(
|
484 |
-
load_progress,
|
485 |
-
inputs=[aign, load_file],
|
486 |
-
outputs=[aign, load_status, novel_outline_text, novel_content_text, writing_plan_text, temp_setting_text, writing_memory_text, user_idea_text, user_requriments_text, chapter_dropdown]
|
487 |
-
)
|
488 |
-
|
489 |
-
# 添加保存正文按钮事件
|
490 |
-
save_content_button.click(
|
491 |
-
save_content,
|
492 |
-
inputs=[novel_content_text],
|
493 |
-
outputs=[download_link]
|
494 |
-
)
|
495 |
-
|
496 |
-
#undo_button.click(
|
497 |
-
#undo_generation,
|
498 |
-
#[aign, chatBox],
|
499 |
-
#[aign, chatBox, writing_plan_text, temp_setting_text, writing_memory_text, novel_content_text, undo_button],
|
500 |
-
#)
|
501 |
-
|
502 |
-
gen_ouline_button.click(
|
503 |
-
gen_ouline_button_clicked,
|
504 |
-
[aign, user_idea_text, chatBox],
|
505 |
-
[aign, chatBox, novel_outline_text, gen_ouline_button],
|
506 |
-
)
|
507 |
-
#gen_beginning_button.click(
|
508 |
-
#gen_beginning_button_clicked,
|
509 |
-
#[
|
510 |
-
#aign,
|
511 |
-
#chatBox,
|
512 |
-
#novel_outline_text,
|
513 |
-
#user_requriments_text,
|
514 |
-
#embellishment_idea_text,
|
515 |
-
#],
|
516 |
-
#[
|
517 |
-
#aign,
|
518 |
-
#chatBox,
|
519 |
-
#writing_plan_text,
|
520 |
-
#temp_setting_text,
|
521 |
-
#novel_content_text,
|
522 |
-
#gen_beginning_button,
|
523 |
-
#],
|
524 |
-
#)
|
525 |
-
|
526 |
-
# 修改生成下一段按钮事件,包含章节下拉列表的更新
|
527 |
-
gen_next_paragraph_button.click(
|
528 |
-
gen_next_paragraph_button_clicked,
|
529 |
-
[
|
530 |
-
aign,
|
531 |
-
chatBox,
|
532 |
-
user_idea_text,
|
533 |
-
novel_outline_text,
|
534 |
-
writing_memory_text,
|
535 |
-
temp_setting_text,
|
536 |
-
writing_plan_text,
|
537 |
-
user_requriments_text,
|
538 |
-
#embellishment_idea_text,
|
539 |
-
],
|
540 |
-
[
|
541 |
-
aign,
|
542 |
-
chatBox,
|
543 |
-
writing_plan_text,
|
544 |
-
temp_setting_text,
|
545 |
-
writing_memory_text,
|
546 |
-
novel_content_text,
|
547 |
-
gen_next_paragraph_button,
|
548 |
-
download_link, # 这里添加输出到下载链接
|
549 |
-
chapter_dropdown
|
550 |
-
],
|
551 |
-
)
|
552 |
-
|
553 |
-
if __name__ == "__main__":
|
554 |
-
demo.queue()
|
555 |
-
port = int(os.environ.get("PORT", 7860))
|
556 |
-
demo.launch(server_name="127.0.0.1", server_port=port
|
|
|
1 |
+
import random
|
2 |
+
import threading
|
3 |
+
import time
|
4 |
+
import requests
|
5 |
+
import json
|
6 |
+
import base64
|
7 |
+
import os
|
8 |
+
import gradio as gr
|
9 |
+
import re
|
10 |
+
|
11 |
+
from AIGN import AIGN
|
12 |
+
from openAI import openAIChatLLM
|
13 |
+
|
14 |
+
chatLLM = openAIChatLLM()
|
15 |
+
|
16 |
+
STREAM_INTERVAL = 0.2
|
17 |
+
CURRENT_MODEL = "gpt-4o-mini" # 默认模型
|
18 |
+
|
19 |
+
# 在文件开头添加以下函数
|
20 |
+
def clear_console():
|
21 |
+
# 根据操作系统类型选择清屏命令
|
22 |
+
if os.name == 'nt': # Windows
|
23 |
+
os.system('cls')
|
24 |
+
else: # Mac and Linux
|
25 |
+
os.system('clear')
|
26 |
+
|
27 |
+
def get_model_options():
|
28 |
+
try:
|
29 |
+
response = requests.get("https://api.deem.love/v1/models")
|
30 |
+
data = response.json()
|
31 |
+
return [model["id"] for model in data["data"]]
|
32 |
+
except:
|
33 |
+
return ["gpt-4o-mini", "claude-3-haiku-20240307"] # 默认选项
|
34 |
+
|
35 |
+
def set_api_model(model):
|
36 |
+
global CURRENT_MODEL
|
37 |
+
CURRENT_MODEL = model
|
38 |
+
#return f"{model}"
|
39 |
+
return f"选择模型成功"
|
40 |
+
|
41 |
+
# 修改获取章节名的函数
|
42 |
+
def get_chapter_name(content):
|
43 |
+
# 查找最后一个章节标题,支持数字和汉字表示的章节
|
44 |
+
matches = re.findall(r'(?:##?|)?\s*第([一二三四五六七八九十百千万亿\d]+)章[::]?\s*(.+)', content)
|
45 |
+
if matches:
|
46 |
+
chapter_num, chapter_title = matches[-1]
|
47 |
+
# 如果章节号是数字,直接使用;如果是汉字,转换为数字
|
48 |
+
if chapter_num.isdigit():
|
49 |
+
return f"第{chapter_num}章:{chapter_title.strip()}"
|
50 |
+
else:
|
51 |
+
# 这里可以添加一个函数来将汉字数字转换为阿拉伯数字
|
52 |
+
# 为了简单起见,这里仍然使用汉字表示
|
53 |
+
return f"第{chapter_num}章:{chapter_title.strip()}"
|
54 |
+
return "未知章节"
|
55 |
+
|
56 |
+
# 修改保存进度函数
|
57 |
+
def save_progress(aign):
|
58 |
+
chapter_name = get_chapter_name(aign.novel_content)
|
59 |
+
# 移除文件名中的非法字符
|
60 |
+
filename = re.sub(r'[\\/*?:"<>|]', '', chapter_name)
|
61 |
+
filename = f"{filename}.json"
|
62 |
+
|
63 |
+
data = {
|
64 |
+
"novel_outline": aign.novel_outline,
|
65 |
+
"paragraph_list": aign.paragraph_list,
|
66 |
+
"novel_content": aign.novel_content,
|
67 |
+
"writing_plan": aign.writing_plan,
|
68 |
+
"temp_setting": aign.temp_setting,
|
69 |
+
"writing_memory": aign.writing_memory,
|
70 |
+
"user_idea": aign.user_idea,
|
71 |
+
"user_requriments": aign.user_requriments,
|
72 |
+
}
|
73 |
+
|
74 |
+
json_str = json.dumps(data, ensure_ascii=False, indent=2)
|
75 |
+
b64 = base64.b64encode(json_str.encode()).decode()
|
76 |
+
href = f"data:application/json;base64,{b64}"
|
77 |
+
download_link = f'<a href="{href}" download="{filename}">点击下载进度文件</a>'
|
78 |
+
return download_link
|
79 |
+
|
80 |
+
# 修改加载函数
|
81 |
+
def load_progress(aign, file):
|
82 |
+
try:
|
83 |
+
if file is None:
|
84 |
+
return aign, "请选择要加载的文件", None, None, None, None, None, None, None, None
|
85 |
+
|
86 |
+
# 检查 file 是否为字符串(文件路径)
|
87 |
+
if isinstance(file, str):
|
88 |
+
with open(file, 'r', encoding='utf-8') as f:
|
89 |
+
content = f.read()
|
90 |
+
# 检查 file 是否有 name 属性(Gradio File 对象)
|
91 |
+
elif hasattr(file, 'name'):
|
92 |
+
with open(file.name, 'r', encoding='utf-8') as f:
|
93 |
+
content = f.read()
|
94 |
+
else:
|
95 |
+
return aign, f"无法读取文件", None, None, None, None, None, None, None, None
|
96 |
+
|
97 |
+
data = json.loads(content)
|
98 |
+
|
99 |
+
aign.novel_outline = data["novel_outline"]
|
100 |
+
aign.paragraph_list = data["paragraph_list"]
|
101 |
+
aign.novel_content = data["novel_content"]
|
102 |
+
aign.writing_plan = data["writing_plan"]
|
103 |
+
aign.temp_setting = data["temp_setting"]
|
104 |
+
aign.writing_memory = data["writing_memory"]
|
105 |
+
aign.user_idea = data["user_idea"]
|
106 |
+
aign.user_requriments = data["user_requriments"]
|
107 |
+
#aign.embellishment_idea = data["embellishment_idea"]
|
108 |
+
aign.update_chapter_list()
|
109 |
+
chapter_choices = [title for title, _ in aign.chapter_list]
|
110 |
+
|
111 |
+
return aign, f"进度已加载", data["novel_outline"], data["novel_content"], data["writing_plan"], data["temp_setting"], data["writing_memory"], data["user_idea"], data["user_requriments"], gr.Dropdown(choices=chapter_choices, value=chapter_choices[-1] if chapter_choices else None)
|
112 |
+
except Exception as e:
|
113 |
+
return aign, f"加载失败: {str(e)}", None, None, None, None, None, None, None, None
|
114 |
+
|
115 |
+
# 新增保存正文函数
|
116 |
+
def save_content(content):
|
117 |
+
if not content:
|
118 |
+
return "正文为空,无需保存"
|
119 |
+
|
120 |
+
b64 = base64.b64encode(content.encode()).decode()
|
121 |
+
href = f"data:text/plain;base64,{b64}"
|
122 |
+
download_link = f'<a href="{href}" download="novel_content.txt">点击下载正文</a>'
|
123 |
+
return download_link
|
124 |
+
|
125 |
+
# 添加撤销功能的事件处理
|
126 |
+
def undo_generation(aign, history):
|
127 |
+
if aign.undo():
|
128 |
+
return [
|
129 |
+
aign,
|
130 |
+
history,
|
131 |
+
aign.writing_plan,
|
132 |
+
aign.temp_setting,
|
133 |
+
aign.writing_memory,
|
134 |
+
aign.novel_content,
|
135 |
+
gr.Button(visible=True),
|
136 |
+
]
|
137 |
+
else:
|
138 |
+
return [
|
139 |
+
aign,
|
140 |
+
history + [["系统", "无法撤销,已经是最初状态"]],
|
141 |
+
aign.writing_plan,
|
142 |
+
aign.temp_setting,
|
143 |
+
aign.writing_memory,
|
144 |
+
aign.novel_content,
|
145 |
+
gr.Button(visible=True),
|
146 |
+
]
|
147 |
+
|
148 |
+
def display_chapter(chapters, page_num):
|
149 |
+
if 1 <= page_num <= len(chapters):
|
150 |
+
chapter_title, chapter_content = chapters[page_num - 1]
|
151 |
+
return f"{chapter_title}\n\n{chapter_content}"
|
152 |
+
else:
|
153 |
+
return "没有更多章节了。"
|
154 |
+
|
155 |
+
def prev_page(aign, current_page):
|
156 |
+
chapters = aign.chapter_list
|
157 |
+
if current_page > 1:
|
158 |
+
current_page -= 1
|
159 |
+
return current_page, display_chapter(chapters, current_page)
|
160 |
+
|
161 |
+
def next_page(aign, current_page):
|
162 |
+
chapters = aign.chapter_list
|
163 |
+
if current_page < len(chapters):
|
164 |
+
current_page += 1
|
165 |
+
return current_page, display_chapter(chapters, current_page)
|
166 |
+
|
167 |
+
def select_chapter(aign, chapter_title):
|
168 |
+
chapters = aign.chapter_list
|
169 |
+
for i, (title, _) in enumerate(chapters, start=1):
|
170 |
+
if title == chapter_title:
|
171 |
+
return i, display_chapter(chapters, i)
|
172 |
+
return 1, "章节未找到。"
|
173 |
+
|
174 |
+
|
175 |
+
def make_middle_chat():
|
176 |
+
carrier = threading.Event()
|
177 |
+
carrier.history = []
|
178 |
+
|
179 |
+
def middle_chat(messages, temperature=None, top_p=None):
|
180 |
+
nonlocal carrier
|
181 |
+
carrier.history.append([None, ""])
|
182 |
+
if len(carrier.history) > 20:
|
183 |
+
carrier.history = carrier.history[-16:]
|
184 |
+
try:
|
185 |
+
for resp in chatLLM(
|
186 |
+
messages, temperature=temperature, top_p=top_p, stream=True, model=CURRENT_MODEL
|
187 |
+
):
|
188 |
+
output_text = resp["content"]
|
189 |
+
total_tokens = resp["total_tokens"]
|
190 |
+
|
191 |
+
carrier.history[-1][1] = f"total_tokens: {total_tokens}\n{output_text}"
|
192 |
+
return {
|
193 |
+
"content": output_text,
|
194 |
+
"total_tokens": total_tokens,
|
195 |
+
}
|
196 |
+
except Exception as e:
|
197 |
+
carrier.history[-1][1] = f"Error: {e}"
|
198 |
+
raise e
|
199 |
+
|
200 |
+
return carrier, middle_chat
|
201 |
+
|
202 |
+
|
203 |
+
def gen_ouline_button_clicked(aign, user_idea, history):
|
204 |
+
clear_console() # 清空命令行
|
205 |
+
aign.user_idea = user_idea
|
206 |
+
|
207 |
+
carrier, middle_chat = make_middle_chat()
|
208 |
+
carrier.history = [] # 清空历史记录
|
209 |
+
aign.novel_outline_writer.chatLLM = middle_chat
|
210 |
+
|
211 |
+
gen_ouline_thread = threading.Thread(target=aign.gen11月elOutline)
|
212 |
+
gen_ouline_thread.start()
|
213 |
+
|
214 |
+
while gen_ouline_thread.is_alive():
|
215 |
+
yield [
|
216 |
+
aign,
|
217 |
+
carrier.history,
|
218 |
+
aign.novel_outline,
|
219 |
+
gr.Button(visible=False),
|
220 |
+
]
|
221 |
+
time.sleep(STREAM_INTERVAL)
|
222 |
+
yield [
|
223 |
+
aign,
|
224 |
+
carrier.history,
|
225 |
+
aign.novel_outline,
|
226 |
+
gr.Button(visible=True),
|
227 |
+
]
|
228 |
+
|
229 |
+
|
230 |
+
def gen_beginning_button_clicked(
|
231 |
+
aign, history, novel_outline, user_requriments#, embellishment_idea
|
232 |
+
):
|
233 |
+
clear_console() # 清空命令行
|
234 |
+
aign.novel_outline = novel_outline
|
235 |
+
aign.user_requriments = user_requriments
|
236 |
+
#aign.embellishment_idea = embellishment_idea
|
237 |
+
|
238 |
+
carrier, middle_chat = make_middle_chat()
|
239 |
+
carrier.history = [] # 清空历史记录
|
240 |
+
aign.novel_beginning_writer.chatLLM = middle_chat
|
241 |
+
#aign.novel_embellisher.chatLLM = middle_chat
|
242 |
+
|
243 |
+
gen_beginning_thread = threading.Thread(target=aign.genBeginning)
|
244 |
+
gen_beginning_thread.start()
|
245 |
+
|
246 |
+
while gen_beginning_thread.is_alive():
|
247 |
+
yield [
|
248 |
+
aign,
|
249 |
+
carrier.history,
|
250 |
+
aign.writing_plan,
|
251 |
+
aign.temp_setting,
|
252 |
+
aign.novel_content,
|
253 |
+
gr.Button(visible=False),
|
254 |
+
]
|
255 |
+
time.sleep(STREAM_INTERVAL)
|
256 |
+
yield [
|
257 |
+
aign,
|
258 |
+
carrier.history,
|
259 |
+
aign.writing_plan,
|
260 |
+
aign.temp_setting,
|
261 |
+
aign.novel_content,
|
262 |
+
gr.Button(visible=True),
|
263 |
+
]
|
264 |
+
|
265 |
+
|
266 |
+
def gen_next_paragraph_button_clicked(
|
267 |
+
aign,
|
268 |
+
history,
|
269 |
+
user_idea,
|
270 |
+
novel_outline,
|
271 |
+
writing_memory,
|
272 |
+
temp_setting,
|
273 |
+
writing_plan,
|
274 |
+
user_requriments,
|
275 |
+
#embellishment_idea,
|
276 |
+
):
|
277 |
+
# 生成保存进度链接
|
278 |
+
save_link = save_progress(aign) # 在函数开头定义保存进度链接
|
279 |
+
|
280 |
+
# 清空命令行
|
281 |
+
clear_console()
|
282 |
+
|
283 |
+
# 更新 AIGN 对象的各个字段
|
284 |
+
aign.user_idea = user_idea
|
285 |
+
aign.novel_outline = novel_outline
|
286 |
+
aign.writing_memory = writing_memory
|
287 |
+
aign.temp_setting = temp_setting
|
288 |
+
aign.writing_plan = writing_plan
|
289 |
+
aign.user_requriments = user_requriments
|
290 |
+
#aign.embellishment_idea = embellishment_idea
|
291 |
+
|
292 |
+
carrier, middle_chat = make_middle_chat()
|
293 |
+
carrier.history = [] # 清空历史记录
|
294 |
+
aign.novel_writer.chatLLM = middle_chat
|
295 |
+
#aign.novel_embellisher.chatLLM = middle_chat
|
296 |
+
aign.memory_maker.chatLLM = middle_chat
|
297 |
+
|
298 |
+
gen_next_paragraph_thread = threading.Thread(target=aign.genNextParagraph)
|
299 |
+
gen_next_paragraph_thread.start()
|
300 |
+
|
301 |
+
while gen_next_paragraph_thread.is_alive():
|
302 |
+
# 生成保存进度链接
|
303 |
+
save_link = save_progress(aign)
|
304 |
+
|
305 |
+
aign.update_chapter_list()
|
306 |
+
# 获取当前章节内容
|
307 |
+
current_chapter_content = display_chapter(aign.chapter_list, len(aign.chapter_list))
|
308 |
+
chapter_choices = [title for title, _ in aign.chapter_list]
|
309 |
+
yield [
|
310 |
+
aign,
|
311 |
+
carrier.history,
|
312 |
+
aign.writing_plan,
|
313 |
+
aign.temp_setting,
|
314 |
+
aign.writing_memory,
|
315 |
+
#aign.novel_content,#全部章节内容
|
316 |
+
current_chapter_content, # 只更新当前章节内容
|
317 |
+
gr.Button(visible=False),
|
318 |
+
save_link, # 返回生成的保存进度链接
|
319 |
+
gr.Dropdown(choices=chapter_choices, value=chapter_choices[-1] if chapter_choices else None),
|
320 |
+
]
|
321 |
+
time.sleep(STREAM_INTERVAL)
|
322 |
+
|
323 |
+
# 生成保存进度链接
|
324 |
+
save_link = save_progress(aign)
|
325 |
+
|
326 |
+
aign.update_chapter_list()
|
327 |
+
# 获取最终的当前章节内容
|
328 |
+
current_chapter_content = display_chapter(aign.chapter_list, len(aign.chapter_list))
|
329 |
+
chapter_choices = [title for title, _ in aign.chapter_list]
|
330 |
+
yield [
|
331 |
+
aign,
|
332 |
+
carrier.history,
|
333 |
+
aign.writing_plan,
|
334 |
+
aign.temp_setting,
|
335 |
+
aign.writing_memory,
|
336 |
+
#aign.novel_content, #全部章节内容
|
337 |
+
current_chapter_content, # 只更新当前章节内容
|
338 |
+
gr.Button(visible=True),
|
339 |
+
save_link, # 返回生成的保存进度链接
|
340 |
+
gr.Dropdown(choices=chapter_choices, value=chapter_choices[-1] if chapter_choices else None),
|
341 |
+
]
|
342 |
+
|
343 |
+
|
344 |
+
css = """
|
345 |
+
#row1 {
|
346 |
+
min-width: 200px;
|
347 |
+
height: calc(100vh - 180px);
|
348 |
+
overflow: auto;
|
349 |
+
}
|
350 |
+
#row2 {
|
351 |
+
min-width: 300px;
|
352 |
+
height: calc(100vh - 180px);
|
353 |
+
overflow: auto;
|
354 |
+
}
|
355 |
+
#row3 {
|
356 |
+
min-width: 200px;
|
357 |
+
height: calc(100vh - 180px);
|
358 |
+
overflow: auto;
|
359 |
+
}
|
360 |
+
"""
|
361 |
+
|
362 |
+
with gr.Blocks(css=css) as demo:
|
363 |
+
aign = gr.State(AIGN(chatLLM))
|
364 |
+
gr.3月kdown("## AI 写小说 Demo")
|
365 |
+
|
366 |
+
#gr.3月kdown("模型服务出问题会导致反复重试,这时切换到可用模型会继续,只要不刷新网页或者保存了进度(至少生成开头之后保存)就可以无限续写(某些模型智能及上下文有限,到极限会导致内容重复,这些模型在这就不适用了,比如gpt-3.5-turbo,当然接着切换到强模型可以再继续)")
|
367 |
+
|
368 |
+
# 添加模型选择下拉框
|
369 |
+
# with gr.Row(): 同一行
|
370 |
+
with gr.Row():
|
371 |
+
with gr.Column(scale=0, elem_id="row1"):
|
372 |
+
with gr.Tab("⚙"):
|
373 |
+
model_dropdown = gr.Dropdown(
|
374 |
+
choices=get_model_options(),
|
375 |
+
label="选择模型",
|
376 |
+
interactive=True,
|
377 |
+
value=CURRENT_MODEL
|
378 |
+
)
|
379 |
+
model_output = gr.Textbox(label="模型设置结果", interactive=False)
|
380 |
+
load_status = gr.Textbox(label="加载状态", interactive=False)
|
381 |
+
load_file = gr.File(label="选择加载文件", file_count="single", file_types=[".json"])
|
382 |
+
load_button = gr.Button("加载进度")
|
383 |
+
with gr.Tab("开始"):
|
384 |
+
gr.3月kdown("生成大纲->大纲标签->生成章节->状态标签->生成章节")
|
385 |
+
user_idea_text = gr.Textbox(
|
386 |
+
"架空历史:\n\n1. 选择关键历史节点并改变\n2. 描述由此引发的历史走向变化\n3. 塑造新兴历史人物(可改编或原创)\n4. 构建独特社会结构、文化和思潮\n5. 想象可能出现的科技创新\n6. 概述世界格局重塑(国界、政体、国际关系)\n7. 用生动叙事呈现,让读者身临其境\n\n目标:创造合理又富想象力的平行宇宙,既有趣又引人深思。",
|
387 |
+
label="想法",
|
388 |
+
lines=16,
|
389 |
+
interactive=True,
|
390 |
+
)
|
391 |
+
user_requriments_text = gr.Textbox(
|
392 |
+
"1. 语言要求:\n - 不直白\n - 句式多变\n - 避免陈词滥调\n - 使用不寻常的词句\n - 运用隐喻和象征\n2. 创作风格:\n - 抽象\n - 富有意境和想象力\n - 具创意个性\n - 有力度\n - 画面感强\n - 音乐感佳\n - 浪漫气息浓厚\n - 语言深邃\n3. 表达目标:\n - 传达独特的神秘和魔幻感\n - 探索和反思自我与世界\n - 表达对自己和社会的孤独与关注\n4. 读者体验:有趣、惊奇、新鲜",
|
393 |
+
label="写作要求",
|
394 |
+
lines=6,
|
395 |
+
interactive=True,
|
396 |
+
)
|
397 |
+
gen_ouline_button = gr.Button("生成大纲")
|
398 |
+
with gr.Tab("大纲"):
|
399 |
+
novel_outline_text = gr.Textbox(
|
400 |
+
label="大纲", lines=33, interactive=True
|
401 |
+
)
|
402 |
+
#gen_beginning_button = gr.Button("生成开头")
|
403 |
+
#gen_next_paragraph_button = gr.Button("生成开头")
|
404 |
+
with gr.Tab("状态"):
|
405 |
+
writing_memory_text = gr.Textbox(
|
406 |
+
label="记忆",
|
407 |
+
lines=8,
|
408 |
+
interactive=True,
|
409 |
+
max_lines=8,
|
410 |
+
)
|
411 |
+
writing_plan_text = gr.Textbox(label="计划", lines=6, interactive=True, max_lines=6)
|
412 |
+
temp_setting_text = gr.Textbox(
|
413 |
+
label="临时设定", lines=5, interactive=True, max_lines=5
|
414 |
+
)
|
415 |
+
gen_next_paragraph_button = gr.Button("生成章节")
|
416 |
+
download_link = gr.HTML()
|
417 |
+
save_button = gr.Button("保存进度")
|
418 |
+
with gr.Tab("导航"):
|
419 |
+
save_content_button = gr.Button("保存正文")
|
420 |
+
current_page = gr.Number(value=1, label="当前页码", interactive=False)
|
421 |
+
prev_button = gr.Button("上一页")
|
422 |
+
next_button = gr.Button("下一页")
|
423 |
+
|
424 |
+
# 添加章节导航下拉列表
|
425 |
+
chapter_dropdown = gr.Dropdown(label="章节导航", choices=[], interactive=True)
|
426 |
+
|
427 |
+
# TODO
|
428 |
+
# gen_next_paragraph_button = gr.Button("撤销生成")
|
429 |
+
#undo_button = gr.Button("撤销生成")
|
430 |
+
# TODO
|
431 |
+
# auto_gen_next_checkbox = gr.Checkbox(
|
432 |
+
# label="自动生成下一段", checked=False, interactive=True
|
433 |
+
# )
|
434 |
+
|
435 |
+
with gr.Column(scale=3, elem_id="row2"):
|
436 |
+
chatBox = gr.Chatbot(height=f"80vh", label="输出")
|
437 |
+
with gr.Column(scale=0, elem_id="row3"):
|
438 |
+
novel_content_text = gr.Textbox(
|
439 |
+
label="小说正文", lines=35, interactive=True, show_copy_button=True
|
440 |
+
)
|
441 |
+
# TODO
|
442 |
+
# download_novel_button = gr.Button("下载小说")
|
443 |
+
|
444 |
+
#gr.3月kdown("导航: https://deem.love")
|
445 |
+
|
446 |
+
prev_button.click(
|
447 |
+
prev_page,
|
448 |
+
inputs=[aign, current_page],
|
449 |
+
outputs=[current_page, novel_content_text],
|
450 |
+
queue=False
|
451 |
+
)
|
452 |
+
|
453 |
+
next_button.click(
|
454 |
+
next_page,
|
455 |
+
inputs=[aign, current_page],
|
456 |
+
outputs=[current_page, novel_content_text],
|
457 |
+
queue=False
|
458 |
+
)
|
459 |
+
|
460 |
+
# 添加章节下拉列表的事件处理
|
461 |
+
chapter_dropdown.change(
|
462 |
+
select_chapter,
|
463 |
+
inputs=[aign, chapter_dropdown],
|
464 |
+
outputs=[current_page, novel_content_text],
|
465 |
+
queue=False
|
466 |
+
)
|
467 |
+
|
468 |
+
# 添加模型选择的事件处理
|
469 |
+
model_dropdown.change(
|
470 |
+
set_api_model,
|
471 |
+
inputs=[model_dropdown],
|
472 |
+
outputs=[model_output]
|
473 |
+
)
|
474 |
+
|
475 |
+
# 修改按钮事件
|
476 |
+
save_button.click(
|
477 |
+
save_progress,
|
478 |
+
inputs=[aign],
|
479 |
+
outputs=[download_link]
|
480 |
+
)
|
481 |
+
|
482 |
+
# 修改加载按钮事件,包含章节下拉列表的更新
|
483 |
+
load_button.click(
|
484 |
+
load_progress,
|
485 |
+
inputs=[aign, load_file],
|
486 |
+
outputs=[aign, load_status, novel_outline_text, novel_content_text, writing_plan_text, temp_setting_text, writing_memory_text, user_idea_text, user_requriments_text, chapter_dropdown]
|
487 |
+
)
|
488 |
+
|
489 |
+
# 添加保存正文按钮事件
|
490 |
+
save_content_button.click(
|
491 |
+
save_content,
|
492 |
+
inputs=[novel_content_text],
|
493 |
+
outputs=[download_link]
|
494 |
+
)
|
495 |
+
|
496 |
+
#undo_button.click(
|
497 |
+
#undo_generation,
|
498 |
+
#[aign, chatBox],
|
499 |
+
#[aign, chatBox, writing_plan_text, temp_setting_text, writing_memory_text, novel_content_text, undo_button],
|
500 |
+
#)
|
501 |
+
|
502 |
+
gen_ouline_button.click(
|
503 |
+
gen_ouline_button_clicked,
|
504 |
+
[aign, user_idea_text, chatBox],
|
505 |
+
[aign, chatBox, novel_outline_text, gen_ouline_button],
|
506 |
+
)
|
507 |
+
#gen_beginning_button.click(
|
508 |
+
#gen_beginning_button_clicked,
|
509 |
+
#[
|
510 |
+
#aign,
|
511 |
+
#chatBox,
|
512 |
+
#novel_outline_text,
|
513 |
+
#user_requriments_text,
|
514 |
+
#embellishment_idea_text,
|
515 |
+
#],
|
516 |
+
#[
|
517 |
+
#aign,
|
518 |
+
#chatBox,
|
519 |
+
#writing_plan_text,
|
520 |
+
#temp_setting_text,
|
521 |
+
#novel_content_text,
|
522 |
+
#gen_beginning_button,
|
523 |
+
#],
|
524 |
+
#)
|
525 |
+
|
526 |
+
# 修改生成下一段按钮事件,包含章节下拉列表的更新
|
527 |
+
gen_next_paragraph_button.click(
|
528 |
+
gen_next_paragraph_button_clicked,
|
529 |
+
[
|
530 |
+
aign,
|
531 |
+
chatBox,
|
532 |
+
user_idea_text,
|
533 |
+
novel_outline_text,
|
534 |
+
writing_memory_text,
|
535 |
+
temp_setting_text,
|
536 |
+
writing_plan_text,
|
537 |
+
user_requriments_text,
|
538 |
+
#embellishment_idea_text,
|
539 |
+
],
|
540 |
+
[
|
541 |
+
aign,
|
542 |
+
chatBox,
|
543 |
+
writing_plan_text,
|
544 |
+
temp_setting_text,
|
545 |
+
writing_memory_text,
|
546 |
+
novel_content_text,
|
547 |
+
gen_next_paragraph_button,
|
548 |
+
download_link, # 这里添加输出到下载链接
|
549 |
+
chapter_dropdown
|
550 |
+
],
|
551 |
+
)
|
552 |
+
|
553 |
+
if __name__ == "__main__":
|
554 |
+
demo.queue()
|
555 |
+
port = int(os.environ.get("PORT", 7860))
|
556 |
+
demo.launch(server_name="127.0.0.1", server_port=port)
|