camel-ai 0.2.15a0__py3-none-any.whl → 0.2.17__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 (95) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +18 -4
  3. camel/agents/multi_hop_generator_agent.py +85 -0
  4. camel/agents/programmed_agent_instruction.py +148 -0
  5. camel/benchmarks/__init__.py +13 -1
  6. camel/benchmarks/apibank.py +565 -0
  7. camel/benchmarks/apibench.py +500 -0
  8. camel/benchmarks/gaia.py +4 -4
  9. camel/benchmarks/nexus.py +518 -0
  10. camel/benchmarks/ragbench.py +333 -0
  11. camel/bots/__init__.py +1 -1
  12. camel/bots/discord/__init__.py +26 -0
  13. camel/bots/discord/discord_app.py +384 -0
  14. camel/bots/discord/discord_installation.py +64 -0
  15. camel/bots/discord/discord_store.py +160 -0
  16. camel/configs/__init__.py +3 -0
  17. camel/configs/anthropic_config.py +17 -15
  18. camel/configs/internlm_config.py +60 -0
  19. camel/data_collector/base.py +5 -5
  20. camel/data_collector/sharegpt_collector.py +2 -2
  21. camel/datagen/__init__.py +6 -2
  22. camel/datagen/{o1datagen.py → cotdatagen.py} +19 -6
  23. camel/datagen/self_instruct/__init__.py +36 -0
  24. camel/datagen/self_instruct/filter/__init__.py +34 -0
  25. camel/datagen/self_instruct/filter/filter_function.py +216 -0
  26. camel/datagen/self_instruct/filter/filter_registry.py +56 -0
  27. camel/datagen/self_instruct/filter/instruction_filter.py +81 -0
  28. camel/datagen/self_instruct/self_instruct.py +393 -0
  29. camel/datagen/self_instruct/templates.py +382 -0
  30. camel/datahubs/huggingface.py +12 -2
  31. camel/datahubs/models.py +2 -3
  32. camel/embeddings/mistral_embedding.py +5 -1
  33. camel/embeddings/openai_compatible_embedding.py +6 -1
  34. camel/embeddings/openai_embedding.py +5 -1
  35. camel/interpreters/e2b_interpreter.py +5 -1
  36. camel/loaders/__init__.py +2 -0
  37. camel/loaders/apify_reader.py +5 -1
  38. camel/loaders/chunkr_reader.py +5 -1
  39. camel/loaders/firecrawl_reader.py +0 -30
  40. camel/loaders/panda_reader.py +337 -0
  41. camel/logger.py +11 -5
  42. camel/messages/__init__.py +10 -4
  43. camel/messages/conversion/conversation_models.py +5 -0
  44. camel/messages/func_message.py +30 -22
  45. camel/models/__init__.py +2 -0
  46. camel/models/anthropic_model.py +6 -23
  47. camel/models/azure_openai_model.py +1 -2
  48. camel/models/cohere_model.py +13 -1
  49. camel/models/deepseek_model.py +5 -1
  50. camel/models/gemini_model.py +15 -2
  51. camel/models/groq_model.py +5 -1
  52. camel/models/internlm_model.py +143 -0
  53. camel/models/mistral_model.py +19 -8
  54. camel/models/model_factory.py +3 -0
  55. camel/models/nemotron_model.py +5 -1
  56. camel/models/nvidia_model.py +5 -1
  57. camel/models/openai_model.py +5 -1
  58. camel/models/qwen_model.py +5 -1
  59. camel/models/reka_model.py +5 -1
  60. camel/models/reward/__init__.py +2 -0
  61. camel/models/reward/nemotron_model.py +5 -1
  62. camel/models/reward/skywork_model.py +88 -0
  63. camel/models/samba_model.py +5 -1
  64. camel/models/togetherai_model.py +5 -1
  65. camel/models/yi_model.py +5 -1
  66. camel/models/zhipuai_model.py +5 -1
  67. camel/schemas/openai_converter.py +5 -1
  68. camel/storages/graph_storages/nebula_graph.py +89 -20
  69. camel/storages/graph_storages/neo4j_graph.py +138 -0
  70. camel/synthetic_datagen/source2synth/data_processor.py +373 -0
  71. camel/synthetic_datagen/source2synth/models.py +68 -0
  72. camel/synthetic_datagen/source2synth/user_data_processor_config.py +73 -0
  73. camel/toolkits/__init__.py +4 -0
  74. camel/toolkits/arxiv_toolkit.py +20 -3
  75. camel/toolkits/dappier_toolkit.py +196 -0
  76. camel/toolkits/function_tool.py +61 -61
  77. camel/toolkits/google_scholar_toolkit.py +9 -0
  78. camel/toolkits/meshy_toolkit.py +5 -1
  79. camel/toolkits/notion_toolkit.py +1 -1
  80. camel/toolkits/openbb_toolkit.py +869 -0
  81. camel/toolkits/search_toolkit.py +91 -5
  82. camel/toolkits/stripe_toolkit.py +5 -1
  83. camel/toolkits/twitter_toolkit.py +24 -16
  84. camel/types/__init__.py +4 -2
  85. camel/types/enums.py +34 -1
  86. camel/types/openai_types.py +6 -4
  87. camel/types/unified_model_type.py +5 -0
  88. camel/utils/__init__.py +2 -0
  89. camel/utils/commons.py +104 -19
  90. camel/utils/token_counting.py +3 -3
  91. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.17.dist-info}/METADATA +160 -177
  92. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.17.dist-info}/RECORD +94 -69
  93. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.17.dist-info}/WHEEL +1 -1
  94. camel/bots/discord_app.py +0 -138
  95. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.17.dist-info}/LICENSE +0 -0
@@ -15,7 +15,7 @@
15
15
  import logging
16
16
  import re
17
17
  import time
18
- from typing import TYPE_CHECKING, Any, Dict, List, Tuple
18
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
19
19
 
20
20
  from camel.storages.graph_storages.base import BaseGraphStorage
21
21
  from camel.storages.graph_storages.graph_element import (
@@ -203,46 +203,62 @@ class NebulaGraph(BaseGraphStorage):
203
203
  def ensure_edge_type_exists(
204
204
  self,
205
205
  edge_type: str,
206
+ time_label: Optional[str] = None,
206
207
  ) -> None:
207
208
  r"""Ensures that a specified edge type exists in the NebulaGraph
208
209
  database. If the edge type already exists, this method does nothing.
209
210
 
210
211
  Args:
211
212
  edge_type (str): The name of the edge type to be created.
213
+ time_label (str, optional): A specific timestamp to set as the
214
+ default value for the time label property. If not
215
+ provided, no timestamp will be added. (default: :obj:`None`)
212
216
 
213
217
  Raises:
214
218
  Exception: If the edge type creation fails after multiple retry
215
219
  attempts, an exception is raised with the error message.
216
220
  """
217
- create_edge_stmt = f'CREATE EDGE IF NOT EXISTS {edge_type}()'
221
+ create_edge_stmt = f"CREATE EDGE IF NOT EXISTS {edge_type} ()"
222
+ if time_label is not None:
223
+ time_label = self._validate_time_label(time_label)
224
+ create_edge_stmt = f"""CREATE EDGE IF NOT EXISTS {edge_type}
225
+ (time_label DATETIME DEFAULT {time_label})"""
218
226
 
219
227
  for attempt in range(MAX_RETRIES):
220
228
  res = self.query(create_edge_stmt)
221
229
  if res.is_succeeded():
222
- return # Tag creation succeeded, exit the method
230
+ return # Edge type creation succeeded
223
231
 
224
232
  if attempt < MAX_RETRIES - 1:
225
233
  time.sleep(RETRY_DELAY)
226
234
  else:
227
235
  # Final attempt failed, raise an exception
228
236
  raise Exception(
229
- f"Failed to create tag `{edge_type}` after "
237
+ f"Failed to create edge type `{edge_type}` after "
230
238
  f"{MAX_RETRIES} attempts: {res.error_msg()}"
231
239
  )
232
240
 
233
- def ensure_tag_exists(self, tag_name: str) -> None:
241
+ def ensure_tag_exists(
242
+ self, tag_name: str, time_label: Optional[str] = None
243
+ ) -> None:
234
244
  r"""Ensures a tag is created in the NebulaGraph database. If the tag
235
245
  already exists, it does nothing.
236
246
 
237
247
  Args:
238
248
  tag_name (str): The name of the tag to be created.
249
+ time_label (str, optional): A specific timestamp to set as the
250
+ default value for the time label property. If not provided,
251
+ no timestamp will be added. (default: :obj:`None`)
239
252
 
240
253
  Raises:
241
254
  Exception: If the tag creation fails after retries, an exception
242
255
  is raised with the error message.
243
256
  """
244
-
245
- create_tag_stmt = f'CREATE TAG IF NOT EXISTS {tag_name}()'
257
+ create_tag_stmt = f"CREATE TAG IF NOT EXISTS {tag_name} ()"
258
+ if time_label is not None:
259
+ time_label = self._validate_time_label(time_label)
260
+ create_tag_stmt = f"""CREATE TAG IF NOT EXISTS {tag_name}
261
+ (time_label DATETIME DEFAULT {time_label})"""
246
262
 
247
263
  for attempt in range(MAX_RETRIES):
248
264
  res = self.query(create_tag_stmt)
@@ -262,27 +278,39 @@ class NebulaGraph(BaseGraphStorage):
262
278
  self,
263
279
  node_id: str,
264
280
  tag_name: str,
281
+ time_label: Optional[str] = None,
265
282
  ) -> None:
266
283
  r"""Add a node with the specified tag and properties.
267
284
 
268
285
  Args:
269
286
  node_id (str): The ID of the node.
270
287
  tag_name (str): The tag name of the node.
288
+ time_label (str, optional): A specific timestamp to set for
289
+ the node's time label property. If not provided, no timestamp
290
+ will be added. (default: :obj:`None`)
271
291
  """
272
292
  node_id = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '', node_id)
273
293
  tag_name = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '', tag_name)
274
294
 
275
- self.ensure_tag_exists(tag_name)
295
+ self.ensure_tag_exists(tag_name, time_label)
276
296
 
277
- # Insert node without properties
278
- insert_stmt = (
279
- f'INSERT VERTEX IF NOT EXISTS {tag_name}() VALUES "{node_id}":()'
280
- )
297
+ # Insert node with or without time_label property
298
+ if time_label is not None:
299
+ time_label = self._validate_time_label(time_label)
300
+ insert_stmt = (
301
+ f'INSERT VERTEX IF NOT EXISTS {tag_name}(time_label) VALUES '
302
+ f'"{node_id}":("{time_label}")'
303
+ )
304
+ else:
305
+ insert_stmt = (
306
+ f'INSERT VERTEX IF NOT EXISTS {tag_name}() VALUES '
307
+ f'"{node_id}":()'
308
+ )
281
309
 
282
310
  for attempt in range(MAX_RETRIES):
283
311
  res = self.query(insert_stmt)
284
312
  if res.is_succeeded():
285
- return # Tag creation succeeded, exit the method
313
+ return # Node creation succeeded, exit the method
286
314
 
287
315
  if attempt < MAX_RETRIES - 1:
288
316
  time.sleep(RETRY_DELAY)
@@ -348,7 +376,7 @@ class NebulaGraph(BaseGraphStorage):
348
376
  @property
349
377
  def get_structured_schema(self) -> Dict[str, Any]:
350
378
  r"""Generates a structured schema consisting of node and relationship
351
- properties, relationships, and metadata.
379
+ properties, relationships, and metadata, including timestamps.
352
380
 
353
381
  Returns:
354
382
  Dict[str, Any]: A dictionary representing the structured schema.
@@ -419,6 +447,7 @@ class NebulaGraph(BaseGraphStorage):
419
447
  subj: str,
420
448
  obj: str,
421
449
  rel: str,
450
+ time_label: Optional[str] = None,
422
451
  ) -> None:
423
452
  r"""Adds a relationship (triplet) between two entities in the Nebula
424
453
  Graph database.
@@ -427,6 +456,13 @@ class NebulaGraph(BaseGraphStorage):
427
456
  subj (str): The identifier for the subject entity.
428
457
  obj (str): The identifier for the object entity.
429
458
  rel (str): The relationship between the subject and object.
459
+ time_label (str, optional): A specific timestamp to set for the
460
+ time label property of the relationship. If not provided,
461
+ no timestamp will be added. (default: :obj:`None`)
462
+
463
+ Raises:
464
+ ValueError: If the time_label format is invalid.
465
+ Exception: If creating the relationship fails.
430
466
  """
431
467
  subj = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '', subj)
432
468
  obj = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '', obj)
@@ -434,21 +470,30 @@ class NebulaGraph(BaseGraphStorage):
434
470
 
435
471
  self.ensure_tag_exists(subj)
436
472
  self.ensure_tag_exists(obj)
437
- self.ensure_edge_type_exists(rel)
473
+ self.ensure_edge_type_exists(rel, time_label)
438
474
  self.add_node(node_id=subj, tag_name=subj)
439
475
  self.add_node(node_id=obj, tag_name=obj)
440
476
 
441
- # Avoid latenicy
477
+ # Avoid latency
442
478
  time.sleep(1)
443
479
 
444
- insert_stmt = (
445
- f'INSERT EDGE IF NOT EXISTS {rel}() VALUES "{subj}"->"{obj}":();'
446
- )
480
+ # Create edge with or without time_label property
481
+ if time_label is not None:
482
+ time_label = self._validate_time_label(time_label)
483
+ insert_stmt = (
484
+ f'INSERT EDGE IF NOT EXISTS {rel}(time_label) VALUES '
485
+ f'"{subj}"->"{obj}":("{time_label}")'
486
+ )
487
+ else:
488
+ insert_stmt = (
489
+ f'INSERT EDGE IF NOT EXISTS {rel}() VALUES '
490
+ f'"{subj}"->"{obj}":()'
491
+ )
447
492
 
448
493
  res = self.query(insert_stmt)
449
494
  if not res.is_succeeded():
450
495
  raise Exception(
451
- f'create relationship `]{subj}` -> `{obj}`'
496
+ f'create relationship `{subj}` -> `{obj}`'
452
497
  + f'failed: {res.error_msg()}'
453
498
  )
454
499
 
@@ -568,3 +613,27 @@ class NebulaGraph(BaseGraphStorage):
568
613
  )
569
614
 
570
615
  return rel_schema_props, rel_structure_props
616
+
617
+ def _validate_time_label(self, time_label: str) -> str:
618
+ r"""Validates the format of a time label string.
619
+
620
+ Args:
621
+ time_label (str): The time label string to validate.
622
+ Should be in format 'YYYY-MM-DDThh:mm:ss'.
623
+
624
+ Returns:
625
+ str: The validated time label.
626
+
627
+ Raises:
628
+ ValueError: If the time label format is invalid.
629
+ """
630
+ try:
631
+ # Check if the format matches YYYY-MM-DDThh:mm:ss
632
+ pattern = r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$'
633
+ if not re.match(pattern, time_label):
634
+ raise ValueError(
635
+ "Time label must be in format 'YYYY-MM-DDThh:mm:ss'"
636
+ )
637
+ return time_label
638
+ except Exception as e:
639
+ raise ValueError(f"Invalid time label format: {e!s}")
@@ -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}")