camel-ai 0.2.14__py3-none-any.whl → 0.2.15__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 (68) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +362 -237
  3. camel/benchmarks/__init__.py +11 -1
  4. camel/benchmarks/apibank.py +560 -0
  5. camel/benchmarks/apibench.py +496 -0
  6. camel/benchmarks/gaia.py +2 -2
  7. camel/benchmarks/nexus.py +518 -0
  8. camel/datagen/__init__.py +21 -0
  9. camel/datagen/cotdatagen.py +448 -0
  10. camel/datagen/self_instruct/__init__.py +36 -0
  11. camel/datagen/self_instruct/filter/__init__.py +34 -0
  12. camel/datagen/self_instruct/filter/filter_function.py +208 -0
  13. camel/datagen/self_instruct/filter/filter_registry.py +56 -0
  14. camel/datagen/self_instruct/filter/instruction_filter.py +76 -0
  15. camel/datagen/self_instruct/self_instruct.py +393 -0
  16. camel/datagen/self_instruct/templates.py +384 -0
  17. camel/datahubs/huggingface.py +12 -2
  18. camel/datahubs/models.py +4 -2
  19. camel/embeddings/mistral_embedding.py +5 -1
  20. camel/embeddings/openai_compatible_embedding.py +6 -1
  21. camel/embeddings/openai_embedding.py +5 -1
  22. camel/interpreters/e2b_interpreter.py +5 -1
  23. camel/loaders/apify_reader.py +5 -1
  24. camel/loaders/chunkr_reader.py +5 -1
  25. camel/loaders/firecrawl_reader.py +0 -30
  26. camel/logger.py +11 -5
  27. camel/messages/conversion/sharegpt/hermes/hermes_function_formatter.py +4 -1
  28. camel/models/anthropic_model.py +5 -1
  29. camel/models/azure_openai_model.py +1 -2
  30. camel/models/cohere_model.py +5 -1
  31. camel/models/deepseek_model.py +5 -1
  32. camel/models/gemini_model.py +5 -1
  33. camel/models/groq_model.py +5 -1
  34. camel/models/mistral_model.py +5 -1
  35. camel/models/nemotron_model.py +5 -1
  36. camel/models/nvidia_model.py +5 -1
  37. camel/models/openai_model.py +5 -1
  38. camel/models/qwen_model.py +5 -1
  39. camel/models/reka_model.py +5 -1
  40. camel/models/reward/nemotron_model.py +5 -1
  41. camel/models/samba_model.py +5 -1
  42. camel/models/togetherai_model.py +5 -1
  43. camel/models/yi_model.py +5 -1
  44. camel/models/zhipuai_model.py +5 -1
  45. camel/retrievers/auto_retriever.py +8 -0
  46. camel/retrievers/vector_retriever.py +6 -3
  47. camel/schemas/openai_converter.py +5 -1
  48. camel/societies/role_playing.py +4 -4
  49. camel/societies/workforce/workforce.py +2 -2
  50. camel/storages/graph_storages/nebula_graph.py +119 -27
  51. camel/storages/graph_storages/neo4j_graph.py +138 -0
  52. camel/toolkits/__init__.py +2 -0
  53. camel/toolkits/arxiv_toolkit.py +20 -3
  54. camel/toolkits/function_tool.py +61 -61
  55. camel/toolkits/meshy_toolkit.py +5 -1
  56. camel/toolkits/notion_toolkit.py +1 -1
  57. camel/toolkits/openbb_toolkit.py +869 -0
  58. camel/toolkits/search_toolkit.py +91 -5
  59. camel/toolkits/stripe_toolkit.py +5 -1
  60. camel/toolkits/twitter_toolkit.py +24 -16
  61. camel/types/enums.py +7 -1
  62. camel/types/unified_model_type.py +5 -0
  63. camel/utils/__init__.py +4 -0
  64. camel/utils/commons.py +142 -20
  65. {camel_ai-0.2.14.dist-info → camel_ai-0.2.15.dist-info}/METADATA +16 -5
  66. {camel_ai-0.2.14.dist-info → camel_ai-0.2.15.dist-info}/RECORD +68 -55
  67. {camel_ai-0.2.14.dist-info → camel_ai-0.2.15.dist-info}/LICENSE +0 -0
  68. {camel_ai-0.2.14.dist-info → camel_ai-0.2.15.dist-info}/WHEEL +0 -0
@@ -583,3 +583,141 @@ class Neo4jGraph(BaseGraphStorage):
583
583
  ]
584
584
  },
585
585
  )
586
+
587
+ def random_walk_with_restarts(
588
+ self,
589
+ graph_name: str,
590
+ sampling_ratio: float,
591
+ start_node_ids: List[int],
592
+ restart_probability: float = 0.1,
593
+ node_label_stratification: bool = False,
594
+ relationship_weight_property: Optional[str] = None,
595
+ ) -> Dict[str, Any]:
596
+ r"""Runs the Random Walk with Restarts (RWR) sampling algorithm.
597
+
598
+ Args:
599
+ graph_name (str): The name of the original graph in the graph
600
+ catalog.
601
+ sampling_ratio (float): The fraction of nodes in the original
602
+ graph to be sampled.
603
+ start_node_ids (List[int]): IDs of the initial set of nodes of the
604
+ original graph from which the sampling random walks will start.
605
+ restart_probability (float, optional): The probability that a
606
+ sampling random walk restarts from one of the start nodes.
607
+ Defaults to `0.1`.
608
+ node_label_stratification (bool, optional): If true, preserves the
609
+ node label distribution of the original graph. Defaults to
610
+ `False`.
611
+ relationship_weight_property (Optional[str], optional): Name of
612
+ the relationship property to use as weights. If unspecified,
613
+ the algorithm runs unweighted. Defaults to `None`.
614
+
615
+ Returns:
616
+ Dict[str, Any]: A dictionary with the results of the RWR sampling.
617
+ """
618
+ from neo4j.exceptions import ClientError, CypherSyntaxError
619
+
620
+ try:
621
+ self.query(query="CALL gds.version() YIELD version RETURN version")
622
+ except ClientError:
623
+ raise ValueError(
624
+ "Graph Data Science (GDS) library is not installed or not"
625
+ " available. Reference: https://neo4j.com/docs/graph-data-science/current/installation/"
626
+ )
627
+
628
+ query = """
629
+ CALL gds.graph.sample.rwr($graphName, $fromGraphName, {
630
+ samplingRatio: $samplingRatio,
631
+ startNodes: $startNodes,
632
+ restartProbability: $restartProbability,
633
+ nodeLabelStratification: $nodeLabelStratification,
634
+ relationshipWeightProperty: $relationshipWeightProperty
635
+ })
636
+ YIELD graphName, fromGraphName, nodeCount,
637
+ relationshipCount, startNodeCount, projectMillis
638
+ RETURN graphName, fromGraphName, nodeCount,
639
+ relationshipCount, startNodeCount, projectMillis
640
+ """
641
+
642
+ params = {
643
+ "graphName": f"{graph_name}_sampled",
644
+ "fromGraphName": graph_name,
645
+ "samplingRatio": sampling_ratio,
646
+ "startNodes": start_node_ids,
647
+ "restartProbability": restart_probability,
648
+ "nodeLabelStratification": node_label_stratification,
649
+ "relationshipWeightProperty": relationship_weight_property,
650
+ }
651
+
652
+ try:
653
+ result = self.query(query, params)
654
+ return result[0] if result else {}
655
+ except CypherSyntaxError as e:
656
+ raise ValueError(f"Generated Cypher Statement is not valid\n{e}")
657
+
658
+ def common_neighbour_aware_random_walk(
659
+ self,
660
+ graph_name: str,
661
+ sampling_ratio: float,
662
+ start_node_ids: List[int],
663
+ node_label_stratification: bool = False,
664
+ relationship_weight_property: Optional[str] = None,
665
+ ) -> Dict[str, Any]:
666
+ r"""Runs the Common Neighbour Aware Random Walk (CNARW) sampling
667
+ algorithm.
668
+
669
+ Args:
670
+ graph_name (str): The name of the original graph in the graph
671
+ catalog.
672
+ sampling_ratio (float): The fraction of nodes in the original
673
+ graph to be sampled.
674
+ start_node_ids (List[int]): IDs of the initial set of nodes of the
675
+ original graph from which the sampling random walks will start.
676
+ node_label_stratification (bool, optional): If true, preserves the
677
+ node label distribution of the original graph. Defaults to
678
+ `False`.
679
+ relationship_weight_property (Optional[str], optional): Name of
680
+ the relationship property to use as weights. If unspecified,
681
+ the algorithm runs unweighted. Defaults to `None`.
682
+
683
+ Returns:
684
+ Dict[str, Any]: A dictionary with the results of the CNARW
685
+ sampling.
686
+ """
687
+ from neo4j.exceptions import ClientError, CypherSyntaxError
688
+
689
+ try:
690
+ self.query(query="CALL gds.version() YIELD version RETURN version")
691
+ except ClientError:
692
+ raise ValueError(
693
+ "Graph Data Science (GDS) library is not installed or not"
694
+ " available. Reference: https://neo4j.com/docs/graph-data-science/current/installation/"
695
+ )
696
+
697
+ query = """
698
+ CALL gds.graph.sample.cnarw($graphName, $fromGraphName, {
699
+ samplingRatio: $samplingRatio,
700
+ startNodes: $startNodes,
701
+ nodeLabelStratification: $nodeLabelStratification,
702
+ relationshipWeightProperty: $relationshipWeightProperty
703
+ })
704
+ YIELD graphName, fromGraphName, nodeCount,
705
+ relationshipCount, startNodeCount, projectMillis
706
+ RETURN graphName, fromGraphName, nodeCount,
707
+ relationshipCount, startNodeCount, projectMillis
708
+ """
709
+
710
+ params = {
711
+ "graphName": f"{graph_name}_sampled_cnarw",
712
+ "fromGraphName": graph_name,
713
+ "samplingRatio": sampling_ratio,
714
+ "startNodes": start_node_ids,
715
+ "nodeLabelStratification": node_label_stratification,
716
+ "relationshipWeightProperty": relationship_weight_property,
717
+ }
718
+
719
+ try:
720
+ result = self.query(query, params)
721
+ return result[0] if result else {}
722
+ except CypherSyntaxError as e:
723
+ raise ValueError(f"Generated Cypher Statement is not valid\n{e}")
@@ -28,6 +28,7 @@ from .ask_news_toolkit import AskNewsToolkit, AsyncAskNewsToolkit
28
28
  from .linkedin_toolkit import LinkedInToolkit
29
29
  from .reddit_toolkit import RedditToolkit
30
30
  from .meshy_toolkit import MeshyToolkit
31
+ from .openbb_toolkit import OpenBBToolkit
31
32
 
32
33
  from .base import BaseToolkit
33
34
  from .google_maps_toolkit import GoogleMapsToolkit
@@ -73,4 +74,5 @@ __all__ = [
73
74
  'VideoDownloaderToolkit',
74
75
  'StripeToolkit',
75
76
  'MeshyToolkit',
77
+ 'OpenBBToolkit',
76
78
  ]
@@ -14,10 +14,13 @@
14
14
 
15
15
  from typing import Dict, Generator, List, Optional
16
16
 
17
+ from camel.logger import get_logger
17
18
  from camel.toolkits.base import BaseToolkit
18
19
  from camel.toolkits.function_tool import FunctionTool
19
20
  from camel.utils import dependencies_required
20
21
 
22
+ logger = get_logger(__name__)
23
+
21
24
 
22
25
  class ArxivToolkit(BaseToolkit):
23
26
  r"""A toolkit for interacting with the arXiv API to search and download
@@ -98,10 +101,24 @@ class ArxivToolkit(BaseToolkit):
98
101
  "authors": [author.name for author in paper.authors],
99
102
  "entry_id": paper.entry_id,
100
103
  "summary": paper.summary,
101
- # TODO: Use chunkr instead of atxiv_to_text for better
102
- # performance
103
- "paper_text": arxiv_to_text(paper.pdf_url),
104
+ "pdf_url": paper.pdf_url,
104
105
  }
106
+
107
+ # Extract text from the paper
108
+ try:
109
+ # TODO: Use chunkr instead of atxiv_to_text for better
110
+ # performance and reliability
111
+ text = arxiv_to_text(paper_info["pdf_url"])
112
+ except Exception as e:
113
+ logger.error(
114
+ "Failed to extract text content from the PDF at "
115
+ "the specified URL. "
116
+ f"URL: {paper_info.get('pdf_url', 'Unknown')} | Error: {e}"
117
+ )
118
+ text = ""
119
+
120
+ paper_info['paper_text'] = text
121
+
105
122
  papers_data.append(paper_info)
106
123
 
107
124
  return papers_data
@@ -14,6 +14,7 @@
14
14
  import ast
15
15
  import inspect
16
16
  import logging
17
+ import textwrap
17
18
  import warnings
18
19
  from inspect import Parameter, getsource, signature
19
20
  from typing import Any, Callable, Dict, Mapping, Optional, Tuple, Type
@@ -24,7 +25,6 @@ from jsonschema.validators import Draft202012Validator as JSONValidator
24
25
  from pydantic import BaseModel, create_model
25
26
  from pydantic.fields import FieldInfo
26
27
 
27
- from camel.agents import ChatAgent
28
28
  from camel.models import BaseModelBackend, ModelFactory
29
29
  from camel.types import ModelPlatformType, ModelType
30
30
  from camel.utils import get_pydantic_object_schema, to_pascal
@@ -237,41 +237,43 @@ def generate_docstring(
237
237
  Returns:
238
238
  str: The generated docstring.
239
239
  """
240
- # Create the docstring prompt
241
- docstring_prompt = '''
242
- **Role**: Generate professional Python docstrings conforming to
243
- PEP 8/PEP 257.
244
240
 
245
- **Requirements**:
246
- - Use appropriate format: reST, Google, or NumPy, as needed.
247
- - Include parameters, return values, and exceptions.
248
- - Reference any existing docstring in the function and
249
- retain useful information.
241
+ from camel.agents import ChatAgent
250
242
 
251
- **Input**: Python function.
243
+ # Create the docstring prompt
244
+ docstring_prompt = textwrap.dedent(
245
+ """\
246
+ **Role**: Generate professional Python docstrings conforming to PEP 8/PEP 257.
252
247
 
253
- **Output**: Docstring content (plain text, no code markers).
248
+ **Requirements**:
249
+ - Use appropriate format: reST, Google, or NumPy, as needed.
250
+ - Include parameters, return values, and exceptions.
251
+ - Reference any existing docstring in the function and retain useful information.
254
252
 
255
- **Example:**
253
+ **Input**: Python function.
256
254
 
257
- Input:
258
- ```python
259
- def add(a: int, b: int) -> int:
260
- return a + b
261
- ```
255
+ **Output**: Docstring content (plain text, no code markers).
262
256
 
263
- Output:
264
- Adds two numbers.
265
- Args:
266
- a (int): The first number.
267
- b (int): The second number.
257
+ **Example:**
268
258
 
269
- Returns:
270
- int: The sum of the two numbers.
259
+ Input:
260
+ ```python
261
+ def add(a: int, b: int) -> int:
262
+ return a + b
263
+ ```
271
264
 
272
- **Task**: Generate a docstring for the function below.
265
+ Output:
266
+ Adds two numbers.
267
+ Args:
268
+ a (int): The first number.
269
+ b (int): The second number.
270
+
271
+ Returns:
272
+ int: The sum of the two numbers.
273
273
 
274
- '''
274
+ **Task**: Generate a docstring for the function below.
275
+ """ # noqa: E501
276
+ )
275
277
  # Initialize assistant with system message and model
276
278
  assistant_sys_msg = "You are a helpful assistant."
277
279
  docstring_assistant = ChatAgent(assistant_sys_msg, model=model)
@@ -665,7 +667,7 @@ class FunctionTool:
665
667
  Any: Synthesized output from the function execution. If no
666
668
  synthesis model is provided, a warning is logged.
667
669
  """
668
- import textwrap
670
+ from camel.agents import ChatAgent
669
671
 
670
672
  # Retrieve the function source code
671
673
  function_string = inspect.getsource(self.func)
@@ -694,39 +696,37 @@ class FunctionTool:
694
696
  function_string += f"\nkwargs:\n{kwargs}"
695
697
 
696
698
  # Define the assistant system message
697
- assistant_sys_msg = '''
698
- **Role:** AI Assistant specialized in synthesizing tool execution outputs
699
- without actual execution.
700
-
701
- **Capabilities:**
702
- - Analyzes function to understand their
703
- purpose and expected outputs.
704
- - Generates synthetic outputs based on the function logic.
705
- - Ensures the synthesized output is contextually accurate and aligns with the
706
- function's intended behavior.
707
-
708
- **Instructions:**
709
- 1. **Input:** Provide the function code, function docstring, args, and kwargs.
710
- 2. **Output:** Synthesize the expected output of the function based on the
711
- provided args and kwargs.
712
-
713
- **Example:**
714
- - **User Input:**
715
- def sum(a, b, c=0):
716
- """Adds three numbers together."""
717
- return a + b + c
718
-
719
- - **Input Arguments:**
720
- args: (1, 2)
721
- kwargs: {"c": 3}
722
-
723
- - **Output:**
724
- 6
725
-
726
- **Note:**
727
- - Just return the synthesized output of the function without any explanation.
728
- - The output should be in plain text without any formatting.
729
- '''
699
+ assistant_sys_msg = textwrap.dedent(
700
+ '''\
701
+ **Role:** AI Assistant specialized in synthesizing tool execution outputs without actual execution.
702
+
703
+ **Capabilities:**
704
+ - Analyzes function to understand their purpose and expected outputs.
705
+ - Generates synthetic outputs based on the function logic.
706
+ - Ensures the synthesized output is contextually accurate and aligns with the function's intended behavior.
707
+
708
+ **Instructions:**
709
+ 1. **Input:** Provide the function code, function docstring, args, and kwargs.
710
+ 2. **Output:** Synthesize the expected output of the function based on the provided args and kwargs.
711
+
712
+ **Example:**
713
+ - **User Input:**
714
+ def sum(a, b, c=0):
715
+ """Adds three numbers together."""
716
+ return a + b + c
717
+
718
+ - **Input Arguments:**
719
+ args: (1, 2)
720
+ kwargs: {"c": 3}
721
+
722
+ - **Output:**
723
+ 6
724
+
725
+ **Note:**
726
+ - Just return the synthesized output of the function without any explanation.
727
+ - The output should be in plain text without any formatting.
728
+ ''' # noqa: E501
729
+ )
730
730
 
731
731
  # Initialize the synthesis agent
732
732
  synthesis_agent = ChatAgent(
@@ -33,7 +33,11 @@ class MeshyToolkit(BaseToolkit):
33
33
  https://docs.meshy.ai/api-text-to-3d-beta#create-a-text-to-3d-preview-task
34
34
  """
35
35
 
36
- @api_keys_required("MESHY_API_KEY")
36
+ @api_keys_required(
37
+ [
38
+ (None, 'MESHY_API_KEY'),
39
+ ]
40
+ )
37
41
  def __init__(self):
38
42
  r"""Initializes the MeshyToolkit with the API key from the
39
43
  environment.
@@ -71,7 +71,7 @@ class NotionToolkit(BaseToolkit):
71
71
 
72
72
  Attributes:
73
73
  notion_token (Optional[str], optional): The notion_token used to
74
- interact with notion APIs.(default: :obj:`None`)
74
+ interact with notion APIs. (default: :obj:`None`)
75
75
  notion_client (module): The notion module for interacting with
76
76
  the notion APIs.
77
77
  """