DmitriiKhizbullin commited on
Commit
97e0caf
1 Parent(s): ccae602

Sync with the main repo

Browse files
apps/agents/agents.py CHANGED
@@ -1,3 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
  Gradio-based web app Agents that uses OpenAI API to generate
3
  a chat between collaborative agents.
@@ -7,7 +20,7 @@ import argparse
7
  import os
8
  import re
9
  from dataclasses import dataclass
10
- from typing import Dict, List, Optional, Tuple, Union
11
 
12
  import gradio as gr
13
  import openai
@@ -15,8 +28,10 @@ import openai.error
15
  import tenacity
16
 
17
  from apps.agents.text_utils import split_markdown_code
18
- from camel.agents import RolePlaying, TaskSpecifyAgent
19
- from camel.messages import AssistantChatMessage
 
 
20
 
21
  REPO_ROOT = os.path.realpath(
22
  os.path.join(os.path.dirname(os.path.abspath(__file__)), "../.."))
@@ -29,17 +44,16 @@ class State:
29
  session: Optional[RolePlaying]
30
  max_messages: int
31
  chat: ChatBotHistory
32
- saved_assistant_msg: Optional[AssistantChatMessage]
33
 
34
  @classmethod
35
  def empty(cls) -> 'State':
36
  return cls(None, 0, [], None)
37
 
38
  @staticmethod
39
- def construct_inplace(
40
- state: 'State', session: Optional[RolePlaying], max_messages: int,
41
- chat: ChatBotHistory,
42
- saved_assistant_msg: Optional[AssistantChatMessage]) -> None:
43
  state.session = session
44
  state.max_messages = max_messages
45
  state.chat = chat
@@ -114,17 +128,20 @@ def cleanup_on_launch(state) -> Tuple[State, ChatBotHistory, Dict]:
114
 
115
  def role_playing_start(
116
  state,
 
117
  assistant: str,
118
  user: str,
119
  original_task: str,
120
  max_messages: float,
121
  with_task_specifier: bool,
122
  word_limit: int,
 
123
  ) -> Union[Dict, Tuple[State, str, Union[str, Dict], ChatBotHistory, Dict]]:
124
  """ Creates a role playing session.
125
 
126
  Args:
127
  state (State): Role playing state.
 
128
  assistant (str): Contents of the Assistant field.
129
  user (str): Contents of the User field.
130
  original_task (str): Original task field.
@@ -144,14 +161,41 @@ def role_playing_start(
144
  print("Double click")
145
  return {} # may fail
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  try:
148
  task_specify_kwargs = dict(word_limit=word_limit) \
149
  if with_task_specifier else None
150
 
151
- session = RolePlaying(assistant, user, original_task,
152
- with_task_specify=with_task_specifier,
153
- task_specify_agent_kwargs=task_specify_kwargs,
154
- with_task_planner=False)
 
 
 
 
 
 
 
 
155
  except (openai.error.RateLimitError, tenacity.RetryError,
156
  RuntimeError) as ex:
157
  print("OpenAI API exception 0 " + str(ex))
@@ -198,16 +242,18 @@ def role_playing_chat_init(state) -> \
198
  print("Error: session is none on role_playing_chat_init call")
199
  return state, state.chat, gr.update()
200
 
 
 
201
  try:
202
- assistant_msg, _ = state.session.init_chat()
203
- assistant_msg: AssistantChatMessage
204
  except (openai.error.RateLimitError, tenacity.RetryError,
205
  RuntimeError) as ex:
206
  print("OpenAI API exception 1 " + str(ex))
207
  state.session = None
208
  return state, state.chat, gr.update()
209
 
210
- state.saved_assistant_msg = assistant_msg
211
 
212
  progress_update = gr.update(maximum=state.max_messages, value=1,
213
  visible=True)
@@ -215,7 +261,7 @@ def role_playing_chat_init(state) -> \
215
  return state, state.chat, progress_update
216
 
217
 
218
- # WORKAROUND: do not add type hinst for session and chatbot_histoty
219
  def role_playing_chat_cont(state) -> \
220
  Tuple[State, ChatBotHistory, Dict, Dict]:
221
  """ Produce a pair of messages by an assistant and a user.
@@ -235,11 +281,13 @@ def role_playing_chat_cont(state) -> \
235
  if state.session is None:
236
  return state, state.chat, gr.update(visible=False), gr.update()
237
 
 
 
238
  if state.saved_assistant_msg is None:
239
  return state, state.chat, gr.update(), gr.update()
240
 
241
  try:
242
- assistant_msgs, user_msgs = state.session.step(
243
  state.saved_assistant_msg)
244
  except (openai.error.RateLimitError, tenacity.RetryError,
245
  RuntimeError) as ex:
@@ -247,8 +295,11 @@ def role_playing_chat_cont(state) -> \
247
  state.session = None
248
  return state, state.chat, gr.update(), gr.update()
249
 
250
- u_msg = user_msgs[0]
251
- a_msg = assistant_msgs[0]
 
 
 
252
 
253
  state.saved_assistant_msg = a_msg
254
 
@@ -301,32 +352,64 @@ def construct_ui(blocks, api_key: Optional[str] = None) -> None:
301
  if api_key is not None:
302
  openai.api_key = api_key
303
 
304
- assistant_role_path = \
305
- os.path.join(REPO_ROOT, "data/ai_society/assistant_roles.txt")
306
- user_role_path = \
307
- os.path.join(REPO_ROOT, "data/ai_society/user_roles.txt")
308
-
309
- assistant_roles = load_roles(assistant_role_path)
310
- user_roles = load_roles(user_role_path)
311
-
312
- assistant_role = "Python Programmer"
313
- user_role = "Stock Trader"
314
-
315
- default_task = "Develop a trading bot for the stock market"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
 
317
  with gr.Row():
318
  with gr.Column(scale=1):
319
- assistant_dd = gr.Dropdown(assistant_roles,
 
 
 
 
320
  label="Example assistant roles",
321
- value=assistant_role, interactive=True)
 
322
  assistant_ta = gr.TextArea(label="Assistant role (EDIT ME)",
323
  lines=1, interactive=True)
324
- with gr.Column(scale=1):
325
- user_dd = gr.Dropdown(user_roles, label="Example user roles",
326
- value=user_role, interactive=True)
 
 
327
  user_ta = gr.TextArea(label="User role (EDIT ME)", lines=1,
328
  interactive=True)
329
- with gr.Column(scale=1):
330
  gr.Markdown(
331
  "## CAMEL: Communicative Agents for \"Mind\" Exploration"
332
  " of Large Scale Language Model Society\n"
@@ -340,7 +423,8 @@ def construct_ui(blocks, api_key: Optional[str] = None) -> None:
340
  with gr.Column(scale=9):
341
  original_task_ta = gr.TextArea(
342
  label="Give me a preliminary idea (EDIT ME)",
343
- value=default_task, lines=1, interactive=True)
 
344
  with gr.Column(scale=1):
345
  universal_task_bn = gr.Button("Insert universal task")
346
  with gr.Row():
@@ -354,10 +438,13 @@ def construct_ui(blocks, api_key: Optional[str] = None) -> None:
354
  label="Word limit for task specifier",
355
  visible=task_specifier_cb.value)
356
  with gr.Column():
357
- num_messages_sl = gr.Slider(minimum=1, maximum=50, step=1,
358
- value=10, interactive=True,
359
- label="Messages to generate")
360
-
 
 
 
361
  with gr.Column(scale=2):
362
  with gr.Row():
363
  start_bn = gr.Button("Make agents chat [takes time]",
@@ -372,7 +459,8 @@ def construct_ui(blocks, api_key: Optional[str] = None) -> None:
372
  task_prompt_ta = gr.TextArea(label="Planned task prompt", lines=1,
373
  interactive=False, visible=False)
374
  chatbot = gr.Chatbot(label="Chat between autonomous agents")
375
- session_state = gr.State(State.empty())
 
376
 
377
  universal_task_bn.click(lambda: "Help me to do my job", None,
378
  original_task_ta)
@@ -383,9 +471,9 @@ def construct_ui(blocks, api_key: Optional[str] = None) -> None:
383
  start_bn.click(cleanup_on_launch, session_state,
384
  [session_state, chatbot, start_bn], queue=False) \
385
  .then(role_playing_start,
386
- [session_state, assistant_ta, user_ta,
387
  original_task_ta, num_messages_sl,
388
- task_specifier_cb, ts_word_limit_nb],
389
  [session_state, specified_task_ta, task_prompt_ta,
390
  chatbot, progress_sl],
391
  queue=False) \
@@ -398,9 +486,13 @@ def construct_ui(blocks, api_key: Optional[str] = None) -> None:
398
  clear_bn.click(stop_session, session_state,
399
  [session_state, progress_sl, start_bn])
400
 
 
 
401
  assistant_dd.change(lambda dd: dd, assistant_dd, assistant_ta)
402
  user_dd.change(lambda dd: dd, user_dd, user_ta)
403
 
 
 
404
  blocks.load(lambda dd: dd, assistant_dd, assistant_ta)
405
  blocks.load(lambda dd: dd, user_dd, user_ta)
406
 
 
1
+ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
2
+ # Licensed under the Apache License, Version 2.0 (the “License”);
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an “AS IS” BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
  """
15
  Gradio-based web app Agents that uses OpenAI API to generate
16
  a chat between collaborative agents.
 
20
  import os
21
  import re
22
  from dataclasses import dataclass
23
+ from typing import Any, Dict, List, Optional, Tuple, Union
24
 
25
  import gradio as gr
26
  import openai
 
28
  import tenacity
29
 
30
  from apps.agents.text_utils import split_markdown_code
31
+ from camel.agents import TaskSpecifyAgent
32
+ from camel.messages import BaseMessage
33
+ from camel.societies import RolePlaying
34
+ from camel.typing import TaskType
35
 
36
  REPO_ROOT = os.path.realpath(
37
  os.path.join(os.path.dirname(os.path.abspath(__file__)), "../.."))
 
44
  session: Optional[RolePlaying]
45
  max_messages: int
46
  chat: ChatBotHistory
47
+ saved_assistant_msg: Optional[BaseMessage]
48
 
49
  @classmethod
50
  def empty(cls) -> 'State':
51
  return cls(None, 0, [], None)
52
 
53
  @staticmethod
54
+ def construct_inplace(state: 'State', session: Optional[RolePlaying],
55
+ max_messages: int, chat: ChatBotHistory,
56
+ saved_assistant_msg: Optional[BaseMessage]) -> None:
 
57
  state.session = session
58
  state.max_messages = max_messages
59
  state.chat = chat
 
128
 
129
  def role_playing_start(
130
  state,
131
+ society_name: str,
132
  assistant: str,
133
  user: str,
134
  original_task: str,
135
  max_messages: float,
136
  with_task_specifier: bool,
137
  word_limit: int,
138
+ language: str,
139
  ) -> Union[Dict, Tuple[State, str, Union[str, Dict], ChatBotHistory, Dict]]:
140
  """ Creates a role playing session.
141
 
142
  Args:
143
  state (State): Role playing state.
144
+ society_name:
145
  assistant (str): Contents of the Assistant field.
146
  user (str): Contents of the User field.
147
  original_task (str): Original task field.
 
161
  print("Double click")
162
  return {} # may fail
163
 
164
+ if society_name not in {"AI Society", "Code"}:
165
+ print(f"Error: unrecognezed society {society_name}")
166
+ return {}
167
+
168
+ meta_dict: Optional[Dict[str, str]]
169
+ extend_sys_msg_meta_dicts: Optional[List[Dict]]
170
+ task_type: TaskType
171
+ if society_name == "AI Society":
172
+ meta_dict = None
173
+ extend_sys_msg_meta_dicts = None
174
+ # Keep user and assistant intact
175
+ task_type = TaskType.AI_SOCIETY
176
+ else: # "Code"
177
+ meta_dict = {"language": assistant, "domain": user}
178
+ extend_sys_msg_meta_dicts = [meta_dict, meta_dict]
179
+ assistant = f"{assistant} Programmer"
180
+ user = f"Person working in {user}"
181
+ task_type = TaskType.CODE
182
+
183
  try:
184
  task_specify_kwargs = dict(word_limit=word_limit) \
185
  if with_task_specifier else None
186
 
187
+ session = RolePlaying(
188
+ assistant,
189
+ user,
190
+ original_task,
191
+ with_task_specify=with_task_specifier,
192
+ task_specify_agent_kwargs=task_specify_kwargs,
193
+ with_task_planner=False,
194
+ task_type=task_type,
195
+ extend_sys_msg_meta_dicts=extend_sys_msg_meta_dicts,
196
+ extend_task_specify_meta_dict=meta_dict,
197
+ output_language=language,
198
+ )
199
  except (openai.error.RateLimitError, tenacity.RetryError,
200
  RuntimeError) as ex:
201
  print("OpenAI API exception 0 " + str(ex))
 
242
  print("Error: session is none on role_playing_chat_init call")
243
  return state, state.chat, gr.update()
244
 
245
+ session: RolePlaying = state.session
246
+
247
  try:
248
+ init_assistant_msg: BaseMessage
249
+ init_assistant_msg, _ = session.init_chat()
250
  except (openai.error.RateLimitError, tenacity.RetryError,
251
  RuntimeError) as ex:
252
  print("OpenAI API exception 1 " + str(ex))
253
  state.session = None
254
  return state, state.chat, gr.update()
255
 
256
+ state.saved_assistant_msg = init_assistant_msg
257
 
258
  progress_update = gr.update(maximum=state.max_messages, value=1,
259
  visible=True)
 
261
  return state, state.chat, progress_update
262
 
263
 
264
+ # WORKAROUND: do not add type hints for session and chatbot_history
265
  def role_playing_chat_cont(state) -> \
266
  Tuple[State, ChatBotHistory, Dict, Dict]:
267
  """ Produce a pair of messages by an assistant and a user.
 
281
  if state.session is None:
282
  return state, state.chat, gr.update(visible=False), gr.update()
283
 
284
+ session: RolePlaying = state.session
285
+
286
  if state.saved_assistant_msg is None:
287
  return state, state.chat, gr.update(), gr.update()
288
 
289
  try:
290
+ assistant_response, user_response = session.step(
291
  state.saved_assistant_msg)
292
  except (openai.error.RateLimitError, tenacity.RetryError,
293
  RuntimeError) as ex:
 
295
  state.session = None
296
  return state, state.chat, gr.update(), gr.update()
297
 
298
+ if len(user_response.msgs) != 1 or len(assistant_response.msgs) != 1:
299
+ return state, state.chat, gr.update(), gr.update()
300
+
301
+ u_msg = user_response.msg
302
+ a_msg = assistant_response.msg
303
 
304
  state.saved_assistant_msg = a_msg
305
 
 
352
  if api_key is not None:
353
  openai.api_key = api_key
354
 
355
+ society_dict: Dict[str, Dict[str, Any]] = {}
356
+ for society_name in ("AI Society", "Code"):
357
+ if society_name == "AI Society":
358
+ assistant_role_subpath = "ai_society/assistant_roles.txt"
359
+ user_role_subpath = "ai_society/user_roles.txt"
360
+ assistant_role = "Python Programmer"
361
+ user_role = "Stock Trader"
362
+ default_task = "Develop a trading bot for the stock market"
363
+ else:
364
+ assistant_role_subpath = "code/languages.txt"
365
+ user_role_subpath = "code/domains.txt"
366
+ assistant_role = "JavaScript"
367
+ user_role = "Sociology"
368
+ default_task = "Develop a poll app"
369
+
370
+ assistant_role_path = os.path.join(REPO_ROOT,
371
+ f"data/{assistant_role_subpath}")
372
+ user_role_path = os.path.join(REPO_ROOT, f"data/{user_role_subpath}")
373
+
374
+ society_info = dict(
375
+ assistant_roles=load_roles(assistant_role_path),
376
+ user_roles=load_roles(user_role_path),
377
+ assistant_role=assistant_role,
378
+ user_role=user_role,
379
+ default_task=default_task,
380
+ )
381
+ society_dict[society_name] = society_info
382
+
383
+ default_society = society_dict["AI Society"]
384
+
385
+ def change_society(society_name: str) -> Tuple[Dict, Dict, str]:
386
+ society = society_dict[society_name]
387
+ assistant_dd_update = gr.update(choices=society['assistant_roles'],
388
+ value=society['assistant_role'])
389
+ user_dd_update = gr.update(choices=society['user_roles'],
390
+ value=society['user_role'])
391
+ return assistant_dd_update, user_dd_update, society['default_task']
392
 
393
  with gr.Row():
394
  with gr.Column(scale=1):
395
+ society_dd = gr.Dropdown(["AI Society", "Code"],
396
+ label="Choose the society",
397
+ value="AI Society", interactive=True)
398
+ with gr.Column(scale=2):
399
+ assistant_dd = gr.Dropdown(default_society['assistant_roles'],
400
  label="Example assistant roles",
401
+ value=default_society['assistant_role'],
402
+ interactive=True)
403
  assistant_ta = gr.TextArea(label="Assistant role (EDIT ME)",
404
  lines=1, interactive=True)
405
+ with gr.Column(scale=2):
406
+ user_dd = gr.Dropdown(default_society['user_roles'],
407
+ label="Example user roles",
408
+ value=default_society['user_role'],
409
+ interactive=True)
410
  user_ta = gr.TextArea(label="User role (EDIT ME)", lines=1,
411
  interactive=True)
412
+ with gr.Column(scale=2):
413
  gr.Markdown(
414
  "## CAMEL: Communicative Agents for \"Mind\" Exploration"
415
  " of Large Scale Language Model Society\n"
 
423
  with gr.Column(scale=9):
424
  original_task_ta = gr.TextArea(
425
  label="Give me a preliminary idea (EDIT ME)",
426
+ value=default_society['default_task'], lines=1,
427
+ interactive=True)
428
  with gr.Column(scale=1):
429
  universal_task_bn = gr.Button("Insert universal task")
430
  with gr.Row():
 
438
  label="Word limit for task specifier",
439
  visible=task_specifier_cb.value)
440
  with gr.Column():
441
+ with gr.Row():
442
+ num_messages_sl = gr.Slider(minimum=1, maximum=50, step=1,
443
+ value=10, interactive=True,
444
+ label="Messages to generate")
445
+ with gr.Row():
446
+ language_ta = gr.TextArea(label="Language", value="English",
447
+ lines=1, interactive=True)
448
  with gr.Column(scale=2):
449
  with gr.Row():
450
  start_bn = gr.Button("Make agents chat [takes time]",
 
459
  task_prompt_ta = gr.TextArea(label="Planned task prompt", lines=1,
460
  interactive=False, visible=False)
461
  chatbot = gr.Chatbot(label="Chat between autonomous agents")
462
+ empty_state = State.empty()
463
+ session_state: gr.State = gr.State(empty_state)
464
 
465
  universal_task_bn.click(lambda: "Help me to do my job", None,
466
  original_task_ta)
 
471
  start_bn.click(cleanup_on_launch, session_state,
472
  [session_state, chatbot, start_bn], queue=False) \
473
  .then(role_playing_start,
474
+ [session_state, society_dd, assistant_ta, user_ta,
475
  original_task_ta, num_messages_sl,
476
+ task_specifier_cb, ts_word_limit_nb, language_ta],
477
  [session_state, specified_task_ta, task_prompt_ta,
478
  chatbot, progress_sl],
479
  queue=False) \
 
486
  clear_bn.click(stop_session, session_state,
487
  [session_state, progress_sl, start_bn])
488
 
489
+ society_dd.change(change_society, society_dd,
490
+ [assistant_dd, user_dd, original_task_ta])
491
  assistant_dd.change(lambda dd: dd, assistant_dd, assistant_ta)
492
  user_dd.change(lambda dd: dd, user_dd, user_ta)
493
 
494
+ blocks.load(change_society, society_dd,
495
+ [assistant_dd, user_dd, original_task_ta])
496
  blocks.load(lambda dd: dd, assistant_dd, assistant_ta)
497
  blocks.load(lambda dd: dd, user_dd, user_ta)
498
 
apps/agents/text_utils.py CHANGED
@@ -1,3 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import re
2
 
3
 
 
1
+ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
2
+ # Licensed under the Apache License, Version 2.0 (the “License”);
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an “AS IS” BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
  import re
15
 
16
 
requirements.txt CHANGED
@@ -2,4 +2,4 @@ openai
2
  tenacity
3
  tiktoken
4
  colorama
5
- git+https://github.com/lightaime/camel.git@hf_spaces_1
 
2
  tenacity
3
  tiktoken
4
  colorama
5
+ git+https://github.com/lightaime/camel.git@hf_spaces_2