Wendong-Fan commited on
Commit
5ff50cb
·
1 Parent(s): b0619c0

update wendong

Browse files
Files changed (3) hide show
  1. owl/app.py +69 -50
  2. owl/script_adapter.py +153 -107
  3. run_app.py +1 -1
owl/app.py CHANGED
@@ -6,7 +6,6 @@ import threading
6
  import time
7
  from datetime import datetime
8
  import queue
9
- import re
10
  from pathlib import Path
11
  import json
12
  import signal
@@ -22,20 +21,20 @@ process_lock = threading.Lock()
22
  # 脚本选项
23
  SCRIPTS = {
24
  "Qwen Mini (中文)": "run_qwen_mini_zh.py",
25
- "Qwen": "run_qwen.py",
26
  "Mini": "run_mini.py",
27
- "DeepSeek": "run_deepseek.py",
28
- "默认": "run.py",
29
  "GAIA Roleplaying": "run_gaia_roleplaying.py"
30
  }
31
 
32
  # 脚本描述
33
  SCRIPT_DESCRIPTIONS = {
34
  "Qwen Mini (中文)": "使用阿里云Qwen模型的中文版本,适合中文问答和任务",
35
- "Qwen": "使用阿里云Qwen模型,支持多种工具和功能",
36
  "Mini": "轻量级版本,使用OpenAI GPT-4o模型",
37
- "DeepSeek": "使用DeepSeek模型,适合复杂推理任务",
38
- "默认": "默认OWL实现,使用OpenAI GPT-4o模型和全套工具",
39
  "GAIA Roleplaying": "GAIA基准测试实现,用于评估模型能力"
40
  }
41
 
@@ -46,7 +45,7 @@ ENV_GROUPS = {
46
  "name": "OPENAI_API_KEY",
47
  "label": "OpenAI API密钥",
48
  "type": "password",
49
- "required": True,
50
  "help": "OpenAI API密钥,用于访问GPT模型。获取方式:https://platform.openai.com/api-keys"
51
  },
52
  {
@@ -176,6 +175,7 @@ def save_env_vars(env_vars):
176
  for key, value in env_vars.items():
177
  if value: # 只保存非空值
178
  # 确保值是字符串形式,并用引号包裹
 
179
  if not (value.startswith('"') and value.endswith('"')) and not (value.startswith("'") and value.endswith("'")):
180
  value = f'"{value}"'
181
  existing_content[key] = value
@@ -243,7 +243,9 @@ def run_script(script_dropdown, question, progress=gr.Progress()):
243
  """运行选定的脚本并返回输出"""
244
  global current_process
245
 
246
- script_name = SCRIPTS[script_dropdown]
 
 
247
 
248
  if not question.strip():
249
  return "请输入问题!", "", "", "", None
@@ -280,14 +282,17 @@ def run_script(script_dropdown, question, progress=gr.Progress()):
280
 
281
  # 创建线程来读取输出
282
  def read_output():
283
- with open(log_file, "w", encoding="utf-8") as f:
284
- for line in iter(current_process.stdout.readline, ""):
285
- if line:
286
- # 写入日志文件
287
- f.write(line)
288
- f.flush()
289
- # 添加到队列
290
- log_queue.put(line)
 
 
 
291
 
292
  # 启动读取线程
293
  threading.Thread(target=read_output, daemon=True).start()
@@ -305,7 +310,10 @@ def run_script(script_dropdown, question, progress=gr.Progress()):
305
  if time.time() - start_time > timeout:
306
  with process_lock:
307
  if current_process.poll() is None:
308
- current_process.terminate()
 
 
 
309
  log_queue.put("执行超时,已终止进程\n")
310
  break
311
 
@@ -355,32 +363,41 @@ def extract_answer(logs):
355
  def extract_chat_history(logs):
356
  """尝试从日志中提取聊天历史"""
357
  try:
358
- for i, log in enumerate(logs):
 
 
 
359
  if "chat_history" in log:
360
- # 尝试找到JSON格式的聊天历史
361
  start_idx = log.find("[")
362
  if start_idx != -1:
363
- # 尝试解析JSON
364
- json_str = log[start_idx:].strip()
365
- # 查找下一行中可能的结束括号
366
- if json_str[-1] != "]" and i+1 < len(logs):
367
- for j in range(i+1, min(i+10, len(logs))):
368
- end_idx = logs[j].find("]")
369
- if end_idx != -1:
370
- json_str += logs[j][:end_idx+1]
371
- break
372
-
373
- try:
374
- chat_data = json.loads(json_str)
375
- # 格式化为Gradio聊天组件可用的格式
376
- formatted_chat = []
377
- for msg in chat_data:
378
- if "role" in msg and "content" in msg:
379
- role = "用户" if msg["role"] == "user" else "助手"
380
- formatted_chat.append([role, msg["content"]])
381
- return formatted_chat
382
- except json.JSONDecodeError:
383
- pass
 
 
 
 
 
 
384
  except Exception:
385
  pass
386
  return None
@@ -400,17 +417,19 @@ def create_ui():
400
  )
401
 
402
  with gr.Tabs() as tabs:
403
- with gr.TabItem("运行模型"):
404
  with gr.Row():
405
  with gr.Column(scale=1):
 
 
406
  script_dropdown = gr.Dropdown(
407
  choices=list(SCRIPTS.keys()),
408
- value=list(SCRIPTS.keys())[0],
409
- label="选择模型"
410
  )
411
 
412
  script_info = gr.Textbox(
413
- value=get_script_info(list(SCRIPTS.keys())[0]),
414
  label="模型描述",
415
  interactive=False
416
  )
@@ -452,9 +471,9 @@ def create_ui():
452
 
453
  # 示例问题
454
  examples = [
455
- ["Qwen Mini (中文)", "打开小红书上浏览推荐栏目下的前三个笔记内容,不要登陆,之后给我一个总结报告"],
456
- ["Mini", "What was the volume in m^3 of the fish bag that was calculated in the University of Leicester paper `Can Hiccup Supply Enough Fish to Maintain a Dragon's Diet?`"],
457
- ["默认", "What is the current weather in New York?"]
458
  ]
459
 
460
  gr.Examples(
@@ -505,14 +524,14 @@ def create_ui():
505
  if var["type"] == "password":
506
  env_inputs[var["name"]] = gr.Textbox(
507
  value=env_vars.get(var["name"], ""),
508
- label=var["label"] + (" (必填)" if var.get("required", False) else ""),
509
  placeholder=f"请输入{var['label']}",
510
  type="password"
511
  )
512
  else:
513
  env_inputs[var["name"]] = gr.Textbox(
514
  value=env_vars.get(var["name"], ""),
515
- label=var["label"] + (" (必填)" if var.get("required", False) else ""),
516
  placeholder=f"请输入{var['label']}"
517
  )
518
 
 
6
  import time
7
  from datetime import datetime
8
  import queue
 
9
  from pathlib import Path
10
  import json
11
  import signal
 
21
  # 脚本选项
22
  SCRIPTS = {
23
  "Qwen Mini (中文)": "run_qwen_mini_zh.py",
24
+ "Qwen (中文)": "run_qwen_zh.py",
25
  "Mini": "run_mini.py",
26
+ "DeepSeek (中文)": "run_deepseek_zh.py",
27
+ "Default": "run.py",
28
  "GAIA Roleplaying": "run_gaia_roleplaying.py"
29
  }
30
 
31
  # 脚本描述
32
  SCRIPT_DESCRIPTIONS = {
33
  "Qwen Mini (中文)": "使用阿里云Qwen模型的中文版本,适合中文问答和任务",
34
+ "Qwen (中文)": "使用阿里云Qwen模型,支持多种工具和功能",
35
  "Mini": "轻量级版本,使用OpenAI GPT-4o模型",
36
+ "DeepSeek (中文)": "使用DeepSeek模型,适合非多模态任务",
37
+ "Default": "默认OWL实现,使用OpenAI GPT-4o模型和全套工具",
38
  "GAIA Roleplaying": "GAIA基准测试实现,用于评估模型能力"
39
  }
40
 
 
45
  "name": "OPENAI_API_KEY",
46
  "label": "OpenAI API密钥",
47
  "type": "password",
48
+ "required": False,
49
  "help": "OpenAI API密钥,用于访问GPT模型。获取方式:https://platform.openai.com/api-keys"
50
  },
51
  {
 
175
  for key, value in env_vars.items():
176
  if value: # 只保存非空值
177
  # 确保值是字符串形式,并用引号包裹
178
+ value = str(value) # 确保值是字符串
179
  if not (value.startswith('"') and value.endswith('"')) and not (value.startswith("'") and value.endswith("'")):
180
  value = f'"{value}"'
181
  existing_content[key] = value
 
243
  """运行选定的脚本并返回输出"""
244
  global current_process
245
 
246
+ script_name = SCRIPTS.get(script_dropdown)
247
+ if not script_name:
248
+ return "❌ 无效的脚本选择", "", "", "", None
249
 
250
  if not question.strip():
251
  return "请输入问题!", "", "", "", None
 
282
 
283
  # 创建线程来读取输出
284
  def read_output():
285
+ try:
286
+ with open(log_file, "w", encoding="utf-8") as f:
287
+ for line in iter(current_process.stdout.readline, ""):
288
+ if line:
289
+ # 写入日志文件
290
+ f.write(line)
291
+ f.flush()
292
+ # 添加到队列
293
+ log_queue.put(line)
294
+ except Exception as e:
295
+ log_queue.put(f"读取输出时出错: {str(e)}\n")
296
 
297
  # 启动读取线程
298
  threading.Thread(target=read_output, daemon=True).start()
 
310
  if time.time() - start_time > timeout:
311
  with process_lock:
312
  if current_process.poll() is None:
313
+ if os.name == 'nt':
314
+ current_process.send_signal(signal.CTRL_BREAK_EVENT)
315
+ else:
316
+ current_process.terminate()
317
  log_queue.put("执行超时,已终止进程\n")
318
  break
319
 
 
363
  def extract_chat_history(logs):
364
  """尝试从日志中提取聊天历史"""
365
  try:
366
+ chat_json_str = ""
367
+ capture_json = False
368
+
369
+ for log in logs:
370
  if "chat_history" in log:
371
+ # 开始捕获JSON
372
  start_idx = log.find("[")
373
  if start_idx != -1:
374
+ capture_json = True
375
+ chat_json_str = log[start_idx:]
376
+ elif capture_json:
377
+ # 继续捕获JSON直到找到匹配的结束括号
378
+ chat_json_str += log
379
+ if "]" in log:
380
+ # 找到结束括号,尝试解析JSON
381
+ end_idx = chat_json_str.rfind("]") + 1
382
+ if end_idx > 0:
383
+ try:
384
+ # 清理可能的额外文本
385
+ json_str = chat_json_str[:end_idx].strip()
386
+ chat_data = json.loads(json_str)
387
+
388
+ # 格式化为Gradio聊天组件可用的格式
389
+ formatted_chat = []
390
+ for msg in chat_data:
391
+ if "role" in msg and "content" in msg:
392
+ role = "用户" if msg["role"] == "user" else "助手"
393
+ formatted_chat.append([role, msg["content"]])
394
+ return formatted_chat
395
+ except json.JSONDecodeError:
396
+ # 如果解析失败,继续捕获
397
+ pass
398
+ except Exception:
399
+ # 其他错误,停止捕获
400
+ capture_json = False
401
  except Exception:
402
  pass
403
  return None
 
417
  )
418
 
419
  with gr.Tabs() as tabs:
420
+ with gr.TabItem("运行模式"):
421
  with gr.Row():
422
  with gr.Column(scale=1):
423
+ # 确保默认值是SCRIPTS中存在的键
424
+ default_script = list(SCRIPTS.keys())[0] if SCRIPTS else None
425
  script_dropdown = gr.Dropdown(
426
  choices=list(SCRIPTS.keys()),
427
+ value=default_script,
428
+ label="选择模式"
429
  )
430
 
431
  script_info = gr.Textbox(
432
+ value=get_script_info(default_script) if default_script else "",
433
  label="模型描述",
434
  interactive=False
435
  )
 
471
 
472
  # 示例问题
473
  examples = [
474
+ ["Qwen Mini (中文)", "浏览亚马逊并找出一款对程序员有吸引力的产品。请提供产品名称和价格"],
475
+ ["DeepSeek (中文)", "请分析GitHub上CAMEL-AI项目的最新统计数据。找出该项目的星标数量、贡献者数量和最近的活跃度。然后,创建一个简单的Excel表格来展示这些数据,并生成一个柱状图来可视化这些指标。最后,总结CAMEL项目的受欢迎程度和发展趋势。"],
476
+ ["Default", "Navigate to Amazon.com and identify one product that is attractive to coders. Please provide me with the product name and price. No need to verify your answer."]
477
  ]
478
 
479
  gr.Examples(
 
524
  if var["type"] == "password":
525
  env_inputs[var["name"]] = gr.Textbox(
526
  value=env_vars.get(var["name"], ""),
527
+ label=var["label"],
528
  placeholder=f"请输入{var['label']}",
529
  type="password"
530
  )
531
  else:
532
  env_inputs[var["name"]] = gr.Textbox(
533
  value=env_vars.get(var["name"], ""),
534
+ label=var["label"],
535
  placeholder=f"请输入{var['label']}"
536
  )
537
 
owl/script_adapter.py CHANGED
@@ -7,11 +7,20 @@ import traceback
7
 
8
  def load_module_from_path(module_name, file_path):
9
  """从文件路径加载Python模块"""
10
- spec = importlib.util.spec_from_file_location(module_name, file_path)
11
- module = importlib.util.module_from_spec(spec)
12
- sys.modules[module_name] = module
13
- spec.loader.exec_module(module)
14
- return module
 
 
 
 
 
 
 
 
 
15
 
16
  def run_script_with_env_question(script_name):
17
  """使用环境变量中的问题运行脚本"""
@@ -27,46 +36,55 @@ def run_script_with_env_question(script_name):
27
  print(f"错误: 脚本 {script_path} 不存在")
28
  sys.exit(1)
29
 
30
- # 读取脚本内容
31
- with open(script_path, "r", encoding="utf-8") as f:
32
- content = f.read()
33
-
34
- # 检查脚本是否有main函数
35
- has_main = re.search(r'def\s+main\s*\(\s*\)\s*:', content) is not None
36
-
37
- # 转义问题中的特殊字符
38
- escaped_question = question.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")
39
 
40
- # 查找脚本中所有的question赋值
41
- question_assignments = re.findall(r'question\s*=\s*(?:["\'].*?["\']|\(.*?\))', content)
42
- print(f"在脚本中找到 {len(question_assignments)} 个question赋值")
43
-
44
- # 修改脚本内容,替换所有的question赋值
45
- modified_content = content
46
-
47
- # 如果脚本中有question赋值,替换所有的赋值
48
- if question_assignments:
49
- for assignment in question_assignments:
50
- modified_content = modified_content.replace(
51
- assignment,
52
- f'question = "{escaped_question}"'
53
- )
54
- print(f"已替换脚本中的所有question赋值为: {question}")
55
- else:
56
- # 如果没有找到question赋值,尝试在main函数前插入
57
- if has_main:
58
- main_match = re.search(r'def\s+main\s*\(\s*\)\s*:', content)
59
- if main_match:
60
- insert_pos = main_match.start()
61
- modified_content = content[:insert_pos] + f'\n# 用户输入的问题\nquestion = "{escaped_question}"\n\n' + content[insert_pos:]
62
- print(f"已在main函数前插入问题: {question}")
 
 
 
 
 
 
 
 
63
  else:
64
- # 如果没有main函数,在文件开头插入
65
- modified_content = f'# 用户输入的问题\nquestion = "{escaped_question}"\n\n' + content
66
- print(f"已在文件开头插入问题: {question}")
67
-
68
- # 添加monkey patch代码,确保construct_society函数使用用户的问题
69
- monkey_patch_code = f'''
 
 
 
 
 
 
 
 
70
  # 确保construct_society函数使用用户的问题
71
  original_construct_society = globals().get('construct_society')
72
  if original_construct_society:
@@ -78,23 +96,23 @@ if original_construct_society:
78
  globals()['construct_society'] = patched_construct_society
79
  print("已修补construct_society函数,确保使用用户问题")
80
  '''
81
-
82
- # 在文件末尾添加monkey patch代码
83
- modified_content += monkey_patch_code
84
-
85
- # 如果脚本没有调用main函数,添加调用代码
86
- if has_main and "__main__" not in content:
87
- modified_content += '''
88
 
89
  # 确保调用main函数
90
  if __name__ == "__main__":
91
  main()
92
  '''
93
- print("已添加main函数调用代码")
94
-
95
- # 如果脚本没有construct_society调用,添加调用代码
96
- if "construct_society" in content and "run_society" in content and "Answer:" not in content:
97
- modified_content += f'''
98
 
99
  # 确保执行construct_society和run_society
100
  if "construct_society" in globals() and "run_society" in globals():
@@ -108,70 +126,98 @@ if "construct_society" in globals() and "run_society" in globals():
108
  import traceback
109
  traceback.print_exc()
110
  '''
111
- print("已添加construct_society和run_society调用代码")
112
-
113
- # 执行修改后的脚本
114
- try:
115
- # 将脚本目录添加到sys.path
116
- script_dir = script_path.parent
117
- if str(script_dir) not in sys.path:
118
- sys.path.insert(0, str(script_dir))
119
-
120
- # 创建临时文件
121
- temp_script_path = script_path.with_name(f"temp_{script_path.name}")
122
- with open(temp_script_path, "w", encoding="utf-8") as f:
123
- f.write(modified_content)
124
-
125
- print(f"已创建临时脚本文件: {temp_script_path}")
126
 
 
127
  try:
128
- # 直接执行临时脚本
129
- print(f"开始执行脚本...")
 
 
130
 
131
- # 如果有main函数,加载模块并调用main
132
- if has_main:
133
- # 加载临时模块
134
- module_name = f"temp_{script_path.stem}"
135
- module = load_module_from_path(module_name, temp_script_path)
136
-
137
- # 确保模块中有question变量,并且值是用户输入的问题
138
- setattr(module, "question", question)
139
-
140
- # 如果模块中有construct_society函数,修补它
141
- if hasattr(module, "construct_society"):
142
- original_func = module.construct_society
143
- def patched_func(*args, **kwargs):
144
- return original_func(question)
145
- module.construct_society = patched_func
146
- print("已在模块级别修补construct_society函数")
147
 
148
- # 调用main函数
149
- if hasattr(module, "main"):
150
- print("调用main函数...")
151
- module.main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  else:
153
- print(f"错误: 脚本 {script_path} 中没有main函数")
154
- sys.exit(1)
155
- else:
156
- # 如果没有main函数,直接执行修改后的脚本
157
- print("直接执行脚本内容...")
158
- exec(modified_content, {"__file__": str(temp_script_path)})
159
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  except Exception as e:
161
- print(f"执行脚本时出错: {e}")
162
  traceback.print_exc()
163
  sys.exit(1)
164
 
165
- finally:
166
- # 删除临时文件
167
- if temp_script_path.exists():
168
- temp_script_path.unlink()
169
- print(f"已删除临时脚本文件: {temp_script_path}")
170
-
171
  except Exception as e:
172
  print(f"处理脚本时出错: {e}")
173
  traceback.print_exc()
174
  sys.exit(1)
 
 
 
 
 
 
 
 
 
175
 
176
  if __name__ == "__main__":
177
  # 检查命令行参数
@@ -180,4 +226,4 @@ if __name__ == "__main__":
180
  sys.exit(1)
181
 
182
  # 运行指定的脚本
183
- run_script_with_env_question(sys.argv[1])
 
7
 
8
  def load_module_from_path(module_name, file_path):
9
  """从文件路径加载Python模块"""
10
+ try:
11
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
12
+ if spec is None:
13
+ print(f"错误: 无法从 {file_path} 创建模块规范")
14
+ return None
15
+
16
+ module = importlib.util.module_from_spec(spec)
17
+ sys.modules[module_name] = module
18
+ spec.loader.exec_module(module)
19
+ return module
20
+ except Exception as e:
21
+ print(f"加载模块时出错: {e}")
22
+ traceback.print_exc()
23
+ return None
24
 
25
  def run_script_with_env_question(script_name):
26
  """使用环境变量中的问题运行脚本"""
 
36
  print(f"错误: 脚本 {script_path} 不存在")
37
  sys.exit(1)
38
 
39
+ # 创建临时文件路径
40
+ temp_script_path = script_path.with_name(f"temp_{script_path.name}")
 
 
 
 
 
 
 
41
 
42
+ try:
43
+ # 读取脚本内容
44
+ try:
45
+ with open(script_path, "r", encoding="utf-8") as f:
46
+ content = f.read()
47
+ except Exception as e:
48
+ print(f"读取脚本文件时出错: {e}")
49
+ sys.exit(1)
50
+
51
+ # 检查脚本是否有main函数
52
+ has_main = re.search(r'def\s+main\s*\(\s*\)\s*:', content) is not None
53
+
54
+ # 转义问题中的特殊字符
55
+ escaped_question = question.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")
56
+
57
+ # 查找脚本中所有的question赋值 - 改进的正则表达式
58
+ # 匹配单行和多行字符串赋值
59
+ question_assignments = re.findall(r'question\s*=\s*(?:["\'].*?["\']|""".*?"""|\'\'\'.*?\'\'\'|\(.*?\))', content, re.DOTALL)
60
+ print(f"在脚本中找到 {len(question_assignments)} 个question赋值")
61
+
62
+ # 修改脚本内容,替换所有的question赋值
63
+ modified_content = content
64
+
65
+ # 如果脚本中有question赋值,替换所有的赋值
66
+ if question_assignments:
67
+ for assignment in question_assignments:
68
+ modified_content = modified_content.replace(
69
+ assignment,
70
+ f'question = "{escaped_question}"'
71
+ )
72
+ print(f"已替换脚本中的所有question赋值为: {question}")
73
  else:
74
+ # 如果没有找到question赋值,尝试在main函数前插入
75
+ if has_main:
76
+ main_match = re.search(r'def\s+main\s*\(\s*\)\s*:', content)
77
+ if main_match:
78
+ insert_pos = main_match.start()
79
+ modified_content = content[:insert_pos] + f'\n# 用户输入的问题\nquestion = "{escaped_question}"\n\n' + content[insert_pos:]
80
+ print(f"已在main函数前插入问题: {question}")
81
+ else:
82
+ # 如��没有main函数,在文件开头插入
83
+ modified_content = f'# 用户输入的问题\nquestion = "{escaped_question}"\n\n' + content
84
+ print(f"已在文件开头插入问题: {question}")
85
+
86
+ # 添加monkey patch代码,确保construct_society函数使用用户的问题
87
+ monkey_patch_code = f'''
88
  # 确保construct_society函数使用用户的问题
89
  original_construct_society = globals().get('construct_society')
90
  if original_construct_society:
 
96
  globals()['construct_society'] = patched_construct_society
97
  print("已修补construct_society函数,确保使用用户问题")
98
  '''
99
+
100
+ # 在文件末尾添加monkey patch代码
101
+ modified_content += monkey_patch_code
102
+
103
+ # 如果脚本没有调用main函数,添加调用代码
104
+ if has_main and "__main__" not in content:
105
+ modified_content += '''
106
 
107
  # 确保调用main函数
108
  if __name__ == "__main__":
109
  main()
110
  '''
111
+ print("已添加main函数调用代码")
112
+
113
+ # 如果脚本没有construct_society调用,添加调用代码
114
+ if "construct_society" in content and "run_society" in content and "Answer:" not in content:
115
+ modified_content += f'''
116
 
117
  # 确保执行construct_society和run_society
118
  if "construct_society" in globals() and "run_society" in globals():
 
126
  import traceback
127
  traceback.print_exc()
128
  '''
129
+ print("已添加construct_society和run_society调用代码")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ # 执行修改后的脚本
132
  try:
133
+ # 将脚本目录添加到sys.path
134
+ script_dir = script_path.parent
135
+ if str(script_dir) not in sys.path:
136
+ sys.path.insert(0, str(script_dir))
137
 
138
+ # 创建临时文件
139
+ try:
140
+ with open(temp_script_path, "w", encoding="utf-8") as f:
141
+ f.write(modified_content)
142
+ print(f"已创建临时脚本文件: {temp_script_path}")
143
+ except Exception as e:
144
+ print(f"创建临时脚本文件时出错: {e}")
145
+ sys.exit(1)
146
+
147
+ try:
148
+ # 直接执行临时脚本
149
+ print(f"开始执行脚本...")
 
 
 
 
150
 
151
+ # 如果有main函数,加载模块并调用main
152
+ if has_main:
153
+ # 加载临时模块
154
+ module_name = f"temp_{script_path.stem}"
155
+ module = load_module_from_path(module_name, temp_script_path)
156
+
157
+ if module is None:
158
+ print(f"错误: 无法加载模块 {module_name}")
159
+ sys.exit(1)
160
+
161
+ # 确保模块中有question变量,并且值是用户输入的问题
162
+ setattr(module, "question", question)
163
+
164
+ # 如果模块中有construct_society函数,修补它
165
+ if hasattr(module, "construct_society"):
166
+ original_func = module.construct_society
167
+ def patched_func(*args, **kwargs):
168
+ return original_func(question)
169
+ module.construct_society = patched_func
170
+ print("已在模块级别修补construct_society函数")
171
+
172
+ # 调用main函数
173
+ if hasattr(module, "main"):
174
+ print("调用main函数...")
175
+ module.main()
176
+ else:
177
+ print(f"错误: 脚本 {script_path} 中没有main函数")
178
+ sys.exit(1)
179
  else:
180
+ # 如果没有main函数,直接执行修改后的脚本
181
+ print("直接执行脚本内容...")
182
+ # 使用更安全的方式执行脚本
183
+ with open(temp_script_path, "r", encoding="utf-8") as f:
184
+ script_code = f.read()
185
+
186
+ # 创建一个安全的全局命名空间
187
+ safe_globals = {
188
+ "__file__": str(temp_script_path),
189
+ "__name__": "__main__"
190
+ }
191
+ # 添加内置函数
192
+ safe_globals.update({k: v for k, v in globals().items()
193
+ if k in ['__builtins__']})
194
+
195
+ # 执行脚本
196
+ exec(script_code, safe_globals)
197
+
198
+ except Exception as e:
199
+ print(f"执行脚本时出错: {e}")
200
+ traceback.print_exc()
201
+ sys.exit(1)
202
+
203
  except Exception as e:
204
+ print(f"处理脚本时出错: {e}")
205
  traceback.print_exc()
206
  sys.exit(1)
207
 
 
 
 
 
 
 
208
  except Exception as e:
209
  print(f"处理脚本时出错: {e}")
210
  traceback.print_exc()
211
  sys.exit(1)
212
+
213
+ finally:
214
+ # 删除临时文件
215
+ if temp_script_path.exists():
216
+ try:
217
+ temp_script_path.unlink()
218
+ print(f"已删除临时脚本文件: {temp_script_path}")
219
+ except Exception as e:
220
+ print(f"删除临时脚本文件时出错: {e}")
221
 
222
  if __name__ == "__main__":
223
  # 检查命令行参数
 
226
  sys.exit(1)
227
 
228
  # 运行指定的脚本
229
+ run_script_with_env_question(sys.argv[1])
run_app.py CHANGED
@@ -27,7 +27,7 @@ def main():
27
 
28
  # 创建并启动应用
29
  app = create_ui()
30
- app.launch(share=False)
31
 
32
  except ImportError as e:
33
  print(f"错误: 无法导入必要的模块。请确保已安装所有依赖项: {e}")
 
27
 
28
  # 创建并启动应用
29
  app = create_ui()
30
+ app.queue().launch(share=False)
31
 
32
  except ImportError as e:
33
  print(f"错误: 无法导入必要的模块。请确保已安装所有依赖项: {e}")