camel-ai 0.1.5__py3-none-any.whl → 0.1.5.2__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 (78) hide show
  1. camel/agents/__init__.py +2 -0
  2. camel/agents/chat_agent.py +217 -36
  3. camel/agents/deductive_reasoner_agent.py +86 -31
  4. camel/agents/knowledge_graph_agent.py +41 -18
  5. camel/agents/role_assignment_agent.py +4 -1
  6. camel/agents/search_agent.py +122 -0
  7. camel/bots/__init__.py +20 -0
  8. camel/bots/discord_bot.py +103 -0
  9. camel/bots/telegram_bot.py +84 -0
  10. camel/configs/__init__.py +3 -0
  11. camel/configs/anthropic_config.py +1 -1
  12. camel/configs/litellm_config.py +113 -0
  13. camel/embeddings/__init__.py +2 -0
  14. camel/embeddings/openai_embedding.py +2 -2
  15. camel/embeddings/sentence_transformers_embeddings.py +6 -5
  16. camel/embeddings/vlm_embedding.py +146 -0
  17. camel/functions/__init__.py +9 -0
  18. camel/functions/open_api_function.py +150 -29
  19. camel/functions/open_api_specs/biztoc/__init__.py +13 -0
  20. camel/functions/open_api_specs/biztoc/ai-plugin.json +34 -0
  21. camel/functions/open_api_specs/biztoc/openapi.yaml +21 -0
  22. camel/functions/open_api_specs/create_qr_code/__init__.py +13 -0
  23. camel/functions/open_api_specs/create_qr_code/openapi.yaml +44 -0
  24. camel/functions/open_api_specs/nasa_apod/__init__.py +13 -0
  25. camel/functions/open_api_specs/nasa_apod/openapi.yaml +72 -0
  26. camel/functions/open_api_specs/outschool/__init__.py +13 -0
  27. camel/functions/open_api_specs/outschool/ai-plugin.json +34 -0
  28. camel/functions/open_api_specs/outschool/openapi.yaml +1 -0
  29. camel/functions/open_api_specs/outschool/paths/__init__.py +14 -0
  30. camel/functions/open_api_specs/outschool/paths/get_classes.py +29 -0
  31. camel/functions/open_api_specs/outschool/paths/search_teachers.py +29 -0
  32. camel/functions/open_api_specs/security_config.py +21 -0
  33. camel/functions/open_api_specs/web_scraper/__init__.py +13 -0
  34. camel/functions/open_api_specs/web_scraper/ai-plugin.json +34 -0
  35. camel/functions/open_api_specs/web_scraper/openapi.yaml +71 -0
  36. camel/functions/open_api_specs/web_scraper/paths/__init__.py +13 -0
  37. camel/functions/open_api_specs/web_scraper/paths/scraper.py +29 -0
  38. camel/functions/openai_function.py +3 -1
  39. camel/functions/search_functions.py +104 -171
  40. camel/functions/slack_functions.py +2 -1
  41. camel/human.py +3 -1
  42. camel/loaders/base_io.py +3 -1
  43. camel/loaders/unstructured_io.py +16 -22
  44. camel/messages/base.py +135 -46
  45. camel/models/__init__.py +4 -0
  46. camel/models/anthropic_model.py +20 -14
  47. camel/models/base_model.py +2 -0
  48. camel/models/litellm_model.py +112 -0
  49. camel/models/model_factory.py +8 -1
  50. camel/models/open_source_model.py +1 -0
  51. camel/models/openai_model.py +6 -2
  52. camel/models/zhipuai_model.py +125 -0
  53. camel/prompts/__init__.py +2 -0
  54. camel/prompts/base.py +2 -1
  55. camel/prompts/descripte_video_prompt.py +33 -0
  56. camel/prompts/task_prompt_template.py +9 -3
  57. camel/retrievers/auto_retriever.py +20 -11
  58. camel/retrievers/base.py +4 -2
  59. camel/retrievers/bm25_retriever.py +2 -1
  60. camel/retrievers/cohere_rerank_retriever.py +2 -1
  61. camel/retrievers/vector_retriever.py +10 -4
  62. camel/societies/babyagi_playing.py +2 -1
  63. camel/societies/role_playing.py +2 -1
  64. camel/storages/graph_storages/base.py +1 -0
  65. camel/storages/graph_storages/neo4j_graph.py +5 -3
  66. camel/storages/vectordb_storages/base.py +2 -1
  67. camel/storages/vectordb_storages/milvus.py +5 -2
  68. camel/toolkits/github_toolkit.py +120 -26
  69. camel/types/__init__.py +3 -2
  70. camel/types/enums.py +25 -1
  71. camel/utils/__init__.py +11 -2
  72. camel/utils/commons.py +74 -4
  73. camel/utils/constants.py +26 -0
  74. camel/utils/token_counting.py +58 -5
  75. {camel_ai-0.1.5.dist-info → camel_ai-0.1.5.2.dist-info}/METADATA +29 -13
  76. camel_ai-0.1.5.2.dist-info/RECORD +148 -0
  77. camel_ai-0.1.5.dist-info/RECORD +0 -119
  78. {camel_ai-0.1.5.dist-info → camel_ai-0.1.5.2.dist-info}/WHEEL +0 -0
camel/prompts/base.py CHANGED
@@ -208,7 +208,8 @@ class TextPromptDict(Dict[Any, TextPrompt]):
208
208
  EMBODIMENT_PROMPT = TextPrompt(
209
209
  "System information :"
210
210
  + "\n".join(
211
- f"{key}: {value}" for key, value in get_system_information().items()
211
+ f"{key}: {value}"
212
+ for key, value in get_system_information().items()
212
213
  )
213
214
  + "\n"
214
215
  + """You are the physical embodiment of the {role} who is working on solving a task: {task}.
@@ -0,0 +1,33 @@
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 typing import Any
15
+
16
+ from camel.prompts.base import TextPrompt, TextPromptDict
17
+ from camel.types import RoleType
18
+
19
+
20
+ # flake8: noqa :E501
21
+ class DescriptionVideoPromptTemplateDict(TextPromptDict):
22
+ ASSISTANT_PROMPT = TextPrompt(
23
+ """You are a master of video analysis.
24
+ Please provide a shot description of the content of the current video."""
25
+ )
26
+
27
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
28
+ super().__init__(*args, **kwargs)
29
+ self.update(
30
+ {
31
+ RoleType.ASSISTANT: self.ASSISTANT_PROMPT,
32
+ }
33
+ )
@@ -18,11 +18,16 @@ from camel.prompts.ai_society import (
18
18
  TextPromptDict,
19
19
  )
20
20
  from camel.prompts.code import CodePromptTemplateDict
21
+ from camel.prompts.descripte_video_prompt import (
22
+ DescriptionVideoPromptTemplateDict,
23
+ )
21
24
  from camel.prompts.evaluation import (
22
25
  EvaluationPromptTemplateDict,
23
26
  )
24
27
  from camel.prompts.misalignment import MisalignmentPromptTemplateDict
25
- from camel.prompts.object_recognition import ObjectRecognitionPromptTemplateDict
28
+ from camel.prompts.object_recognition import (
29
+ ObjectRecognitionPromptTemplateDict,
30
+ )
26
31
  from camel.prompts.role_description_prompt_template import (
27
32
  RoleDescriptionPromptTemplateDict,
28
33
  )
@@ -52,8 +57,9 @@ class TaskPromptTemplateDict(Dict[Any, TextPromptDict]):
52
57
  TaskType.MISALIGNMENT: MisalignmentPromptTemplateDict(),
53
58
  TaskType.TRANSLATION: TranslationPromptTemplateDict(),
54
59
  TaskType.EVALUATION: EvaluationPromptTemplateDict(),
55
- TaskType.SOLUTION_EXTRACTION: SolutionExtractionPromptTemplateDict(),
60
+ TaskType.SOLUTION_EXTRACTION: SolutionExtractionPromptTemplateDict(), # noqa: E501
56
61
  TaskType.ROLE_DESCRIPTION: RoleDescriptionPromptTemplateDict(),
57
- TaskType.OBJECT_RECOGNITION: ObjectRecognitionPromptTemplateDict(),
62
+ TaskType.OBJECT_RECOGNITION: ObjectRecognitionPromptTemplateDict(), # noqa: E501
63
+ TaskType.VIDEO_DESCRIPTION: DescriptionVideoPromptTemplateDict(), # noqa: E501
58
64
  }
59
65
  )
@@ -42,7 +42,7 @@ class AutoRetriever:
42
42
  vector_storage_local_path (Optional[str]): Local path for vector
43
43
  storage, if applicable.
44
44
  storage_type (Optional[StorageType]): The type of vector storage to
45
- use. Defaults to `StorageType.MILVUS`.
45
+ use. Defaults to `StorageType.QDRANT`.
46
46
  embedding_model (Optional[BaseEmbedding]): Model used for embedding
47
47
  queries and documents. Defaults to `OpenAIEmbedding()`.
48
48
  """
@@ -54,7 +54,7 @@ class AutoRetriever:
54
54
  storage_type: Optional[StorageType] = None,
55
55
  embedding_model: Optional[BaseEmbedding] = None,
56
56
  ):
57
- self.storage_type = storage_type or StorageType.MILVUS
57
+ self.storage_type = storage_type or StorageType.QDRANT
58
58
  self.embedding_model = embedding_model or OpenAIEmbedding()
59
59
  self.vector_storage_local_path = vector_storage_local_path
60
60
  self.url_and_api_key = url_and_api_key
@@ -101,8 +101,8 @@ class AutoRetriever:
101
101
  r"""Generates a valid collection name from a given file path or URL.
102
102
 
103
103
  Args:
104
- content_input_path: str. The input URL or file path from which to
105
- generate the collection name.
104
+ content_input_path: str. The input URL or file path from which to
105
+ generate the collection name.
106
106
 
107
107
  Returns:
108
108
  str: A sanitized, valid collection name suitable for use.
@@ -134,7 +134,9 @@ class AutoRetriever:
134
134
  collection_name = collection_name[:30]
135
135
  return collection_name
136
136
 
137
- def _get_file_modified_date_from_file(self, content_input_path: str) -> str:
137
+ def _get_file_modified_date_from_file(
138
+ self, content_input_path: str
139
+ ) -> str:
138
140
  r"""Retrieves the last modified date and time of a given file. This
139
141
  function takes a file path as input and returns the last modified date
140
142
  and time of that file.
@@ -147,9 +149,9 @@ class AutoRetriever:
147
149
  str: The last modified time from file.
148
150
  """
149
151
  mod_time = os.path.getmtime(content_input_path)
150
- readable_mod_time = datetime.datetime.fromtimestamp(mod_time).isoformat(
151
- timespec='seconds'
152
- )
152
+ readable_mod_time = datetime.datetime.fromtimestamp(
153
+ mod_time
154
+ ).isoformat(timespec='seconds')
153
155
  return readable_mod_time
154
156
 
155
157
  def _get_file_modified_date_from_storage(
@@ -211,7 +213,7 @@ class AutoRetriever:
211
213
  `DEFAULT_SIMILARITY_THRESHOLD`.
212
214
  return_detailed_info (bool, optional): Whether to return detailed
213
215
  information including similarity score, content path and
214
- metadata. Defaults to False.
216
+ metadata. Defaults to `False`.
215
217
 
216
218
  Returns:
217
219
  string: By default, returns only the text information. If
@@ -321,8 +323,15 @@ class AutoRetriever:
321
323
  info['text'] for info in all_retrieved_info if 'text' in info
322
324
  )
323
325
 
324
- detailed_info = f"Original Query:\n{{ {query} }}\nRetrieved Context:\n{retrieved_infos}"
325
- text_info = f"Original Query:\n{{ {query} }}\nRetrieved Context:\n{retrieved_infos_text}"
326
+ detailed_info = (
327
+ f"Original Query:\n{{ {query} }}\n"
328
+ f"Retrieved Context:\n{retrieved_infos}"
329
+ )
330
+
331
+ text_info = (
332
+ f"Original Query:\n{{ {query} }}\n"
333
+ f"Retrieved Context:\n{retrieved_infos_text}"
334
+ )
326
335
 
327
336
  if return_detailed_info:
328
337
  return detailed_info
camel/retrievers/base.py CHANGED
@@ -32,7 +32,8 @@ def _query_unimplemented(self, *input: Any) -> None:
32
32
  registered hooks while the latter silently ignores them.
33
33
  """
34
34
  raise NotImplementedError(
35
- f"Retriever [{type(self).__name__}] is missing the required \"query\" function"
35
+ f"Retriever [{type(self).__name__}] is missing the required"
36
+ " \"query\" function"
36
37
  )
37
38
 
38
39
 
@@ -52,7 +53,8 @@ def _process_unimplemented(self, *input: Any) -> None:
52
53
  registered hooks while the latter silently ignores them.
53
54
  """
54
55
  raise NotImplementedError(
55
- f"Retriever [{type(self).__name__}] is missing the required \"process\" function"
56
+ f"Retriever [{type(self).__name__}] is missing the required "
57
+ "\"process\" function"
56
58
  )
57
59
 
58
60
 
@@ -47,7 +47,8 @@ class BM25Retriever(BaseRetriever):
47
47
  from rank_bm25 import BM25Okapi
48
48
  except ImportError as e:
49
49
  raise ImportError(
50
- "Package `rank_bm25` not installed, install by running 'pip install rank_bm25'"
50
+ "Package `rank_bm25` not installed, install by running 'pip "
51
+ "install rank_bm25'"
51
52
  ) from e
52
53
 
53
54
  self.bm25: BM25Okapi = None
@@ -66,7 +66,8 @@ class CohereRerankRetriever(BaseRetriever):
66
66
  self.api_key = api_key or os.environ["COHERE_API_KEY"]
67
67
  except ValueError as e:
68
68
  raise ValueError(
69
- "Must pass in cohere api key or specify via COHERE_API_KEY environment variable."
69
+ "Must pass in cohere api key or specify via COHERE_API_KEY"
70
+ " environment variable."
70
71
  ) from e
71
72
 
72
73
  self.co = cohere.Client(self.api_key)
@@ -64,7 +64,9 @@ class VectorRetriever(BaseRetriever):
64
64
  self.storage = (
65
65
  storage
66
66
  if storage is not None
67
- else QdrantStorage(vector_dim=self.embedding_model.get_output_dim())
67
+ else QdrantStorage(
68
+ vector_dim=self.embedding_model.get_output_dim()
69
+ )
68
70
  )
69
71
  self.similarity_threshold = similarity_threshold
70
72
  self.unstructured_modules: UnstructuredIO = UnstructuredIO()
@@ -151,7 +153,8 @@ class VectorRetriever(BaseRetriever):
151
153
 
152
154
  if query_results[0].record.payload is None:
153
155
  raise ValueError(
154
- "Payload of vector storage is None, please check the collection."
156
+ "Payload of vector storage is None, please check the "
157
+ "collection."
155
158
  )
156
159
 
157
160
  # format the results
@@ -176,8 +179,11 @@ class VectorRetriever(BaseRetriever):
176
179
  if not formatted_results:
177
180
  return [
178
181
  {
179
- 'text': f"""No suitable information retrieved from {content_path} \
180
- with similarity_threshold = {self.similarity_threshold}."""
182
+ 'text': (
183
+ f"No suitable information retrieved "
184
+ f"from {content_path} with similarity_threshold"
185
+ f" = {self.similarity_threshold}."
186
+ )
181
187
  }
182
188
  ]
183
189
  return formatted_results
@@ -150,7 +150,8 @@ class BabyAGI:
150
150
  if self.task_type in [TaskType.AI_SOCIETY, TaskType.MISALIGNMENT]:
151
151
  task_specify_meta_dict.update(
152
152
  dict(
153
- assistant_role=assistant_role_name, user_role=user_role_name
153
+ assistant_role=assistant_role_name,
154
+ user_role=user_role_name,
154
155
  )
155
156
  )
156
157
  task_specify_meta_dict.update(extend_task_specify_meta_dict or {})
@@ -274,7 +274,8 @@ class RolePlaying:
274
274
  ]:
275
275
  extend_sys_msg_meta_dicts = [
276
276
  dict(
277
- assistant_role=assistant_role_name, user_role=user_role_name
277
+ assistant_role=assistant_role_name,
278
+ user_role=user_role_name,
278
279
  )
279
280
  for _ in range(2)
280
281
  ]
@@ -70,6 +70,7 @@ class BaseGraphStorage(ABC):
70
70
  self, query: str, params: Optional[Dict[str, Any]] = None
71
71
  ) -> List[Dict[str, Any]]:
72
72
  r"""Query the graph store with statement and parameters.
73
+
73
74
  Args:
74
75
  query (str): The query to be executed.
75
76
  params (Optional[Dict[str, Any]]): A dictionary of parameters to
@@ -99,7 +99,9 @@ class Neo4jGraph(BaseGraphStorage):
99
99
  "Please install it with `pip install neo4j`."
100
100
  )
101
101
 
102
- self.driver = neo4j.GraphDatabase.driver(url, auth=(username, password))
102
+ self.driver = neo4j.GraphDatabase.driver(
103
+ url, auth=(username, password)
104
+ )
103
105
  self.database = database
104
106
  self.timeout = timeout
105
107
  self.truncate = truncate
@@ -373,8 +375,8 @@ class Neo4jGraph(BaseGraphStorage):
373
375
  with self.driver.session(database=self.database) as session:
374
376
  session.run(
375
377
  (
376
- "MATCH (n1:{})-[r:{}]->(n2:{}) WHERE n1.id = $subj AND n2.id"
377
- " = $obj DELETE r"
378
+ "MATCH (n1:{})-[r:{}]->(n2:{}) WHERE n1.id = $subj AND"
379
+ " n2.id = $obj DELETE r"
378
380
  ).format(
379
381
  BASE_ENTITY_LABEL.replace("_", ""),
380
382
  rel,
@@ -147,7 +147,8 @@ class BaseVectorStorage(ABC):
147
147
  query: VectorDBQuery,
148
148
  **kwargs: Any,
149
149
  ) -> List[VectorDBQueryResult]:
150
- r"""Searches for similar vectors in the storage based on the provided query.
150
+ r"""Searches for similar vectors in the storage based on the provided
151
+ query.
151
152
 
152
153
  Args:
153
154
  query (VectorDBQuery): The query object containing the search
@@ -155,7 +155,8 @@ class MilvusStorage(BaseVectorStorage):
155
155
  field_name="payload",
156
156
  datatype=DataType.JSON,
157
157
  description=(
158
- 'Any additional metadata or information related' 'to the vector'
158
+ 'Any additional metadata or information related'
159
+ 'to the vector'
159
160
  ),
160
161
  )
161
162
 
@@ -267,7 +268,9 @@ class MilvusStorage(BaseVectorStorage):
267
268
  for record in records:
268
269
  record_dict = {
269
270
  "id": record.id,
270
- "payload": record.payload if record.payload is not None else '',
271
+ "payload": record.payload
272
+ if record.payload is not None
273
+ else '',
271
274
  "vector": record.vector,
272
275
  }
273
276
  validated_data.append(record_dict)
@@ -14,6 +14,7 @@
14
14
 
15
15
  import os
16
16
  from dataclasses import dataclass
17
+ from datetime import datetime, timedelta
17
18
  from typing import List, Optional
18
19
 
19
20
  from camel.functions import OpenAIFunction
@@ -48,7 +49,8 @@ class GithubIssue:
48
49
  body (str): The body/content of the GitHub issue.
49
50
  number (int): The issue number.
50
51
  file_path (str): The path of the file associated with the issue.
51
- file_content (str): The content of the file associated with the issue.
52
+ file_content (str): The content of the file associated with the
53
+ issue.
52
54
  """
53
55
  self.title = title
54
56
  self.body = body
@@ -56,11 +58,12 @@ class GithubIssue:
56
58
  self.file_path = file_path
57
59
  self.file_content = file_content
58
60
 
59
- def summary(self) -> str:
60
- r"""Returns a summary of the issue.
61
+ def __str__(self) -> str:
62
+ r"""Returns a string representation of the issue.
61
63
 
62
64
  Returns:
63
- str: A string containing the title, body, number, file path, and file content of the issue.
65
+ str: A string containing the title, body, number, file path, and
66
+ file content of the issue.
64
67
  """
65
68
  return (
66
69
  f"Title: {self.title}\n"
@@ -71,16 +74,60 @@ class GithubIssue:
71
74
  )
72
75
 
73
76
 
77
+ @dataclass
78
+ class GithubPullRequestDiff:
79
+ r"""Represents a single diff of a pull request on Github.
80
+
81
+ Attributes:
82
+ filename (str): The name of the file that was changed.
83
+ patch (str): The diff patch for the file.
84
+ """
85
+
86
+ filename: str
87
+ patch: str
88
+
89
+ def __str__(self) -> str:
90
+ r"""Returns a string representation of this diff."""
91
+ return f"Filename: {self.filename}\nPatch: {self.patch}"
92
+
93
+
94
+ @dataclass
95
+ class GithubPullRequest:
96
+ r"""Represents a pull request on Github.
97
+
98
+ Attributes:
99
+ title (str): The title of the GitHub pull request.
100
+ body (str): The body/content of the GitHub pull request.
101
+ diffs (List[GithubPullRequestDiff]): A list of diffs for the pull
102
+ request.
103
+ """
104
+
105
+ title: str
106
+ body: str
107
+ diffs: List[GithubPullRequestDiff]
108
+
109
+ def __str__(self) -> str:
110
+ r"""Returns a string representation of the pull request."""
111
+ diff_summaries = '\n'.join(str(diff) for diff in self.diffs)
112
+ return (
113
+ f"Title: {self.title}\n"
114
+ f"Body: {self.body}\n"
115
+ f"Diffs: {diff_summaries}\n"
116
+ )
117
+
118
+
74
119
  class GithubToolkit(BaseToolkit):
75
- r"""A class representing a toolkit for interacting with GitHub repositories.
120
+ r"""A class representing a toolkit for interacting with GitHub
121
+ repositories.
76
122
 
77
- This class provides methods for retrieving open issues, retrieving specific issues,
78
- and creating pull requests in a GitHub repository.
123
+ This class provides methods for retrieving open issues, retrieving
124
+ specific issues, and creating pull requests in a GitHub repository.
79
125
 
80
126
  Args:
81
127
  repo_name (str): The name of the GitHub repository.
82
- access_token (str, optional): The access token to authenticate with GitHub.
83
- If not provided, it will be obtained using the `get_github_access_token` method.
128
+ access_token (str, optional): The access token to authenticate with
129
+ GitHub. If not provided, it will be obtained using the
130
+ `get_github_access_token` method.
84
131
  """
85
132
 
86
133
  def __init__(
@@ -90,8 +137,9 @@ class GithubToolkit(BaseToolkit):
90
137
 
91
138
  Args:
92
139
  repo_name (str): The name of the GitHub repository.
93
- access_token (str, optional): The access token to authenticate with GitHub.
94
- If not provided, it will be obtained using the `get_github_access_token` method.
140
+ access_token (str, optional): The access token to authenticate
141
+ with GitHub. If not provided, it will be obtained using the
142
+ `get_github_access_token` method.
95
143
  """
96
144
  if access_token is None:
97
145
  access_token = self.get_github_access_token()
@@ -101,21 +149,24 @@ class GithubToolkit(BaseToolkit):
101
149
  except ImportError:
102
150
  raise ImportError(
103
151
  "Please install `github` first. You can install it by running "
104
- "`pip install wikipedia`."
152
+ "`pip install pygithub`."
105
153
  )
106
154
  self.github = Github(auth=Auth.Token(access_token))
107
155
  self.repo = self.github.get_repo(repo_name)
108
156
 
109
157
  def get_tools(self) -> List[OpenAIFunction]:
110
- r"""Returns a list of OpenAIFunction objects representing the functions in the toolkit.
158
+ r"""Returns a list of OpenAIFunction objects representing the
159
+ functions in the toolkit.
111
160
 
112
161
  Returns:
113
- List[OpenAIFunction]: A list of OpenAIFunction objects representing the functions in the toolkit.
162
+ List[OpenAIFunction]: A list of OpenAIFunction objects
163
+ representing the functions in the toolkit.
114
164
  """
115
165
  return [
116
166
  OpenAIFunction(self.retrieve_issue_list),
117
167
  OpenAIFunction(self.retrieve_issue),
118
168
  OpenAIFunction(self.create_pull_request),
169
+ OpenAIFunction(self.retrieve_pull_requests),
119
170
  ]
120
171
 
121
172
  def get_github_access_token(self) -> str:
@@ -125,15 +176,16 @@ class GithubToolkit(BaseToolkit):
125
176
  str: A string containing the GitHub access token.
126
177
 
127
178
  Raises:
128
- ValueError: If the API key or secret is not found in the environment variables.
179
+ ValueError: If the API key or secret is not found in the
180
+ environment variables.
129
181
  """
130
182
  # Get `GITHUB_ACCESS_TOKEN` here: https://github.com/settings/tokens
131
183
  GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN")
132
184
 
133
185
  if not GITHUB_ACCESS_TOKEN:
134
186
  raise ValueError(
135
- "`GITHUB_ACCESS_TOKEN` not found in environment variables. Get it "
136
- "here: `https://github.com/settings/tokens`."
187
+ "`GITHUB_ACCESS_TOKEN` not found in environment variables. Get"
188
+ " it here: `https://github.com/settings/tokens`."
137
189
  )
138
190
  return GITHUB_ACCESS_TOKEN
139
191
 
@@ -151,7 +203,7 @@ class GithubToolkit(BaseToolkit):
151
203
  number=issue.number,
152
204
  file_path=issue.labels[
153
205
  0
154
- ].name, # for now we require file path to be the first label in the PR
206
+ ].name, # we require file path to be the first label in the PR
155
207
  file_content=self.retrieve_file_content(issue.labels[0].name),
156
208
  )
157
209
  for issue in issues
@@ -173,9 +225,47 @@ class GithubToolkit(BaseToolkit):
173
225
  issues = self.retrieve_issue_list()
174
226
  for issue in issues:
175
227
  if issue.number == issue_number:
176
- return issue.summary()
228
+ return str(issue)
177
229
  return None
178
230
 
231
+ def retrieve_pull_requests(
232
+ self, days: int, state: str, max_prs: int
233
+ ) -> List[str]:
234
+ r"""Retrieves a summary of merged pull requests from the repository.
235
+ The summary will be provided for the last specified number of days.
236
+
237
+ Args:
238
+ days (int): The number of days to retrieve merged pull requests
239
+ for.
240
+ state (str): A specific state of PRs to retrieve. Can be open or
241
+ closed.
242
+ max_prs (int): The maximum number of PRs to retrieve.
243
+
244
+ Returns:
245
+ List[str]: A list of merged pull request summaries.
246
+ """
247
+ pull_requests = self.repo.get_pulls(state=state)
248
+ merged_prs = []
249
+ earliest_date: datetime = datetime.utcnow() - timedelta(days=days)
250
+
251
+ for pr in pull_requests[:max_prs]:
252
+ if (
253
+ pr.merged
254
+ and pr.merged_at is not None
255
+ and pr.merged_at.timestamp() > earliest_date.timestamp()
256
+ ):
257
+ pr_details = GithubPullRequest(pr.title, pr.body, [])
258
+
259
+ # Get files changed in the PR
260
+ files = pr.get_files()
261
+
262
+ for file in files:
263
+ diff = GithubPullRequestDiff(file.filename, file.patch)
264
+ pr_details.diffs.append(diff)
265
+
266
+ merged_prs.append(str(pr_details))
267
+ return merged_prs
268
+
179
269
  def create_pull_request(
180
270
  self,
181
271
  file_path: str,
@@ -186,19 +276,23 @@ class GithubToolkit(BaseToolkit):
186
276
  ) -> str:
187
277
  r"""Creates a pull request.
188
278
 
189
- This function creates a pull request in specified repository, which updates a
190
- file in the specific path with new content. The pull request description
191
- contains information about the issue title and number.
279
+ This function creates a pull request in specified repository, which
280
+ updates a file in the specific path with new content. The pull request
281
+ description contains information about the issue title and number.
192
282
 
193
283
  Args:
194
- file_path (str): The path of the file to be updated in the repository.
284
+ file_path (str): The path of the file to be updated in the
285
+ repository.
195
286
  new_content (str): The specified new content of the specified file.
196
- pr_title (str): The title of the issue that is solved by this pull request.
287
+ pr_title (str): The title of the issue that is solved by this pull
288
+ request.
197
289
  body (str): The commit message for the pull request.
198
- branch_name (str): The name of the branch to create and submit the pull request from.
290
+ branch_name (str): The name of the branch to create and submit the
291
+ pull request from.
199
292
 
200
293
  Returns:
201
- str: A formatted report of whether the pull request was created successfully or not.
294
+ str: A formatted report of whether the pull request was created
295
+ successfully or not.
202
296
  """
203
297
  sb = self.repo.get_branch(self.repo.default_branch)
204
298
  self.repo.create_git_ref(
camel/types/__init__.py CHANGED
@@ -16,8 +16,8 @@ from .enums import (
16
16
  EmbeddingModelType,
17
17
  ModelType,
18
18
  OpenAIBackendRole,
19
- OpenAIImageDetailType,
20
19
  OpenAIImageType,
20
+ OpenAIVisionDetailType,
21
21
  OpenAPIName,
22
22
  RoleType,
23
23
  StorageType,
@@ -58,8 +58,9 @@ __all__ = [
58
58
  'ChatCompletionAssistantMessageParam',
59
59
  'ChatCompletionFunctionMessageParam',
60
60
  'CompletionUsage',
61
+ 'OpenAIVideoType',
61
62
  'OpenAIImageType',
62
- 'OpenAIImageDetailType',
63
+ 'OpenAIVisionDetailType',
63
64
  'OpenAPIName',
64
65
  'AudioModelType',
65
66
  'VoiceType',
camel/types/enums.py CHANGED
@@ -29,6 +29,9 @@ class ModelType(Enum):
29
29
  GPT_4_32K = "gpt-4-32k"
30
30
  GPT_4_TURBO = "gpt-4-turbo"
31
31
  GPT_4O = "gpt-4o"
32
+ GLM_4 = "glm-4"
33
+ GLM_4V = 'glm-4v'
34
+ GLM_3_TURBO = "glm-3-turbo"
32
35
 
33
36
  STUB = "stub"
34
37
 
@@ -62,6 +65,15 @@ class ModelType(Enum):
62
65
  ModelType.GPT_4O,
63
66
  }
64
67
 
68
+ @property
69
+ def is_zhipuai(self) -> bool:
70
+ r"""Returns whether this type of models is an ZhipuAI model."""
71
+ return self in {
72
+ ModelType.GLM_3_TURBO,
73
+ ModelType.GLM_4,
74
+ ModelType.GLM_4V,
75
+ }
76
+
65
77
  @property
66
78
  def is_open_source(self) -> bool:
67
79
  r"""Returns whether this type of models is open-source."""
@@ -103,6 +115,12 @@ class ModelType(Enum):
103
115
  return 128000
104
116
  elif self is ModelType.GPT_4O:
105
117
  return 128000
118
+ elif self == ModelType.GLM_4:
119
+ return 8192
120
+ elif self == ModelType.GLM_3_TURBO:
121
+ return 8192
122
+ elif self == ModelType.GLM_4V:
123
+ return 1024
106
124
  elif self is ModelType.STUB:
107
125
  return 4096
108
126
  elif self is ModelType.LLAMA_2:
@@ -191,6 +209,7 @@ class TaskType(Enum):
191
209
  ROLE_DESCRIPTION = "role_description"
192
210
  OBJECT_RECOGNITION = "object_recognition"
193
211
  DEFAULT = "default"
212
+ VIDEO_DESCRIPTION = "video_description"
194
213
 
195
214
 
196
215
  class VectorDistance(Enum):
@@ -238,7 +257,7 @@ class OpenAIImageType(Enum, metaclass=OpenAIImageTypeMeta):
238
257
  GIF = "gif"
239
258
 
240
259
 
241
- class OpenAIImageDetailType(Enum):
260
+ class OpenAIVisionDetailType(Enum):
242
261
  AUTO = "auto"
243
262
  LOW = "low"
244
263
  HIGH = "high"
@@ -253,6 +272,11 @@ class OpenAPIName(Enum):
253
272
  COURSERA = "coursera"
254
273
  KLARNA = "klarna"
255
274
  SPEAK = "speak"
275
+ NASA_APOD = "nasa_apod"
276
+ BIZTOC = "biztoc"
277
+ CREATE_QR_CODE = "create_qr_code"
278
+ OUTSCHOOL = "outschool"
279
+ WEB_SCRAPER = "web_scraper"
256
280
 
257
281
 
258
282
  class AudioModelType(Enum):