camel-ai 0.2.67__py3-none-any.whl → 0.2.69a1__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 (43) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +170 -11
  3. camel/configs/vllm_config.py +2 -0
  4. camel/datagen/self_improving_cot.py +1 -1
  5. camel/environments/__init__.py +12 -0
  6. camel/environments/rlcards_env.py +860 -0
  7. camel/interpreters/docker/Dockerfile +2 -5
  8. camel/loaders/firecrawl_reader.py +4 -4
  9. camel/memories/blocks/vectordb_block.py +8 -1
  10. camel/memories/context_creators/score_based.py +185 -39
  11. camel/models/anthropic_model.py +114 -2
  12. camel/runtimes/configs.py +11 -11
  13. camel/runtimes/daytona_runtime.py +4 -4
  14. camel/runtimes/docker_runtime.py +6 -6
  15. camel/runtimes/remote_http_runtime.py +5 -5
  16. camel/societies/workforce/prompts.py +55 -21
  17. camel/societies/workforce/single_agent_worker.py +274 -14
  18. camel/societies/workforce/task_channel.py +9 -2
  19. camel/societies/workforce/utils.py +10 -2
  20. camel/societies/workforce/worker.py +74 -16
  21. camel/societies/workforce/workforce.py +90 -35
  22. camel/tasks/task.py +18 -12
  23. camel/toolkits/__init__.py +2 -0
  24. camel/toolkits/aci_toolkit.py +19 -19
  25. camel/toolkits/arxiv_toolkit.py +6 -6
  26. camel/toolkits/dappier_toolkit.py +5 -5
  27. camel/toolkits/file_write_toolkit.py +10 -10
  28. camel/toolkits/github_toolkit.py +3 -3
  29. camel/toolkits/non_visual_browser_toolkit/__init__.py +18 -0
  30. camel/toolkits/non_visual_browser_toolkit/actions.py +196 -0
  31. camel/toolkits/non_visual_browser_toolkit/agent.py +278 -0
  32. camel/toolkits/non_visual_browser_toolkit/browser_non_visual_toolkit.py +363 -0
  33. camel/toolkits/non_visual_browser_toolkit/nv_browser_session.py +175 -0
  34. camel/toolkits/non_visual_browser_toolkit/snapshot.js +188 -0
  35. camel/toolkits/non_visual_browser_toolkit/snapshot.py +164 -0
  36. camel/toolkits/pptx_toolkit.py +4 -4
  37. camel/toolkits/sympy_toolkit.py +1 -1
  38. camel/toolkits/task_planning_toolkit.py +3 -3
  39. camel/toolkits/thinking_toolkit.py +1 -1
  40. {camel_ai-0.2.67.dist-info → camel_ai-0.2.69a1.dist-info}/METADATA +2 -1
  41. {camel_ai-0.2.67.dist-info → camel_ai-0.2.69a1.dist-info}/RECORD +43 -35
  42. {camel_ai-0.2.67.dist-info → camel_ai-0.2.69a1.dist-info}/WHEEL +0 -0
  43. {camel_ai-0.2.67.dist-info → camel_ai-0.2.69a1.dist-info}/licenses/LICENSE +0 -0
@@ -274,10 +274,13 @@ class Workforce(BaseNode):
274
274
  "of agents. This ensures efficient execution by minimizing "
275
275
  "context switching between agents.",
276
276
  )
277
- _kwargs = dict(task_agent_kwargs or {})
277
+ _task_agent_kwargs = dict(task_agent_kwargs or {})
278
278
  extra_tools = TaskPlanningToolkit().get_tools()
279
- _kwargs["tools"] = [*_kwargs.get("tools", []), *extra_tools]
280
- self.task_agent = ChatAgent(task_sys_msg, **_kwargs)
279
+ _task_agent_kwargs["tools"] = [
280
+ *_task_agent_kwargs.get("tools", []),
281
+ *extra_tools,
282
+ ]
283
+ self.task_agent = ChatAgent(task_sys_msg, **_task_agent_kwargs)
281
284
 
282
285
  def __repr__(self):
283
286
  return (
@@ -671,8 +674,8 @@ class Workforce(BaseNode):
671
674
  # Reset state for tasks being moved back to pending
672
675
  for task in tasks_to_move_back:
673
676
  # Handle all possible task states
674
- if task.state in [TaskState.DONE, TaskState.FAILED]:
675
- task.state = TaskState.OPEN
677
+ if task.state in [TaskState.DONE, TaskState.OPEN]:
678
+ task.state = TaskState.FAILED # TODO: Add logic for OPEN
676
679
  # Clear result to avoid confusion
677
680
  task.result = None
678
681
  # Reset failure count to give task a fresh start
@@ -823,9 +826,17 @@ class Workforce(BaseNode):
823
826
 
824
827
  # Check if we're already in an event loop
825
828
  try:
826
- asyncio.get_running_loop()
829
+ current_loop = asyncio.get_running_loop()
830
+ # Store the current loop for potential reuse by async tools
831
+ self._loop = current_loop
832
+
833
+ logger.info(
834
+ "Running in active event loop context. "
835
+ "Consider using process_task_async() directly for better "
836
+ "async tool compatibility."
837
+ )
827
838
 
828
- # If we're in an event loop, we need to run in a thread
839
+ # Create a new thread with a fresh event loop
829
840
  def run_in_thread():
830
841
  # Create new event loop for this thread
831
842
  new_loop = asyncio.new_event_loop()
@@ -836,6 +847,8 @@ class Workforce(BaseNode):
836
847
  )
837
848
  finally:
838
849
  new_loop.close()
850
+ # Restore original loop reference
851
+ self._loop = current_loop
839
852
 
840
853
  with concurrent.futures.ThreadPoolExecutor() as executor:
841
854
  future = executor.submit(run_in_thread)
@@ -868,7 +881,7 @@ class Workforce(BaseNode):
868
881
  self.reset()
869
882
  self._task = task
870
883
  self._state = WorkforceState.RUNNING
871
- task.state = TaskState.OPEN
884
+ task.state = TaskState.FAILED # TODO: Add logic for OPEN
872
885
  self._pending_tasks.append(task)
873
886
 
874
887
  # Decompose the task into subtasks first
@@ -982,18 +995,27 @@ class Workforce(BaseNode):
982
995
 
983
996
  @check_if_running(False)
984
997
  def add_single_agent_worker(
985
- self, description: str, worker: ChatAgent
998
+ self,
999
+ description: str,
1000
+ worker: ChatAgent,
1001
+ pool_max_size: int = 10,
986
1002
  ) -> Workforce:
987
1003
  r"""Add a worker node to the workforce that uses a single agent.
988
1004
 
989
1005
  Args:
990
1006
  description (str): Description of the worker node.
991
1007
  worker (ChatAgent): The agent to be added.
1008
+ pool_max_size (int): Maximum size of the agent pool.
1009
+ (default: :obj:`10`)
992
1010
 
993
1011
  Returns:
994
1012
  Workforce: The workforce node itself.
995
1013
  """
996
- worker_node = SingleAgentWorker(description, worker)
1014
+ worker_node = SingleAgentWorker(
1015
+ description=description,
1016
+ worker=worker,
1017
+ pool_max_size=pool_max_size,
1018
+ )
997
1019
  self._children.append(worker_node)
998
1020
  if self.metrics_logger:
999
1021
  self.metrics_logger.log_worker_created(
@@ -1174,6 +1196,13 @@ class Workforce(BaseNode):
1174
1196
  response = self.coordinator_agent.step(
1175
1197
  prompt, response_format=TaskAssignResult
1176
1198
  )
1199
+ if response.msg is None or response.msg.content is None:
1200
+ logger.error(
1201
+ "Coordinator agent returned empty response for task assignment"
1202
+ )
1203
+ # Return empty result as fallback
1204
+ return TaskAssignResult(assignments=[])
1205
+
1177
1206
  result_dict = json.loads(response.msg.content, parse_int=str)
1178
1207
  task_assign_result = TaskAssignResult(**result_dict)
1179
1208
  return task_assign_result
@@ -1211,8 +1240,21 @@ class Workforce(BaseNode):
1211
1240
  response = self.coordinator_agent.step(
1212
1241
  prompt, response_format=WorkerConf
1213
1242
  )
1214
- result_dict = json.loads(response.msg.content)
1215
- new_node_conf = WorkerConf(**result_dict)
1243
+ if response.msg is None or response.msg.content is None:
1244
+ logger.error(
1245
+ "Coordinator agent returned empty response for worker creation"
1246
+ )
1247
+ # Create a fallback worker configuration
1248
+ new_node_conf = WorkerConf(
1249
+ description=f"Fallback worker for "
1250
+ f"task: {task.content[:50]}...",
1251
+ role="General Assistant",
1252
+ sys_msg="You are a general assistant that can help "
1253
+ "with various tasks.",
1254
+ )
1255
+ else:
1256
+ result_dict = json.loads(response.msg.content)
1257
+ new_node_conf = WorkerConf(**result_dict)
1216
1258
 
1217
1259
  new_agent = self._create_new_agent(
1218
1260
  new_node_conf.role,
@@ -1222,6 +1264,7 @@ class Workforce(BaseNode):
1222
1264
  new_node = SingleAgentWorker(
1223
1265
  description=new_node_conf.description,
1224
1266
  worker=new_agent,
1267
+ pool_max_size=10, # TODO: make this configurable
1225
1268
  )
1226
1269
  new_node.set_channel(self._channel)
1227
1270
 
@@ -1273,14 +1316,17 @@ class Workforce(BaseNode):
1273
1316
  # Add timeout to prevent indefinite waiting
1274
1317
  return await asyncio.wait_for(
1275
1318
  self._channel.get_returned_task_by_publisher(self.node_id),
1276
- timeout=300.0, # 5 minute timeout
1319
+ timeout=180.0, # 3 minute timeout
1277
1320
  )
1278
1321
  except asyncio.TimeoutError:
1279
1322
  logger.warning(
1280
1323
  f"Timeout waiting for returned task in "
1281
- f"workforce {self.node_id}"
1324
+ f"workforce {self.node_id}. "
1325
+ f"This may indicate an issue with async tool execution. "
1326
+ f"Current pending tasks: {len(self._pending_tasks)}, "
1327
+ f"In-flight tasks: {self._in_flight_tasks}"
1282
1328
  )
1283
- raise ValueError("Timeout waiting for task to be returned")
1329
+ raise
1284
1330
 
1285
1331
  async def _post_ready_tasks(self) -> None:
1286
1332
  r"""Checks for unassigned tasks, assigns them, and then posts any
@@ -1360,10 +1406,10 @@ class Workforce(BaseNode):
1360
1406
  metadata={'failure_count': task.failure_count},
1361
1407
  )
1362
1408
 
1363
- if task.failure_count >= 3:
1409
+ if task.failure_count > 3:
1364
1410
  return True
1365
1411
 
1366
- if task.get_depth() >= 3:
1412
+ if task.get_depth() > 3:
1367
1413
  # Create a new worker node and reassign
1368
1414
  assignee = self._create_worker_node_for_task(task)
1369
1415
 
@@ -1448,25 +1494,32 @@ class Workforce(BaseNode):
1448
1494
  'processing_time_seconds'
1449
1495
  ]
1450
1496
 
1451
- # Get token usage from task additional info
1497
+ # Get token usage from task additional info (preferred - actual
1498
+ # usage)
1452
1499
  if (
1453
1500
  task.additional_info is not None
1454
1501
  and 'token_usage' in task.additional_info
1455
1502
  ):
1456
1503
  token_usage = task.additional_info['token_usage']
1457
-
1458
- # Try to get token usage from SingleAgentWorker memory if available
1459
- assignee_node = next(
1460
- (
1461
- child
1462
- for child in self._children
1463
- if child.node_id == worker_id
1464
- ),
1465
- None,
1466
- )
1467
- if isinstance(assignee_node, SingleAgentWorker):
1468
- _, total_tokens = assignee_node.worker.memory.get_context()
1469
- token_usage = {'total_tokens': total_tokens}
1504
+ else:
1505
+ # Fallback: Try to get token usage from SingleAgentWorker
1506
+ # memory
1507
+ assignee_node = next(
1508
+ (
1509
+ child
1510
+ for child in self._children
1511
+ if child.node_id == worker_id
1512
+ ),
1513
+ None,
1514
+ )
1515
+ if isinstance(assignee_node, SingleAgentWorker):
1516
+ try:
1517
+ _, total_tokens = (
1518
+ assignee_node.worker.memory.get_context()
1519
+ )
1520
+ token_usage = {'total_tokens': total_tokens}
1521
+ except Exception:
1522
+ token_usage = None
1470
1523
 
1471
1524
  # Log the completed task
1472
1525
  self.metrics_logger.log_task_completed(
@@ -1654,7 +1707,7 @@ class Workforce(BaseNode):
1654
1707
  await self._graceful_shutdown(returned_task)
1655
1708
  break
1656
1709
  elif returned_task.state == TaskState.OPEN:
1657
- # TODO: multi-layer workforce
1710
+ # TODO: Add logic for OPEN
1658
1711
  pass
1659
1712
  else:
1660
1713
  raise ValueError(
@@ -1764,17 +1817,19 @@ class Workforce(BaseNode):
1764
1817
  if isinstance(child, SingleAgentWorker):
1765
1818
  cloned_worker = child.worker.clone(with_memory)
1766
1819
  new_instance.add_single_agent_worker(
1767
- child.description, cloned_worker
1820
+ child.description,
1821
+ cloned_worker,
1822
+ pool_max_size=10,
1768
1823
  )
1769
1824
  elif isinstance(child, RolePlayingWorker):
1770
1825
  new_instance.add_role_playing_worker(
1771
1826
  child.description,
1772
1827
  child.assistant_role_name,
1773
1828
  child.user_role_name,
1774
- child.chat_turn_limit,
1775
1829
  child.assistant_agent_kwargs,
1776
1830
  child.user_agent_kwargs,
1777
1831
  child.summarize_agent_kwargs,
1832
+ child.chat_turn_limit,
1778
1833
  )
1779
1834
  elif isinstance(child, Workforce):
1780
1835
  new_instance.add_workforce(child.clone(with_memory))
@@ -1868,7 +1923,7 @@ class Workforce(BaseNode):
1868
1923
  )
1869
1924
 
1870
1925
  try:
1871
- result_task = await workforce_instance.process_task(task)
1926
+ result_task = await workforce_instance.process_task_async(task)
1872
1927
  return {
1873
1928
  "status": "success",
1874
1929
  "task_id": result_task.id,
camel/tasks/task.py CHANGED
@@ -25,10 +25,12 @@ from typing import (
25
25
  Union,
26
26
  )
27
27
 
28
- from pydantic import BaseModel
28
+ from pydantic import BaseModel, Field
29
29
 
30
30
  if TYPE_CHECKING:
31
31
  from camel.agents import ChatAgent
32
+ import uuid
33
+
32
34
  from camel.logger import get_logger
33
35
  from camel.messages import BaseMessage
34
36
  from camel.prompts import TextPrompt
@@ -142,27 +144,29 @@ class Task(BaseModel):
142
144
  content (str): string content for task.
143
145
  id (str): An unique string identifier for the task. This should
144
146
  ideally be provided by the provider/model which created the task.
145
- (default: :obj: `""`)
147
+ (default: :obj:`uuid.uuid4()`)
146
148
  state (TaskState): The state which should be OPEN, RUNNING, DONE or
147
- DELETED. (default: :obj: `TaskState.OPEN`)
148
- type (Optional[str]): task type. (default: :obj: `None`)
149
+ DELETED. (default: :obj:`TaskState.FAILED`)
150
+ type (Optional[str]): task type. (default: :obj:`None`)
149
151
  parent (Optional[Task]): The parent task, None for root task.
150
- (default: :obj: `None`)
152
+ (default: :obj:`None`)
151
153
  subtasks (List[Task]): The childrent sub-tasks for the task.
152
- (default: :obj: `[]`)
154
+ (default: :obj:`[]`)
153
155
  result (Optional[str]): The answer for the task.
154
- (default: :obj: `""`)
156
+ (default: :obj:`""`)
155
157
  failure_count (int): The failure count for the task.
156
- (default: :obj: `0`)
158
+ (default: :obj:`0`)
157
159
  additional_info (Optional[Dict[str, Any]]): Additional information for
158
- the task. (default: :obj: `None`)
160
+ the task. (default: :obj:`None`)
159
161
  """
160
162
 
161
163
  content: str
162
164
 
163
- id: str = ""
165
+ id: str = Field(default_factory=lambda: str(uuid.uuid4()))
164
166
 
165
- state: TaskState = TaskState.OPEN
167
+ state: TaskState = (
168
+ TaskState.FAILED
169
+ ) # TODO: Add logic for OPEN in workforce.py
166
170
 
167
171
  type: Optional[str] = None
168
172
 
@@ -204,7 +208,9 @@ class Task(BaseModel):
204
208
 
205
209
  def reset(self):
206
210
  r"""Reset Task to initial state."""
207
- self.state = TaskState.OPEN
211
+ self.state = (
212
+ TaskState.FAILED
213
+ ) # TODO: Add logic for OPEN in workforce.py
208
214
  self.result = ""
209
215
 
210
216
  def update_result(self, result: str):
@@ -77,6 +77,7 @@ from .aci_toolkit import ACIToolkit
77
77
  from .playwright_mcp_toolkit import PlaywrightMCPToolkit
78
78
  from .wolfram_alpha_toolkit import WolframAlphaToolkit
79
79
  from .task_planning_toolkit import TaskPlanningToolkit
80
+ from .non_visual_browser_toolkit import BrowserNonVisualToolkit
80
81
 
81
82
 
82
83
  __all__ = [
@@ -142,4 +143,5 @@ __all__ = [
142
143
  'WolframAlphaToolkit',
143
144
  'BohriumToolkit',
144
145
  'TaskPlanningToolkit',
146
+ 'BrowserNonVisualToolkit',
145
147
  ]
@@ -48,14 +48,14 @@ class ACIToolkit(BaseToolkit):
48
48
 
49
49
  Args:
50
50
  api_key (Optional[str]): The API key for authentication.
51
- (default: :obj: `None`)
51
+ (default: :obj:`None`)
52
52
  base_url (Optional[str]): The base URL for the ACI API.
53
- (default: :obj: `None`)
53
+ (default: :obj:`None`)
54
54
  linked_account_owner_id (Optional[str]): ID of the owner of the
55
55
  linked account, e.g., "johndoe"
56
- (default: :obj: `None`)
56
+ (default: :obj:`None`)
57
57
  timeout (Optional[float]): Request timeout.
58
- (default: :obj: `None`)
58
+ (default: :obj:`None`)
59
59
  """
60
60
  from aci import ACI
61
61
 
@@ -80,20 +80,20 @@ class ACIToolkit(BaseToolkit):
80
80
  Args:
81
81
  intent (Optional[str]): Search results will be sorted by relevance
82
82
  to this intent.
83
- (default: :obj: `None`)
83
+ (default: :obj:`None`)
84
84
  allowed_app_only (bool): If true, only return apps that
85
85
  are allowed by the agent/accessor, identified by the api key.
86
- (default: :obj: `True`)
86
+ (default: :obj:`True`)
87
87
  include_functions (bool): If true, include functions
88
88
  (name and description) in the search results.
89
- (default: :obj: `False`)
89
+ (default: :obj:`False`)
90
90
  categories (Optional[List[str]]): List of categories to filter the
91
91
  search results. Defaults to an empty list.
92
- (default: :obj: `None`)
92
+ (default: :obj:`None`)
93
93
  limit (Optional[int]): Maximum number of results to return.
94
- (default: :obj: `10`)
94
+ (default: :obj:`10`)
95
95
  offset (Optional[int]): Offset for pagination.
96
- (default: :obj: `0`)
96
+ (default: :obj:`0`)
97
97
 
98
98
  Returns:
99
99
  Optional[List[AppBasic]]: List of matching apps if successful,
@@ -123,10 +123,10 @@ class ACIToolkit(BaseToolkit):
123
123
 
124
124
  Args:
125
125
  app_names (Optional[List[str]]): List of app names to filter the
126
- results. (default: :obj: `None`)
126
+ results. (default: :obj:`None`)
127
127
  limit (Optional[int]): Maximum number of results to return.
128
- (default: :obj: `10`)
129
- offset (Optional[int]): Offset for pagination. (default: :obj: `0`)
128
+ (default: :obj:`10`)
129
+ offset (Optional[int]): Offset for pagination. (default: :obj:`0`)
130
130
 
131
131
  Returns:
132
132
  Union[List[AppConfiguration], str]: List of configured apps if
@@ -356,15 +356,15 @@ class ACIToolkit(BaseToolkit):
356
356
 
357
357
  Args:
358
358
  app_names (Optional[List[str]]): List of app names to filter the
359
- search results. (default: :obj: `None`)
359
+ search results. (default: :obj:`None`)
360
360
  intent (Optional[str]): The search query/intent.
361
- (default: :obj: `None`)
361
+ (default: :obj:`None`)
362
362
  allowed_apps_only (bool): If true, only return
363
- functions from allowed apps. (default: :obj: `True`)
363
+ functions from allowed apps. (default: :obj:`True`)
364
364
  limit (Optional[int]): Maximum number of results to return.
365
- (default: :obj: `10`)
365
+ (default: :obj:`10`)
366
366
  offset (Optional[int]): Offset for pagination.
367
- (default: :obj: `0`)
367
+ (default: :obj:`0`)
368
368
 
369
369
  Returns:
370
370
  List[Dict]: List of matching functions
@@ -395,7 +395,7 @@ class ACIToolkit(BaseToolkit):
395
395
  owner id in the ACI dashboard (https://platform.aci.dev).
396
396
  allowed_apps_only (bool): If true, only returns functions/apps
397
397
  that are allowed to be used by the agent/accessor, identified
398
- by the api key. (default: :obj: `False`)
398
+ by the api key. (default: :obj:`False`)
399
399
 
400
400
  Returns:
401
401
  Dict: Result of the function execution
@@ -49,9 +49,9 @@ class ArxivToolkit(BaseToolkit):
49
49
  query (str): The search query string used to search for papers on
50
50
  arXiv.
51
51
  paper_ids (List[str], optional): A list of specific arXiv paper
52
- IDs to search for. (default: :obj: `None`)
52
+ IDs to search for. (default: :obj:`None`)
53
53
  max_results (int, optional): The maximum number of search results
54
- to retrieve. (default: :obj: `5`)
54
+ to retrieve. (default: :obj:`5`)
55
55
 
56
56
  Returns:
57
57
  Generator: A generator that yields results from the arXiv search
@@ -80,9 +80,9 @@ class ArxivToolkit(BaseToolkit):
80
80
  Args:
81
81
  query (str): The search query string.
82
82
  paper_ids (List[str], optional): A list of specific arXiv paper
83
- IDs to search for. (default: :obj: `None`)
83
+ IDs to search for. (default: :obj:`None`)
84
84
  max_results (int, optional): The maximum number of search results
85
- to return. (default: :obj: `5`)
85
+ to return. (default: :obj:`5`)
86
86
 
87
87
  Returns:
88
88
  List[Dict[str, str]]: A list of dictionaries, each containing
@@ -138,9 +138,9 @@ class ArxivToolkit(BaseToolkit):
138
138
  Args:
139
139
  query (str): The search query string.
140
140
  paper_ids (List[str], optional): A list of specific arXiv paper
141
- IDs to download. (default: :obj: `None`)
141
+ IDs to download. (default: :obj:`None`)
142
142
  max_results (int, optional): The maximum number of search results
143
- to download. (default: :obj: `5`)
143
+ to download. (default: :obj:`5`)
144
144
  output_dir (str, optional): The directory to save the downloaded
145
145
  PDFs. Defaults to the current directory.
146
146
 
@@ -126,22 +126,22 @@ class DappierToolkit(BaseToolkit):
126
126
  query (str): The user query for retrieving recommendations.
127
127
  data_model_id (str, optional): The data model ID to use for
128
128
  recommendations. Data model IDs always start with the prefix
129
- "dm_". (default: :obj: `dm_01j0pb465keqmatq9k83dthx34`)
129
+ "dm_". (default: :obj:`dm_01j0pb465keqmatq9k83dthx34`)
130
130
  similarity_top_k (int, optional): The number of top documents to
131
- retrieve based on similarity. (default: :obj: `9`)
131
+ retrieve based on similarity. (default: :obj:`9`)
132
132
  ref (Optional[str], optional): The site domain where AI
133
- recommendations should be displayed. (default: :obj: `None`)
133
+ recommendations should be displayed. (default: :obj:`None`)
134
134
  num_articles_ref (int, optional): The minimum number of articles
135
135
  to return from the specified reference domain (`ref`). The
136
136
  remaining articles will come from other sites in the RAG
137
- model. (default: :obj: `0`)
137
+ model. (default: :obj:`0`)
138
138
  search_algorithm (Literal[
139
139
  "most_recent",
140
140
  "semantic",
141
141
  "most_recent_semantic",
142
142
  "trending",
143
143
  ], optional): The search algorithm to use for retrieving
144
- articles. (default: :obj: `most_recent`)
144
+ articles. (default: :obj:`most_recent`)
145
145
 
146
146
  Returns:
147
147
  List[Dict[str, str]]: A list of recommended articles or content
@@ -50,11 +50,11 @@ class FileWriteToolkit(BaseToolkit):
50
50
  output_dir (str): The default directory for output files.
51
51
  Defaults to the current working directory.
52
52
  timeout (Optional[float]): The timeout for the toolkit.
53
- (default: :obj: `None`)
53
+ (default: :obj:`None`)
54
54
  default_encoding (str): Default character encoding for text
55
- operations. (default: :obj: `utf-8`)
55
+ operations. (default: :obj:`utf-8`)
56
56
  backup_enabled (bool): Whether to create backups of existing files
57
- before overwriting. (default: :obj: `True`)
57
+ before overwriting. (default: :obj:`True`)
58
58
  """
59
59
  super().__init__(timeout=timeout)
60
60
  self.output_dir = Path(output_dir).resolve()
@@ -96,7 +96,7 @@ class FileWriteToolkit(BaseToolkit):
96
96
  Args:
97
97
  file_path (Path): The target file path.
98
98
  content (str): The text content to write.
99
- encoding (str): Character encoding to use. (default: :obj: `utf-8`)
99
+ encoding (str): Character encoding to use. (default: :obj:`utf-8`)
100
100
  """
101
101
  with file_path.open("w", encoding=encoding) as f:
102
102
  f.write(content)
@@ -157,7 +157,7 @@ class FileWriteToolkit(BaseToolkit):
157
157
  content (str): The text content to write.
158
158
  use_latex (bool): Whether to use LaTeX for rendering. (requires
159
159
  LaTeX toolchain). If False, uses FPDF for simpler PDF
160
- generation. (default: :obj: `False`)
160
+ generation. (default: :obj:`False`)
161
161
 
162
162
  Raises:
163
163
  RuntimeError: If the 'pylatex' or 'fpdf' library is not installed
@@ -236,7 +236,7 @@ class FileWriteToolkit(BaseToolkit):
236
236
  file_path (Path): The target file path.
237
237
  content (Union[str, List[List]]): The CSV content as a string or
238
238
  list of lists.
239
- encoding (str): Character encoding to use. (default: :obj: `utf-8`)
239
+ encoding (str): Character encoding to use. (default: :obj:`utf-8`)
240
240
  """
241
241
  import csv
242
242
 
@@ -259,7 +259,7 @@ class FileWriteToolkit(BaseToolkit):
259
259
  Args:
260
260
  file_path (Path): The target file path.
261
261
  content (str): The JSON content as a string.
262
- encoding (str): Character encoding to use. (default: :obj: `utf-8`)
262
+ encoding (str): Character encoding to use. (default: :obj:`utf-8`)
263
263
  """
264
264
  import json
265
265
 
@@ -288,7 +288,7 @@ class FileWriteToolkit(BaseToolkit):
288
288
  Args:
289
289
  file_path (Path): The target file path.
290
290
  content (str): The YAML content as a string.
291
- encoding (str): Character encoding to use. (default: :obj: `utf-8`)
291
+ encoding (str): Character encoding to use. (default: :obj:`utf-8`)
292
292
  """
293
293
  with file_path.open("w", encoding=encoding) as f:
294
294
  f.write(content)
@@ -302,7 +302,7 @@ class FileWriteToolkit(BaseToolkit):
302
302
  Args:
303
303
  file_path (Path): The target file path.
304
304
  content (str): The HTML content to write.
305
- encoding (str): Character encoding to use. (default: :obj: `utf-8`)
305
+ encoding (str): Character encoding to use. (default: :obj:`utf-8`)
306
306
  """
307
307
  with file_path.open("w", encoding=encoding) as f:
308
308
  f.write(content)
@@ -316,7 +316,7 @@ class FileWriteToolkit(BaseToolkit):
316
316
  Args:
317
317
  file_path (Path): The target file path.
318
318
  content (str): The Markdown content to write.
319
- encoding (str): Character encoding to use. (default: :obj: `utf-8`)
319
+ encoding (str): Character encoding to use. (default: :obj:`utf-8`)
320
320
  """
321
321
  with file_path.open("w", encoding=encoding) as f:
322
322
  f.write(content)
@@ -158,7 +158,7 @@ class GithubToolkit(BaseToolkit):
158
158
  Args:
159
159
  repo_name (str): The name of the GitHub repository.
160
160
  state (Literal["open", "closed", "all"]): The state of pull
161
- requests to retrieve. (default: :obj: `all`)
161
+ requests to retrieve. (default: :obj:`all`)
162
162
  Options are:
163
163
  - "open": Retrieve only open pull requests.
164
164
  - "closed": Retrieve only closed pull requests.
@@ -202,7 +202,7 @@ class GithubToolkit(BaseToolkit):
202
202
  Args:
203
203
  repo_name (str): The name of the GitHub repository.
204
204
  state (Literal["open", "closed", "all"]): The state of pull
205
- requests to retrieve. (default: :obj: `all`)
205
+ requests to retrieve. (default: :obj:`all`)
206
206
  Options are:
207
207
  - "open": Retrieve only open pull requests.
208
208
  - "closed": Retrieve only closed pull requests.
@@ -285,7 +285,7 @@ class GithubToolkit(BaseToolkit):
285
285
  repo_name (str): The name of the GitHub repository.
286
286
  path (str): The repository path to start the traversal from.
287
287
  empty string means starts from the root directory.
288
- (default: :obj: `""`)
288
+ (default: :obj:`""`)
289
289
 
290
290
  Returns:
291
291
  List[str]: A list of file paths within the specified directory
@@ -0,0 +1,18 @@
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 .browser_non_visual_toolkit import BrowserNonVisualToolkit
15
+
16
+ __all__ = [
17
+ "BrowserNonVisualToolkit",
18
+ ]