Skip to content

Commit bca70a2

Browse files
feat: aci toolkit async support (#3044)
Co-authored-by: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com> Co-authored-by: Wendong-Fan <w3ndong.fan@gmail.com>
1 parent 54cbc17 commit bca70a2

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

camel/toolkits/aci_toolkit.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# limitations under the License.
1313
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
1414

15+
import asyncio
1516
import os
1617
from typing import TYPE_CHECKING, Dict, List, Optional, Union
1718

@@ -408,6 +409,38 @@ def execute_function(
408409
)
409410
return result
410411

412+
async def aexecute_function(
413+
self,
414+
function_name: str,
415+
function_arguments: Dict,
416+
linked_account_owner_id: str,
417+
allowed_apps_only: bool = False,
418+
) -> Dict:
419+
r"""Execute a function call asynchronously.
420+
421+
Args:
422+
function_name (str): Name of the function to execute.
423+
function_arguments (Dict): Arguments to pass to the function.
424+
linked_account_owner_id (str): To specify the end-user (account
425+
owner) on behalf of whom you want to execute functions
426+
You need to first link corresponding account with the same
427+
owner id in the ACI dashboard (https://platform.aci.dev).
428+
allowed_apps_only (bool): If true, only returns functions/apps
429+
that are allowed to be used by the agent/accessor, identified
430+
by the api key. (default: :obj:`False`)
431+
432+
Returns:
433+
Dict: Result of the function execution
434+
"""
435+
result = await asyncio.to_thread(
436+
self.client.handle_function_call,
437+
function_name,
438+
function_arguments,
439+
linked_account_owner_id,
440+
allowed_apps_only,
441+
)
442+
return result
443+
411444
def get_tools(self) -> List[FunctionTool]:
412445
r"""Get a list of tools (functions) available in the configured apps.
413446
@@ -434,6 +467,8 @@ def get_tools(self) -> List[FunctionTool]:
434467
FunctionTool(self.delete_linked_account),
435468
FunctionTool(self.function_definition),
436469
FunctionTool(self.search_function),
470+
FunctionTool(self.execute_function),
471+
FunctionTool(self.aexecute_function),
437472
]
438473

439474
for function in _all_function:
@@ -448,6 +483,16 @@ def dummy_func(*, schema=schema, **kwargs):
448483
linked_account_owner_id=self.linked_account_owner_id,
449484
)
450485

486+
async def async_dummy_func(*, schema=schema, **kwargs):
487+
return await self.aexecute_function(
488+
function_name=schema['function']['name'],
489+
function_arguments=kwargs,
490+
linked_account_owner_id=self.linked_account_owner_id,
491+
)
492+
493+
# Add async_call method to the sync function for compatibility
494+
dummy_func.async_call = async_dummy_func # type: ignore[attr-defined]
495+
451496
tool = FunctionTool(
452497
func=dummy_func,
453498
openai_tool_schema=schema,

test/toolkits/test_aci_toolkit.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def test_get_tools(mock_aci):
249249
result = toolkit.get_tools()
250250

251251
# Verify results
252-
assert len(result) == 14
252+
assert len(result) == 16
253253
mock_client.app_configurations.list.assert_called_once()
254254
mock_client.functions.search.assert_called_once()
255255
mock_client.functions.get_definition.assert_called_once_with(
@@ -279,3 +279,31 @@ def test_execute_function(mock_aci):
279279
mock_client.handle_function_call.assert_called_once_with(
280280
"test_function", {"arg1": "value1"}, "test_owner", True
281281
)
282+
283+
284+
@patch("aci.ACI")
285+
@pytest.mark.asyncio
286+
async def test_aexecute_function(mock_aci):
287+
r"""Test aexecute_function async method."""
288+
# Setup mock
289+
mock_client = MagicMock()
290+
mock_aci.return_value = mock_client
291+
mock_client.handle_function_call.return_value = {"result": "async_success"}
292+
293+
# Initialize toolkit and call async method
294+
toolkit = ACIToolkit(api_key="test_key")
295+
result = await toolkit.aexecute_function(
296+
function_name="test_async_function",
297+
function_arguments={"arg1": "async_value1"},
298+
linked_account_owner_id="test_async_owner",
299+
allowed_apps_only=False,
300+
)
301+
302+
# Verify results
303+
assert result == {"result": "async_success"}
304+
mock_client.handle_function_call.assert_called_once_with(
305+
"test_async_function",
306+
{"arg1": "async_value1"},
307+
"test_async_owner",
308+
False,
309+
)

0 commit comments

Comments
 (0)