camel-ai 0.1.1__py3-none-any.whl → 0.1.3__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 (99) hide show
  1. camel/__init__.py +1 -11
  2. camel/agents/__init__.py +5 -5
  3. camel/agents/chat_agent.py +124 -63
  4. camel/agents/critic_agent.py +28 -17
  5. camel/agents/deductive_reasoner_agent.py +235 -0
  6. camel/agents/embodied_agent.py +92 -40
  7. camel/agents/role_assignment_agent.py +27 -17
  8. camel/agents/task_agent.py +60 -34
  9. camel/agents/tool_agents/base.py +0 -1
  10. camel/agents/tool_agents/hugging_face_tool_agent.py +7 -4
  11. camel/configs.py +119 -7
  12. camel/embeddings/__init__.py +2 -0
  13. camel/embeddings/base.py +3 -2
  14. camel/embeddings/openai_embedding.py +3 -3
  15. camel/embeddings/sentence_transformers_embeddings.py +65 -0
  16. camel/functions/__init__.py +13 -3
  17. camel/functions/google_maps_function.py +335 -0
  18. camel/functions/math_functions.py +7 -7
  19. camel/functions/openai_function.py +344 -42
  20. camel/functions/search_functions.py +100 -35
  21. camel/functions/twitter_function.py +484 -0
  22. camel/functions/weather_functions.py +36 -23
  23. camel/generators.py +65 -46
  24. camel/human.py +17 -11
  25. camel/interpreters/__init__.py +25 -0
  26. camel/interpreters/base.py +49 -0
  27. camel/{utils/python_interpreter.py → interpreters/internal_python_interpreter.py} +129 -48
  28. camel/interpreters/interpreter_error.py +19 -0
  29. camel/interpreters/subprocess_interpreter.py +190 -0
  30. camel/loaders/__init__.py +22 -0
  31. camel/{functions/base_io_functions.py → loaders/base_io.py} +38 -35
  32. camel/{functions/unstructured_io_fuctions.py → loaders/unstructured_io.py} +199 -110
  33. camel/memories/__init__.py +17 -7
  34. camel/memories/agent_memories.py +156 -0
  35. camel/memories/base.py +97 -32
  36. camel/memories/blocks/__init__.py +21 -0
  37. camel/memories/{chat_history_memory.py → blocks/chat_history_block.py} +34 -34
  38. camel/memories/blocks/vectordb_block.py +101 -0
  39. camel/memories/context_creators/__init__.py +3 -2
  40. camel/memories/context_creators/score_based.py +32 -20
  41. camel/memories/records.py +6 -5
  42. camel/messages/__init__.py +2 -2
  43. camel/messages/base.py +99 -16
  44. camel/messages/func_message.py +7 -4
  45. camel/models/__init__.py +4 -2
  46. camel/models/anthropic_model.py +132 -0
  47. camel/models/base_model.py +3 -2
  48. camel/models/model_factory.py +10 -8
  49. camel/models/open_source_model.py +25 -13
  50. camel/models/openai_model.py +9 -10
  51. camel/models/stub_model.py +6 -5
  52. camel/prompts/__init__.py +7 -5
  53. camel/prompts/ai_society.py +21 -14
  54. camel/prompts/base.py +54 -47
  55. camel/prompts/code.py +22 -14
  56. camel/prompts/evaluation.py +8 -5
  57. camel/prompts/misalignment.py +26 -19
  58. camel/prompts/object_recognition.py +35 -0
  59. camel/prompts/prompt_templates.py +14 -8
  60. camel/prompts/role_description_prompt_template.py +16 -10
  61. camel/prompts/solution_extraction.py +9 -5
  62. camel/prompts/task_prompt_template.py +24 -21
  63. camel/prompts/translation.py +9 -5
  64. camel/responses/agent_responses.py +5 -2
  65. camel/retrievers/__init__.py +24 -0
  66. camel/retrievers/auto_retriever.py +319 -0
  67. camel/retrievers/base.py +64 -0
  68. camel/retrievers/bm25_retriever.py +149 -0
  69. camel/retrievers/vector_retriever.py +166 -0
  70. camel/societies/__init__.py +1 -1
  71. camel/societies/babyagi_playing.py +56 -32
  72. camel/societies/role_playing.py +188 -133
  73. camel/storages/__init__.py +18 -0
  74. camel/storages/graph_storages/__init__.py +23 -0
  75. camel/storages/graph_storages/base.py +82 -0
  76. camel/storages/graph_storages/graph_element.py +74 -0
  77. camel/storages/graph_storages/neo4j_graph.py +582 -0
  78. camel/storages/key_value_storages/base.py +1 -2
  79. camel/storages/key_value_storages/in_memory.py +1 -2
  80. camel/storages/key_value_storages/json.py +8 -13
  81. camel/storages/vectordb_storages/__init__.py +33 -0
  82. camel/storages/vectordb_storages/base.py +202 -0
  83. camel/storages/vectordb_storages/milvus.py +396 -0
  84. camel/storages/vectordb_storages/qdrant.py +371 -0
  85. camel/terminators/__init__.py +1 -1
  86. camel/terminators/base.py +2 -3
  87. camel/terminators/response_terminator.py +21 -12
  88. camel/terminators/token_limit_terminator.py +5 -3
  89. camel/types/__init__.py +12 -6
  90. camel/types/enums.py +86 -13
  91. camel/types/openai_types.py +10 -5
  92. camel/utils/__init__.py +18 -13
  93. camel/utils/commons.py +242 -81
  94. camel/utils/token_counting.py +135 -15
  95. {camel_ai-0.1.1.dist-info → camel_ai-0.1.3.dist-info}/METADATA +116 -74
  96. camel_ai-0.1.3.dist-info/RECORD +101 -0
  97. {camel_ai-0.1.1.dist-info → camel_ai-0.1.3.dist-info}/WHEEL +1 -1
  98. camel/memories/context_creators/base.py +0 -72
  99. camel_ai-0.1.1.dist-info/RECORD +0 -75
camel/messages/base.py CHANGED
@@ -11,8 +11,12 @@
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
+ import base64
15
+ import io
14
16
  from dataclasses import dataclass
15
- from typing import Any, Dict, List, Optional, Tuple, Union
17
+ from typing import Any, Dict, List, Literal, Optional, Tuple, Union
18
+
19
+ from PIL import Image
16
20
 
17
21
  from camel.messages import (
18
22
  OpenAIAssistantMessage,
@@ -21,7 +25,12 @@ from camel.messages import (
21
25
  OpenAIUserMessage,
22
26
  )
23
27
  from camel.prompts import CodePrompt, TextPrompt
24
- from camel.types import OpenAIBackendRole, RoleType
28
+ from camel.types import (
29
+ OpenAIBackendRole,
30
+ OpenAIImageDetailType,
31
+ OpenAIImageType,
32
+ RoleType,
33
+ )
25
34
 
26
35
 
27
36
  @dataclass
@@ -36,22 +45,49 @@ class BaseMessage:
36
45
  for the message.
37
46
  content (str): The content of the message.
38
47
  """
48
+
39
49
  role_name: str
40
50
  role_type: RoleType
41
51
  meta_dict: Optional[Dict[str, str]]
42
52
  content: str
53
+ image: Optional[Image.Image] = None
54
+ image_detail: Literal["auto", "low", "high"] = "auto"
43
55
 
44
56
  @classmethod
45
57
  def make_user_message(
46
- cls, role_name: str, content: str,
47
- meta_dict: Optional[Dict[str, str]] = None) -> 'BaseMessage':
48
- return cls(role_name, RoleType.USER, meta_dict, content)
58
+ cls,
59
+ role_name: str,
60
+ content: str,
61
+ meta_dict: Optional[Dict[str, str]] = None,
62
+ image: Optional[Image.Image] = None,
63
+ image_detail: Union[OpenAIImageDetailType, str] = "auto",
64
+ ) -> 'BaseMessage':
65
+ return cls(
66
+ role_name,
67
+ RoleType.USER,
68
+ meta_dict,
69
+ content,
70
+ image,
71
+ OpenAIImageDetailType(image_detail).value,
72
+ )
49
73
 
50
74
  @classmethod
51
75
  def make_assistant_message(
52
- cls, role_name: str, content: str,
53
- meta_dict: Optional[Dict[str, str]] = None) -> 'BaseMessage':
54
- return cls(role_name, RoleType.ASSISTANT, meta_dict, content)
76
+ cls,
77
+ role_name: str,
78
+ content: str,
79
+ meta_dict: Optional[Dict[str, str]] = None,
80
+ image: Optional[Image.Image] = None,
81
+ image_detail: Union[OpenAIImageDetailType, str] = "auto",
82
+ ) -> 'BaseMessage':
83
+ return cls(
84
+ role_name,
85
+ RoleType.ASSISTANT,
86
+ meta_dict,
87
+ content,
88
+ image,
89
+ OpenAIImageDetailType(image_detail).value,
90
+ )
55
91
 
56
92
  def create_new_instance(self, content: str) -> "BaseMessage":
57
93
  r"""Create a new instance of the :obj:`BaseMessage` with updated
@@ -63,9 +99,12 @@ class BaseMessage:
63
99
  Returns:
64
100
  BaseMessage: The new instance of :obj:`BaseMessage`.
65
101
  """
66
- return self.__class__(role_name=self.role_name,
67
- role_type=self.role_type,
68
- meta_dict=self.meta_dict, content=content)
102
+ return self.__class__(
103
+ role_name=self.role_name,
104
+ role_type=self.role_type,
105
+ meta_dict=self.meta_dict,
106
+ content=content,
107
+ )
69
108
 
70
109
  def __add__(self, other: Any) -> Union["BaseMessage", Any]:
71
110
  r"""Addition operator override for :obj:`BaseMessage`.
@@ -83,7 +122,8 @@ class BaseMessage:
83
122
  else:
84
123
  raise TypeError(
85
124
  f"Unsupported operand type(s) for +: '{type(self)}' and "
86
- f"'{type(other)}'")
125
+ f"'{type(other)}'"
126
+ )
87
127
  return self.create_new_instance(combined_content)
88
128
 
89
129
  def __mul__(self, other: Any) -> Union["BaseMessage", Any]:
@@ -101,7 +141,8 @@ class BaseMessage:
101
141
  else:
102
142
  raise TypeError(
103
143
  f"Unsupported operand type(s) for *: '{type(self)}' and "
104
- f"'{type(other)}'")
144
+ f"'{type(other)}'"
145
+ )
105
146
 
106
147
  def __len__(self) -> int:
107
148
  r"""Length operator override for :obj:`BaseMessage`.
@@ -124,7 +165,8 @@ class BaseMessage:
124
165
  return item in self.content
125
166
 
126
167
  def extract_text_and_code_prompts(
127
- self) -> Tuple[List[TextPrompt], List[CodePrompt]]:
168
+ self,
169
+ ) -> Tuple[List[TextPrompt], List[CodePrompt]]:
128
170
  r"""Extract text and code prompts from the message content.
129
171
 
130
172
  Returns:
@@ -140,7 +182,8 @@ class BaseMessage:
140
182
  start_idx = 0
141
183
  while idx < len(lines):
142
184
  while idx < len(lines) and (
143
- not lines[idx].lstrip().startswith("```")):
185
+ not lines[idx].lstrip().startswith("```")
186
+ ):
144
187
  idx += 1
145
188
  text = "\n".join(lines[start_idx:idx]).strip()
146
189
  text_prompts.append(TextPrompt(text))
@@ -198,7 +241,47 @@ class BaseMessage:
198
241
  Returns:
199
242
  OpenAIUserMessage: The converted :obj:`OpenAIUserMessage` object.
200
243
  """
201
- return {"role": "user", "content": self.content}
244
+ if self.image is None:
245
+ return {"role": "user", "content": self.content}
246
+ else:
247
+ #
248
+ if self.image.format is None:
249
+ raise ValueError(
250
+ f"Image's `format` is `None`, please "
251
+ f"transform the `PIL.Image.Image` to one of "
252
+ f"following supported formats, such as "
253
+ f"{list(OpenAIImageType)}"
254
+ )
255
+
256
+ image_type: str = self.image.format.lower()
257
+ if image_type not in OpenAIImageType:
258
+ raise ValueError(
259
+ f"Image type {self.image.format} "
260
+ f"is not supported by OpenAI vision model"
261
+ )
262
+ with io.BytesIO() as buffer:
263
+ self.image.save(fp=buffer, format=self.image.format)
264
+ encoded_image = base64.b64encode(buffer.getvalue()).decode(
265
+ "utf-8"
266
+ )
267
+ image_prefix = f"data:image/{image_type};base64,"
268
+
269
+ return {
270
+ "role": "user",
271
+ "content": [
272
+ {
273
+ "type": "text",
274
+ "text": self.content,
275
+ },
276
+ {
277
+ "type": "image_url",
278
+ "image_url": {
279
+ "url": f"{image_prefix}{encoded_image}",
280
+ "detail": self.image_detail,
281
+ },
282
+ },
283
+ ],
284
+ }
202
285
 
203
286
  def to_openai_assistant_message(self) -> OpenAIAssistantMessage:
204
287
  r"""Converts the message to an :obj:`OpenAIAssistantMessage` object.
@@ -36,6 +36,7 @@ class FunctionCallingMessage(BaseMessage):
36
36
  result (Optional[Any]): The result of function execution.
37
37
  (default: :obj:`None`)
38
38
  """
39
+
39
40
  func_name: Optional[str] = None
40
41
  args: Optional[Dict] = None
41
42
  result: Optional[Any] = None
@@ -67,10 +68,11 @@ class FunctionCallingMessage(BaseMessage):
67
68
  OpenAIAssistantMessage: The converted :obj:`OpenAIAssistantMessage`
68
69
  object.
69
70
  """
70
- if (not self.func_name) or (not self.args):
71
+ if (not self.func_name) or (self.args is None):
71
72
  raise ValueError(
72
73
  "Invalid request for converting into assistant message"
73
- " due to missing function name or arguments.")
74
+ " due to missing function name or arguments."
75
+ )
74
76
 
75
77
  msg_dict: OpenAIAssistantMessage = {
76
78
  "role": "assistant",
@@ -78,7 +80,7 @@ class FunctionCallingMessage(BaseMessage):
78
80
  "function_call": {
79
81
  "name": self.func_name,
80
82
  "arguments": str(self.args),
81
- }
83
+ },
82
84
  }
83
85
 
84
86
  return msg_dict
@@ -94,7 +96,8 @@ class FunctionCallingMessage(BaseMessage):
94
96
  if (not self.func_name) or (not self.result):
95
97
  raise ValueError(
96
98
  "Invalid request for converting into function message"
97
- " due to missing function name or results.")
99
+ " due to missing function name or results."
100
+ )
98
101
 
99
102
  result_content = {"result": {str(self.result)}}
100
103
  msg_dict: OpenAIFunctionMessage = {
camel/models/__init__.py CHANGED
@@ -11,15 +11,17 @@
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
+ from .anthropic_model import AnthropicModel
14
15
  from .base_model import BaseModelBackend
16
+ from .model_factory import ModelFactory
17
+ from .open_source_model import OpenSourceModel
15
18
  from .openai_model import OpenAIModel
16
19
  from .stub_model import StubModel
17
- from .open_source_model import OpenSourceModel
18
- from .model_factory import ModelFactory
19
20
 
20
21
  __all__ = [
21
22
  'BaseModelBackend',
22
23
  'OpenAIModel',
24
+ 'AnthropicModel',
23
25
  'StubModel',
24
26
  'OpenSourceModel',
25
27
  'ModelFactory',
@@ -0,0 +1,132 @@
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 os
15
+ from typing import Any, Dict, Optional
16
+
17
+ from anthropic import Anthropic
18
+ from anthropic._types import NOT_GIVEN
19
+
20
+ from camel.configs import ANTHROPIC_API_PARAMS
21
+ from camel.models.base_model import BaseModelBackend
22
+ from camel.types import ChatCompletion, ModelType
23
+ from camel.utils import AnthropicTokenCounter, BaseTokenCounter
24
+
25
+
26
+ class AnthropicModel(BaseModelBackend):
27
+ r"""Anthropic API in a unified BaseModelBackend interface."""
28
+
29
+ def __init__(
30
+ self, model_type: ModelType, model_config_dict: Dict[str, Any]
31
+ ) -> None:
32
+ super().__init__(model_type, model_config_dict)
33
+ self.client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
34
+ self._token_counter: Optional[BaseTokenCounter] = None
35
+
36
+ def _convert_response_from_anthropic_to_openai(self, response):
37
+ # openai ^1.0.0 format, reference openai/types/chat/chat_completion.py
38
+ obj = ChatCompletion.construct(
39
+ id=None,
40
+ choices=[
41
+ dict(
42
+ index=0,
43
+ message={
44
+ "role": "assistant",
45
+ "content": response.content[0].text,
46
+ },
47
+ finish_reason=response.stop_reason,
48
+ )
49
+ ],
50
+ created=None,
51
+ model=response.model,
52
+ object="chat.completion",
53
+ )
54
+ return obj
55
+
56
+ @property
57
+ def token_counter(self) -> BaseTokenCounter:
58
+ r"""Initialize the token counter for the model backend.
59
+
60
+ Returns:
61
+ BaseTokenCounter: The token counter following the model's
62
+ tokenization style.
63
+ """
64
+ if not self._token_counter:
65
+ self._token_counter = AnthropicTokenCounter(self.model_type)
66
+ return self._token_counter
67
+
68
+ def count_tokens_from_prompt(self, prompt: str) -> int:
69
+ r"""Count the number of tokens from a prompt.
70
+
71
+ Args:
72
+ prompt (str): The prompt string.
73
+
74
+ Returns:
75
+ int: The number of tokens in the prompt.
76
+ """
77
+ return self.client.count_tokens(prompt)
78
+
79
+ def run(
80
+ self,
81
+ messages,
82
+ ):
83
+ r"""Run inference of Anthropic chat completion.
84
+
85
+ Args:
86
+ messages (List[Dict]): Message list with the chat history
87
+ in OpenAI API format.
88
+
89
+ Returns:
90
+ Dict[str, Any]: Response in the OpenAI API format.
91
+ """
92
+
93
+ if messages[0]["role"] == "system":
94
+ sys_msg = messages.pop(0)["content"]
95
+ else:
96
+ sys_msg = NOT_GIVEN
97
+ response = self.client.messages.create(
98
+ model=self.model_type.value,
99
+ system=sys_msg,
100
+ messages=messages,
101
+ **self.model_config_dict,
102
+ )
103
+
104
+ # format response to openai format
105
+ response = self._convert_response_from_anthropic_to_openai(response)
106
+
107
+ return response
108
+
109
+ def check_model_config(self):
110
+ r"""Check whether the model configuration is valid for anthropic
111
+ model backends.
112
+
113
+ Raises:
114
+ ValueError: If the model configuration dictionary contains any
115
+ unexpected arguments to OpenAI API, or it does not contain
116
+ :obj:`model_path` or :obj:`server_url`.
117
+ """
118
+ for param in self.model_config_dict:
119
+ if param not in ANTHROPIC_API_PARAMS:
120
+ raise ValueError(
121
+ f"Unexpected argument `{param}` is "
122
+ "input into Anthropic model backend."
123
+ )
124
+
125
+ @property
126
+ def stream(self) -> bool:
127
+ r"""Returns whether the model is in stream mode,
128
+ which sends partial results each time.
129
+ Returns:
130
+ bool: Whether the model is in stream mode.
131
+ """
132
+ return self.model_config_dict.get("stream", False)
@@ -26,8 +26,9 @@ class BaseModelBackend(ABC):
26
26
  May be OpenAI API, a local LLM, a stub for unit tests, etc.
27
27
  """
28
28
 
29
- def __init__(self, model_type: ModelType,
30
- model_config_dict: Dict[str, Any]) -> None:
29
+ def __init__(
30
+ self, model_type: ModelType, model_config_dict: Dict[str, Any]
31
+ ) -> None:
31
32
  r"""Constructor for the model backend.
32
33
 
33
34
  Args:
@@ -13,12 +13,11 @@
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
14
  from typing import Any, Dict
15
15
 
16
- from camel.models import (
17
- BaseModelBackend,
18
- OpenAIModel,
19
- OpenSourceModel,
20
- StubModel,
21
- )
16
+ from camel.models.anthropic_model import AnthropicModel
17
+ from camel.models.base_model import BaseModelBackend
18
+ from camel.models.open_source_model import OpenSourceModel
19
+ from camel.models.openai_model import OpenAIModel
20
+ from camel.models.stub_model import StubModel
22
21
  from camel.types import ModelType
23
22
 
24
23
 
@@ -30,8 +29,9 @@ class ModelFactory:
30
29
  """
31
30
 
32
31
  @staticmethod
33
- def create(model_type: ModelType,
34
- model_config_dict: Dict) -> BaseModelBackend:
32
+ def create(
33
+ model_type: ModelType, model_config_dict: Dict
34
+ ) -> BaseModelBackend:
35
35
  r"""Creates an instance of `BaseModelBackend` of the specified type.
36
36
 
37
37
  Args:
@@ -52,6 +52,8 @@ class ModelFactory:
52
52
  model_class = StubModel
53
53
  elif model_type.is_open_source:
54
54
  model_class = OpenSourceModel
55
+ elif model_type.is_anthropic:
56
+ model_class = AnthropicModel
55
57
  else:
56
58
  raise ValueError(f"Unknown model type `{model_type}` is input")
57
59
 
@@ -45,11 +45,13 @@ class OpenSourceModel(BaseModelBackend):
45
45
  # Check whether the input model type is open-source
46
46
  if not model_type.is_open_source:
47
47
  raise ValueError(
48
- f"Model `{model_type}` is not a supported open-source model.")
48
+ f"Model `{model_type}` is not a supported open-source model."
49
+ )
49
50
 
50
51
  # Check whether input model path is empty
51
- model_path: Optional[str] = (self.model_config_dict.get(
52
- "model_path", None))
52
+ model_path: Optional[str] = self.model_config_dict.get(
53
+ "model_path", None
54
+ )
53
55
  if not model_path:
54
56
  raise ValueError("Path to open-source model is not provided.")
55
57
  self.model_path: str = model_path
@@ -59,19 +61,23 @@ class OpenSourceModel(BaseModelBackend):
59
61
  if not self.model_type.validate_model_name(self.model_name):
60
62
  raise ValueError(
61
63
  f"Model name `{self.model_name}` does not match model type "
62
- f"`{self.model_type.value}`.")
64
+ f"`{self.model_type.value}`."
65
+ )
63
66
 
64
67
  # Load the server URL and check whether it is None
65
- server_url: Optional[str] = (self.model_config_dict.get(
66
- "server_url", None))
68
+ server_url: Optional[str] = self.model_config_dict.get(
69
+ "server_url", None
70
+ )
67
71
  if not server_url:
68
72
  raise ValueError(
69
- "URL to server running open-source LLM is not provided.")
73
+ "URL to server running open-source LLM is not provided."
74
+ )
70
75
  self.server_url: str = server_url
71
76
  self._client = OpenAI(
72
77
  base_url=self.server_url,
73
78
  timeout=60,
74
79
  max_retries=3,
80
+ api_key="fake_key",
75
81
  )
76
82
 
77
83
  # Replace `model_config_dict` with only the params to be
@@ -88,7 +94,8 @@ class OpenSourceModel(BaseModelBackend):
88
94
  """
89
95
  if not self._token_counter:
90
96
  self._token_counter = OpenSourceTokenCounter(
91
- self.model_type, self.model_path)
97
+ self.model_type, self.model_path
98
+ )
92
99
  return self._token_counter
93
100
 
94
101
  def run(
@@ -123,16 +130,21 @@ class OpenSourceModel(BaseModelBackend):
123
130
  unexpected arguments to OpenAI API, or it does not contain
124
131
  :obj:`model_path` or :obj:`server_url`.
125
132
  """
126
- if ("model_path" not in self.model_config_dict
127
- or "server_url" not in self.model_config_dict):
133
+ if (
134
+ "model_path" not in self.model_config_dict
135
+ or "server_url" not in self.model_config_dict
136
+ ):
128
137
  raise ValueError(
129
138
  "Invalid configuration for open-source model backend with "
130
- ":obj:`model_path` or :obj:`server_url` missing.")
139
+ ":obj:`model_path` or :obj:`server_url` missing."
140
+ )
131
141
 
132
142
  for param in self.model_config_dict["api_params"].__dict__:
133
143
  if param not in OPENAI_API_PARAMS:
134
- raise ValueError(f"Unexpected argument `{param}` is "
135
- "input into open-source model backend.")
144
+ raise ValueError(
145
+ f"Unexpected argument `{param}` is "
146
+ "input into open-source model backend."
147
+ )
136
148
 
137
149
  @property
138
150
  def stream(self) -> bool:
@@ -20,18 +20,15 @@ from camel.configs import OPENAI_API_PARAMS_WITH_FUNCTIONS
20
20
  from camel.messages import OpenAIMessage
21
21
  from camel.models import BaseModelBackend
22
22
  from camel.types import ChatCompletion, ChatCompletionChunk, ModelType
23
- from camel.utils import (
24
- BaseTokenCounter,
25
- OpenAITokenCounter,
26
- openai_api_key_required,
27
- )
23
+ from camel.utils import BaseTokenCounter, OpenAITokenCounter, api_key_required
28
24
 
29
25
 
30
26
  class OpenAIModel(BaseModelBackend):
31
27
  r"""OpenAI API in a unified BaseModelBackend interface."""
32
28
 
33
- def __init__(self, model_type: ModelType,
34
- model_config_dict: Dict[str, Any]) -> None:
29
+ def __init__(
30
+ self, model_type: ModelType, model_config_dict: Dict[str, Any]
31
+ ) -> None:
35
32
  r"""Constructor for OpenAI backend.
36
33
 
37
34
  Args:
@@ -57,7 +54,7 @@ class OpenAIModel(BaseModelBackend):
57
54
  self._token_counter = OpenAITokenCounter(self.model_type)
58
55
  return self._token_counter
59
56
 
60
- @openai_api_key_required
57
+ @api_key_required
61
58
  def run(
62
59
  self,
63
60
  messages: List[OpenAIMessage],
@@ -90,8 +87,10 @@ class OpenAIModel(BaseModelBackend):
90
87
  """
91
88
  for param in self.model_config_dict:
92
89
  if param not in OPENAI_API_PARAMS_WITH_FUNCTIONS:
93
- raise ValueError(f"Unexpected argument `{param}` is "
94
- "input into OpenAI model backend.")
90
+ raise ValueError(
91
+ f"Unexpected argument `{param}` is "
92
+ "input into OpenAI model backend."
93
+ )
95
94
 
96
95
  @property
97
96
  def stream(self) -> bool:
@@ -30,7 +30,6 @@ from camel.utils import BaseTokenCounter
30
30
 
31
31
 
32
32
  class StubTokenCounter(BaseTokenCounter):
33
-
34
33
  def count_tokens_from_messages(self, messages: List[OpenAIMessage]) -> int:
35
34
  r"""Token counting for STUB models, directly returning a constant.
36
35
 
@@ -47,10 +46,12 @@ class StubTokenCounter(BaseTokenCounter):
47
46
 
48
47
  class StubModel(BaseModelBackend):
49
48
  r"""A dummy model used for unit tests."""
49
+
50
50
  model_type = ModelType.STUB
51
51
 
52
- def __init__(self, model_type: ModelType,
53
- model_config_dict: Dict[str, Any]) -> None:
52
+ def __init__(
53
+ self, model_type: ModelType, model_config_dict: Dict[str, Any]
54
+ ) -> None:
54
55
  r"""All arguments are unused for the dummy model."""
55
56
  super().__init__(model_type, model_config_dict)
56
57
  self._token_counter: Optional[BaseTokenCounter] = None
@@ -90,6 +91,7 @@ class StubModel(BaseModelBackend):
90
91
  content=ARBITRARY_STRING,
91
92
  role="assistant",
92
93
  ),
94
+ logprobs=None,
93
95
  )
94
96
  ],
95
97
  usage=CompletionUsage(
@@ -101,6 +103,5 @@ class StubModel(BaseModelBackend):
101
103
  return response
102
104
 
103
105
  def check_model_config(self):
104
- r"""Directly pass the check on arguments to STUB model.
105
- """
106
+ r"""Directly pass the check on arguments to STUB model."""
106
107
  pass
camel/prompts/__init__.py CHANGED
@@ -11,16 +11,17 @@
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
- from .base import TextPrompt, CodePrompt, TextPromptDict
15
14
  from .ai_society import AISocietyPromptTemplateDict
15
+ from .base import CodePrompt, TextPrompt, TextPromptDict
16
16
  from .code import CodePromptTemplateDict
17
- from .misalignment import MisalignmentPromptTemplateDict
18
- from .translation import TranslationPromptTemplateDict
19
- from .solution_extraction import SolutionExtractionPromptTemplateDict
20
17
  from .evaluation import EvaluationPromptTemplateDict
18
+ from .misalignment import MisalignmentPromptTemplateDict
19
+ from .object_recognition import ObjectRecognitionPromptTemplateDict
20
+ from .prompt_templates import PromptTemplateGenerator
21
21
  from .role_description_prompt_template import RoleDescriptionPromptTemplateDict
22
+ from .solution_extraction import SolutionExtractionPromptTemplateDict
22
23
  from .task_prompt_template import TaskPromptTemplateDict
23
- from .prompt_templates import PromptTemplateGenerator
24
+ from .translation import TranslationPromptTemplateDict
24
25
 
25
26
  __all__ = [
26
27
  'TextPrompt',
@@ -35,4 +36,5 @@ __all__ = [
35
36
  'TaskPromptTemplateDict',
36
37
  'PromptTemplateGenerator',
37
38
  'SolutionExtractionPromptTemplateDict',
39
+ 'ObjectRecognitionPromptTemplateDict',
38
40
  ]