Skip to content

Commit a91dacd

Browse files
authored
Merge branch 'master' into st_fix_deepseek_stream
2 parents 4535df0 + 69f65f0 commit a91dacd

File tree

10 files changed

+306
-125
lines changed

10 files changed

+306
-125
lines changed

camel/agents/chat_agent.py

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,7 @@ def __init__(
506506

507507
# Set up system message and initialize messages
508508
self._original_system_message = (
509-
BaseMessage.make_assistant_message(
510-
role_name="Assistant", content=system_message
511-
)
509+
BaseMessage.make_system_message(system_message)
512510
if isinstance(system_message, str)
513511
else system_message
514512
)
@@ -1644,10 +1642,7 @@ def _generate_system_message_for_output_language(
16441642
content = self._original_system_message.content + language_prompt
16451643
return self._original_system_message.create_new_instance(content)
16461644
else:
1647-
return BaseMessage.make_assistant_message(
1648-
role_name="Assistant",
1649-
content=language_prompt,
1650-
)
1645+
return BaseMessage.make_system_message(language_prompt)
16511646

16521647
def init_messages(self) -> None:
16531648
r"""Initializes the stored messages list with the current system
@@ -1665,6 +1660,62 @@ def init_messages(self) -> None:
16651660
)
16661661
)
16671662

1663+
def update_system_message(
1664+
self,
1665+
system_message: Union[BaseMessage, str],
1666+
reset_memory: bool = True,
1667+
) -> None:
1668+
r"""Update the system message.
1669+
It will reset conversation with new system message.
1670+
1671+
Args:
1672+
system_message (Union[BaseMessage, str]): The new system message.
1673+
Can be either a BaseMessage object or a string.
1674+
If a string is provided, it will be converted
1675+
into a BaseMessage object.
1676+
reset_memory (bool):
1677+
Whether to reinitialize conversation messages after updating
1678+
the system message. Defaults to True.
1679+
"""
1680+
if system_message is None:
1681+
raise ValueError("system_message is required and cannot be None. ")
1682+
self._original_system_message = (
1683+
BaseMessage.make_system_message(system_message)
1684+
if isinstance(system_message, str)
1685+
else system_message
1686+
)
1687+
self._system_message = (
1688+
self._generate_system_message_for_output_language()
1689+
)
1690+
if reset_memory:
1691+
self.init_messages()
1692+
1693+
def append_to_system_message(
1694+
self, content: str, reset_memory: bool = True
1695+
) -> None:
1696+
"""Append additional context to existing system message.
1697+
1698+
Args:
1699+
content (str): The additional system message.
1700+
reset_memory (bool):
1701+
Whether to reinitialize conversation messages after appending
1702+
additional context. Defaults to True.
1703+
"""
1704+
original_content = (
1705+
self._original_system_message.content
1706+
if self._original_system_message
1707+
else ""
1708+
)
1709+
new_system_message = original_content + '\n' + content
1710+
self._original_system_message = BaseMessage.make_system_message(
1711+
new_system_message
1712+
)
1713+
self._system_message = (
1714+
self._generate_system_message_for_output_language()
1715+
)
1716+
if reset_memory:
1717+
self.init_messages()
1718+
16681719
def reset_to_original_system_message(self) -> None:
16691720
r"""Reset system message to original, removing any appended context.
16701721
@@ -4541,23 +4592,29 @@ def _clone_tools(
45414592
# Toolkit doesn't support cloning, use original
45424593
cloned_toolkits[toolkit_id] = toolkit_instance
45434594

4544-
if getattr(
4545-
tool.func, "__message_integration_enhanced__", False
4546-
):
4547-
cloned_tools.append(
4548-
FunctionTool(
4549-
func=tool.func,
4550-
openai_tool_schema=tool.get_openai_tool_schema(),
4551-
)
4552-
)
4553-
continue
4554-
45554595
# Get the method from the cloned (or original) toolkit
45564596
toolkit = cloned_toolkits[toolkit_id]
45574597
method_name = tool.func.__name__
45584598

4599+
# Check if toolkit was actually cloned or just reused
4600+
toolkit_was_cloned = toolkit is not toolkit_instance
4601+
45594602
if hasattr(toolkit, method_name):
45604603
new_method = getattr(toolkit, method_name)
4604+
4605+
# If toolkit wasn't cloned (stateless), preserve the
4606+
# original function to maintain any enhancements/wrappers
4607+
if not toolkit_was_cloned:
4608+
# Toolkit is stateless, safe to reuse original function
4609+
cloned_tools.append(
4610+
FunctionTool(
4611+
func=tool.func,
4612+
openai_tool_schema=tool.get_openai_tool_schema(),
4613+
)
4614+
)
4615+
continue
4616+
4617+
# Toolkit was cloned, use the new method
45614618
# Wrap cloned method into a new FunctionTool,
45624619
# preserving schema
45634620
try:

camel/messages/base.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,32 @@ def make_assistant_message(
178178
OpenAIVisionDetailType(video_detail).value,
179179
)
180180

181+
@classmethod
182+
def make_system_message(
183+
cls,
184+
content: str,
185+
role_name: str = "System",
186+
meta_dict: Optional[Dict[str, str]] = None,
187+
) -> "BaseMessage":
188+
r"""Create a new system message.
189+
190+
Args:
191+
content (str): The content of the system message.
192+
role_name (str): The name of the system role.
193+
(default: :obj:`"System"`)
194+
meta_dict (Optional[Dict[str, str]]): Additional metadata
195+
dictionary for the message.
196+
197+
Returns:
198+
BaseMessage: The new system message.
199+
"""
200+
return cls(
201+
role_name,
202+
RoleType.SYSTEM,
203+
meta_dict,
204+
content,
205+
)
206+
181207
def create_new_instance(self, content: str) -> "BaseMessage":
182208
r"""Create a new instance of the :obj:`BaseMessage` with updated
183209
content.

camel/toolkits/message_integration.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,10 @@ def get_message_tool(self) -> FunctionTool:
148148
"""
149149
return FunctionTool(self.send_message_to_user)
150150

151-
def register_toolkits(
152-
self, toolkit: BaseToolkit, tool_names: Optional[List[str]] = None
153-
) -> BaseToolkit:
154-
r"""Add messaging capabilities to toolkit methods.
151+
def register_toolkits(self, toolkit: BaseToolkit) -> BaseToolkit:
152+
r"""Add messaging capabilities to all toolkit methods.
155153
156-
This method modifies a toolkit so that specified tools can send
154+
This method modifies a toolkit so that all its tools can send
157155
status messages to users while executing their primary function.
158156
The tools will accept optional messaging parameters:
159157
- message_title: Title of the status message
@@ -162,20 +160,18 @@ def register_toolkits(
162160
163161
Args:
164162
toolkit: The toolkit to add messaging capabilities to
165-
tool_names: List of specific tool names to modify.
166-
If None, messaging is added to all tools.
167163
168164
Returns:
169-
The toolkit with messaging capabilities added
165+
The same toolkit instance with messaging capabilities added to
166+
all methods.
170167
"""
171168
original_tools = toolkit.get_tools()
172169
enhanced_methods = {}
173170
for tool in original_tools:
174171
method_name = tool.func.__name__
175-
if tool_names is None or method_name in tool_names:
176-
enhanced_func = self._add_messaging_to_tool(tool.func)
177-
enhanced_methods[method_name] = enhanced_func
178-
setattr(toolkit, method_name, enhanced_func)
172+
enhanced_func = self._add_messaging_to_tool(tool.func)
173+
enhanced_methods[method_name] = enhanced_func
174+
setattr(toolkit, method_name, enhanced_func)
179175
original_get_tools_method = toolkit.get_tools
180176

181177
def enhanced_get_tools() -> List[FunctionTool]:
@@ -201,7 +197,7 @@ def enhanced_get_tools() -> List[FunctionTool]:
201197
def enhanced_clone_for_new_session(new_session_id=None):
202198
cloned_toolkit = original_clone_method(new_session_id)
203199
return message_integration_instance.register_toolkits(
204-
cloned_toolkit, tool_names
200+
cloned_toolkit
205201
)
206202

207203
toolkit.clone_for_new_session = enhanced_clone_for_new_session
@@ -300,6 +296,12 @@ def _add_messaging_to_tool(self, func: Callable) -> Callable:
300296
This internal method modifies the function signature and docstring
301297
to include optional messaging parameters that trigger status updates.
302298
"""
299+
if getattr(func, "__message_integration_enhanced__", False):
300+
logger.debug(
301+
f"Function {func.__name__} already enhanced, skipping"
302+
)
303+
return func
304+
303305
# Get the original signature
304306
original_sig = inspect.signature(func)
305307

0 commit comments

Comments
 (0)