camel-ai 0.1.5.6__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 (133) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +249 -36
  3. camel/agents/critic_agent.py +18 -2
  4. camel/agents/deductive_reasoner_agent.py +16 -4
  5. camel/agents/embodied_agent.py +20 -6
  6. camel/agents/knowledge_graph_agent.py +24 -5
  7. camel/agents/role_assignment_agent.py +13 -1
  8. camel/agents/search_agent.py +16 -5
  9. camel/agents/task_agent.py +20 -5
  10. camel/configs/__init__.py +11 -9
  11. camel/configs/anthropic_config.py +5 -6
  12. camel/configs/base_config.py +50 -4
  13. camel/configs/gemini_config.py +69 -17
  14. camel/configs/groq_config.py +105 -0
  15. camel/configs/litellm_config.py +2 -8
  16. camel/configs/mistral_config.py +78 -0
  17. camel/configs/ollama_config.py +5 -7
  18. camel/configs/openai_config.py +12 -23
  19. camel/configs/vllm_config.py +102 -0
  20. camel/configs/zhipuai_config.py +5 -11
  21. camel/embeddings/__init__.py +2 -0
  22. camel/embeddings/mistral_embedding.py +89 -0
  23. camel/human.py +1 -1
  24. camel/interpreters/__init__.py +2 -0
  25. camel/interpreters/ipython_interpreter.py +167 -0
  26. camel/loaders/__init__.py +2 -0
  27. camel/loaders/firecrawl_reader.py +213 -0
  28. camel/memories/agent_memories.py +1 -4
  29. camel/memories/blocks/chat_history_block.py +6 -2
  30. camel/memories/blocks/vectordb_block.py +3 -1
  31. camel/memories/context_creators/score_based.py +6 -6
  32. camel/memories/records.py +9 -7
  33. camel/messages/base.py +1 -0
  34. camel/models/__init__.py +8 -0
  35. camel/models/anthropic_model.py +7 -2
  36. camel/models/azure_openai_model.py +152 -0
  37. camel/models/base_model.py +9 -2
  38. camel/models/gemini_model.py +14 -2
  39. camel/models/groq_model.py +131 -0
  40. camel/models/litellm_model.py +26 -4
  41. camel/models/mistral_model.py +169 -0
  42. camel/models/model_factory.py +30 -3
  43. camel/models/ollama_model.py +21 -2
  44. camel/models/open_source_model.py +13 -5
  45. camel/models/openai_model.py +7 -2
  46. camel/models/stub_model.py +4 -4
  47. camel/models/vllm_model.py +138 -0
  48. camel/models/zhipuai_model.py +7 -4
  49. camel/prompts/__init__.py +8 -1
  50. camel/prompts/image_craft.py +34 -0
  51. camel/prompts/multi_condition_image_craft.py +34 -0
  52. camel/prompts/task_prompt_template.py +10 -4
  53. camel/prompts/{descripte_video_prompt.py → video_description_prompt.py} +1 -1
  54. camel/responses/agent_responses.py +4 -3
  55. camel/retrievers/auto_retriever.py +2 -2
  56. camel/societies/babyagi_playing.py +6 -4
  57. camel/societies/role_playing.py +16 -8
  58. camel/storages/graph_storages/graph_element.py +10 -14
  59. camel/storages/graph_storages/neo4j_graph.py +5 -0
  60. camel/storages/vectordb_storages/base.py +24 -13
  61. camel/storages/vectordb_storages/milvus.py +1 -1
  62. camel/storages/vectordb_storages/qdrant.py +2 -3
  63. camel/tasks/__init__.py +22 -0
  64. camel/tasks/task.py +408 -0
  65. camel/tasks/task_prompt.py +65 -0
  66. camel/toolkits/__init__.py +39 -0
  67. camel/toolkits/base.py +4 -2
  68. camel/toolkits/code_execution.py +1 -1
  69. camel/toolkits/dalle_toolkit.py +146 -0
  70. camel/toolkits/github_toolkit.py +19 -34
  71. camel/toolkits/google_maps_toolkit.py +368 -0
  72. camel/toolkits/math_toolkit.py +79 -0
  73. camel/toolkits/open_api_toolkit.py +547 -0
  74. camel/{functions → toolkits}/openai_function.py +2 -7
  75. camel/toolkits/retrieval_toolkit.py +76 -0
  76. camel/toolkits/search_toolkit.py +326 -0
  77. camel/toolkits/slack_toolkit.py +308 -0
  78. camel/toolkits/twitter_toolkit.py +522 -0
  79. camel/toolkits/weather_toolkit.py +173 -0
  80. camel/types/enums.py +154 -35
  81. camel/utils/__init__.py +14 -2
  82. camel/utils/async_func.py +1 -1
  83. camel/utils/commons.py +152 -2
  84. camel/utils/constants.py +3 -0
  85. camel/utils/token_counting.py +148 -40
  86. camel/workforce/__init__.py +23 -0
  87. camel/workforce/base.py +50 -0
  88. camel/workforce/manager_node.py +299 -0
  89. camel/workforce/role_playing_node.py +168 -0
  90. camel/workforce/single_agent_node.py +77 -0
  91. camel/workforce/task_channel.py +173 -0
  92. camel/workforce/utils.py +97 -0
  93. camel/workforce/worker_node.py +115 -0
  94. camel/workforce/workforce.py +49 -0
  95. camel/workforce/workforce_prompt.py +125 -0
  96. {camel_ai-0.1.5.6.dist-info → camel_ai-0.1.6.1.dist-info}/METADATA +45 -3
  97. camel_ai-0.1.6.1.dist-info/RECORD +182 -0
  98. camel/functions/__init__.py +0 -51
  99. camel/functions/google_maps_function.py +0 -335
  100. camel/functions/math_functions.py +0 -61
  101. camel/functions/open_api_function.py +0 -508
  102. camel/functions/retrieval_functions.py +0 -61
  103. camel/functions/search_functions.py +0 -298
  104. camel/functions/slack_functions.py +0 -286
  105. camel/functions/twitter_function.py +0 -479
  106. camel/functions/weather_functions.py +0 -144
  107. camel_ai-0.1.5.6.dist-info/RECORD +0 -157
  108. /camel/{functions → toolkits}/open_api_specs/biztoc/__init__.py +0 -0
  109. /camel/{functions → toolkits}/open_api_specs/biztoc/ai-plugin.json +0 -0
  110. /camel/{functions → toolkits}/open_api_specs/biztoc/openapi.yaml +0 -0
  111. /camel/{functions → toolkits}/open_api_specs/coursera/__init__.py +0 -0
  112. /camel/{functions → toolkits}/open_api_specs/coursera/openapi.yaml +0 -0
  113. /camel/{functions → toolkits}/open_api_specs/create_qr_code/__init__.py +0 -0
  114. /camel/{functions → toolkits}/open_api_specs/create_qr_code/openapi.yaml +0 -0
  115. /camel/{functions → toolkits}/open_api_specs/klarna/__init__.py +0 -0
  116. /camel/{functions → toolkits}/open_api_specs/klarna/openapi.yaml +0 -0
  117. /camel/{functions → toolkits}/open_api_specs/nasa_apod/__init__.py +0 -0
  118. /camel/{functions → toolkits}/open_api_specs/nasa_apod/openapi.yaml +0 -0
  119. /camel/{functions → toolkits}/open_api_specs/outschool/__init__.py +0 -0
  120. /camel/{functions → toolkits}/open_api_specs/outschool/ai-plugin.json +0 -0
  121. /camel/{functions → toolkits}/open_api_specs/outschool/openapi.yaml +0 -0
  122. /camel/{functions → toolkits}/open_api_specs/outschool/paths/__init__.py +0 -0
  123. /camel/{functions → toolkits}/open_api_specs/outschool/paths/get_classes.py +0 -0
  124. /camel/{functions → toolkits}/open_api_specs/outschool/paths/search_teachers.py +0 -0
  125. /camel/{functions → toolkits}/open_api_specs/security_config.py +0 -0
  126. /camel/{functions → toolkits}/open_api_specs/speak/__init__.py +0 -0
  127. /camel/{functions → toolkits}/open_api_specs/speak/openapi.yaml +0 -0
  128. /camel/{functions → toolkits}/open_api_specs/web_scraper/__init__.py +0 -0
  129. /camel/{functions → toolkits}/open_api_specs/web_scraper/ai-plugin.json +0 -0
  130. /camel/{functions → toolkits}/open_api_specs/web_scraper/openapi.yaml +0 -0
  131. /camel/{functions → toolkits}/open_api_specs/web_scraper/paths/__init__.py +0 -0
  132. /camel/{functions → toolkits}/open_api_specs/web_scraper/paths/scraper.py +0 -0
  133. {camel_ai-0.1.5.6.dist-info → camel_ai-0.1.6.1.dist-info}/WHEEL +0 -0
@@ -13,18 +13,14 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
  from __future__ import annotations
15
15
 
16
- from dataclasses import asdict, dataclass, field
17
- from typing import TYPE_CHECKING, Optional, Sequence
16
+ from typing import Optional, Sequence, Union
18
17
 
19
18
  from openai._types import NOT_GIVEN, NotGiven
19
+ from pydantic import Field
20
20
 
21
21
  from camel.configs.base_config import BaseConfig
22
22
 
23
- if TYPE_CHECKING:
24
- from camel.functions import OpenAIFunction
25
23
 
26
-
27
- @dataclass(frozen=True)
28
24
  class ChatGPTConfig(BaseConfig):
29
25
  r"""Defines the parameters for generating chat completions using the
30
26
  OpenAI API.
@@ -105,29 +101,19 @@ class ChatGPTConfig(BaseConfig):
105
101
  top_p: float = 1.0
106
102
  n: int = 1
107
103
  stream: bool = False
108
- stop: str | Sequence[str] | NotGiven = NOT_GIVEN
109
- max_tokens: int | NotGiven = NOT_GIVEN
104
+ stop: Union[str, Sequence[str], NotGiven] = NOT_GIVEN
105
+ max_tokens: Union[int, NotGiven] = NOT_GIVEN
110
106
  presence_penalty: float = 0.0
111
- response_format: dict | NotGiven = NOT_GIVEN
107
+ response_format: Union[dict, NotGiven] = NOT_GIVEN
112
108
  frequency_penalty: float = 0.0
113
- logit_bias: dict = field(default_factory=dict)
109
+ logit_bias: dict = Field(default_factory=dict)
114
110
  user: str = ""
115
- tools: Optional[list[OpenAIFunction]] = None
116
- tool_choice: Optional[dict[str, str] | str] = None
117
-
118
- def __post_init__(self):
119
- if self.tools is not None:
120
- object.__setattr__(
121
- self,
122
- 'tools',
123
- [tool.get_openai_tool_schema() for tool in self.tools],
124
- )
111
+ tool_choice: Optional[Union[dict[str, str], str]] = None
125
112
 
126
113
 
127
- OPENAI_API_PARAMS = {param for param in asdict(ChatGPTConfig()).keys()}
114
+ OPENAI_API_PARAMS = {param for param in ChatGPTConfig.model_fields.keys()}
128
115
 
129
116
 
130
- @dataclass(frozen=True)
131
117
  class OpenSourceConfig(BaseConfig):
132
118
  r"""Defines parameters for setting up open-source models and includes
133
119
  parameters to be passed to chat completion function of OpenAI API.
@@ -141,6 +127,9 @@ class OpenSourceConfig(BaseConfig):
141
127
  contain the arguments to be passed to OpenAI API.
142
128
  """
143
129
 
130
+ # Maybe the param needs to be renamed.
131
+ # Warning: Field "model_path" has conflict with protected namespace
132
+ # "model_".
144
133
  model_path: str
145
134
  server_url: str
146
- api_params: ChatGPTConfig = field(default_factory=ChatGPTConfig)
135
+ api_params: ChatGPTConfig = Field(default_factory=ChatGPTConfig)
@@ -0,0 +1,102 @@
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 Sequence, Union
17
+
18
+ from openai._types import NOT_GIVEN, NotGiven
19
+ from pydantic import Field
20
+
21
+ from camel.configs.base_config import BaseConfig
22
+
23
+
24
+ # flake8: noqa: E501
25
+ class VLLMConfig(BaseConfig):
26
+ r"""Defines the parameters for generating chat completions using the
27
+ OpenAI API.
28
+
29
+ Reference: https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html
30
+
31
+ Args:
32
+ temperature (float, optional): Sampling temperature to use, between
33
+ :obj:`0` and :obj:`2`. Higher values make the output more random,
34
+ while lower values make it more focused and deterministic.
35
+ (default: :obj:`0.2`)
36
+ top_p (float, optional): An alternative to sampling with temperature,
37
+ called nucleus sampling, where the model considers the results of
38
+ the tokens with top_p probability mass. So :obj:`0.1` means only
39
+ the tokens comprising the top 10% probability mass are considered.
40
+ (default: :obj:`1.0`)
41
+ n (int, optional): How many chat completion choices to generate for
42
+ each input message. (default: :obj:`1`)
43
+ response_format (object, optional): An object specifying the format
44
+ that the model must output. Compatible with GPT-4 Turbo and all
45
+ GPT-3.5 Turbo models newer than gpt-3.5-turbo-1106. Setting to
46
+ {"type": "json_object"} enables JSON mode, which guarantees the
47
+ message the model generates is valid JSON. Important: when using
48
+ JSON mode, you must also instruct the model to produce JSON
49
+ yourself via a system or user message. Without this, the model
50
+ may generate an unending stream of whitespace until the generation
51
+ reaches the token limit, resulting in a long-running and seemingly
52
+ "stuck" request. Also note that the message content may be
53
+ partially cut off if finish_reason="length", which indicates the
54
+ generation exceeded max_tokens or the conversation exceeded the
55
+ max context length.
56
+ stream (bool, optional): If True, partial message deltas will be sent
57
+ as data-only server-sent events as they become available.
58
+ (default: :obj:`False`)
59
+ stop (str or list, optional): Up to :obj:`4` sequences where the API
60
+ will stop generating further tokens. (default: :obj:`None`)
61
+ max_tokens (int, optional): The maximum number of tokens to generate
62
+ in the chat completion. The total length of input tokens and
63
+ generated tokens is limited by the model's context length.
64
+ (default: :obj:`None`)
65
+ presence_penalty (float, optional): Number between :obj:`-2.0` and
66
+ :obj:`2.0`. Positive values penalize new tokens based on whether
67
+ they appear in the text so far, increasing the model's likelihood
68
+ to talk about new topics. See more information about frequency and
69
+ presence penalties. (default: :obj:`0.0`)
70
+ frequency_penalty (float, optional): Number between :obj:`-2.0` and
71
+ :obj:`2.0`. Positive values penalize new tokens based on their
72
+ existing frequency in the text so far, decreasing the model's
73
+ likelihood to repeat the same line verbatim. See more information
74
+ about frequency and presence penalties. (default: :obj:`0.0`)
75
+ logit_bias (dict, optional): Modify the likelihood of specified tokens
76
+ appearing in the completion. Accepts a json object that maps tokens
77
+ (specified by their token ID in the tokenizer) to an associated
78
+ bias value from :obj:`-100` to :obj:`100`. Mathematically, the bias
79
+ is added to the logits generated by the model prior to sampling.
80
+ The exact effect will vary per model, but values between:obj:` -1`
81
+ and :obj:`1` should decrease or increase likelihood of selection;
82
+ values like :obj:`-100` or :obj:`100` should result in a ban or
83
+ exclusive selection of the relevant token. (default: :obj:`{}`)
84
+ user (str, optional): A unique identifier representing your end-user,
85
+ which can help OpenAI to monitor and detect abuse.
86
+ (default: :obj:`""`)
87
+ """
88
+
89
+ temperature: float = 0.2 # openai default: 1.0
90
+ top_p: float = 1.0
91
+ n: int = 1
92
+ stream: bool = False
93
+ stop: Union[str, Sequence[str], NotGiven] = NOT_GIVEN
94
+ max_tokens: Union[int, NotGiven] = NOT_GIVEN
95
+ presence_penalty: float = 0.0
96
+ response_format: Union[dict, NotGiven] = NOT_GIVEN
97
+ frequency_penalty: float = 0.0
98
+ logit_bias: dict = Field(default_factory=dict)
99
+ user: str = ""
100
+
101
+
102
+ VLLM_API_PARAMS = {param for param in VLLMConfig.model_fields.keys()}
@@ -13,18 +13,13 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
  from __future__ import annotations
15
15
 
16
- from dataclasses import asdict, dataclass
17
- from typing import TYPE_CHECKING, Optional, Sequence
16
+ from typing import Optional, Sequence, Union
18
17
 
19
18
  from openai._types import NOT_GIVEN, NotGiven
20
19
 
21
20
  from camel.configs.base_config import BaseConfig
22
21
 
23
- if TYPE_CHECKING:
24
- from camel.functions import OpenAIFunction
25
22
 
26
-
27
- @dataclass(frozen=True)
28
23
  class ZhipuAIConfig(BaseConfig):
29
24
  r"""Defines the parameters for generating chat completions using OpenAI
30
25
  compatibility
@@ -69,10 +64,9 @@ class ZhipuAIConfig(BaseConfig):
69
64
  temperature: float = 0.2
70
65
  top_p: float = 0.6
71
66
  stream: bool = False
72
- stop: str | Sequence[str] | NotGiven = NOT_GIVEN
73
- max_tokens: int | NotGiven = NOT_GIVEN
74
- tools: Optional[list[OpenAIFunction]] = None
75
- tool_choice: Optional[dict[str, str] | str] = None
67
+ stop: Union[str, Sequence[str], NotGiven] = NOT_GIVEN
68
+ max_tokens: Union[int, NotGiven] = NOT_GIVEN
69
+ tool_choice: Optional[Union[dict[str, str], str]] = None
76
70
 
77
71
 
78
- ZHIPUAI_API_PARAMS = {param for param in asdict(ZhipuAIConfig()).keys()}
72
+ ZHIPUAI_API_PARAMS = {param for param in ZhipuAIConfig.model_fields.keys()}
@@ -12,6 +12,7 @@
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
  from .base import BaseEmbedding
15
+ from .mistral_embedding import MistralEmbedding
15
16
  from .openai_embedding import OpenAIEmbedding
16
17
  from .sentence_transformers_embeddings import SentenceTransformerEncoder
17
18
  from .vlm_embedding import VisionLanguageEmbedding
@@ -21,4 +22,5 @@ __all__ = [
21
22
  "OpenAIEmbedding",
22
23
  "SentenceTransformerEncoder",
23
24
  "VisionLanguageEmbedding",
25
+ "MistralEmbedding",
24
26
  ]
@@ -0,0 +1,89 @@
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 os
17
+ from typing import Any
18
+
19
+ from camel.embeddings.base import BaseEmbedding
20
+ from camel.types import EmbeddingModelType
21
+ from camel.utils import api_keys_required
22
+
23
+
24
+ class MistralEmbedding(BaseEmbedding[str]):
25
+ r"""Provides text embedding functionalities using Mistral's models.
26
+
27
+ Args:
28
+ model_type (EmbeddingModelType, optional): The model type to be
29
+ used for text embeddings.
30
+ (default: :obj:`MISTRAL_EMBED`)
31
+ api_key (str, optional): The API key for authenticating with the
32
+ Mistral service. (default: :obj:`None`)
33
+ dimensions (int, optional): The text embedding output dimensions.
34
+ (default: :obj:`None`)
35
+
36
+ Raises:
37
+ RuntimeError: If an unsupported model type is specified.
38
+ """
39
+
40
+ def __init__(
41
+ self,
42
+ model_type: EmbeddingModelType = (EmbeddingModelType.MISTRAL_EMBED),
43
+ api_key: str | None = None,
44
+ dimensions: int | None = None,
45
+ ) -> None:
46
+ from mistralai.client import MistralClient
47
+
48
+ if not model_type.is_mistral:
49
+ raise ValueError("Invalid Mistral embedding model type.")
50
+ self.model_type = model_type
51
+ if dimensions is None:
52
+ self.output_dim = model_type.output_dim
53
+ else:
54
+ assert isinstance(dimensions, int)
55
+ self.output_dim = dimensions
56
+ self._api_key = api_key or os.environ.get("MISTRAL_API_KEY")
57
+ self._client = MistralClient(api_key=self._api_key)
58
+
59
+ @api_keys_required("MISTRAL_API_KEY")
60
+ def embed_list(
61
+ self,
62
+ objs: list[str],
63
+ **kwargs: Any,
64
+ ) -> list[list[float]]:
65
+ r"""Generates embeddings for the given texts.
66
+
67
+ Args:
68
+ objs (list[str]): The texts for which to generate the embeddings.
69
+ **kwargs (Any): Extra kwargs passed to the embedding API.
70
+
71
+ Returns:
72
+ list[list[float]]: A list that represents the generated embedding
73
+ as a list of floating-point numbers.
74
+ """
75
+ # TODO: count tokens
76
+ response = self._client.embeddings(
77
+ input=objs,
78
+ model=self.model_type.value,
79
+ **kwargs,
80
+ )
81
+ return [data.embedding for data in response.data]
82
+
83
+ def get_output_dim(self) -> int:
84
+ r"""Returns the output dimension of the embeddings.
85
+
86
+ Returns:
87
+ int: The dimensionality of the embedding for the current model.
88
+ """
89
+ return self.output_dim
camel/human.py CHANGED
@@ -135,4 +135,4 @@ class Human:
135
135
  human_input = self.get_input()
136
136
  content = self.parse_input(human_input)
137
137
  message = meta_chat_message.create_new_instance(content)
138
- return ChatAgentResponse([message], terminated=False, info={})
138
+ return ChatAgentResponse(msgs=[message], terminated=False, info={})
@@ -16,6 +16,7 @@ from .base import BaseInterpreter
16
16
  from .docker_interpreter import DockerInterpreter
17
17
  from .internal_python_interpreter import InternalPythonInterpreter
18
18
  from .interpreter_error import InterpreterError
19
+ from .ipython_interpreter import JupyterKernelInterpreter
19
20
  from .subprocess_interpreter import SubprocessInterpreter
20
21
 
21
22
  __all__ = [
@@ -24,4 +25,5 @@ __all__ = [
24
25
  'InternalPythonInterpreter',
25
26
  'SubprocessInterpreter',
26
27
  'DockerInterpreter',
28
+ 'JupyterKernelInterpreter',
27
29
  ]
@@ -0,0 +1,167 @@
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
+ import queue
16
+ import re
17
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
18
+
19
+ from camel.interpreters.base import BaseInterpreter
20
+ from camel.interpreters.interpreter_error import InterpreterError
21
+
22
+ if TYPE_CHECKING:
23
+ from jupyter_client import BlockingKernelClient, KernelManager
24
+
25
+ TIMEOUT = 30
26
+
27
+
28
+ class JupyterKernelInterpreter(BaseInterpreter):
29
+ r"""A class for executing code strings in a Jupyter Kernel.
30
+
31
+ Args:
32
+ require_confirm (bool, optional): If `True`, prompt user before
33
+ running code strings for security. Defaults to `True`.
34
+ print_stdout (bool, optional): If `True`, print the standard
35
+ output of the executed code. Defaults to `False`.
36
+ print_stderr (bool, optional): If `True`, print the standard error
37
+ of the executed code. Defaults to `True`.
38
+ """
39
+
40
+ def __init__(
41
+ self,
42
+ require_confirm: bool = True,
43
+ print_stdout: bool = False,
44
+ print_stderr: bool = True,
45
+ ) -> None:
46
+ self.require_confirm = require_confirm
47
+ self.print_stdout = print_stdout
48
+ self.print_stderr = print_stderr
49
+
50
+ self.kernel_manager: Optional[KernelManager] = None
51
+ self.client: Optional[BlockingKernelClient] = None
52
+
53
+ def __del__(self) -> None:
54
+ r"""Clean up the kernel and client."""
55
+
56
+ if self.kernel_manager:
57
+ self.kernel_manager.shutdown_kernel()
58
+ if self.client:
59
+ self.client.stop_channels()
60
+
61
+ def _initialize_if_needed(self) -> None:
62
+ r"""Initialize the kernel manager and client if they are not already
63
+ initialized.
64
+ """
65
+
66
+ if self.kernel_manager is not None:
67
+ return
68
+
69
+ from jupyter_client.manager import start_new_kernel
70
+
71
+ self.kernel_manager, self.client = start_new_kernel()
72
+
73
+ @staticmethod
74
+ def _clean_ipython_output(output: str) -> str:
75
+ r"""Remove ANSI escape sequences from the output."""
76
+
77
+ ansi_escape = re.compile(r'\x1B[@-_][0-?]*[ -/]*[@-~]')
78
+ return ansi_escape.sub('', output)
79
+
80
+ def _execute(self, code: str, timeout: float) -> str:
81
+ r"""Execute the code in the Jupyter kernel and return the result."""
82
+
83
+ if not self.kernel_manager or not self.client:
84
+ raise InterpreterError("Jupyter client is not initialized.")
85
+
86
+ self.client.execute(code)
87
+ outputs = []
88
+ while True:
89
+ try:
90
+ msg = self.client.get_iopub_msg(timeout=timeout)
91
+ msg_content = msg["content"]
92
+ msg_type = msg.get("msg_type", None)
93
+
94
+ if msg_content.get("execution_state", None) == "idle":
95
+ break
96
+
97
+ if msg_type == "error":
98
+ print(msg_content.keys())
99
+ print(msg_content)
100
+ traceback = "\n".join(msg_content["traceback"])
101
+ outputs.append(traceback)
102
+ elif msg_type == "stream":
103
+ outputs.append(msg_content["text"])
104
+ elif msg_type in ["execute_result", "display_data"]:
105
+ outputs.append(msg_content["data"]["text/plain"])
106
+ if "image/png" in msg_content["data"]:
107
+ outputs.append(
108
+ f"\n![image](data:image/png;base64,{msg_content['data']['image/png']})\n"
109
+ )
110
+ except queue.Empty:
111
+ outputs.append("Time out")
112
+ break
113
+ except Exception as e:
114
+ outputs.append(f"Exception occurred: {e!s}")
115
+ break
116
+
117
+ exec_result = "\n".join(outputs)
118
+ return self._clean_ipython_output(exec_result)
119
+
120
+ def run(self, code: str, code_type: str) -> str:
121
+ r"""Executes the given code in the Jupyter kernel.
122
+
123
+ Args:
124
+ code (str): The code string to execute.
125
+ code_type (str): The type of code to execute (e.g., 'python',
126
+ 'bash').
127
+
128
+ Returns:
129
+ str: A string containing the captured result of the
130
+ executed code.
131
+
132
+ Raises:
133
+ InterpreterError: If there is an error when doing code execution.
134
+ """
135
+ self._initialize_if_needed()
136
+
137
+ if code_type == "bash":
138
+ code = f"%%bash\n({code})"
139
+ try:
140
+ result = self._execute(code, timeout=TIMEOUT)
141
+ except Exception as e:
142
+ raise InterpreterError(f"Execution failed: {e!s}")
143
+
144
+ return result
145
+
146
+ def supported_code_types(self) -> List[str]:
147
+ r"""Provides supported code types by the interpreter.
148
+
149
+ Returns:
150
+ List[str]: Supported code types.
151
+ """
152
+ return ["python", "bash"]
153
+
154
+ def update_action_space(self, action_space: Dict[str, Any]) -> None:
155
+ r"""Updates the action space for the interpreter.
156
+
157
+ Args:
158
+ action_space (Dict[str, Any]): A dictionary representing the
159
+ new or updated action space.
160
+
161
+ Raises:
162
+ RuntimeError: Always raised because `JupyterKernelInterpreter`
163
+ does not support updating the action space.
164
+ """
165
+ raise RuntimeError(
166
+ "SubprocessInterpreter doesn't support " "`action_space`."
167
+ )
camel/loaders/__init__.py CHANGED
@@ -13,6 +13,7 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
 
15
15
  from .base_io import File, read_file
16
+ from .firecrawl_reader import Firecrawl
16
17
  from .jina_url_reader import JinaURLReader
17
18
  from .unstructured_io import UnstructuredIO
18
19
 
@@ -21,4 +22,5 @@ __all__ = [
21
22
  'read_file',
22
23
  'UnstructuredIO',
23
24
  'JinaURLReader',
25
+ 'Firecrawl',
24
26
  ]