zjrwtx commited on
Commit
355d1a1
·
1 Parent(s): f67af61

fix input question

Browse files
Files changed (3) hide show
  1. owl/app.py +107 -44
  2. owl/script_adapter.py +100 -51
  3. owl/temp_run.py +0 -129
owl/app.py CHANGED
@@ -109,7 +109,8 @@ ENV_GROUPS = {
109
  "required": False,
110
  "help": "Firecrawl API密钥,用于网页爬取功能。获取方式:https://www.firecrawl.dev/"
111
  },
112
- ]
 
113
  }
114
 
115
  def get_script_info(script_name):
@@ -127,6 +128,34 @@ def load_env_vars():
127
  for var in group:
128
  env_vars[var["name"]] = os.environ.get(var["name"], "")
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  return env_vars
131
 
132
  def save_env_vars(env_vars):
@@ -160,6 +189,32 @@ def save_env_vars(env_vars):
160
 
161
  return "✅ 环境变量已保存"
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  def terminate_process():
164
  """终止当前运行的进程"""
165
  global current_process
@@ -330,29 +385,6 @@ def extract_chat_history(logs):
330
  pass
331
  return None
332
 
333
- def modify_script(script_name, question):
334
- """修改脚本以使用提供的问题"""
335
- script_path = os.path.join("owl", script_name)
336
-
337
- with open(script_path, "r", encoding="utf-8") as f:
338
- content = f.read()
339
-
340
- # 查找并替换问题变量
341
- if "question = " in content:
342
- # 使用正则表达式替换问题字符串
343
- modified_content = re.sub(
344
- r'question\s*=\s*["\'].*?["\']',
345
- f'question = "{question}"',
346
- content
347
- )
348
-
349
- with open(script_path, "w", encoding="utf-8") as f:
350
- f.write(modified_content)
351
-
352
- return True
353
-
354
- return False
355
-
356
  def create_ui():
357
  """创建Gradio界面"""
358
  # 加载环境变量
@@ -434,32 +466,62 @@ def create_ui():
434
  env_inputs = {}
435
  save_status = gr.Textbox(label="保存状态", interactive=False)
436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  for group_name, vars in ENV_GROUPS.items():
438
- with gr.Accordion(group_name, open=True):
439
- for var in vars:
440
- # 添加帮助信息
441
- gr.Markdown(f"**{var['help']}**")
442
-
443
- if var["type"] == "password":
444
- env_inputs[var["name"]] = gr.Textbox(
445
- value=env_vars.get(var["name"], ""),
446
- label=var["label"] + (" (必填)" if var.get("required", False) else ""),
447
- placeholder=f"请输入{var['label']}",
448
- type="password"
449
- )
450
- else:
451
- env_inputs[var["name"]] = gr.Textbox(
452
- value=env_vars.get(var["name"], ""),
453
- label=var["label"] + (" (必填)" if var.get("required", False) else ""),
454
- placeholder=f"请输入{var['label']}"
455
- )
 
456
 
457
  save_button = gr.Button("保存环境变量", variant="primary")
458
 
459
  # 保存环境变量
460
- save_inputs = [env_inputs[var_name] for group in ENV_GROUPS.values() for var in group for var_name in [var["name"]]]
461
  save_button.click(
462
- fn=lambda *values: save_env_vars(dict(zip([var["name"] for group in ENV_GROUPS.values() for var in group], values))),
463
  inputs=save_inputs,
464
  outputs=save_status
465
  )
@@ -494,6 +556,7 @@ def create_ui():
494
  - 在"运行日志"标签页查看完整日志
495
  - 在"聊天历史"标签页查看对话历史(如果有)
496
  - 在"环境变量配置"标签页配置API密钥和其他环境变量
 
497
 
498
  ### ⚠️ 注意事项
499
 
 
109
  "required": False,
110
  "help": "Firecrawl API密钥,用于网页爬取功能。获取方式:https://www.firecrawl.dev/"
111
  },
112
+ ],
113
+ "自定义环境变量": [] # 用户自定义的环境变量将存储在这里
114
  }
115
 
116
  def get_script_info(script_name):
 
128
  for var in group:
129
  env_vars[var["name"]] = os.environ.get(var["name"], "")
130
 
131
+ # 加载.env文件中可能存在的其他环境变量
132
+ if Path(".env").exists():
133
+ with open(".env", "r", encoding="utf-8") as f:
134
+ for line in f:
135
+ line = line.strip()
136
+ if line and not line.startswith("#") and "=" in line:
137
+ key, value = line.split("=", 1)
138
+ key = key.strip()
139
+ value = value.strip().strip('"\'')
140
+
141
+ # 检查是否是已知的环境变量
142
+ known_var = False
143
+ for group in ENV_GROUPS.values():
144
+ if any(var["name"] == key for var in group):
145
+ known_var = True
146
+ break
147
+
148
+ # 如果不是已知的环境变量,添加到自定义环境变量组
149
+ if not known_var and key not in env_vars:
150
+ ENV_GROUPS["自定义环境变量"].append({
151
+ "name": key,
152
+ "label": key,
153
+ "type": "text",
154
+ "required": False,
155
+ "help": "用户自定义环境变量"
156
+ })
157
+ env_vars[key] = value
158
+
159
  return env_vars
160
 
161
  def save_env_vars(env_vars):
 
189
 
190
  return "✅ 环境变量已保存"
191
 
192
+ def add_custom_env_var(name, value, var_type):
193
+ """添加自定义环境变量"""
194
+ if not name:
195
+ return "❌ 环境变量名不能为空", None
196
+
197
+ # 检查是否已存在同名环境变量
198
+ for group in ENV_GROUPS.values():
199
+ if any(var["name"] == name for var in group):
200
+ return f"❌ 环境变量 {name} 已存在", None
201
+
202
+ # 添加到自定义环境变量组
203
+ ENV_GROUPS["自定义环境变量"].append({
204
+ "name": name,
205
+ "label": name,
206
+ "type": var_type,
207
+ "required": False,
208
+ "help": "用户自定义环境变量"
209
+ })
210
+
211
+ # 保存环境变量
212
+ env_vars = {name: value}
213
+ save_env_vars(env_vars)
214
+
215
+ # 返回成功消息和更新后的环境变量组
216
+ return f"✅ 已添加环境变量 {name}", ENV_GROUPS["自定义环境变量"]
217
+
218
  def terminate_process():
219
  """终止当前运行的进程"""
220
  global current_process
 
385
  pass
386
  return None
387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  def create_ui():
389
  """创建Gradio界面"""
390
  # 加载环境变量
 
466
  env_inputs = {}
467
  save_status = gr.Textbox(label="保存状态", interactive=False)
468
 
469
+ # 添加自定义环境变量部分
470
+ with gr.Accordion("添加自定义环境变量", open=True):
471
+ with gr.Row():
472
+ new_var_name = gr.Textbox(label="环境变量名", placeholder="例如:MY_CUSTOM_API_KEY")
473
+ new_var_value = gr.Textbox(label="环境变量值", placeholder="输入值")
474
+ new_var_type = gr.Dropdown(
475
+ choices=["text", "password"],
476
+ value="text",
477
+ label="类型"
478
+ )
479
+
480
+ add_var_button = gr.Button("添加环境变量", variant="primary")
481
+ add_var_status = gr.Textbox(label="添加状态", interactive=False)
482
+
483
+ # 自定义环境变量列表
484
+ custom_vars_list = gr.JSON(
485
+ value=ENV_GROUPS["自定义环境变量"],
486
+ label="已添加的自定义环境变量",
487
+ visible=len(ENV_GROUPS["自定义环境变量"]) > 0
488
+ )
489
+
490
+ # 添加环境变量按钮点击事件
491
+ add_var_button.click(
492
+ fn=add_custom_env_var,
493
+ inputs=[new_var_name, new_var_value, new_var_type],
494
+ outputs=[add_var_status, custom_vars_list]
495
+ )
496
+
497
+ # 现有环境变量配置
498
  for group_name, vars in ENV_GROUPS.items():
499
+ if group_name != "自定义环境变量" or len(vars) > 0: # 只显示非空的自定义环境变量组
500
+ with gr.Accordion(group_name, open=(group_name != "自定义环境变量")):
501
+ for var in vars:
502
+ # 添加帮助信息
503
+ gr.Markdown(f"**{var['help']}**")
504
+
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
 
519
  save_button = gr.Button("保存环境变量", variant="primary")
520
 
521
  # 保存环境变量
522
+ save_inputs = [env_inputs[var_name] for group in ENV_GROUPS.values() for var in group for var_name in [var["name"]] if var_name in env_inputs]
523
  save_button.click(
524
+ fn=lambda *values: save_env_vars(dict(zip([var["name"] for group in ENV_GROUPS.values() for var in group if var["name"] in env_inputs], values))),
525
  inputs=save_inputs,
526
  outputs=save_status
527
  )
 
556
  - 在"运行日志"标签页查看完整日志
557
  - 在"聊天历史"标签页查看对话历史(如果有)
558
  - 在"环境变量配置"标签页配置API密钥和其他环境变量
559
+ - 您可以添加自定义环境变量,满足特殊需求
560
 
561
  ### ⚠️ 注意事项
562
 
owl/script_adapter.py CHANGED
@@ -3,6 +3,7 @@ import sys
3
  import importlib.util
4
  import re
5
  from pathlib import Path
 
6
 
7
  def load_module_from_path(module_name, file_path):
8
  """从文件路径加载Python模块"""
@@ -33,57 +34,81 @@ def run_script_with_env_question(script_name):
33
  # 检查脚本是否有main函数
34
  has_main = re.search(r'def\s+main\s*\(\s*\)\s*:', content) is not None
35
 
36
- # 尝试查找并替换question变量
37
- # 匹配多种可能的question定义模式
38
- patterns = [
39
- r'question\s*=\s*["\'].*?["\']', # 简单字符串赋值
40
- r'question\s*=\s*\(\s*["\'].*?["\']\s*\)', # 带括号的字符串赋值
41
- r'question\s*=\s*f["\'].*?["\']', # f-string赋值
42
- r'question\s*=\s*r["\'].*?["\']', # 原始字符串赋值
43
- ]
44
 
45
- question_replaced = False
46
- for pattern in patterns:
47
- if re.search(pattern, content):
48
- # 转义问题中的特殊字符
49
- escaped_question = question.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")
50
- # 替换问题
51
- modified_content = re.sub(
52
- pattern,
53
- f'question = "{escaped_question}"',
54
- content
55
- )
56
- question_replaced = True
57
- break
58
 
59
- if not question_replaced:
60
- # 如果没有找到question变量,尝试在main函数前插入
 
 
 
 
 
 
 
 
61
  if has_main:
62
- # 在main函数前插入question变量
63
  main_match = re.search(r'def\s+main\s*\(\s*\)\s*:', content)
64
  if main_match:
65
  insert_pos = main_match.start()
66
- # 转义问题中的特殊字符
67
- escaped_question = question.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")
68
  modified_content = content[:insert_pos] + f'\n# 用户输入的问题\nquestion = "{escaped_question}"\n\n' + content[insert_pos:]
69
- question_replaced = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- if not question_replaced:
72
- # 如果仍然无法替换,尝试在文件末尾添加代码来使用用户的问题
73
- modified_content = content + f'\n\n# 用户输入的问题\nquestion = "{question}"\n\n'
74
  modified_content += '''
75
- # 如果脚本中有construct_society函数,使用用户问题运行
76
- if "construct_society" in globals():
 
 
 
 
 
 
 
 
 
 
 
77
  try:
78
- society = construct_society(question)
79
  from utils import run_society
80
  answer, chat_history, token_count = run_society(society)
81
- print(f"Answer: {answer}")
82
  except Exception as e:
83
- print(f"运行时出错: {e}")
84
  import traceback
85
  traceback.print_exc()
86
  '''
 
87
 
88
  # 执行修改后的脚本
89
  try:
@@ -92,35 +117,59 @@ if "construct_society" in globals():
92
  if str(script_dir) not in sys.path:
93
  sys.path.insert(0, str(script_dir))
94
 
95
- if has_main:
96
- # 如果有main函数,加载模块并调用main
97
- # 创建临时文件
98
- temp_script_path = script_path.with_name(f"temp_{script_path.name}")
99
- with open(temp_script_path, "w", encoding="utf-8") as f:
100
- f.write(modified_content)
 
 
 
 
101
 
102
- try:
 
103
  # 加载临时模块
104
  module_name = f"temp_{script_path.stem}"
105
  module = load_module_from_path(module_name, temp_script_path)
106
 
 
 
 
 
 
 
 
 
 
 
 
107
  # 调用main函数
108
  if hasattr(module, "main"):
 
109
  module.main()
110
  else:
111
  print(f"错误: 脚本 {script_path} 中没有main函数")
112
  sys.exit(1)
113
- finally:
114
- # 删除临时文件
115
- if temp_script_path.exists():
116
- temp_script_path.unlink()
117
- else:
118
- # 如果没有main函数,直接执行修改后的脚本
119
- exec(modified_content, {"__file__": str(script_path)})
 
 
 
 
 
 
 
 
120
 
121
  except Exception as e:
122
- print(f"执行脚本时出错: {e}")
123
- import traceback
124
  traceback.print_exc()
125
  sys.exit(1)
126
 
 
3
  import importlib.util
4
  import re
5
  from pathlib import Path
6
+ import traceback
7
 
8
  def load_module_from_path(module_name, file_path):
9
  """从文件路径加载Python模块"""
 
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:
73
+ def patched_construct_society(*args, **kwargs):
74
+ # 忽略传入的参数,始终使用用户的问题
75
+ return original_construct_society("{escaped_question}")
76
+
77
+ # 替换原始函数
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():
101
  try:
102
+ society = construct_society("{escaped_question}")
103
  from utils import run_society
104
  answer, chat_history, token_count = run_society(society)
105
+ print(f"Answer: {{answer}}")
106
  except Exception as e:
107
+ print(f"运行时出错: {{e}}")
108
  import traceback
109
  traceback.print_exc()
110
  '''
111
+ print("已添加construct_society和run_society调用代码")
112
 
113
  # 执行修改后的脚本
114
  try:
 
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
 
owl/temp_run.py DELETED
@@ -1,129 +0,0 @@
1
- from dotenv import load_dotenv
2
- load_dotenv()
3
-
4
- from camel.models import ModelFactory
5
- from camel.toolkits import (
6
- AudioAnalysisToolkit,
7
- CodeExecutionToolkit,
8
- DocumentProcessingToolkit,
9
- ExcelToolkit,
10
- ImageAnalysisToolkit,
11
- SearchToolkit,
12
- VideoAnalysisToolkit,
13
- WebToolkit,
14
- )
15
- from camel.types import ModelPlatformType, ModelType
16
-
17
- from utils import OwlRolePlaying, run_society
18
-
19
-
20
- def construct_society(question: str) -> OwlRolePlaying:
21
- r"""Construct a society of agents based on the given question.
22
-
23
- Args:
24
- question (str): The task or question to be addressed by the society.
25
-
26
- Returns:
27
- OwlRolePlaying: A configured society of agents ready to address the question.
28
- """
29
-
30
- # Create models for different components
31
- models = {
32
- "user": ModelFactory.create(
33
- model_platform=ModelPlatformType.OPENAI,
34
- model_type=ModelType.GPT_4O,
35
- model_config_dict={"temperature": 0},
36
- ),
37
- "assistant": ModelFactory.create(
38
- model_platform=ModelPlatformType.OPENAI,
39
- model_type=ModelType.GPT_4O,
40
- model_config_dict={"temperature": 0},
41
- ),
42
- "web": ModelFactory.create(
43
- model_platform=ModelPlatformType.OPENAI,
44
- model_type=ModelType.GPT_4O,
45
- model_config_dict={"temperature": 0},
46
- ),
47
- "planning": ModelFactory.create(
48
- model_platform=ModelPlatformType.OPENAI,
49
- model_type=ModelType.GPT_4O,
50
- model_config_dict={"temperature": 0},
51
- ),
52
- "video": ModelFactory.create(
53
- model_platform=ModelPlatformType.OPENAI,
54
- model_type=ModelType.GPT_4O,
55
- model_config_dict={"temperature": 0},
56
- ),
57
- "image": ModelFactory.create(
58
- model_platform=ModelPlatformType.OPENAI,
59
- model_type=ModelType.GPT_4O,
60
- model_config_dict={"temperature": 0},
61
- ),
62
- "search": ModelFactory.create(
63
- model_platform=ModelPlatformType.OPENAI,
64
- model_type=ModelType.GPT_4O,
65
- model_config_dict={"temperature": 0},
66
- ),
67
- }
68
-
69
- # Configure toolkits
70
- tools = [
71
- *WebToolkit(
72
- headless=False, # Set to True for headless mode (e.g., on remote servers)
73
- web_agent_model=models["web"],
74
- planning_agent_model=models["planning"],
75
- ).get_tools(),
76
- *DocumentProcessingToolkit().get_tools(),
77
- *VideoAnalysisToolkit(model=models["video"]).get_tools(), # This requires OpenAI Key
78
- *AudioAnalysisToolkit().get_tools(), # This requires OpenAI Key
79
- *CodeExecutionToolkit(sandbox="subprocess", verbose=True).get_tools(),
80
- *ImageAnalysisToolkit(model=models["image"]).get_tools(),
81
- *SearchToolkit(model=models["search"]).get_tools(),
82
- *ExcelToolkit().get_tools(),
83
- ]
84
-
85
- # Configure agent roles and parameters
86
- user_agent_kwargs = {"model": models["user"]}
87
- assistant_agent_kwargs = {"model": models["assistant"], "tools": tools}
88
-
89
- # Configure task parameters
90
- task_kwargs = {
91
- "task_prompt": question,
92
- "with_task_specify": False,
93
- }
94
-
95
- # Create and return the society
96
- society = OwlRolePlaying(
97
- **task_kwargs,
98
- user_role_name="user",
99
- user_agent_kwargs=user_agent_kwargs,
100
- assistant_role_name="assistant",
101
- assistant_agent_kwargs=assistant_agent_kwargs,
102
- )
103
-
104
- return society
105
-
106
-
107
-
108
- # 用户输入的问题
109
- question = "What is the current weather in New York?"
110
-
111
- def main():
112
- r"""Main function to run the OWL system with an example question."""
113
- # Example research question
114
- question = (
115
- "What was the volume in m^3 of the fish bag that was calculated in "
116
- "the University of Leicester paper `Can Hiccup Supply Enough Fish "
117
- "to Maintain a Dragon's Diet?`"
118
- )
119
-
120
- # Construct and run the society
121
- society = construct_society(question)
122
- answer, chat_history, token_count = run_society(society)
123
-
124
- # Output the result
125
- print(f"Answer: {answer}")
126
-
127
-
128
- if __name__ == "__main__":
129
- main()