Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 45 additions & 125 deletions 01_funccall.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"outputs": [],
"source": [
"#| exports\n",
"import inspect, json, ast\n",
"import asyncio, inspect, json, ast\n",
"from collections import abc\n",
"from fastcore.utils import *\n",
"from fastcore.docments import docments\n",
Expand Down Expand Up @@ -965,27 +965,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Adds a + b.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Returns:\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Adds a + b.\n",
"\n",
"Returns:\n",
"- The sum of the inputs (type: integer)\n"
]
},
Expand Down Expand Up @@ -1869,90 +1851,18 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Traceback (most recent call last):\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" File \"/var/folders/51/b2_szf2945n072c0vj2cyty40000gn/T/ipymini_45858/2052945749.py\", line 14, in python\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" try: return _run(code, glb, loc)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" ^^^^^^^^^^^^^^^^^^^^\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" File \"/var/folders/51/b2_szf2945n072c0vj2cyty40000gn/T/ipymini_45858/1858893181.py\", line 18, in _run\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" try: exec(compiled_code, glb, loc)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" File \"<ast>\", line 1, in <module>\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" File \"/var/folders/51/b2_szf2945n072c0vj2cyty40000gn/T/ipymini_45858/2052945749.py\", line 9, in handler\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" def handler(*args): raise TimeoutError()\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" ^^^^^^^^^^^^^^^^^^^^\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"TimeoutError\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Traceback (most recent call last):\n",
" File \"/var/folders/zl/js35kg3914qc7d8lsdtqsyf00000gn/T/ipykernel_75165/2052945749.py\", line 14, in python\n",
" try: return _run(code, glb, loc)\n",
" ^^^^^^^^^^^^^^^^^^^^\n",
" File \"/var/folders/zl/js35kg3914qc7d8lsdtqsyf00000gn/T/ipykernel_75165/1858893181.py\", line 18, in _run\n",
" try: exec(compiled_code, glb, loc)\n",
" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
" File \"<ast>\", line 1, in <module>\n",
" File \"/var/folders/zl/js35kg3914qc7d8lsdtqsyf00000gn/T/ipykernel_75165/2052945749.py\", line 9, in handler\n",
" def handler(*args): raise TimeoutError()\n",
" ^^^^^^^^^^^^^^^^^^^^\n",
"TimeoutError\n",
"\n"
]
}
Expand Down Expand Up @@ -2374,34 +2284,44 @@
"#| exports\n",
"async def call_func_async(fc_name, fc_inputs, ns, raise_on_err=True):\n",
" \"Awaits the function `fc_name` with the given `fc_inputs` using namespace `ns`.\"\n",
" res = call_func(fc_name, fc_inputs, ns, raise_on_err=raise_on_err)\n",
" if inspect.iscoroutine(res):\n",
" try: res = await res\n",
" except Exception as e:\n",
" if raise_on_err: raise e from None\n",
" else: return traceback.format_exc()\n",
" if not isinstance(ns, abc.Mapping): ns = mk_ns(ns)\n",
" func = resolve_nm(fc_name, ns)\n",
" if inspect.iscoroutinefunction(func):\n",
" res = call_func(fc_name, fc_inputs, ns, raise_on_err=raise_on_err)\n",
" else: res = asyncio.to_thread(call_func, fc_name, fc_inputs, ns, raise_on_err=raise_on_err)\n",
" try: res = await res\n",
" except Exception as e:\n",
" if raise_on_err: raise e from None\n",
" else: return traceback.format_exc()\n",
" return res"
]
},
{
"cell_type": "markdown",
"id": "740ada11",
"metadata": {},
"source": [
"Testing async `call_func_async` both with sync and async functions. Sync functions are automatically run in a separate thread via `asyncio.to_thread`, allowing `asyncio.gather` to execute multiple sync tool calls in parallel without blocking the event loop."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b83998ac-68e2-4dbe-b594-65fb4fdf59b8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"test_eq(await call_func_async('asums', {'a': 1, 'b': 2}, ns=[asums]), 3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1c4d8b2b",
"metadata": {},
"outputs": [],
"source": [
"await call_func_async('asums', {'a': 1, 'b': 2}, ns=[asums])"
"test_eq(await call_func_async('sums', {'a': 1, 'b': 2}, ns=[sums]), 3)"
]
},
{
Expand Down
17 changes: 10 additions & 7 deletions toolslm/funccall.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
'call_func_async', 'mk_param', 'schema2sig', 'mk_tool']

# %% ../01_funccall.ipynb #e5ad6b86
import inspect, json, ast
import asyncio, inspect, json, ast
from collections import abc
from fastcore.utils import *
from fastcore.docments import docments
Expand Down Expand Up @@ -257,12 +257,15 @@ def call_func(fc_name, fc_inputs, ns, raise_on_err=True):
# %% ../01_funccall.ipynb #73bca085
async def call_func_async(fc_name, fc_inputs, ns, raise_on_err=True):
"Awaits the function `fc_name` with the given `fc_inputs` using namespace `ns`."
res = call_func(fc_name, fc_inputs, ns, raise_on_err=raise_on_err)
if inspect.iscoroutine(res):
try: res = await res
except Exception as e:
if raise_on_err: raise e from None
else: return traceback.format_exc()
if not isinstance(ns, abc.Mapping): ns = mk_ns(ns)
func = resolve_nm(fc_name, ns)
if inspect.iscoroutinefunction(func):
res = call_func(fc_name, fc_inputs, ns, raise_on_err=raise_on_err)
else: res = asyncio.to_thread(call_func, fc_name, fc_inputs, ns, raise_on_err=raise_on_err)
try: res = await res
except Exception as e:
if raise_on_err: raise e from None
else: return traceback.format_exc()
return res

# %% ../01_funccall.ipynb #ede7ea66
Expand Down