Skip to content

Commit 0ed0c21

Browse files
committed
fix: avoid duplicated LangChain parameter descriptions
1 parent 7cb3ab1 commit 0ed0c21

4 files changed

Lines changed: 36 additions & 6 deletions

File tree

packages/toolbox-langchain/src/toolbox_langchain/async_tools.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
from toolbox_core.utils import params_to_pydantic_model
2121

2222

23+
def _get_tool_description(core_tool: ToolboxCoreTool) -> str:
24+
description = core_tool._description
25+
if isinstance(description, str):
26+
return description
27+
return core_tool.__doc__ or ""
28+
29+
2330
# This class is an internal implementation detail and is not exposed to the
2431
# end-user. It should not be used directly by external code. Changes to this
2532
# class will not be considered breaking changes to the public API.
@@ -44,7 +51,7 @@ def __init__(
4451
# BaseTool class before assigning values to member variables.
4552
super().__init__(
4653
name=core_tool.__name__,
47-
description=core_tool.__doc__,
54+
description=_get_tool_description(core_tool),
4855
args_schema=params_to_pydantic_model(core_tool._name, core_tool._params),
4956
)
5057
self.__core_tool = core_tool

packages/toolbox-langchain/src/toolbox_langchain/tools.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121
from toolbox_core.utils import params_to_pydantic_model
2222

2323

24+
def _get_tool_description(core_tool: ToolboxCoreSyncTool) -> str:
25+
description = core_tool._description
26+
if isinstance(description, str):
27+
return description
28+
return core_tool.__doc__ or ""
29+
30+
2431
class ToolboxTool(BaseTool):
2532
"""
2633
A subclass of LangChain's BaseTool that supports features specific to
@@ -42,7 +49,7 @@ def __init__(
4249
# BaseTool class before assigning values to member variables.
4350
super().__init__(
4451
name=core_tool.__name__,
45-
description=core_tool.__doc__,
52+
description=_get_tool_description(core_tool),
4653
args_schema=params_to_pydantic_model(core_tool._name, core_tool._params),
4754
)
4855
self.__core_tool = core_tool

packages/toolbox-langchain/tests/test_async_tools.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ async def test_toolbox_tool_init(self, tool_schema_dict):
149149
)
150150
tool = AsyncToolboxTool(core_tool=core_tool_instance)
151151
assert tool.name == "test_tool"
152-
assert tool.description == core_tool_instance.__doc__
152+
assert tool.description == core_tool_instance._description
153+
assert "Args:" not in tool.description
153154

154155
@pytest.mark.parametrize(
155156
"params_to_bind",

packages/toolbox-langchain/tests/test_tools.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,13 @@ def mock_core_tool(self, tool_schema_dict):
109109
sync_mock = Mock(spec=ToolboxCoreSyncTool)
110110

111111
sync_mock.__name__ = "test_tool_name_for_langchain"
112-
sync_mock.__doc__ = tool_schema_dict["description"]
112+
sync_mock._description = tool_schema_dict["description"]
113+
sync_mock.__doc__ = (
114+
f"{tool_schema_dict['description']}\n\n"
115+
"Args:\n"
116+
" param1 (str): Param 1\n"
117+
" param2 (int): Param 2"
118+
)
113119
sync_mock._name = "TestToolPydanticModel"
114120
sync_mock._params = [
115121
CoreParameterSchema(**p) for p in tool_schema_dict["parameters"]
@@ -123,6 +129,7 @@ def mock_core_tool(self, tool_schema_dict):
123129

124130
new_mock_instance_for_methods = Mock(spec=ToolboxCoreSyncTool)
125131
new_mock_instance_for_methods.__name__ = sync_mock.__name__
132+
new_mock_instance_for_methods._description = sync_mock._description
126133
new_mock_instance_for_methods.__doc__ = sync_mock.__doc__
127134
new_mock_instance_for_methods._name = sync_mock._name
128135
new_mock_instance_for_methods._params = sync_mock._params
@@ -145,7 +152,13 @@ def mock_core_tool(self, tool_schema_dict):
145152
def mock_core_sync_auth_tool(self, auth_tool_schema_dict):
146153
sync_mock = Mock(spec=ToolboxCoreSyncTool)
147154
sync_mock.__name__ = "test_auth_tool_lc_name"
148-
sync_mock.__doc__ = auth_tool_schema_dict["description"]
155+
sync_mock._description = auth_tool_schema_dict["description"]
156+
sync_mock.__doc__ = (
157+
f"{auth_tool_schema_dict['description']}\n\n"
158+
"Args:\n"
159+
" param1 (str): Param 1\n"
160+
" param2 (int): Param 2"
161+
)
149162
sync_mock._name = "TestAuthToolPydanticModel"
150163
sync_mock._params = [
151164
CoreParameterSchema(**p) for p in auth_tool_schema_dict["parameters"]
@@ -159,6 +172,7 @@ def mock_core_sync_auth_tool(self, auth_tool_schema_dict):
159172

160173
new_mock_instance_for_methods = Mock(spec=ToolboxCoreSyncTool)
161174
new_mock_instance_for_methods.__name__ = sync_mock.__name__
175+
new_mock_instance_for_methods._description = sync_mock._description
162176
new_mock_instance_for_methods.__doc__ = sync_mock.__doc__
163177
new_mock_instance_for_methods._name = sync_mock._name
164178
new_mock_instance_for_methods._params = sync_mock._params
@@ -188,7 +202,8 @@ def test_toolbox_tool_init(self, mock_core_tool):
188202
tool = ToolboxTool(core_tool=mock_core_tool)
189203

190204
assert tool.name == mock_core_tool.__name__
191-
assert tool.description == mock_core_tool.__doc__
205+
assert tool.description == mock_core_tool._description
206+
assert "Args:" not in tool.description
192207
assert tool._ToolboxTool__core_tool == mock_core_tool
193208

194209
expected_args_schema = params_to_pydantic_model(

0 commit comments

Comments
 (0)