camel-ai 0.1.5.9__py3-none-any.whl → 0.1.6.1__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.

Files changed (69) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +246 -33
  3. camel/agents/critic_agent.py +17 -1
  4. camel/agents/deductive_reasoner_agent.py +12 -0
  5. camel/agents/embodied_agent.py +19 -5
  6. camel/agents/knowledge_graph_agent.py +22 -3
  7. camel/agents/role_assignment_agent.py +12 -0
  8. camel/agents/search_agent.py +12 -0
  9. camel/agents/task_agent.py +15 -0
  10. camel/configs/__init__.py +2 -9
  11. camel/configs/anthropic_config.py +5 -6
  12. camel/configs/base_config.py +50 -4
  13. camel/configs/gemini_config.py +69 -18
  14. camel/configs/groq_config.py +6 -20
  15. camel/configs/litellm_config.py +2 -8
  16. camel/configs/mistral_config.py +17 -20
  17. camel/configs/ollama_config.py +6 -8
  18. camel/configs/openai_config.py +12 -23
  19. camel/configs/vllm_config.py +7 -8
  20. camel/configs/zhipuai_config.py +5 -11
  21. camel/human.py +1 -1
  22. camel/loaders/__init__.py +2 -0
  23. camel/loaders/firecrawl_reader.py +213 -0
  24. camel/memories/agent_memories.py +1 -4
  25. camel/memories/blocks/chat_history_block.py +6 -2
  26. camel/memories/blocks/vectordb_block.py +3 -1
  27. camel/memories/context_creators/score_based.py +6 -6
  28. camel/memories/records.py +9 -7
  29. camel/messages/base.py +1 -0
  30. camel/models/open_source_model.py +2 -2
  31. camel/prompts/__init__.py +7 -0
  32. camel/prompts/image_craft.py +34 -0
  33. camel/prompts/multi_condition_image_craft.py +34 -0
  34. camel/prompts/task_prompt_template.py +6 -0
  35. camel/responses/agent_responses.py +4 -3
  36. camel/retrievers/auto_retriever.py +0 -2
  37. camel/societies/babyagi_playing.py +6 -4
  38. camel/societies/role_playing.py +16 -8
  39. camel/storages/graph_storages/graph_element.py +10 -14
  40. camel/storages/vectordb_storages/base.py +24 -13
  41. camel/storages/vectordb_storages/milvus.py +1 -1
  42. camel/storages/vectordb_storages/qdrant.py +2 -3
  43. camel/tasks/__init__.py +22 -0
  44. camel/tasks/task.py +408 -0
  45. camel/tasks/task_prompt.py +65 -0
  46. camel/toolkits/__init__.py +3 -0
  47. camel/toolkits/base.py +3 -1
  48. camel/toolkits/dalle_toolkit.py +146 -0
  49. camel/toolkits/github_toolkit.py +16 -32
  50. camel/toolkits/google_maps_toolkit.py +2 -1
  51. camel/toolkits/open_api_toolkit.py +1 -2
  52. camel/toolkits/openai_function.py +2 -7
  53. camel/types/enums.py +6 -2
  54. camel/utils/__init__.py +12 -2
  55. camel/utils/commons.py +152 -2
  56. camel/utils/constants.py +3 -0
  57. camel/workforce/__init__.py +23 -0
  58. camel/workforce/base.py +50 -0
  59. camel/workforce/manager_node.py +299 -0
  60. camel/workforce/role_playing_node.py +168 -0
  61. camel/workforce/single_agent_node.py +77 -0
  62. camel/workforce/task_channel.py +173 -0
  63. camel/workforce/utils.py +97 -0
  64. camel/workforce/worker_node.py +115 -0
  65. camel/workforce/workforce.py +49 -0
  66. camel/workforce/workforce_prompt.py +125 -0
  67. {camel_ai-0.1.5.9.dist-info → camel_ai-0.1.6.1.dist-info}/METADATA +5 -2
  68. {camel_ai-0.1.5.9.dist-info → camel_ai-0.1.6.1.dist-info}/RECORD +69 -52
  69. {camel_ai-0.1.5.9.dist-info → camel_ai-0.1.6.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,146 @@
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 base64
15
+ import os
16
+ import uuid
17
+ from io import BytesIO
18
+ from typing import List, Optional
19
+
20
+ from openai import OpenAI
21
+ from PIL import Image
22
+
23
+ from camel.toolkits import OpenAIFunction
24
+ from camel.toolkits.base import BaseToolkit
25
+
26
+
27
+ class DalleToolkit(BaseToolkit):
28
+ r"""A class representing a toolkit for image generation using OpenAI's.
29
+
30
+ This class provides methods handle image generation using OpenAI's DALL-E.
31
+ """
32
+
33
+ def base64_to_image(self, base64_string: str) -> Optional[Image.Image]:
34
+ r"""Converts a base64 encoded string into a PIL Image object.
35
+
36
+ Args:
37
+ base64_string (str): The base64 encoded string of the image.
38
+
39
+ Returns:
40
+ Optional[Image.Image]: The PIL Image object or None if conversion
41
+ fails.
42
+ """
43
+ try:
44
+ # Decode the base64 string to get the image data
45
+ image_data = base64.b64decode(base64_string)
46
+ # Create a memory buffer for the image data
47
+ image_buffer = BytesIO(image_data)
48
+ # Open the image using the PIL library
49
+ image = Image.open(image_buffer)
50
+ return image
51
+ except Exception as e:
52
+ print(f"An error occurred while converting base64 to image: {e}")
53
+ return None
54
+
55
+ def image_path_to_base64(self, image_path: str) -> str:
56
+ r"""Converts the file path of an image to a Base64 encoded string.
57
+
58
+ Args:
59
+ image_path (str): The path to the image file.
60
+
61
+ Returns:
62
+ str: A Base64 encoded string representing the content of the image
63
+ file.
64
+ """
65
+ try:
66
+ with open(image_path, "rb") as image_file:
67
+ return base64.b64encode(image_file.read()).decode('utf-8')
68
+ except Exception as e:
69
+ print(
70
+ f"An error occurred while converting image path to base64: {e}"
71
+ )
72
+ return ""
73
+
74
+ def image_to_base64(self, image: Image.Image) -> str:
75
+ r"""Converts an image into a base64-encoded string.
76
+
77
+ This function takes an image object as input, encodes the image into a
78
+ PNG format base64 string, and returns it.
79
+ If the encoding process encounters an error, it prints the error
80
+ message and returns None.
81
+
82
+ Args:
83
+ image: The image object to be encoded, supports any image format
84
+ that can be saved in PNG format.
85
+
86
+ Returns:
87
+ str: A base64-encoded string of the image.
88
+ """
89
+ try:
90
+ with BytesIO() as buffered_image:
91
+ image.save(buffered_image, format="PNG")
92
+ buffered_image.seek(0)
93
+ image_bytes = buffered_image.read()
94
+ base64_str = base64.b64encode(image_bytes).decode('utf-8')
95
+ return base64_str
96
+ except Exception as e:
97
+ print(f"An error occurred: {e}")
98
+ return ""
99
+
100
+ def get_dalle_img(self, prompt: str, image_dir: str = "img") -> str:
101
+ r"""Generate an image using OpenAI's DALL-E model.
102
+ The generated image is saved to the specified directory.
103
+
104
+ Args:
105
+ prompt (str): The text prompt based on which the image is
106
+ generated.
107
+ image_dir (str): The directory to save the generated image.
108
+ Defaults to 'img'.
109
+
110
+ Returns:
111
+ str: The path to the saved image.
112
+ """
113
+
114
+ dalle_client = OpenAI()
115
+ response = dalle_client.images.generate(
116
+ model="dall-e-3",
117
+ prompt=prompt,
118
+ size="1024x1792",
119
+ quality="standard",
120
+ n=1, # NOTE: now dall-e-3 only supports n=1
121
+ response_format="b64_json",
122
+ )
123
+ image_b64 = response.data[0].b64_json
124
+ image = self.base64_to_image(image_b64) # type: ignore[arg-type]
125
+
126
+ if image is None:
127
+ raise ValueError("Failed to convert base64 string to image.")
128
+
129
+ os.makedirs(image_dir, exist_ok=True)
130
+ image_path = os.path.join(image_dir, f"{uuid.uuid4()}.png")
131
+ image.save(image_path)
132
+
133
+ return image_path
134
+
135
+ def get_tools(self) -> List[OpenAIFunction]:
136
+ r"""Returns a list of OpenAIFunction objects representing the
137
+ functions in the toolkit.
138
+
139
+ Returns:
140
+ List[OpenAIFunction]: A list of OpenAIFunction objects
141
+ representing the functions in the toolkit.
142
+ """
143
+ return [OpenAIFunction(self.get_dalle_img)]
144
+
145
+
146
+ DALLE_FUNCS: List[OpenAIFunction] = DalleToolkit().get_tools()
@@ -13,18 +13,18 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
 
15
15
  import os
16
- from dataclasses import dataclass
17
16
  from datetime import datetime, timedelta
18
17
  from typing import List, Optional
19
18
 
19
+ from pydantic import BaseModel
20
+
20
21
  from camel.utils import dependencies_required
21
22
 
22
23
  from .base import BaseToolkit
23
24
  from .openai_function import OpenAIFunction
24
25
 
25
26
 
26
- @dataclass
27
- class GithubIssue:
27
+ class GithubIssue(BaseModel):
28
28
  r"""Represents a GitHub issue.
29
29
 
30
30
  Attributes:
@@ -35,29 +35,11 @@ class GithubIssue:
35
35
  file_content (str): The content of the file associated with the issue.
36
36
  """
37
37
 
38
- def __init__(
39
- self,
40
- title: str,
41
- body: str,
42
- number: int,
43
- file_path: str,
44
- file_content: str,
45
- ) -> None:
46
- r"""Initialize a GithubIssue object.
47
-
48
- Args:
49
- title (str): The title of the GitHub issue.
50
- body (str): The body/content of the GitHub issue.
51
- number (int): The issue number.
52
- file_path (str): The path of the file associated with the issue.
53
- file_content (str): The content of the file associated with the
54
- issue.
55
- """
56
- self.title = title
57
- self.body = body
58
- self.number = number
59
- self.file_path = file_path
60
- self.file_content = file_content
38
+ title: str
39
+ body: str
40
+ number: int
41
+ file_path: str
42
+ file_content: str
61
43
 
62
44
  def __str__(self) -> str:
63
45
  r"""Returns a string representation of the issue.
@@ -75,8 +57,7 @@ class GithubIssue:
75
57
  )
76
58
 
77
59
 
78
- @dataclass
79
- class GithubPullRequestDiff:
60
+ class GithubPullRequestDiff(BaseModel):
80
61
  r"""Represents a single diff of a pull request on Github.
81
62
 
82
63
  Attributes:
@@ -92,8 +73,7 @@ class GithubPullRequestDiff:
92
73
  return f"Filename: {self.filename}\nPatch: {self.patch}"
93
74
 
94
75
 
95
- @dataclass
96
- class GithubPullRequest:
76
+ class GithubPullRequest(BaseModel):
97
77
  r"""Represents a pull request on Github.
98
78
 
99
79
  Attributes:
@@ -251,13 +231,17 @@ class GithubToolkit(BaseToolkit):
251
231
  and pr.merged_at is not None
252
232
  and pr.merged_at.timestamp() > earliest_date.timestamp()
253
233
  ):
254
- pr_details = GithubPullRequest(pr.title, pr.body, [])
234
+ pr_details = GithubPullRequest(
235
+ title=pr.title, body=pr.body, diffs=[]
236
+ )
255
237
 
256
238
  # Get files changed in the PR
257
239
  files = pr.get_files()
258
240
 
259
241
  for file in files:
260
- diff = GithubPullRequestDiff(file.filename, file.patch)
242
+ diff = GithubPullRequestDiff(
243
+ filename=file.filename, patch=file.patch
244
+ )
261
245
  pr_details.diffs.append(diff)
262
246
 
263
247
  merged_prs.append(str(pr_details))
@@ -36,7 +36,8 @@ def handle_googlemaps_exceptions(
36
36
  @wraps(func)
37
37
  def wrapper(*args: Any, **kwargs: Any) -> Any:
38
38
  try:
39
- from googlemaps.exceptions import ( # type: ignore[import-untyped] # isort: skip
39
+ # ruff: noqa: E501
40
+ from googlemaps.exceptions import ( # type: ignore[import]
40
41
  ApiError,
41
42
  HTTPError,
42
43
  Timeout,
@@ -18,11 +18,10 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
18
18
  import requests
19
19
 
20
20
  from camel.toolkits import OpenAIFunction, openapi_security_config
21
- from camel.toolkits.base import BaseToolkit
22
21
  from camel.types import OpenAPIName
23
22
 
24
23
 
25
- class OpenAPIToolkit(BaseToolkit):
24
+ class OpenAPIToolkit:
26
25
  r"""A class representing a toolkit for interacting with OpenAPI APIs.
27
26
 
28
27
  This class provides methods for interacting with APIs based on OpenAPI
@@ -20,7 +20,7 @@ from jsonschema.validators import Draft202012Validator as JSONValidator
20
20
  from pydantic import create_model
21
21
  from pydantic.fields import FieldInfo
22
22
 
23
- from camel.utils import PYDANTIC_V2, to_pascal
23
+ from camel.utils import get_pydantic_object_schema, to_pascal
24
24
 
25
25
 
26
26
  def _remove_a_key(d: Dict, remove_key: Any) -> None:
@@ -110,12 +110,7 @@ def get_openai_tool_schema(func: Callable) -> Dict[str, Any]:
110
110
  return create_model(name, **field)
111
111
 
112
112
  model = _create_mol(to_pascal(func.__name__), fields)
113
- # NOTE: Method `.schema()` is deprecated in pydantic v2.
114
- # the result would be identical to `.model_json_schema()` in v2
115
- if PYDANTIC_V2:
116
- parameters_dict = model.model_json_schema()
117
- else:
118
- parameters_dict = model.schema()
113
+ parameters_dict = get_pydantic_object_schema(model)
119
114
  # The `"title"` is generated by `model.model_json_schema()`
120
115
  # but is useless for openai json schema
121
116
  _remove_a_key(parameters_dict, "title")
camel/types/enums.py CHANGED
@@ -208,7 +208,6 @@ class ModelType(Enum):
208
208
  # reference: https://lmsys.org/blog/2023-03-30-vicuna/
209
209
  return 2048
210
210
  elif self in {
211
- ModelType.GPT_3_5_TURBO,
212
211
  ModelType.LLAMA_2,
213
212
  ModelType.NEMOTRON_4_REWARD,
214
213
  ModelType.STUB,
@@ -226,7 +225,10 @@ class ModelType(Enum):
226
225
  ModelType.GLM_4_OPEN_SOURCE,
227
226
  }:
228
227
  return 8_192
229
- elif self is ModelType.VICUNA_16K:
228
+ elif self in {
229
+ ModelType.GPT_3_5_TURBO,
230
+ ModelType.VICUNA_16K,
231
+ }:
230
232
  return 16_384
231
233
  elif self in {
232
234
  ModelType.GPT_4_32K,
@@ -359,6 +361,8 @@ class TaskType(Enum):
359
361
  ROLE_DESCRIPTION = "role_description"
360
362
  GENERATE_TEXT_EMBEDDING_DATA = "generate_text_embedding_data"
361
363
  OBJECT_RECOGNITION = "object_recognition"
364
+ IMAGE_CRAFT = "image_craft"
365
+ MULTI_CONDITION_IMAGE_CRAFT = "multi_condition_image_craft"
362
366
  DEFAULT = "default"
363
367
  VIDEO_DESCRIPTION = "video_description"
364
368
 
camel/utils/__init__.py CHANGED
@@ -13,17 +13,22 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
 
15
15
  from .commons import (
16
- PYDANTIC_V2,
16
+ AgentOpsMeta,
17
+ agentops_decorator,
17
18
  api_keys_required,
18
19
  check_server_running,
19
20
  create_chunks,
20
21
  dependencies_required,
21
22
  download_tasks,
23
+ func_string_to_callable,
22
24
  get_first_int,
23
25
  get_prompt_template_key_words,
26
+ get_pydantic_major_version,
27
+ get_pydantic_object_schema,
24
28
  get_system_information,
25
29
  get_task_list,
26
30
  is_docker_running,
31
+ json_to_function_code,
27
32
  print_text_animated,
28
33
  text_extract_from_web,
29
34
  to_pascal,
@@ -50,7 +55,6 @@ __all__ = [
50
55
  'AnthropicTokenCounter',
51
56
  'get_system_information',
52
57
  'to_pascal',
53
- 'PYDANTIC_V2',
54
58
  'get_model_encoding',
55
59
  'BaseTokenCounter',
56
60
  'OpenAITokenCounter',
@@ -64,4 +68,10 @@ __all__ = [
64
68
  'is_docker_running',
65
69
  'GeminiTokenCounter',
66
70
  'MistralTokenCounter',
71
+ 'get_pydantic_major_version',
72
+ 'get_pydantic_object_schema',
73
+ 'func_string_to_callable',
74
+ 'json_to_function_code',
75
+ 'agentops_decorator',
76
+ 'AgentOpsMeta',
67
77
  ]
camel/utils/commons.py CHANGED
@@ -20,14 +20,27 @@ import subprocess
20
20
  import time
21
21
  import zipfile
22
22
  from functools import wraps
23
- from typing import Any, Callable, List, Optional, Set, TypeVar, cast
23
+ from typing import (
24
+ Any,
25
+ Callable,
26
+ Dict,
27
+ List,
28
+ Mapping,
29
+ Optional,
30
+ Set,
31
+ TypeVar,
32
+ cast,
33
+ )
24
34
  from urllib.parse import urlparse
25
35
 
26
36
  import pydantic
27
37
  import requests
38
+ from pydantic import BaseModel
28
39
 
29
40
  from camel.types import TaskType
30
41
 
42
+ from .constants import Constants
43
+
31
44
  F = TypeVar('F', bound=Callable[..., Any])
32
45
 
33
46
 
@@ -303,7 +316,97 @@ def to_pascal(snake: str) -> str:
303
316
  )
304
317
 
305
318
 
306
- PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
319
+ def get_pydantic_major_version() -> int:
320
+ r"""Get the major version of Pydantic.
321
+
322
+ Returns:
323
+ int: The major version number of Pydantic if installed, otherwise 0.
324
+ """
325
+ try:
326
+ return int(pydantic.__version__.split(".")[0])
327
+ except ImportError:
328
+ return 0
329
+
330
+
331
+ def get_pydantic_object_schema(pydantic_params: BaseModel) -> Dict:
332
+ r"""Get the JSON schema of a Pydantic model.
333
+
334
+ Args:
335
+ pydantic_params (BaseModel): The Pydantic model to retrieve the schema
336
+ for.
337
+
338
+ Returns:
339
+ dict: The JSON schema of the Pydantic model.
340
+ """
341
+ return pydantic_params.model_json_schema()
342
+
343
+
344
+ def func_string_to_callable(code: str):
345
+ r"""Convert a function code string to a callable function object.
346
+
347
+ Args:
348
+ code (str): The function code as a string.
349
+
350
+ Returns:
351
+ Callable[..., Any]: The callable function object extracted from the
352
+ code string.
353
+ """
354
+ local_vars: Mapping[str, object] = {}
355
+ exec(code, globals(), local_vars)
356
+ func = local_vars.get(Constants.FUNC_NAME_FOR_STRUCTURE_OUTPUT)
357
+ return func
358
+
359
+
360
+ def json_to_function_code(json_obj: Dict) -> str:
361
+ r"""Generate a Python function code from a JSON schema.
362
+
363
+ Args:
364
+ json_obj (dict): The JSON schema object containing properties and
365
+ required fields, and json format is follow openai tools schema
366
+
367
+ Returns:
368
+ str: The generated Python function code as a string.
369
+ """
370
+ properties = json_obj.get('properties', {})
371
+ required = json_obj.get('required', [])
372
+
373
+ if not properties or not required:
374
+ raise ValueError(
375
+ "JSON schema must contain 'properties' and 'required' fields"
376
+ )
377
+
378
+ args = []
379
+ docstring_args = []
380
+ return_keys = []
381
+
382
+ for prop in required:
383
+ description = properties[prop]['description']
384
+ prop_type = properties[prop]['type']
385
+ python_type = 'str' if prop_type == 'string' else prop_type
386
+ args.append(f"{prop}: {python_type}")
387
+ docstring_args.append(
388
+ f" {prop} ({python_type}): {description}."
389
+ )
390
+ return_keys.append(prop)
391
+
392
+ # extract entity of schema
393
+ args_str = ", ".join(args)
394
+ docstring_args_str = "\n".join(docstring_args)
395
+ return_keys_str = ", ".join(return_keys)
396
+
397
+ # function template
398
+ function_code = f'''
399
+ def {Constants.FUNC_NAME_FOR_STRUCTURE_OUTPUT}({args_str}):
400
+ r"""Return response with a specified json format.
401
+ Args:
402
+ {docstring_args_str}
403
+ Returns:
404
+ Dict: A dictionary containing {return_keys_str}.
405
+ """
406
+ return {{{", ".join([f'"{prop}": {prop}' for prop in required])}}}
407
+ '''
408
+
409
+ return function_code
307
410
 
308
411
 
309
412
  def text_extract_from_web(url: str) -> str:
@@ -382,3 +485,50 @@ def is_docker_running() -> bool:
382
485
  return result.returncode == 0
383
486
  except (subprocess.CalledProcessError, FileNotFoundError):
384
487
  return False
488
+
489
+
490
+ try:
491
+ from agentops import ToolEvent, record
492
+ except ImportError:
493
+ ToolEvent = None
494
+
495
+
496
+ def agentops_decorator(func):
497
+ r"""Decorator that records the execution of a function if ToolEvent is
498
+ available.
499
+
500
+ Parameters:
501
+ func (callable): The function to be decorated.
502
+
503
+ Returns:
504
+ callable: The wrapped function which records its execution details.
505
+ """
506
+
507
+ @wraps(func)
508
+ def wrapper(*args, **kwargs):
509
+ if ToolEvent:
510
+ tool_event = ToolEvent(name=func.__name__, params=kwargs)
511
+ result = func(*args, **kwargs)
512
+ tool_event.returns = result
513
+ record(tool_event)
514
+ return result
515
+ return func(*args, **kwargs)
516
+
517
+ return wrapper
518
+
519
+
520
+ class AgentOpsMeta(type):
521
+ r"""Metaclass that automatically decorates all callable attributes with
522
+ the agentops_decorator,
523
+ except for the 'get_tools' method.
524
+
525
+ Methods:
526
+ __new__(cls, name, bases, dct):
527
+ Creates a new class with decorated methods.
528
+ """
529
+
530
+ def __new__(cls, name, bases, dct):
531
+ for attr, value in dct.items():
532
+ if callable(value) and attr != 'get_tools':
533
+ dct[attr] = agentops_decorator(value)
534
+ return super(AgentOpsMeta, cls).__new__(cls, name, bases, dct)
camel/utils/constants.py CHANGED
@@ -24,3 +24,6 @@ class Constants:
24
24
 
25
25
  # default plug of imageio to read video
26
26
  VIDEO_DEFAULT_PLUG_PYAV = "pyav"
27
+
28
+ # return response with json format
29
+ FUNC_NAME_FOR_STRUCTURE_OUTPUT = "return_json_response"
@@ -0,0 +1,23 @@
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
+ from .base import BaseNode
16
+ from .manager_node import ManagerNode
17
+ from .worker_node import WorkerNode
18
+
19
+ __all__ = [
20
+ "BaseNode",
21
+ "WorkerNode",
22
+ "ManagerNode",
23
+ ]
@@ -0,0 +1,50 @@
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 abc import ABC, abstractmethod
15
+ from typing import Any
16
+
17
+ from camel.workforce.task_channel import TaskChannel
18
+
19
+
20
+ class BaseNode(ABC):
21
+ def __init__(self, description: str) -> None:
22
+ self.node_id = str(id(self))
23
+ self.description = description
24
+ # every node is initialized to use its own channel
25
+ self._channel: TaskChannel = TaskChannel()
26
+ self._running = False
27
+
28
+ def reset(self, *args: Any, **kwargs: Any) -> Any:
29
+ """Resets the node to its initial state."""
30
+ raise NotImplementedError()
31
+
32
+ @abstractmethod
33
+ def set_channel(self, channel: TaskChannel):
34
+ r"""Sets the channel for the node."""
35
+
36
+ @abstractmethod
37
+ async def _listen_to_channel(self):
38
+ r"""Listens to the channel and handle tasks. This method should be
39
+ the main loop for the node.
40
+ """
41
+
42
+ @abstractmethod
43
+ async def start(self):
44
+ r"""Start the node."""
45
+
46
+ @abstractmethod
47
+ def stop(self):
48
+ r"""
49
+ Stop the node.
50
+ """