From 0ff5ed10095cd281744a25e08589f718a3323521 Mon Sep 17 00:00:00 2001 From: ncoop57 Date: Wed, 16 Oct 2024 10:50:24 -0500 Subject: [PATCH] Add check for 'self' property in _get_nested_schema Checks if a property is 'self' and skips it when processing the function signature to generate the schema. This ensures that the 'self' argument is not included in the generated input schema for class methods. --- 01_funccall.ipynb | 66 +++++++++++++++++++++++++++++++++++++++++++-- toolslm/funccall.py | 10 +++---- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/01_funccall.ipynb b/01_funccall.ipynb index 22d9148..55d153a 100644 --- a/01_funccall.ipynb +++ b/01_funccall.ipynb @@ -363,7 +363,7 @@ " props, req, defs = {}, {}, {}\n", " \n", " for n, o in d.items():\n", - " if n != 'return':\n", + " if n != 'return' and n != 'self':\n", " _process_property(n, o, props, req, defs)\n", " \n", " schema = dict(type='object', properties=props, title=obj.__name__ if isinstance(obj, type) else None)\n", @@ -577,6 +577,53 @@ "get_schema(silly_test)" ] }, + { + "cell_type": "markdown", + "id": "e3f36f8a", + "metadata": {}, + "source": [ + "This also works with class methods:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05d33447", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'sums',\n", + " 'description': 'Adds a + b.\\n\\nReturns:\\n- type: integer',\n", + " 'input_schema': {'type': 'object',\n", + " 'properties': {'a': {'type': 'integer', 'description': 'First thing to sum'},\n", + " 'b': {'type': 'integer',\n", + " 'description': 'Second thing to sum',\n", + " 'default': 1}},\n", + " 'title': None,\n", + " 'required': ['a']}}" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class Dummy:\n", + " def sums(\n", + " self,\n", + " a:int, # First thing to sum\n", + " b:int=1 # Second thing to sum\n", + " ) -> int: # The sum of the inputs\n", + " \"Adds a + b.\"\n", + " print(f\"Finding the sum of {a} and {b}\")\n", + " return a + b\n", + "\n", + "get_schema(Dummy.sums)" + ] + }, { "cell_type": "markdown", "id": "ae3fdfa4", @@ -950,7 +997,22 @@ "execution_count": null, "id": "1e9ee5c1", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/nathan/git/.venv/lib/python3.10/site-packages/nbdev/export.py:80: UserWarning: Notebook '/Users/nathan/git/toolslm/01_funccall-aimagic-2.ipynb' uses `#|export` without `#|default_exp` cell.\n", + "Note nbdev2 no longer supports nbdev1 syntax. Run `nbdev_migrate` to upgrade.\n", + "See https://nbdev.fast.ai/getting_started.html for more information.\n", + " warn(f\"Notebook '{nbname}' uses `#|export` without `#|default_exp` cell.\\n\"\n", + "/Users/nathan/git/.venv/lib/python3.10/site-packages/nbdev/export.py:80: UserWarning: Notebook '/Users/nathan/git/toolslm/01_funccall-aimagic.ipynb' uses `#|export` without `#|default_exp` cell.\n", + "Note nbdev2 no longer supports nbdev1 syntax. Run `nbdev_migrate` to upgrade.\n", + "See https://nbdev.fast.ai/getting_started.html for more information.\n", + " warn(f\"Notebook '{nbname}' uses `#|export` without `#|default_exp` cell.\\n\"\n" + ] + } + ], "source": [ "#|hide\n", "#|eval: false\n", diff --git a/toolslm/funccall.py b/toolslm/funccall.py index 0d5fde2..b0d0683 100644 --- a/toolslm/funccall.py +++ b/toolslm/funccall.py @@ -76,7 +76,7 @@ def _get_nested_schema(obj): props, req, defs = {}, {}, {} for n, o in d.items(): - if n != 'return': + if n != 'return' and n != 'self': _process_property(n, o, props, req, defs) schema = dict(type='object', properties=props, title=obj.__name__ if isinstance(obj, type) else None) @@ -95,11 +95,11 @@ def get_schema(f:callable, pname='input_schema')->dict: if ret.anno is not empty: desc += f'\n\nReturns:\n- type: {_types(ret.anno)[0]}' return {"name": f.__name__, "description": desc, pname: schema} -# %% ../01_funccall.ipynb 37 +# %% ../01_funccall.ipynb 39 import ast, time, signal, traceback from fastcore.utils import * -# %% ../01_funccall.ipynb 38 +# %% ../01_funccall.ipynb 40 def _copy_loc(new, orig): "Copy location information from original node to new node and all children." new = ast.copy_location(new, orig) @@ -108,7 +108,7 @@ def _copy_loc(new, orig): elif isinstance(o, list): setattr(new, field, [_copy_loc(value, orig) for value in o]) return new -# %% ../01_funccall.ipynb 40 +# %% ../01_funccall.ipynb 42 def _run(code:str ): "Run `code`, returning final expression (similar to IPython)" tree = ast.parse(code) @@ -131,7 +131,7 @@ def _run(code:str ): if _result is not None: return _result return stdout_buffer.getvalue().strip() -# %% ../01_funccall.ipynb 45 +# %% ../01_funccall.ipynb 47 def python(code, # Code to execute timeout=5 # Maximum run time in seconds before a `TimeoutError` is raised ): # Result of last node, if it's an expression, or `None` otherwise