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
camel/__init__.py CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  from camel.logger import disable_logging, enable_logging, set_log_level
16
16
 
17
- __version__ = '0.2.15a0'
17
+ __version__ = '0.2.17'
18
18
 
19
19
  __all__ = [
20
20
  '__version__',
@@ -94,11 +94,13 @@ class FunctionCallingRecord(BaseModel):
94
94
  args (Dict[str, Any]): The dictionary of arguments passed to
95
95
  the function.
96
96
  result (Any): The execution result of calling this function.
97
+ tool_call_id (str): The ID of the tool call, if available.
97
98
  """
98
99
 
99
100
  func_name: str
100
101
  args: Dict[str, Any]
101
102
  result: Any
103
+ tool_call_id: str
102
104
 
103
105
  def __str__(self) -> str:
104
106
  r"""Overridden version of the string function.
@@ -109,7 +111,7 @@ class FunctionCallingRecord(BaseModel):
109
111
  return (
110
112
  f"Function Execution: {self.func_name}\n"
111
113
  f"\tArgs: {self.args}\n"
112
- f"\tResult: {self.result}"
114
+ f"\tResult: {self.result}\n"
113
115
  )
114
116
 
115
117
  def as_dict(self) -> dict[str, Any]:
@@ -824,7 +826,7 @@ class ChatAgent(BaseAgent):
824
826
  return True
825
827
 
826
828
  if self.model_type.support_native_tool_calling:
827
- return response.choices[0].message.tool_calls is None
829
+ return not response.choices[0].message.tool_calls
828
830
 
829
831
  return "</function>" not in str(
830
832
  response.choices[0].message.content or ""
@@ -1384,6 +1386,7 @@ class ChatAgent(BaseAgent):
1384
1386
 
1385
1387
  tool = self.tool_dict[func_name]
1386
1388
  result = tool(**args)
1389
+ tool_call_id = choice.message.tool_calls[0].id
1387
1390
 
1388
1391
  assist_msg = FunctionCallingMessage(
1389
1392
  role_name=self.role_name,
@@ -1392,6 +1395,7 @@ class ChatAgent(BaseAgent):
1392
1395
  content="",
1393
1396
  func_name=func_name,
1394
1397
  args=args,
1398
+ tool_call_id=tool_call_id,
1395
1399
  )
1396
1400
  func_msg = FunctionCallingMessage(
1397
1401
  role_name=self.role_name,
@@ -1400,11 +1404,15 @@ class ChatAgent(BaseAgent):
1400
1404
  content="",
1401
1405
  func_name=func_name,
1402
1406
  result=result,
1407
+ tool_call_id=tool_call_id,
1403
1408
  )
1404
1409
 
1405
1410
  # Record information about this function call
1406
1411
  func_record = FunctionCallingRecord(
1407
- func_name=func_name, args=args, result=result
1412
+ func_name=func_name,
1413
+ args=args,
1414
+ result=result,
1415
+ tool_call_id=tool_call_id,
1408
1416
  )
1409
1417
  return assist_msg, func_msg, func_record
1410
1418
 
@@ -1448,6 +1456,7 @@ class ChatAgent(BaseAgent):
1448
1456
  args = json.loads(choice.message.tool_calls[0].function.arguments)
1449
1457
  tool = self.tool_dict[func_name]
1450
1458
  result = await tool(**args)
1459
+ tool_call_id = choice.message.tool_calls[0].id
1451
1460
 
1452
1461
  assist_msg = FunctionCallingMessage(
1453
1462
  role_name=self.role_name,
@@ -1456,6 +1465,7 @@ class ChatAgent(BaseAgent):
1456
1465
  content="",
1457
1466
  func_name=func_name,
1458
1467
  args=args,
1468
+ tool_call_id=tool_call_id,
1459
1469
  )
1460
1470
  func_msg = FunctionCallingMessage(
1461
1471
  role_name=self.role_name,
@@ -1464,11 +1474,15 @@ class ChatAgent(BaseAgent):
1464
1474
  content="",
1465
1475
  func_name=func_name,
1466
1476
  result=result,
1477
+ tool_call_id=tool_call_id,
1467
1478
  )
1468
1479
 
1469
1480
  # Record information about this function call
1470
1481
  func_record = FunctionCallingRecord(
1471
- func_name=func_name, args=args, result=result
1482
+ func_name=func_name,
1483
+ args=args,
1484
+ result=result,
1485
+ tool_call_id=tool_call_id,
1472
1486
  )
1473
1487
  return assist_msg, func_msg, func_record
1474
1488
 
@@ -0,0 +1,85 @@
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
+
15
+ import textwrap
16
+ from typing import Any
17
+
18
+ from pydantic import ConfigDict
19
+
20
+ from camel.agents.programmed_agent_instruction import (
21
+ ProgrammableChatAgent,
22
+ ProgrammedAgentInstructionResult,
23
+ programmable_capability,
24
+ )
25
+ from camel.messages import BaseMessage
26
+ from camel.synthetic_datagen.source2synth.models import (
27
+ ContextPrompt,
28
+ MultiHopQA,
29
+ )
30
+
31
+
32
+ class MultiHopGeneratorAgent(ProgrammableChatAgent):
33
+ model_config = ConfigDict(arbitrary_types_allowed=True)
34
+
35
+ def __init__(self, **kwargs: Any):
36
+ super().__init__(**kwargs)
37
+
38
+ system_text: str = textwrap.dedent(
39
+ """\
40
+ You are an expert at generating
41
+ multi-hop question-answer pairs.
42
+ For each context, you should:
43
+ 1. Identify multiple related facts or pieces of information
44
+ 2. Create questions that require reasoning across these multiple pieces
45
+ 3. Ensure the reasoning chain is clear and logical
46
+ 4. Generate questions that require at least 2-3 steps of reasoning
47
+ 5. Include the reasoning steps in the answer
48
+
49
+ Give your response with this information:
50
+ Question: [Complex question requiring multiple reasoning steps]
51
+ Reasoning Steps:
52
+ 1. [First reasoning step]
53
+ 2. [Second reasoning step]
54
+ 3. [Final reasoning step]
55
+ Answer: [Final answer]
56
+ Supporting Facts: [List of relevant text segments used]
57
+ """ # noqa: E501
58
+ )
59
+ self.system_message = BaseMessage.make_assistant_message(
60
+ role_name='Assistant', content=system_text
61
+ )
62
+
63
+ @programmable_capability
64
+ def generate_multi_hop_qa(
65
+ self, context: str
66
+ ) -> ProgrammedAgentInstructionResult[MultiHopQA]:
67
+ context_prompt = ContextPrompt(
68
+ main_context=context, related_contexts=None
69
+ )
70
+
71
+ user_message = BaseMessage.make_user_message(
72
+ content=context_prompt.model_dump_json(), role_name="User"
73
+ )
74
+ response = self.step(
75
+ input_message=user_message, response_format=MultiHopQA
76
+ )
77
+ value = MultiHopQA.model_validate_json(response.msgs[0].content)
78
+
79
+ if response.msgs:
80
+ return ProgrammedAgentInstructionResult(
81
+ user_message=user_message,
82
+ agent_message=response.msgs[0],
83
+ value=value,
84
+ )
85
+ raise RuntimeError("No response from agent")
@@ -0,0 +1,148 @@
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
+ import abc
15
+ import threading
16
+ from enum import Enum
17
+ from functools import wraps
18
+ from typing import Any, Callable, Generic, Optional, TypeVar
19
+
20
+ from pydantic import BaseModel, ConfigDict
21
+
22
+ from camel.agents import ChatAgent
23
+ from camel.messages import BaseMessage
24
+
25
+ T = TypeVar('T')
26
+
27
+
28
+ class ProgrammableAgentRequirement(Enum):
29
+ LAST_MESSAGE_NOT_USER = "LAST_MESSAGE_NOT_USER"
30
+
31
+
32
+ class ProgrammedAgentInstructionResult(BaseModel, Generic[T]):
33
+ r"""Result of a programmable agent instruction execution.
34
+
35
+ Contains the messages exchanged during execution and the computed value.
36
+ The value type is specified by the generic type parameter T.
37
+ """
38
+
39
+ user_message: BaseMessage
40
+ agent_message: BaseMessage
41
+ value: T
42
+
43
+ model_config = ConfigDict(arbitrary_types_allowed=True)
44
+
45
+
46
+ class AbstractProgrammableAgent(abc.ABC):
47
+ r"""Abstract class for a programmable agent.
48
+
49
+ A programmable agent is an agent that can be programmed to perform a
50
+ specific function or task. This class defines the interface for a
51
+ programmable
52
+ agent.
53
+
54
+ These methods should be implemented in order to ensure the agent supports
55
+ the necessary guarantees to enable a programming interface while
56
+ maintaining compatibility in a multi-agent system.
57
+
58
+ A programmable agent is responsible for providing and maintaining a
59
+ programming interface for its functionality.
60
+ """
61
+
62
+ @abc.abstractmethod
63
+ def run_atomic(
64
+ self, callback: Callable[[], ProgrammedAgentInstructionResult[T]]
65
+ ) -> ProgrammedAgentInstructionResult[T]:
66
+ r"""Run an atomic operation on the agent.
67
+
68
+ An atomic operation is an operation that is guaranteed to
69
+ be executed without interruption by any other operation.
70
+
71
+ If the operation fails or times out the agents state should be
72
+ unchanged.
73
+
74
+ If an operation is already in progress, this method should throw an
75
+ exception. (It is up to the caller to do any queuing)
76
+
77
+ If the agent is in a state where it can perform the operation,
78
+ it must leave the agent in a state where it can perform the
79
+ operation again. Though if state changes in successful operation
80
+ improve its ability to perform the operation, it should keep them.
81
+ """
82
+ raise NotImplementedError
83
+
84
+ @abc.abstractmethod
85
+ def repair_state(self, requirement: ProgrammableAgentRequirement) -> None:
86
+ r"""Repair the state of the agent.
87
+
88
+ Agents may have other non-atomic interfaces, such as a user interface,
89
+ or chat between other agents.
90
+
91
+ This method should restore the agent to a state where it can perform
92
+ operations according to the specified requirement.
93
+ """
94
+ raise NotImplementedError
95
+
96
+
97
+ def programmable_capability(
98
+ func: Callable[..., ProgrammedAgentInstructionResult[T]],
99
+ ) -> Callable[..., ProgrammedAgentInstructionResult[T]]:
100
+ r"""Decorator for programmable agent capabilities.
101
+
102
+ Wraps a method to ensure it is executed atomically via the agent's
103
+ run_atomic interface.
104
+ The decorated method must return a ProgrammedAgentInstructionResult with
105
+ appropriate type parameter.
106
+ """
107
+
108
+ @wraps(func)
109
+ def wrapper(
110
+ self, *args: Any, **kwargs: Any
111
+ ) -> ProgrammedAgentInstructionResult[T]:
112
+ return self.run_atomic(lambda: func(self, *args, **kwargs))
113
+
114
+ return wrapper
115
+
116
+
117
+ class ProgrammableChatAgent(ChatAgent, AbstractProgrammableAgent):
118
+ r"""A chat agent that can be programmed to perform specific tasks.
119
+
120
+ Provides a default implementation of atomic execution using threading locks
121
+ and basic state tracking for message roles. Implementing classes need to
122
+ provide specific repair logic for their use cases.
123
+ """
124
+
125
+ def __init__(self, **kwargs: Any):
126
+ super().__init__(**kwargs)
127
+ self._operation_lock = threading.Lock()
128
+ self._last_message_role: Optional[str] = None
129
+
130
+ def run_atomic(
131
+ self, callback: Callable[[], ProgrammedAgentInstructionResult[T]]
132
+ ) -> ProgrammedAgentInstructionResult[T]:
133
+ if not self._operation_lock.acquire(blocking=False):
134
+ raise RuntimeError("Operation already in progress")
135
+
136
+ try:
137
+ result = callback()
138
+ self._last_message_role = result.agent_message.role_name
139
+ return result
140
+ finally:
141
+ self._operation_lock.release()
142
+
143
+ def repair_state(self, requirement: ProgrammableAgentRequirement) -> None:
144
+ if requirement == ProgrammableAgentRequirement.LAST_MESSAGE_NOT_USER:
145
+ if self._last_message_role == "user":
146
+ raise NotImplementedError(
147
+ "Must implement repair for LAST_MESSAGE_NOT_USER"
148
+ )
@@ -12,7 +12,19 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
+ from .apibank import APIBankBenchmark
16
+ from .apibench import APIBenchBenchmark
15
17
  from .base import BaseBenchmark
16
18
  from .gaia import DefaultGAIARetriever, GAIABenchmark
19
+ from .nexus import NexusBenchmark
20
+ from .ragbench import RAGBenchBenchmark
17
21
 
18
- __all__ = ["BaseBenchmark", "GAIABenchmark", "DefaultGAIARetriever"]
22
+ __all__ = [
23
+ "BaseBenchmark",
24
+ "GAIABenchmark",
25
+ "DefaultGAIARetriever",
26
+ "NexusBenchmark",
27
+ "APIBenchBenchmark",
28
+ "APIBankBenchmark",
29
+ "RAGBenchBenchmark",
30
+ ]