camel-ai 0.2.0__py3-none-any.whl → 0.2.3a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of camel-ai might be problematic. Click here for more details.

@@ -1,7 +1,7 @@
1
- camel/__init__.py,sha256=zzLXt4OmIHyizUAU7n1idW4aN99Vcbjpo9JHPUUprko,778
1
+ camel/__init__.py,sha256=lQSKaE7GqJm4K6yZtPgrzu5SimTTJ16AVlL93Pk2DuI,778
2
2
  camel/agents/__init__.py,sha256=SSU1wbhZXWwQnE0rRxkpyN57kEu72KklsZNcdLkXfTs,1551
3
3
  camel/agents/base.py,sha256=X39qWSiT1WnDqaJ9k3gQrTpOQSwUKzNEVpp5AY6fDH8,1130
4
- camel/agents/chat_agent.py,sha256=cIAGXDTbZVrVsq8UsZRv8Et9eAx-lFIT73DsYTVopo0,36276
4
+ camel/agents/chat_agent.py,sha256=KwbKYfNzYSgNDHeUeBWOFUTlqVn8P8h2eHTVpeBNK8Q,43735
5
5
  camel/agents/critic_agent.py,sha256=To-istnO-9Eb0iabdeIDrgfvkxYYfsdX9xIZiSrc3oM,7493
6
6
  camel/agents/deductive_reasoner_agent.py,sha256=49vwglWYHgXf-VRftdMN9OFGOwqdsXyTt45PP6z-pbg,13473
7
7
  camel/agents/embodied_agent.py,sha256=3ABuiRQXBpplKbuhPY5KNLJyKc6Z8SgXgzIges3ZwVs,7542
@@ -12,10 +12,13 @@ camel/agents/task_agent.py,sha256=n9xIU3QtcptRPSuHZJ4ntQ_M_a8AvJ6U9ZRV8VaxV5A,14
12
12
  camel/agents/tool_agents/__init__.py,sha256=ulTNWU2qoFGe3pvVmCq_sdfeSX3NKZ0due66TYvsL-M,862
13
13
  camel/agents/tool_agents/base.py,sha256=nQAhfWi8a_bCgzlf5-G-tmj1fKm6AjpRc89NQkWwpnc,1399
14
14
  camel/agents/tool_agents/hugging_face_tool_agent.py,sha256=1Z5tG6f_86eL0vmtRZ-BJvoLDFFLhoHt8JtDvgat1xU,8723
15
+ camel/bots/__init__.py,sha256=DGgIhb7Gr_ShnAldq-4wAXucOdSvKtiV3m6e9G10rbA,834
16
+ camel/bots/discord_bot.py,sha256=VplQA162NqSohMzpCexSsuCCx_GdhAXOnL3040Ba1uE,8138
17
+ camel/bots/telegram_bot.py,sha256=MM91afWKUtEZLOoybFY7LGisQJFypc_p_P8kQOUlXwg,2747
15
18
  camel/configs/__init__.py,sha256=3SCXrA7ML8CNoOWQ1poJY6dE2e07Qxf7ACD_mdo2aJ8,2341
16
19
  camel/configs/anthropic_config.py,sha256=DGQoPyYrayhYQ7aSjkYYGHOZ5VdQ9qahtaS0p_GpU0Q,3294
17
20
  camel/configs/base_config.py,sha256=gjsDACMCk-hXDBk7qkeHcpbQrWy6jbp4iyzfqgghJEk,2485
18
- camel/configs/gemini_config.py,sha256=YHJSNEAIxBxPX1NAj2rWvM4OOR7vmIANH88pZO-aOsY,6880
21
+ camel/configs/gemini_config.py,sha256=qhGdWMRP87E99ApQdRrf9UyFpp2R0k6Y2n9ZV27qpzs,6879
19
22
  camel/configs/groq_config.py,sha256=-ihiO5h4N_kUSlPNeBqIlnIkLkhC7oXsC2FYyAqtKp0,5755
20
23
  camel/configs/litellm_config.py,sha256=77k7HT-0s9Sq_g4KeDjL_MZId0Tx5TB8oupIyGQHx08,4692
21
24
  camel/configs/mistral_config.py,sha256=G9LuY0-3S6az-8j8kpqB-4asgoaxTOsZVYeZBYJl6LI,3634
@@ -43,9 +46,9 @@ camel/interpreters/ipython_interpreter.py,sha256=B0v1DCiq6PmOYQXXQAQBX1oOYjgJ0ge
43
46
  camel/interpreters/subprocess_interpreter.py,sha256=nKxFXZJ9zGYlKdNlz6Ln7bvg65ejKZ8yAHgIFuR2WzM,6835
44
47
  camel/loaders/__init__.py,sha256=ClE516UbyUes6Zut8CCiH0zWqFwwpgEcP9ur3dte8iU,949
45
48
  camel/loaders/base_io.py,sha256=xzK67fqx66eYaM6fMXRJiSZfwKhFVNQmzuKURPtTzhk,10339
46
- camel/loaders/firecrawl_reader.py,sha256=6CfuSA3LrjnDhApoPnZfmTHbauN2TmseBTWpx0sutzo,7943
49
+ camel/loaders/firecrawl_reader.py,sha256=OmnT4XdoL-naTg_nvUnN_sjiP6Xf4gdDxFUOqyQbKJo,6691
47
50
  camel/loaders/jina_url_reader.py,sha256=ur_2Z3NFrz5AbPFi5REyZh5fISkJ9H_UZV4gtmOSO04,3607
48
- camel/loaders/unstructured_io.py,sha256=cY-5mqViE5Sobr3dnbK-KYcXjalUfeDfb8Yk6yOsu_g,16330
51
+ camel/loaders/unstructured_io.py,sha256=c2-vBhgVAWD3bJ3Gqo4nOcM5-xGc8CIMXogkc5Li9dw,17502
49
52
  camel/memories/__init__.py,sha256=ml1Uj4Y_1Q2LfrTXOY38niF0x1H-N-u_zoN_VvR939U,1364
50
53
  camel/memories/agent_memories.py,sha256=pzmjztFXPyNpabMWLi_-oJljMkYQvDP_s6Yq5U0hVEs,6097
51
54
  camel/memories/base.py,sha256=kbyAmKkOfFdOKfHxwao8bIAbRSuOEXyzxPFd0NlvUCE,5003
@@ -57,7 +60,7 @@ camel/memories/context_creators/score_based.py,sha256=UrioLcsj4jB4Rz5mg5hYmR8UYZ
57
60
  camel/memories/records.py,sha256=kcXOATDTRRo-SCAcDpsV8Ttfie7p1GcXYzuXgXKJB0E,3686
58
61
  camel/messages/__init__.py,sha256=djLvpz6AmjeLzuUSQl7J6T2O4x8MwSdcH0l9fbj_3yg,1468
59
62
  camel/messages/base.py,sha256=694Zz19D4u-j8mmpRXwCVJ8cd2Wll6h7acbyNRofNTI,13722
60
- camel/messages/func_message.py,sha256=CCVkbz-2pdxXV0vBETI0xt7d7uiN8zACpRI7lCnfTFQ,3841
63
+ camel/messages/func_message.py,sha256=wqVhTC81g5Fb2b_2EPsOBP3rHZBTP6o9wMiIRkN_HAE,3807
61
64
  camel/models/__init__.py,sha256=CxrRisXkHgJPv7HdC6pblHuhSpDjUbUjrTdZeZ-0v7w,1971
62
65
  camel/models/anthropic_model.py,sha256=_xhnbrMsuumB2jkuv2pVv3MFYxNE5EL5kVlZbYYBo5E,5751
63
66
  camel/models/azure_openai_model.py,sha256=r5diPZp4XmCcZClkCqvTHB8frzRNou559j89dryKLKw,6078
@@ -65,13 +68,13 @@ camel/models/base_model.py,sha256=UHyAgo6GzYZNLTZD1T0C3_WmHUPoh9Qoe_SfvdI7HrU,43
65
68
  camel/models/gemini_model.py,sha256=h_kyD8LSpXCn2dQ4OEer5HwwEUwuTD65yRIRV4LD3Vs,7700
66
69
  camel/models/groq_model.py,sha256=Lm1br_2FBdqNQ3pCgMNf3VnjykYzttUKnHWExEXshLo,4753
67
70
  camel/models/litellm_model.py,sha256=5sTOzI07FsxDEW3jSK-XXBx91Yo8z9voahyCsK36U6U,5748
68
- camel/models/mistral_model.py,sha256=39rHJ-z_6Z-UbtUqZPEAbCdFYY1Ft0Drs42jG5hHaho,9517
71
+ camel/models/mistral_model.py,sha256=7K0hwk4QEGtCO_Btq9v7_iLQRgg6COpdgvXxRB8rd3U,9517
69
72
  camel/models/model_factory.py,sha256=_dQOx_MYxXih6uQOjkKR7uoIrhDcWRsMTKHbO3NLYN0,5974
70
73
  camel/models/nemotron_model.py,sha256=2Idf4wrZervxvfu6av42EKjefFtDnBb6cKnWCJUkqI4,2682
71
74
  camel/models/ollama_model.py,sha256=FSMwH2-856Zhxusm4B773xBBHdlD3UOw9OAuH5eTJTw,5686
72
75
  camel/models/open_source_model.py,sha256=p5a2sCeZl5SyrgkygClndOrHEjpJxmyhE1CqKE2fZSw,6363
73
76
  camel/models/openai_audio_models.py,sha256=_ddOxqzFZCVZaK6h33Z0THU6HXk2XlJTxVWquZ3oOaQ,10042
74
- camel/models/openai_compatibility_model.py,sha256=7h1zSFBgg_mQojFvtSqC54tcZOZY0NFsZ7ZNlns5CWk,4229
77
+ camel/models/openai_compatibility_model.py,sha256=jeYBqB3xjV8jx8CJGFShkISO_TrgwubCU1WfmSiDhBY,4758
75
78
  camel/models/openai_model.py,sha256=27NbN0bU_cAPmWjwsWceNO4zW8WS2j3P_YWNTXeg1O8,5464
76
79
  camel/models/reka_model.py,sha256=_ERZvtkK0Gd7GUx3f4VVqqtH093clVMoJfa896t9f2M,8043
77
80
  camel/models/samba_model.py,sha256=CgAYMIVJFAEoyCOsYS7qD_bvWhzOkvA6SD5nGBClbzE,17699
@@ -102,14 +105,15 @@ camel/retrievers/auto_retriever.py,sha256=XPyECIXO7lFbHoLMPasFurYmC9Me6wa7JPKHZW
102
105
  camel/retrievers/base.py,sha256=sgqaJDwIkWluEgPBlukFN7RYZJnrp0imCAOEWm6bZ40,2646
103
106
  camel/retrievers/bm25_retriever.py,sha256=Dr7Yfkjw45sovI1EVNByGIMj7KERWrr8JHlh8csSF1s,5155
104
107
  camel/retrievers/cohere_rerank_retriever.py,sha256=HvnFqXpsX9EdBOab0kFLDyxxJnknPFMVxyQJQDlHbOA,4100
105
- camel/retrievers/vector_retriever.py,sha256=4tzqsUIW29Pq8uvQw_2iXhcJyTmIhvq7CinhCrr7Sps,8256
108
+ camel/retrievers/vector_retriever.py,sha256=zVsxWrv7-69GBRzC90Bt_JuMy8rQLsUYXXn5glZgdgo,9019
106
109
  camel/societies/__init__.py,sha256=JhGwUHjht4CewzC3shKuxmgB3oS7FIxIxmiKyhNsfIs,832
107
110
  camel/societies/babyagi_playing.py,sha256=tZTcfQrD9ECUhkqwdthsM2yFPfYGKsoAGMfTlrxt5as,11675
108
- camel/societies/role_playing.py,sha256=ZiiT1RtS3cQtV3XqyAXOH_Up7-b7WRDznC2qiX4PDGg,22982
109
- camel/storages/__init__.py,sha256=ghlDZ1cF3O_QxwX9xIIZ__bnHcUjh7dbAF1X_ivkofc,1551
110
- camel/storages/graph_storages/__init__.py,sha256=vsJZkedaCS-cLQ-KgMqio8cxXvbousBWVqzZJvlimT8,897
111
+ camel/societies/role_playing.py,sha256=tu6AyUPEe0j3rGNwzCCTiGqHw9RWdyTStB5JbPNvBs8,23403
112
+ camel/storages/__init__.py,sha256=erzsXX2rPVodgWxlV6hSjwmc4UCguzVb6m3ahBoyWu0,1623
113
+ camel/storages/graph_storages/__init__.py,sha256=YFwNjNYaxpKT2j5dxWZur62T8J0ZPER3DHaWGEAXgo8,954
111
114
  camel/storages/graph_storages/base.py,sha256=-Ys1BIuz4H5FvYMZTBIjg8Cfv40CPQ-OsovwMzygEgU,2858
112
115
  camel/storages/graph_storages/graph_element.py,sha256=FGYJZpS3UeSd9yyzz5KelMqbpJ6m5177PspZ8ueoQQI,2580
116
+ camel/storages/graph_storages/nebula_graph.py,sha256=PFLI--kgC93Nt5kPFWH2DVqwvk2GrC--dr2bzwvmeXw,18863
113
117
  camel/storages/graph_storages/neo4j_graph.py,sha256=YAT7u2jPs5pNSO_tSwARHJyt3HqYXpbpE4ZBtv935Kg,22138
114
118
  camel/storages/key_value_storages/__init__.py,sha256=v3Wy3CAJNgrPyBV4miOC6TxQDL-PYdGW8HbqiYl7k00,968
115
119
  camel/storages/key_value_storages/base.py,sha256=knxni8WiyTXJ2emZQO-JIsbxw6Ei7EO6dj-bU2YCoSY,2183
@@ -126,8 +130,8 @@ camel/storages/vectordb_storages/base.py,sha256=XNRv6CFg1rb9G_hZhUmN4t9XCU9rCakH
126
130
  camel/storages/vectordb_storages/milvus.py,sha256=EkwaG3bq7djektSI2jdSTccE7GjBpZruqXQoPTxtyoo,13489
127
131
  camel/storages/vectordb_storages/qdrant.py,sha256=lG_tOdjfTybSUNluQ1TEqYX96dSMrVSPg6HjO6Uzw7I,13439
128
132
  camel/tasks/__init__.py,sha256=g8_UAa4WmhaesYtzAUMW7m3mg-3ILEUvTaB7eOU9-3I,912
129
- camel/tasks/task.py,sha256=1klroUleHhnEJmWqnFHILqMryVBqL0bUXyvzoabuga4,12614
130
- camel/tasks/task_prompt.py,sha256=eDmjB0vv2InmPjKAMzy8wU5PzTPy3WFk5F7zKW9d_ZQ,2093
133
+ camel/tasks/task.py,sha256=ptVnC1cbY6einAPf7_p8AV5d04IcTsvv7gay_qmKJ48,12817
134
+ camel/tasks/task_prompt.py,sha256=iQRzCe6YoOH29ktjp5iOsE_qbWCNljV0HyaWmNsHH2s,2156
131
135
  camel/terminators/__init__.py,sha256=pE7fcfDUNngdbm1BhzSQPRMXNbdd28rl9YbF4gKWwXE,997
132
136
  camel/terminators/base.py,sha256=TSkl3maNEsdjyAniJaSgFfD4UF8RQ1LwNIiGw0dN8Gg,1396
133
137
  camel/terminators/response_terminator.py,sha256=zcXuigbvlclUoBv4xcVbfU36ZohUT1RhI-rSnukloUY,4951
@@ -174,23 +178,22 @@ camel/toolkits/slack_toolkit.py,sha256=gblCbN_RCsOdgo1GGUF-R8YJneNRjezJMHhYoRFjC
174
178
  camel/toolkits/twitter_toolkit.py,sha256=0QYLlsg4hUVev2Z0hPJHksDNHG_54IiVHsB3IxCqrXs,19741
175
179
  camel/toolkits/weather_toolkit.py,sha256=n4YrUI_jTIH7oqH918IdHbXLgfQ2BPGIWWK8Jp8G1Uw,7054
176
180
  camel/types/__init__.py,sha256=ArKXATj3z_Vv4ISmROVeo6Mv3tj5kE1dTkqfgwyxVY4,1975
177
- camel/types/enums.py,sha256=APqZIKtR2tVbUe-1JZWi7a50gjjDC7QHw9A0eKJuefA,17642
181
+ camel/types/enums.py,sha256=OfxiXL7VRcIQgfEEu0gdFeHPWGQpiuXHOC86jJE47DA,17773
178
182
  camel/types/openai_types.py,sha256=BNQ6iCzKTjSvgcXFsAFIgrUS_YUFZBU6bDoyAp387hI,2045
179
183
  camel/utils/__init__.py,sha256=IdI9v0FetNR-nx-Hg4bmNHoYto6Xfcs_uaomksdewmo,2303
180
184
  camel/utils/async_func.py,sha256=SLo8KPkrNKdsONvFf3KBb33EgFn4gH2EKSX1aI_LKes,1578
181
- camel/utils/commons.py,sha256=y7eng5QF5Hkt5tuNhtEOJycTIq9hXymrUuwIS5nRad4,16481
185
+ camel/utils/commons.py,sha256=kJ6-9pnt6HgERZh3DXofMUzT0FvDujvybuZG4rzjlso,16611
182
186
  camel/utils/constants.py,sha256=8n4F8Y-DZy4z2F0hRvAq6f-d9SbS59kK5FyLrnJ3mkY,1360
183
187
  camel/utils/token_counting.py,sha256=AVGml8X_qq3rPdzw2tc9I3n-oEkGyNH_vPsedhVtew0,21318
184
- camel/workforce/__init__.py,sha256=6jwJWDlESEqcnWCm61WCyjzFUF6KLzXA_fGI86rHfiE,878
185
- camel/workforce/base.py,sha256=lEHqgOV1tmsy7y4wuuKClcDkoPCRvXVdMrBngsM_6yY,1722
186
- camel/workforce/manager_node.py,sha256=eMmsOAoy0Wtk92b_06GhGnwKDgrTo0w-UgQorkh-az0,11529
187
- camel/workforce/role_playing_node.py,sha256=OrHI0WbN8-jW7UPnl0hzmRkNSjQERhvc4QaoNSl_3Iw,7008
188
- camel/workforce/single_agent_node.py,sha256=AzbsAX58q_2VpVN1iArauLKu76VwpTMqvlyrHTyDWjw,2928
189
- camel/workforce/task_channel.py,sha256=jYwhF3Ppc7839Kv0kWXDXkWtjRwPvoP_uF0zTwC_-jg,6752
190
- camel/workforce/utils.py,sha256=Z-kODz5PMPtfeKKVqpcQq-b-B8oqC7XSwi_F3__Ijhs,3526
191
- camel/workforce/worker_node.py,sha256=wsRqk2rugCvvkcmCzvn-y-gQuyuJGAG8PIr1KtgqJFw,3878
192
- camel/workforce/workforce.py,sha256=SVJJgSSkYvk05RgL9oaJzHwzziH7u51KLINRuzLB8BI,1773
193
- camel/workforce/workforce_prompt.py,sha256=cAWYEIA0rau5itEekSoUIFttBzpKM9RzB6x-mfukGSU,4665
194
- camel_ai-0.2.0.dist-info/METADATA,sha256=6mTZQestY-Rvn1pkyLO2-DycdgKFKy6YO7yDf37Vmq8,24677
195
- camel_ai-0.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
196
- camel_ai-0.2.0.dist-info/RECORD,,
188
+ camel/workforce/__init__.py,sha256=m2KbPItARjIyKiHc_Z34joWTJ-1XnIJfQqAZEeonz2U,926
189
+ camel/workforce/base.py,sha256=ScUPdtMLJgvvJkGEku6rrr4gBRw3GFt3V8HlYOY5Y8A,1809
190
+ camel/workforce/prompts.py,sha256=0Wcu7HpiyaD_387urc2P1uY9-DN8JAdk00HSlhNWz34,6184
191
+ camel/workforce/role_playing_worker.py,sha256=pKKT6MdVCPeag5s45yOzjT4Gn1u_aTbERSVw53ISBUY,7107
192
+ camel/workforce/single_agent_worker.py,sha256=DsibU4VkdFWuzi6mhMnT-YYm3FcVGcKfF7r1WtGii3E,3561
193
+ camel/workforce/task_channel.py,sha256=oQJ-qzXWBqZljwV3EdZ7Kpo7RExZfI_tqg0bop14clM,6741
194
+ camel/workforce/utils.py,sha256=kBrjA_k9BblJBT13kW0eQYcBDjetyjOUHMbRuh_IfPM,2270
195
+ camel/workforce/worker.py,sha256=oZtl3PhxgpizKy7W_wB94Qm4Z2Tw4k1SQsqAGAi_XoI,3844
196
+ camel/workforce/workforce.py,sha256=lF0ZeGtol91N3kAlAFwDxnO6YYVKmZPohxNb5ezHEUc,18185
197
+ camel_ai-0.2.3a0.dist-info/METADATA,sha256=usnLO_QSIxLsoD6iyL09pp0ED-Z5foxzcpvclWoKWpo,25040
198
+ camel_ai-0.2.3a0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
199
+ camel_ai-0.2.3a0.dist-info/RECORD,,
@@ -1,299 +0,0 @@
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
- from __future__ import annotations
15
-
16
- import asyncio
17
- from collections import deque
18
- from typing import Deque, Dict, List, Optional
19
-
20
- from colorama import Fore
21
-
22
- from camel.agents import ChatAgent
23
- from camel.messages.base import BaseMessage
24
- from camel.tasks.task import Task, TaskState
25
- from camel.workforce.base import BaseNode
26
- from camel.workforce.single_agent_node import SingleAgentNode
27
- from camel.workforce.task_channel import TaskChannel
28
- from camel.workforce.utils import (
29
- check_if_running,
30
- parse_assign_task_resp,
31
- parse_create_node_resp,
32
- )
33
- from camel.workforce.worker_node import WorkerNode
34
- from camel.workforce.workforce_prompt import (
35
- ASSIGN_TASK_PROMPT,
36
- CREATE_NODE_PROMPT,
37
- )
38
-
39
-
40
- class ManagerNode(BaseNode):
41
- r"""A node that manages multiple nodes. It will split the task it
42
- receives into subtasks and assign them to the child nodes under
43
- it, and also handles the situation when the task fails.
44
-
45
- Args:
46
- description (str): Description of the node.
47
- coordinator_agent_kwargs (Optional[Dict]): Keyword arguments for the
48
- coordinator agent, e.g. `model`, `api_key`, `tools`, etc.
49
- task_agent_kwargs (Optional[Dict]): Keyword arguments for the task
50
- agent, e.g. `model`, `api_key`, `tools`, etc.
51
- """
52
-
53
- def __init__(
54
- self,
55
- description: str,
56
- children: List[BaseNode],
57
- coordinator_agent_kwargs: Optional[Dict] = None,
58
- task_agent_kwargs: Optional[Dict] = None,
59
- ) -> None:
60
- super().__init__(description)
61
- self._child_listening_tasks: Deque[asyncio.Task] = deque()
62
- self._children = children
63
-
64
- coord_agent_sysmsg = BaseMessage.make_assistant_message(
65
- role_name="Workforce Manager",
66
- content="You are coordinating a group of workers. A worker can be "
67
- "a group of agents or a single agent. Each worker is created to"
68
- " solve a specific kind of task. Your job includes assigning "
69
- "tasks to a existing worker, creating a new worker for a task, "
70
- "etc.",
71
- )
72
- self.coordinator_agent = ChatAgent(
73
- coord_agent_sysmsg, **(coordinator_agent_kwargs or {})
74
- )
75
-
76
- task_sys_msg = BaseMessage.make_assistant_message(
77
- role_name="Task Planner",
78
- content="You are going to compose and decompose tasks.",
79
- )
80
- self.task_agent = ChatAgent(task_sys_msg, **(task_agent_kwargs or {}))
81
-
82
- # if there is one, will set by the workforce class wrapping this
83
- self._task: Optional[Task] = None
84
- self._pending_tasks: Deque[Task] = deque()
85
-
86
- @check_if_running(False)
87
- def set_main_task(self, task: Task) -> None:
88
- r"""Set the main task for the node."""
89
- self._task = task
90
-
91
- def _get_child_nodes_info(self) -> str:
92
- r"""Get the information of all the child nodes under this node."""
93
- return '\n'.join(
94
- f'{child.node_id}: {child.description}' for child in self._children
95
- )
96
-
97
- def _find_assignee(
98
- self,
99
- task: Task,
100
- failed_log: Optional[str] = None,
101
- ) -> str:
102
- r"""Assigns a task to a child node if capable, otherwise create a
103
- new worker node.
104
-
105
- Parameters:
106
- task (Task): The task to be assigned.
107
- failed_log (Optional[str]): Optional log of a previous failed
108
- attempt.
109
-
110
- Returns:
111
- str: ID of the assigned node.
112
- """
113
- prompt = ASSIGN_TASK_PROMPT.format(
114
- content=task.content,
115
- child_nodes_info=self._get_child_nodes_info(),
116
- )
117
- req = BaseMessage.make_user_message(
118
- role_name="User",
119
- content=prompt,
120
- )
121
- response = self.coordinator_agent.step(req)
122
- try:
123
- print(f"{Fore.YELLOW}{response.msg.content}{Fore.RESET}")
124
- assignee_id = parse_assign_task_resp(response.msg.content)
125
- except ValueError:
126
- assignee_id = self._create_worker_node_for_task(task).node_id
127
- return assignee_id
128
-
129
- async def _post_task(self, task: Task, assignee_id: str) -> None:
130
- await self._channel.post_task(task, self.node_id, assignee_id)
131
-
132
- async def _post_dependency(self, dependency: Task) -> None:
133
- await self._channel.post_dependency(dependency, self.node_id)
134
-
135
- def _create_worker_node_for_task(self, task: Task) -> WorkerNode:
136
- r"""Creates a new worker node for a given task and add it to the
137
- children list of this node. This is one of the actions that
138
- the coordinator can take when a task has failed.
139
-
140
- Args:
141
- task (Task): The task for which the worker node is created.
142
-
143
- Returns:
144
- WorkerNode: The created worker node.
145
- """
146
- prompt = CREATE_NODE_PROMPT.format(
147
- content=task.content,
148
- child_nodes_info=self._get_child_nodes_info(),
149
- )
150
- req = BaseMessage.make_user_message(
151
- role_name="User",
152
- content=prompt,
153
- )
154
- response = self.coordinator_agent.step(req)
155
- new_node_conf = parse_create_node_resp(response.msg.content)
156
-
157
- worker_sysmsg = BaseMessage.make_assistant_message(
158
- role_name=new_node_conf.role,
159
- content=new_node_conf.system,
160
- )
161
-
162
- # TODO: add a default selection of tools for the worker
163
- worker = ChatAgent(worker_sysmsg)
164
-
165
- new_node = SingleAgentNode(
166
- description=new_node_conf.description,
167
- worker=worker,
168
- )
169
- new_node.set_channel(self._channel)
170
-
171
- print(
172
- f"{Fore.GREEN}New worker node {new_node.node_id} created."
173
- f"{Fore.RESET}"
174
- )
175
-
176
- self._children.append(new_node)
177
- self._child_listening_tasks.append(
178
- asyncio.create_task(new_node.start())
179
- )
180
- return new_node
181
-
182
- async def _get_returned_task(self) -> Task:
183
- r"""Get the task that's published by this node and just get returned
184
- from the assignee.
185
- """
186
- return await self._channel.get_returned_task_by_publisher(self.node_id)
187
-
188
- async def _post_ready_tasks(self) -> None:
189
- r"""Send all the pending tasks that have all the dependencies met to
190
- the channel, or directly return if there is none. For now, we will
191
- directly send the first task in the pending list because all the tasks
192
- are linearly dependent."""
193
-
194
- if not self._pending_tasks:
195
- return
196
-
197
- ready_task = self._pending_tasks[0]
198
-
199
- # if the task has failed previously, just compose and send the task
200
- # to the channel as a dependency
201
- if ready_task.state == TaskState.FAILED:
202
- # TODO: the composing of tasks seems not work very well
203
- ready_task.compose(self.task_agent)
204
- # remove the subtasks from the channel
205
- for subtask in ready_task.subtasks:
206
- await self._channel.remove_task(subtask.id)
207
- # send the task to the channel as a dependency
208
- await self._post_dependency(ready_task)
209
- self._pending_tasks.popleft()
210
- # try to send the next task in the pending list
211
- await self._post_ready_tasks()
212
- else:
213
- # directly post the task to the channel if it's a new one
214
- # find a node to assign the task
215
- assignee_id = self._find_assignee(task=ready_task)
216
- await self._post_task(ready_task, assignee_id)
217
-
218
- async def _handle_failed_task(self, task: Task) -> None:
219
- # remove the failed task from the channel
220
- await self._channel.remove_task(task.id)
221
- if task.get_depth() >= 3:
222
- # create a new WF and reassign
223
- # TODO: add a state for reassign?
224
- assignee = self._create_worker_node_for_task(task)
225
- # print('create_new_assignee:', assignee)
226
- await self._post_task(task, assignee.node_id)
227
- else:
228
- subtasks = task.decompose(self.task_agent)
229
- # Insert packets at the head of the queue
230
- self._pending_tasks.extendleft(reversed(subtasks))
231
- await self._post_ready_tasks()
232
-
233
- async def _handle_completed_task(self, task: Task) -> None:
234
- # archive the packet, making it into a dependency
235
- self._pending_tasks.popleft()
236
- await self._channel.archive_task(task.id)
237
- await self._post_ready_tasks()
238
-
239
- @check_if_running(False)
240
- def set_channel(self, channel: TaskChannel):
241
- r"""Set the channel for the node and all the child nodes under it."""
242
- self._channel = channel
243
- for child in self._children:
244
- child.set_channel(channel)
245
-
246
- @check_if_running(False)
247
- async def _listen_to_channel(self) -> None:
248
- r"""Continuously listen to the channel, post task to the channel and
249
- track the status of posted tasks.
250
- """
251
-
252
- self._running = True
253
- print(f"{Fore.GREEN}Manager node {self.node_id} started.{Fore.RESET}")
254
-
255
- # if this node is at the top level, it will have an initial task
256
- # the initial task must be decomposed into subtasks first
257
- if self._task is not None:
258
- subtasks = self._task.decompose(self.task_agent)
259
- self._pending_tasks.extend(subtasks)
260
- self._task.state = TaskState.FAILED
261
- self._pending_tasks.append(self._task)
262
-
263
- # before starting the loop, send ready pending tasks to the channel
264
- await self._post_ready_tasks()
265
-
266
- await self._channel.print_channel()
267
-
268
- while self._task is None or self._pending_tasks:
269
- returned_task = await self._get_returned_task()
270
- if returned_task.state == TaskState.DONE:
271
- await self._handle_completed_task(returned_task)
272
- elif returned_task.state == TaskState.FAILED:
273
- await self._handle_failed_task(returned_task)
274
- else:
275
- raise ValueError(
276
- f"Task {returned_task.id} has an unexpected state."
277
- )
278
-
279
- # shut down the whole workforce tree
280
- self.stop()
281
-
282
- @check_if_running(False)
283
- async def start(self) -> None:
284
- r"""Start itself and all the child nodes under it."""
285
- for child in self._children:
286
- child_listening_task = asyncio.create_task(child.start())
287
- self._child_listening_tasks.append(child_listening_task)
288
- await self._listen_to_channel()
289
-
290
- @check_if_running(True)
291
- def stop(self) -> None:
292
- r"""Stop all the child nodes under it. The node itself will be stopped
293
- by its parent node.
294
- """
295
- for child in self._children:
296
- child.stop()
297
- for child_task in self._child_listening_tasks:
298
- child_task.cancel()
299
- self._running = False
@@ -1,168 +0,0 @@
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
- from __future__ import annotations
15
-
16
- from typing import Dict, List, Optional
17
-
18
- from colorama import Fore, Style
19
-
20
- from camel.agents.chat_agent import ChatAgent, FunctionCallingRecord
21
- from camel.messages.base import BaseMessage
22
- from camel.societies import RolePlaying
23
- from camel.tasks.task import Task, TaskState
24
- from camel.utils import print_text_animated
25
- from camel.workforce.utils import parse_task_result_resp
26
- from camel.workforce.worker_node import WorkerNode
27
- from camel.workforce.workforce_prompt import (
28
- ROLEPLAY_PROCESS_TASK_PROMPT,
29
- ROLEPLAY_SUMMERIZE_PROMPT,
30
- )
31
-
32
-
33
- class RolePlayingNode(WorkerNode):
34
- r"""A worker node that contains a role playing.
35
-
36
- Args:
37
- description (str): Description of the node.
38
- assistant_role_name (str): The role name of the assistant agent.
39
- user_role_name (str): The role name of the user agent.
40
- assistant_agent_kwargs (Optional[Dict], optional): The keyword
41
- arguments to initialize the assistant agent in the role playing,
42
- like the model name, etc. Defaults to None.
43
- user_agent_kwargs (Optional[Dict], optional): The keyword arguments to
44
- initialize the user agent in the role playing, like the model name,
45
- etc. Defaults to None.
46
- chat_turn_limit (int, optional): The maximum number of chat turns in
47
- the role playing. Defaults to 3.
48
- """
49
-
50
- def __init__(
51
- self,
52
- description: str,
53
- assistant_role_name: str,
54
- user_role_name: str,
55
- assistant_agent_kwargs: Optional[Dict] = None,
56
- user_agent_kwargs: Optional[Dict] = None,
57
- chat_turn_limit: int = 3,
58
- ) -> None:
59
- super().__init__(description)
60
- sys_message = BaseMessage.make_assistant_message(
61
- role_name="Summarizer",
62
- content="Good at summarizing the results of the chat logs",
63
- )
64
- self.summerize_agent = ChatAgent(sys_message)
65
- self.chat_turn_limit = chat_turn_limit
66
- self.assistant_role_name = assistant_role_name
67
- self.user_role_name = user_role_name
68
- self.assistant_agent_kwargs = assistant_agent_kwargs
69
- self.user_agent_kwargs = user_agent_kwargs
70
-
71
- async def _process_task(
72
- self, task: Task, dependencies: List[Task]
73
- ) -> TaskState:
74
- r"""Processes a task leveraging its dependencies through role-playing.
75
-
76
- This method orchestrates a role-playing session between an AI
77
- assistant and an AI user to process a given task. It initiates with a
78
- generated prompt based on the task and its dependencies, conducts a
79
- dialogue up to a specified chat turn limit, and then summarizes the
80
- dialogue to determine the task's outcome.
81
-
82
- Args:
83
- task (Task): The task object to be processed, containing necessary
84
- details like content and type.
85
- dependencies (List[Task]): A list of task objects that the current
86
- task depends on.
87
-
88
- Returns:
89
- TaskState: `TaskState.DONE` if processed successfully, otherwise
90
- `TaskState.FAILED`.
91
- """
92
- try:
93
- dependency_tasks_info = self._get_dep_tasks_info(dependencies)
94
- prompt = ROLEPLAY_PROCESS_TASK_PROMPT.format(
95
- content=task.content,
96
- type=task.type,
97
- dependency_task_info=dependency_tasks_info,
98
- )
99
- role_play_session = RolePlaying(
100
- assistant_role_name=self.assistant_role_name,
101
- user_role_name=self.user_role_name,
102
- assistant_agent_kwargs=self.assistant_agent_kwargs,
103
- user_agent_kwargs=self.user_agent_kwargs,
104
- task_prompt=prompt,
105
- with_task_specify=False,
106
- )
107
- n = 0
108
- input_msg = role_play_session.init_chat()
109
- chat_history = []
110
- while n < self.chat_turn_limit:
111
- n += 1
112
- assistant_response, user_response = role_play_session.step(
113
- input_msg
114
- )
115
-
116
- if assistant_response.terminated:
117
- reason = assistant_response.info['termination_reasons']
118
- print(
119
- Fore.GREEN + f"AI Assistant terminated. Reason: "
120
- f"{reason}. "
121
- )
122
- break
123
- if user_response.terminated:
124
- reason = user_response.info['termination_reasons']
125
- print(
126
- Fore.GREEN + f"AI User terminated. Reason: {reason}."
127
- )
128
- break
129
- print_text_animated(
130
- Fore.BLUE + f"AI User:\n\n{user_response.msg.content}\n",
131
- delay=0.005,
132
- )
133
- chat_history.append(f"AI User: {user_response.msg.content}")
134
-
135
- print_text_animated(Fore.GREEN + "AI Assistant:", delay=0.005)
136
- tool_calls: List[FunctionCallingRecord] = (
137
- assistant_response.info['tool_calls']
138
- )
139
- for func_record in tool_calls:
140
- print_text_animated(f"{func_record}", delay=0.005)
141
- print_text_animated(
142
- f"{assistant_response.msg.content}\n", delay=0.005
143
- )
144
- chat_history.append(
145
- f"AI Assistant: {assistant_response.msg.content}"
146
- )
147
-
148
- if "CAMEL_TASK_DONE" in user_response.msg.content:
149
- break
150
-
151
- input_msg = assistant_response.msg
152
-
153
- chat_history_str = "\n".join(chat_history)
154
- prompt = ROLEPLAY_SUMMERIZE_PROMPT.format(
155
- content=task.content,
156
- type=task.type,
157
- chat_history=chat_history_str,
158
- )
159
- req = BaseMessage.make_user_message(
160
- role_name="User",
161
- content=prompt,
162
- )
163
- response = self.summerize_agent.step(req)
164
- task.result = parse_task_result_resp(response.msg.content)
165
- print(Style.RESET_ALL + 'Task result:', task.result, '\n')
166
- return TaskState.DONE
167
- except Exception:
168
- return TaskState.FAILED