Skip to content

Commit 01b5bd4

Browse files
committed
feat: Wrap toolbox-langchain's AsyncToolboxTool over toolbox-core's ToolboxTool.
This simplifies code and increases maintainability while removing duplicate code.
1 parent 4afccae commit 01b5bd4

File tree

3 files changed

+75
-255
lines changed

3 files changed

+75
-255
lines changed

packages/toolbox-core/src/toolbox_core/client.py

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313
# limitations under the License.
1414

1515

16-
import types
1716
from typing import Any, Callable, Mapping, Optional, Union
1817

1918
from aiohttp import ClientSession
2019

2120
from .protocol import ManifestSchema, ToolSchema
2221
from .tool import ToolboxTool, identify_required_authn_params
23-
22+
from .utils import parse_tool
2423

2524
class ToolboxClient:
2625
"""
@@ -55,42 +54,6 @@ def __init__(
5554
session = ClientSession()
5655
self.__session = session
5756

58-
def __parse_tool(
59-
self,
60-
name: str,
61-
schema: ToolSchema,
62-
auth_token_getters: dict[str, Callable[[], str]],
63-
all_bound_params: Mapping[str, Union[Callable[[], Any], Any]],
64-
) -> ToolboxTool:
65-
"""Internal helper to create a callable tool from its schema."""
66-
# sort into reg, authn, and bound params
67-
params = []
68-
authn_params: dict[str, list[str]] = {}
69-
bound_params: dict[str, Callable[[], str]] = {}
70-
for p in schema.parameters:
71-
if p.authSources: # authn parameter
72-
authn_params[p.name] = p.authSources
73-
elif p.name in all_bound_params: # bound parameter
74-
bound_params[p.name] = all_bound_params[p.name]
75-
else: # regular parameter
76-
params.append(p)
77-
78-
authn_params = identify_required_authn_params(
79-
authn_params, auth_token_getters.keys()
80-
)
81-
82-
tool = ToolboxTool(
83-
session=self.__session,
84-
base_url=self.__base_url,
85-
name=name,
86-
description=schema.description,
87-
params=params,
88-
# create a read-only values for the maps to prevent mutation
89-
required_authn_params=types.MappingProxyType(authn_params),
90-
auth_service_token_getters=types.MappingProxyType(auth_token_getters),
91-
bound_params=types.MappingProxyType(bound_params),
92-
)
93-
return tool
9457

9558
async def __aenter__(self):
9659
"""
@@ -163,8 +126,8 @@ async def load_tool(
163126
if name not in manifest.tools:
164127
# TODO: Better exception
165128
raise Exception(f"Tool '{name}' not found!")
166-
tool = self.__parse_tool(
167-
name, manifest.tools[name], auth_token_getters, bound_params
129+
tool = parse_tool(
130+
self.__session, self.__base_url, name, manifest.tools[name], auth_token_getters, bound_params
168131
)
169132

170133
return tool
@@ -199,7 +162,7 @@ async def load_toolset(
199162

200163
# parse each tools name and schema into a list of ToolboxTools
201164
tools = [
202-
self.__parse_tool(n, s, auth_token_getters, bound_params)
165+
parse_tool(self.__session, self.__base_url, n, s, auth_token_getters, bound_params)
203166
for n, s in manifest.tools.items()
204167
]
205168
return tools

packages/toolbox-core/src/toolbox_core/utils.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
Union,
2626
cast,
2727
)
28-
28+
from aiohttp import ClientSession
29+
from types import MappingProxyType
2930
from pydantic import BaseModel, Field, create_model
3031

31-
from toolbox_core.protocol import ParameterSchema
32+
from toolbox_core.protocol import ParameterSchema, ToolSchema
33+
from toolbox_core.tool import ToolboxTool
3234

3335

3436
def create_func_docstring(description: str, params: Sequence[ParameterSchema]) -> str:
@@ -110,3 +112,42 @@ async def resolve_value(
110112
elif callable(source):
111113
return source()
112114
return source
115+
116+
117+
def parse_tool(
118+
session: ClientSession,
119+
base_url: str,
120+
name: str,
121+
schema: ToolSchema,
122+
auth_token_getters: dict[str, Callable[[], str]],
123+
all_bound_params: Mapping[str, Union[Callable[[], Any], Any]],
124+
) -> ToolboxTool:
125+
"""Helper to create a callable tool from its schema."""
126+
# sort into reg, authn, and bound params
127+
params = []
128+
authn_params: dict[str, list[str]] = {}
129+
bound_params: dict[str, Callable[[], str]] = {}
130+
for p in schema.parameters:
131+
if p.authSources: # authn parameter
132+
authn_params[p.name] = p.authSources
133+
elif p.name in all_bound_params: # bound parameter
134+
bound_params[p.name] = all_bound_params[p.name]
135+
else: # regular parameter
136+
params.append(p)
137+
138+
authn_params = identify_required_authn_params(
139+
authn_params, auth_token_getters.keys()
140+
)
141+
142+
tool = ToolboxTool(
143+
session=session,
144+
base_url=base_url,
145+
name=name,
146+
description=schema.description,
147+
params=params,
148+
# create a read-only values for the maps to prevent mutation
149+
required_authn_params=MappingProxyType(authn_params),
150+
auth_service_token_getters=MappingProxyType(auth_token_getters),
151+
bound_params=MappingProxyType(bound_params),
152+
)
153+
return tool

0 commit comments

Comments
 (0)