Source code for camel.messages.conversion.sharegpt.hermes.hermes_function_formatter
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
import json
import re
from typing import Any, Dict, List, Optional
from camel.messages.conversion import (
ToolCall,
ToolResponse,
)
from camel.messages.conversion.sharegpt.function_call_formatter import (
FunctionCallFormatter,
)
class HermesToolResponse(ToolResponse):
r"""Represents a single tool/function call with validation"""
pass
class HermesToolCall(ToolCall):
r"""Represents a single tool/function call with validation"""
pass
[docs]
class HermesFunctionFormatter(
FunctionCallFormatter[HermesToolCall, HermesToolResponse]
):
r"""Hermes-style function calling format implementation with validation"""
[docs]
def extract_tool_calls(self, message: str) -> List[HermesToolCall]:
r"""Extracts all tool calls from the provided message string.
Args:
message (str): The input message string containing potential tool
calls.
Returns:
List[HermesToolCall]: A list of parsed HermesToolCall objects.
"""
tool_calls = []
pattern = r"<tool_call>\s*({.*?})\s*</tool_call>"
matches = re.finditer(pattern, message, re.DOTALL)
for match in matches:
try:
call_dict = json.loads(match.group(1).replace("'", '"'))
tool_calls.append(HermesToolCall.model_validate(call_dict))
except Exception as e:
print(f"Warning: Failed to parse tool call: {e}")
continue
return tool_calls
[docs]
def extract_tool_response(
self, message: str
) -> Optional[HermesToolResponse]:
r"""Extracts a single tool response from the provided message string.
Args:
message (str): The input message string containing a potential
tool response.
Returns:
Optional[HermesToolResponse]: A parsed HermesToolResponse object,
or None if no valid response is found.
"""
pattern = r"<tool_response>\s*({.*?})\s*</tool_response>"
match = re.search(pattern, message, re.DOTALL)
if match:
try:
response_json = match.group(1)
response_dict = json.loads(response_json.replace("'", '"'))
return HermesToolResponse.model_validate(response_dict)
except Exception as e:
print(f"Warning: Failed to parse tool response: {e}")
return None
return None
[docs]
def format_tool_call(
self, content: str, func_name: str, args: Dict[str, Any]
) -> str:
r"""Formats a tool call message with the given content, function name,
and arguments.
Args:
content (str): The content or message to be included in the tool
call.
func_name (str): The name of the function being called.
args (Dict[str, Any]): A dictionary of arguments to be passed to
the function.
Returns:
str: A formatted string representing the tool call in Hermes
format.
"""
tool_call_dict = {"name": func_name, "arguments": args}
if content:
return f"{content}\n<tool_call>\n{tool_call_dict}\n</tool_call>"
return f"<tool_call>\n{tool_call_dict}\n</tool_call>"
[docs]
def format_tool_response(self, func_name: str, result: Any) -> str:
r"""Formats a tool response message with the given function name and
result.
Args:
func_name (str): The name of the function whose result is being
returned.
result (Any): The result to be included in the tool response.
Returns:
str: A formatted string representing the tool response in Hermes
format.
"""
response_dict = {"name": func_name, "content": result}
return f"<tool_response>\n{response_dict}\n</tool_response>"