camel-ai 0.2.10__py3-none-any.whl → 0.2.11__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 (36) hide show
  1. camel/__init__.py +6 -1
  2. camel/agents/chat_agent.py +74 -5
  3. camel/agents/deductive_reasoner_agent.py +4 -1
  4. camel/configs/__init__.py +3 -0
  5. camel/configs/mistral_config.py +0 -3
  6. camel/configs/nvidia_config.py +70 -0
  7. camel/configs/vllm_config.py +10 -1
  8. camel/embeddings/vlm_embedding.py +4 -1
  9. camel/interpreters/docker_interpreter.py +7 -2
  10. camel/interpreters/subprocess_interpreter.py +7 -2
  11. camel/loaders/firecrawl_reader.py +0 -3
  12. camel/logger.py +112 -0
  13. camel/messages/__init__.py +1 -1
  14. camel/messages/base.py +10 -7
  15. camel/messages/conversion/__init__.py +3 -1
  16. camel/messages/conversion/alpaca.py +122 -0
  17. camel/models/__init__.py +5 -0
  18. camel/models/model_factory.py +3 -0
  19. camel/models/model_manager.py +212 -0
  20. camel/models/nvidia_model.py +141 -0
  21. camel/models/openai_model.py +1 -0
  22. camel/retrievers/vector_retriever.py +22 -5
  23. camel/societies/babyagi_playing.py +4 -1
  24. camel/toolkits/__init__.py +3 -0
  25. camel/toolkits/code_execution.py +38 -4
  26. camel/toolkits/human_toolkit.py +1 -0
  27. camel/toolkits/meshy_toolkit.py +185 -0
  28. camel/toolkits/twitter_toolkit.py +3 -0
  29. camel/types/enums.py +41 -8
  30. camel/utils/commons.py +22 -5
  31. camel/utils/token_counting.py +4 -1
  32. {camel_ai-0.2.10.dist-info → camel_ai-0.2.11.dist-info}/METADATA +2 -2
  33. {camel_ai-0.2.10.dist-info → camel_ai-0.2.11.dist-info}/RECORD +36 -30
  34. /camel/messages/conversion/{models.py → conversation_models.py} +0 -0
  35. {camel_ai-0.2.10.dist-info → camel_ai-0.2.11.dist-info}/LICENSE +0 -0
  36. {camel_ai-0.2.10.dist-info → camel_ai-0.2.11.dist-info}/WHEEL +0 -0
camel/__init__.py CHANGED
@@ -12,9 +12,14 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
- __version__ = '0.2.10'
15
+ from camel.logger import disable_logging, enable_logging, set_log_level
16
+
17
+ __version__ = '0.2.11'
16
18
 
17
19
  __all__ = [
18
20
  '__version__',
19
21
  'camel',
22
+ 'disable_logging',
23
+ 'enable_logging',
24
+ 'set_log_level',
20
25
  ]
@@ -21,6 +21,7 @@ from collections import defaultdict
21
21
  from typing import (
22
22
  TYPE_CHECKING,
23
23
  Any,
24
+ Callable,
24
25
  Dict,
25
26
  List,
26
27
  Optional,
@@ -41,7 +42,12 @@ from camel.memories import (
41
42
  ScoreBasedContextCreator,
42
43
  )
43
44
  from camel.messages import BaseMessage, FunctionCallingMessage, OpenAIMessage
44
- from camel.models import BaseModelBackend, ModelFactory
45
+ from camel.models import (
46
+ BaseModelBackend,
47
+ ModelFactory,
48
+ ModelManager,
49
+ ModelProcessingError,
50
+ )
45
51
  from camel.responses import ChatAgentResponse
46
52
  from camel.types import (
47
53
  ChatCompletion,
@@ -145,12 +151,16 @@ class ChatAgent(BaseAgent):
145
151
  response_terminators (List[ResponseTerminator], optional): List of
146
152
  :obj:`ResponseTerminator` bind to one chat agent.
147
153
  (default: :obj:`None`)
154
+ scheduling_strategy (str): name of function that defines how to select
155
+ the next model in ModelManager. (default: :str:`round_robin`)
148
156
  """
149
157
 
150
158
  def __init__(
151
159
  self,
152
160
  system_message: Optional[Union[BaseMessage, str]] = None,
153
- model: Optional[BaseModelBackend] = None,
161
+ model: Optional[
162
+ Union[BaseModelBackend, List[BaseModelBackend]]
163
+ ] = None,
154
164
  memory: Optional[AgentMemory] = None,
155
165
  message_window_size: Optional[int] = None,
156
166
  token_limit: Optional[int] = None,
@@ -158,6 +168,7 @@ class ChatAgent(BaseAgent):
158
168
  tools: Optional[List[FunctionTool]] = None,
159
169
  external_tools: Optional[List[FunctionTool]] = None,
160
170
  response_terminators: Optional[List[ResponseTerminator]] = None,
171
+ scheduling_strategy: str = "round_robin",
161
172
  ) -> None:
162
173
  if isinstance(system_message, str):
163
174
  system_message = BaseMessage.make_assistant_message(
@@ -172,13 +183,14 @@ class ChatAgent(BaseAgent):
172
183
  self.role_type: RoleType = (
173
184
  getattr(system_message, 'role_type', None) or RoleType.ASSISTANT
174
185
  )
175
- self.model_backend: BaseModelBackend = (
186
+ self.model_backend = ModelManager(
176
187
  model
177
188
  if model is not None
178
189
  else ModelFactory.create(
179
190
  model_platform=ModelPlatformType.DEFAULT,
180
191
  model_type=ModelType.DEFAULT,
181
- )
192
+ ),
193
+ scheduling_strategy=scheduling_strategy,
182
194
  )
183
195
 
184
196
  self.model_type = self.model_backend.model_type
@@ -945,8 +957,32 @@ class ChatAgent(BaseAgent):
945
957
  str,
946
958
  ]:
947
959
  r"""Internal function for agent step model response."""
960
+
961
+ response = None
948
962
  # Obtain the model's response
949
- response = self.model_backend.run(openai_messages)
963
+ for _ in range(len(self.model_backend.models)):
964
+ try:
965
+ response = self.model_backend.run(openai_messages)
966
+ break
967
+ except Exception as exc:
968
+ logger.error(
969
+ f"An error occurred while running model "
970
+ f"{self.model_backend.model_type}, "
971
+ f"index: {self.model_backend.current_model_index}",
972
+ exc_info=exc,
973
+ )
974
+ continue
975
+ if not response:
976
+ raise ModelProcessingError(
977
+ "Unable to process messages: none of the provided models "
978
+ "run succesfully."
979
+ )
980
+
981
+ logger.info(
982
+ f"Model {self.model_backend.model_type}, "
983
+ f"index {self.model_backend.current_model_index}, "
984
+ f"processed these messages: {openai_messages}"
985
+ )
950
986
 
951
987
  if isinstance(response, ChatCompletion):
952
988
  output_messages, finish_reasons, usage_dict, response_id = (
@@ -1054,8 +1090,32 @@ class ChatAgent(BaseAgent):
1054
1090
  role_type=self.role_type,
1055
1091
  meta_dict=dict(),
1056
1092
  content=choice.message.content or "",
1093
+ parsed=getattr(choice.message, 'parsed', None),
1057
1094
  )
1095
+ # Process log probabilities and append to the message meta information
1096
+ if choice.logprobs is not None:
1097
+ tokens_logprobs = choice.logprobs.content
1098
+
1099
+ if tokens_logprobs is not None:
1100
+ # Extract and structure logprob information
1101
+ logprobs_info = [
1102
+ {
1103
+ "token": token_logprob.token,
1104
+ "logprob": token_logprob.logprob,
1105
+ "top_logprobs": [
1106
+ (top_logprob.token, top_logprob.logprob)
1107
+ for top_logprob in token_logprob.top_logprobs
1108
+ ],
1109
+ }
1110
+ for token_logprob in tokens_logprobs
1111
+ ]
1112
+ # Ensure meta_dict exists before adding logprobs info
1113
+ if chat_message.meta_dict is None:
1114
+ chat_message.meta_dict = {}
1115
+ chat_message.meta_dict["logprobs_info"] = logprobs_info
1116
+ # Append the processed chat message to output
1058
1117
  output_messages.append(chat_message)
1118
+
1059
1119
  finish_reasons = [
1060
1120
  str(choice.finish_reason) for choice in response.choices
1061
1121
  ]
@@ -1298,6 +1358,15 @@ class ChatAgent(BaseAgent):
1298
1358
  )
1299
1359
  return usage_dict
1300
1360
 
1361
+ def add_model_scheduling_strategy(self, name: str, strategy_fn: Callable):
1362
+ r"""Add a scheduling strategy method provided by user to ModelManger.
1363
+
1364
+ Args:
1365
+ name (str): The name of the strategy.
1366
+ strategy_fn (Callable): The scheduling strategy function.
1367
+ """
1368
+ self.model_backend.add_strategy(name, strategy_fn)
1369
+
1301
1370
  def __repr__(self) -> str:
1302
1371
  r"""Returns a string representation of the :obj:`ChatAgent`.
1303
1372
 
@@ -15,11 +15,14 @@ import re
15
15
  from typing import Dict, List, Optional, Union
16
16
 
17
17
  from camel.agents.chat_agent import ChatAgent
18
+ from camel.logger import get_logger
18
19
  from camel.messages import BaseMessage
19
20
  from camel.models import BaseModelBackend
20
21
  from camel.prompts import TextPrompt
21
22
  from camel.types import RoleType
22
23
 
24
+ logger = get_logger(__name__)
25
+
23
26
  # AgentOps decorator setting
24
27
  try:
25
28
  import os
@@ -253,7 +256,7 @@ square brackets)
253
256
  "Deduction failed. Error:\n" + f"{response.info}"
254
257
  )
255
258
  msg: BaseMessage = response.msg
256
- print(f"Message content:\n{msg.content}")
259
+ logger.info(f"Message content:\n{msg.content}")
257
260
 
258
261
  # Extract the conditions from the message
259
262
  conditions_dict = {
camel/configs/__init__.py CHANGED
@@ -19,6 +19,7 @@ from .gemini_config import Gemini_API_PARAMS, GeminiConfig
19
19
  from .groq_config import GROQ_API_PARAMS, GroqConfig
20
20
  from .litellm_config import LITELLM_API_PARAMS, LiteLLMConfig
21
21
  from .mistral_config import MISTRAL_API_PARAMS, MistralConfig
22
+ from .nvidia_config import NVIDIA_API_PARAMS, NvidiaConfig
22
23
  from .ollama_config import OLLAMA_API_PARAMS, OllamaConfig
23
24
  from .openai_config import OPENAI_API_PARAMS, ChatGPTConfig
24
25
  from .qwen_config import QWEN_API_PARAMS, QwenConfig
@@ -44,6 +45,8 @@ __all__ = [
44
45
  'GroqConfig',
45
46
  'LiteLLMConfig',
46
47
  'LITELLM_API_PARAMS',
48
+ 'NvidiaConfig',
49
+ 'NVIDIA_API_PARAMS',
47
50
  'OllamaConfig',
48
51
  'OLLAMA_API_PARAMS',
49
52
  'ZhipuAIConfig',
@@ -35,8 +35,6 @@ class MistralConfig(BaseConfig):
35
35
  tokens to generate, e.g. 0.9. Defaults to None.
36
36
  max_tokens (Optional[int], optional): the maximum number of tokens to
37
37
  generate, e.g. 100. Defaults to None.
38
- min_tokens (Optional[int], optional): the minimum number of tokens to
39
- generate, e.g. 100. Defaults to None.
40
38
  stop (Optional[Union[str,list[str]]]): Stop generation if this token
41
39
  is detected. Or if one of these tokens is detected when providing
42
40
  a string list.
@@ -58,7 +56,6 @@ class MistralConfig(BaseConfig):
58
56
  temperature: Optional[float] = None
59
57
  top_p: Optional[float] = None
60
58
  max_tokens: Optional[int] = None
61
- min_tokens: Optional[int] = None
62
59
  stop: Optional[Union[str, list[str]]] = None
63
60
  random_seed: Optional[int] = None
64
61
  safe_prompt: bool = False
@@ -0,0 +1,70 @@
1
+ # ========= Copyright 2023-2024 @ 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-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+ from __future__ import annotations
15
+
16
+ from typing import List, Optional, Union
17
+
18
+ from pydantic import Field
19
+
20
+ from camel.configs.base_config import BaseConfig
21
+ from camel.types import NOT_GIVEN, NotGiven
22
+
23
+
24
+ class NvidiaConfig(BaseConfig):
25
+ r"""Configuration class for NVIDIA API models.
26
+
27
+ This class defines the configuration parameters for NVIDIA's language
28
+ models, including temperature, sampling parameters, and response format
29
+ settings.
30
+
31
+ Args:
32
+ stream (bool, optional): Whether to stream the response.
33
+ (default: :obj:`False`)
34
+ temperature (float, optional): Controls randomness in the response.
35
+ Higher values make output more random, lower values make it more
36
+ deterministic. Range: [0.0, 2.0]. (default: :obj:`0.7`)
37
+ top_p (float, optional): Controls diversity via nucleus sampling.
38
+ Range: [0.0, 1.0]. (default: :obj:`0.95`)
39
+ presence_penalty (float, optional): Penalizes new tokens based on
40
+ whether they appear in the text so far. Range: [-2.0, 2.0].
41
+ (default: :obj:`0.0`)
42
+ frequency_penalty (float, optional): Penalizes new tokens based on
43
+ their frequency in the text so far. Range: [-2.0, 2.0].
44
+ (default: :obj:`0.0`)
45
+ max_tokens (Union[int, NotGiven], optional): Maximum number of tokens
46
+ to generate. If not provided, model will use its default maximum.
47
+ (default: :obj:`NOT_GIVEN`)
48
+ seed (Optional[int], optional): Random seed for deterministic sampling.
49
+ (default: :obj:`None`)
50
+ tools (Optional[List[Dict]], optional): List of tools available to the
51
+ model. This includes tools such as a text editor, a calculator, or
52
+ a search engine. (default: :obj:`None`)
53
+ tool_choice (Optional[str], optional): Tool choice configuration.
54
+ (default: :obj:`None`)
55
+ stop (Optional[List[str]], optional): List of stop sequences.
56
+ (default: :obj:`None`)
57
+ """
58
+
59
+ stream: bool = Field(default=False)
60
+ temperature: float = Field(default=0.7)
61
+ top_p: float = Field(default=0.95)
62
+ presence_penalty: float = Field(default=0.0)
63
+ frequency_penalty: float = Field(default=0.0)
64
+ max_tokens: Union[int, NotGiven] = Field(default=NOT_GIVEN)
65
+ seed: Optional[int] = Field(default=None)
66
+ tool_choice: Optional[str] = Field(default=None)
67
+ stop: Optional[List[str]] = Field(default=None)
68
+
69
+
70
+ NVIDIA_API_PARAMS = {param for param in NvidiaConfig.model_fields.keys()}
@@ -13,7 +13,7 @@
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  from __future__ import annotations
15
15
 
16
- from typing import Sequence, Union
16
+ from typing import Optional, Sequence, Union
17
17
 
18
18
  from pydantic import Field
19
19
 
@@ -84,6 +84,13 @@ class VLLMConfig(BaseConfig):
84
84
  user (str, optional): A unique identifier representing your end-user,
85
85
  which can help OpenAI to monitor and detect abuse.
86
86
  (default: :obj:`""`)
87
+ logprobs: Whether to return log probabilities of the output tokens or
88
+ not. If true, returns the log probabilities of each output token
89
+ returned in the `logits` of `message`. (default: :obj:`None`)
90
+ top_logprobs: An integer between 0 and 20 specifying the number of
91
+ most likely tokens to return at each token position, each with an
92
+ associated log probability. `logprobs` must be set to `true` if
93
+ this parameter is used. (default: :obj:`None`)
87
94
  """
88
95
 
89
96
  temperature: float = 0.2 # openai default: 1.0
@@ -97,6 +104,8 @@ class VLLMConfig(BaseConfig):
97
104
  frequency_penalty: float = 0.0
98
105
  logit_bias: dict = Field(default_factory=dict)
99
106
  user: str = ""
107
+ logprobs: Optional[bool] = None
108
+ top_logprobs: Optional[int] = None
100
109
 
101
110
 
102
111
  VLLM_API_PARAMS = {param for param in VLLMConfig.model_fields.keys()}
@@ -16,6 +16,9 @@ from typing import Any, List, Optional, Union
16
16
  from PIL import Image
17
17
 
18
18
  from camel.embeddings import BaseEmbedding
19
+ from camel.logger import get_logger
20
+
21
+ logger = get_logger(__name__)
19
22
 
20
23
 
21
24
  class VisionLanguageEmbedding(BaseEmbedding[Union[str, Image.Image]]):
@@ -60,7 +63,7 @@ class VisionLanguageEmbedding(BaseEmbedding[Union[str, Image.Image]]):
60
63
  "interpolate_pos_encoding",
61
64
  ]
62
65
  except Exception:
63
- print("Warning: not typically processor and model structure")
66
+ logger.warning("not typically processor and model structure")
64
67
  pass
65
68
  self.dim: Optional[int] = None
66
69
 
@@ -23,11 +23,14 @@ from colorama import Fore
23
23
 
24
24
  from camel.interpreters.base import BaseInterpreter
25
25
  from camel.interpreters.interpreter_error import InterpreterError
26
+ from camel.logger import get_logger
26
27
  from camel.utils import is_docker_running
27
28
 
28
29
  if TYPE_CHECKING:
29
30
  from docker.models.containers import Container
30
31
 
32
+ logger = get_logger(__name__)
33
+
31
34
 
32
35
  class DockerInterpreter(BaseInterpreter):
33
36
  r"""A class for executing code files or code strings in a docker container.
@@ -187,8 +190,10 @@ class DockerInterpreter(BaseInterpreter):
187
190
 
188
191
  # Print code for security checking
189
192
  if self.require_confirm:
190
- print(f"The following {code_type} code will run in container:")
191
- print(Fore.CYAN + code + Fore.RESET)
193
+ logger.info(
194
+ f"The following {code_type} code will run on your "
195
+ "computer: {code}"
196
+ )
192
197
  while True:
193
198
  choice = input("Running code? [Y/n]:").lower()
194
199
  if choice in ["y", "yes", "ye", ""]:
@@ -22,6 +22,9 @@ from colorama import Fore
22
22
 
23
23
  from camel.interpreters.base import BaseInterpreter
24
24
  from camel.interpreters.interpreter_error import InterpreterError
25
+ from camel.logger import get_logger
26
+
27
+ logger = get_logger(__name__)
25
28
 
26
29
 
27
30
  class SubprocessInterpreter(BaseInterpreter):
@@ -141,8 +144,10 @@ class SubprocessInterpreter(BaseInterpreter):
141
144
 
142
145
  # Print code for security checking
143
146
  if self.require_confirm:
144
- print(f"The following {code_type} code will run on your computer:")
145
- print(Fore.CYAN + code + Fore.RESET)
147
+ logger.info(
148
+ f"The following {code_type} code will run on your "
149
+ "computer: {code}"
150
+ )
146
151
  while True:
147
152
  choice = input("Running code? [Y/n]:").lower()
148
153
  if choice in ["y", "yes", "ye", ""]:
@@ -17,8 +17,6 @@ from typing import Any, Dict, Optional
17
17
 
18
18
  from pydantic import BaseModel
19
19
 
20
- from camel.utils import api_keys_required
21
-
22
20
 
23
21
  class Firecrawl:
24
22
  r"""Firecrawl allows you to turn entire websites into LLM-ready markdown.
@@ -32,7 +30,6 @@ class Firecrawl:
32
30
  https://docs.firecrawl.dev/introduction
33
31
  """
34
32
 
35
- @api_keys_required("FIRECRAWL_API_KEY")
36
33
  def __init__(
37
34
  self,
38
35
  api_key: Optional[str] = None,
camel/logger.py ADDED
@@ -0,0 +1,112 @@
1
+ # ========= Copyright 2023-2024 @ 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-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
+
15
+ import logging
16
+ import os
17
+ import sys
18
+
19
+ # Create a private logger
20
+ _logger = logging.getLogger('camel')
21
+
22
+
23
+ def _configure_library_logging():
24
+ if os.environ.get('CAMEL_LOGGING_DISABLED', 'False').lower() == 'true':
25
+ return
26
+
27
+ if not logging.root.handlers and not _logger.handlers:
28
+ logging.basicConfig(
29
+ level=os.environ.get('LOGLEVEL', 'INFO').upper(),
30
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
31
+ stream=sys.stdout,
32
+ )
33
+ logging.setLoggerClass(logging.Logger)
34
+ _logger.info("Camel library logging has been configured.")
35
+ else:
36
+ _logger.debug("Existing logger configuration found, using that.")
37
+
38
+
39
+ def disable_logging():
40
+ r"""Disable all logging for the Camel library.
41
+
42
+ This function sets the log level to a value higher than CRITICAL,
43
+ effectively disabling all log messages, and adds a NullHandler to
44
+ suppress any potential warnings about no handlers being found.
45
+ """
46
+ os.environ['CAMEL_LOGGING_DISABLED'] = 'true'
47
+ _logger.setLevel(logging.CRITICAL + 1)
48
+ # Avoid adding multiple NullHandlers
49
+ if not any(
50
+ isinstance(handler, logging.NullHandler)
51
+ for handler in _logger.handlers
52
+ ):
53
+ _logger.addHandler(logging.NullHandler())
54
+ _logger.debug("Logging has been disabled.")
55
+
56
+
57
+ def enable_logging():
58
+ r"""Enable logging for the Camel library.
59
+
60
+ This function re-enables logging if it was previously disabled,
61
+ and configures the library logging using the default settings.
62
+ If the logging is already configured,
63
+ this function does not change its configuration.
64
+ """
65
+ os.environ['CAMEL_LOGGING_DISABLED'] = 'false'
66
+ _configure_library_logging()
67
+
68
+
69
+ def set_log_level(level):
70
+ r"""Set the logging level for the Camel library.
71
+
72
+ Args:
73
+ level (Union[str, int]): The logging level to set. This can be a string
74
+ (e.g., 'INFO') or a logging level constant (e.g., logging.INFO,
75
+ logging.DEBUG).
76
+ See https://docs.python.org/3/library/logging.html#levels
77
+
78
+ Raises:
79
+ ValueError: If the provided level is not a valid logging level.
80
+ """
81
+ valid_levels = ['NOTSET', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
82
+ if isinstance(level, str):
83
+ if level.upper() not in valid_levels:
84
+ raise ValueError(
85
+ f"Invalid logging level."
86
+ f" Choose from: {', '.join(valid_levels)}"
87
+ )
88
+ level = level.upper()
89
+ elif not isinstance(level, int):
90
+ raise ValueError(
91
+ "Logging level must be an option from the logging module."
92
+ )
93
+
94
+ _logger.setLevel(level)
95
+ _logger.debug(f"Logging level set to: {logging.getLevelName(level)}")
96
+
97
+
98
+ def get_logger(name):
99
+ r"""Get a logger with the specified name, prefixed with 'camel.'.
100
+
101
+ Args:
102
+ name (str): The name to be appended to 'camel.' to create the logger.
103
+
104
+ Returns:
105
+ logging.Logger: A logger instance with the name 'camel.{name}'.
106
+ """
107
+ return logging.getLogger(f'camel.{name}')
108
+
109
+
110
+ # Lazy configuration: Only configure logging if explicitly enabled.
111
+ if os.environ.get('CAMEL_LOGGING_DISABLED', 'False').strip().lower() != 'true':
112
+ _configure_library_logging()
@@ -23,7 +23,7 @@ from .conversion import (
23
23
  HermesFunctionFormatter,
24
24
  ShareGPTMessage,
25
25
  )
26
- from .conversion.models import (
26
+ from .conversion.conversation_models import (
27
27
  ShareGPTConversation,
28
28
  )
29
29
  from .conversion.sharegpt.function_call_formatter import (
camel/messages/base.py CHANGED
@@ -15,10 +15,11 @@ import base64
15
15
  import io
16
16
  import re
17
17
  from dataclasses import dataclass
18
- from typing import Any, Dict, List, Literal, Optional, Tuple, Union
18
+ from typing import Any, Dict, List, Literal, Optional, Tuple, Type, Union
19
19
 
20
20
  import numpy as np
21
21
  from PIL import Image
22
+ from pydantic import BaseModel
22
23
 
23
24
  from camel.messages import (
24
25
  FunctionCallFormatter,
@@ -51,24 +52,27 @@ class BaseMessage:
51
52
  for the message.
52
53
  content (str): The content of the message.
53
54
  video_bytes (Optional[bytes]): Optional bytes of a video associated
54
- with the message. Default is None.
55
+ with the message. (default::obj:`None`)
55
56
  image_list (Optional[List[Image.Image]]): Optional list of PIL Image
56
- objects associated with the message. Default is None.
57
+ objects associated with the message. (default::obj:`None`)
57
58
  image_detail (Literal["auto", "low", "high"]): Detail level of the
58
- images associated with the message. Default is "auto".
59
+ images associated with the message. (default::obj:`auto`)
59
60
  video_detail (Literal["auto", "low", "high"]): Detail level of the
60
- videos associated with the message. Default is "low".
61
+ videos associated with the message. (default::obj:`low`)
62
+ parsed: Optional[Union[Type[BaseModel], dict]]: Optional object which
63
+ is parsed from the content. (default::obj:`None`)
61
64
  """
62
65
 
63
66
  role_name: str
64
67
  role_type: RoleType
65
- meta_dict: Optional[Dict[str, str]]
68
+ meta_dict: Optional[Dict[str, Any]]
66
69
  content: str
67
70
 
68
71
  video_bytes: Optional[bytes] = None
69
72
  image_list: Optional[List[Image.Image]] = None
70
73
  image_detail: Literal["auto", "low", "high"] = "auto"
71
74
  video_detail: Literal["auto", "low", "high"] = "low"
75
+ parsed: Optional[Union[Type[BaseModel], dict]] = None
72
76
 
73
77
  @classmethod
74
78
  def make_user_message(
@@ -419,7 +423,6 @@ class BaseMessage:
419
423
  "text": self.content,
420
424
  }
421
425
  )
422
-
423
426
  if self.image_list and len(self.image_list) > 0:
424
427
  for image in self.image_list:
425
428
  if image.format is None:
@@ -12,7 +12,8 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
- from .models import (
15
+ from .alpaca import AlpacaItem
16
+ from .conversation_models import (
16
17
  ShareGPTConversation,
17
18
  ShareGPTMessage,
18
19
  ToolCall,
@@ -24,6 +25,7 @@ __all__ = [
24
25
  'ShareGPTMessage',
25
26
  'ShareGPTConversation',
26
27
  'HermesFunctionFormatter',
28
+ 'AlpacaItem',
27
29
  'ToolCall',
28
30
  'ToolResponse',
29
31
  ]