Fix: Skip invalid Python parameter names when wrapping tools for LangChain #1967
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Prevents tool wrapping failures in
composio_langchainwhen tool schemas contain parameter names that are not valid Python identifiers (e.g.,@microsoft.graph.conflictBehavior). Instead of crashing, invalid parameters are silently skipped — preserving tool usability while logging a warning for visibility.Changes
get_signature_format_from_schema_paramsinpython/composio/utils/shared.py:Parameter(...)constructor intry/except ValueErrorProblem Solved
LangChain tool wrapping crashes when integrating with toolkits like
one_drive,google_drive, or others that use JSON Schema parameter names containing@,$, or other invalid Python identifier characters.This breaks agent workflows silently and prevents use of otherwise functional tools.
Example error before fix:
Traceback (most recent call last):
\src\scripts\composio_cli.py", line 32, in
app_tools = composio.tools.get(user_id=os.environ["COMPOSIO_USER"],
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
]composio\core\models\base.py", line 59, in trace_wrapper
raise e
\composio\core\models\base.py", line 50, in trace_wrapper
return method(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\composio\core\models\tools.py", line 259, in get
return self._get(
^^^^^^^^^^
\composio\core\models\tools.py", line 182, in _get
return t.cast(AgenticProvider, self.provider).wrap_tools(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\composio_langchain\provider.py", line 140, in wrap_tools
return [self.wrap_tool(tool=tool, execute_tool=execute_tool) for tool in tools]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\composio_langchain\provider.py", line 110, in wrap_tool
parameters=get_signature_format_from_schema_params(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\composio\utils\shared.py", line 358, in get_signature_format_from_schema_params
parameter = Parameter(
^^^^^^^^^^
\uv\python\cpython-3.12.11-windows-x86_64-none\Lib\inspect.py", line 2782, in init
raise ValueError('{!r} is not a valid parameter name'.format(name))
ValueError: '$filter' is not a valid parameter name