Skip to content

feat: allow async functions as tools#1041

Merged
ajbozarth merged 1 commit into
generative-computing:mainfrom
ajbozarth:feat/from-callable-async
May 8, 2026
Merged

feat: allow async functions as tools#1041
ajbozarth merged 1 commit into
generative-computing:mainfrom
ajbozarth:feat/from-callable-async

Conversation

@ajbozarth
Copy link
Copy Markdown
Contributor

@ajbozarth ajbozarth commented May 8, 2026

Misc PR

Type of PR

  • Bug Fix
  • New Feature
  • Documentation
  • Other

Description

Add async support to MelleaTool.from_callable (and by extension the @tool
decorator) so any developer can register an async function as a tool.

  • from_callable detects inspect.iscoroutinefunction(func) and wraps the
    coroutine through mellea's shared event loop (_run_async_in_thread), so
    sync callers of .run() receive the resolved value rather than an
    un-awaited coroutine.
  • The @tool decorator gets the same support for free (it delegates to
    from_callable).
  • Added overloads on both from_callable and @tool so
    Callable[P, Awaitable[R]] narrows to MelleaTool[P, R], keeping
    static return types correct whether the wrapped function is sync or async.

Split out from a broader plan that also adds MCP tool support.

Testing

  • Tests added to the respective file if code was changed
  • New code has 100% coverage if code as added
  • Ensure existing tests and github automation passes (a maintainer will kick off the github automation when the rest of the PR is populated)

Added:

  • test/backends/test_mellea_tool.py — async wrap, schema parity with sync, exception propagation.
  • test/backends/test_tool_decorator.py@tool on async (edge case class).
  • test/typing/check_tools.py — mypy assert_type verification that the async overload narrows through .run().

Attribution

  • AI coding assistants used (Claude Code)

Detect coroutine functions in MelleaTool.from_callable and wrap them
through mellea's shared event loop so sync .run() callers receive the
resolved value rather than an un-awaited coroutine. Add overloads on
both from_callable and the @tool decorator so Callable[P, Awaitable[R]]
narrows to MelleaTool[P, R].

Closes part of generative-computing#1032.

Assisted-by: Claude Code
Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
@ajbozarth
Copy link
Copy Markdown
Contributor Author

@jakelorocco When moving the MCP tool support over I tried moving it's asynchronous handling into MelleaTool, but realized that it didn't make sense to have MCPToolSpec leverage from_callable instead of just creating MelleaTool directly. But as the feature was still worth doing I have opened this.

I also opened #1043 as a follow up issue to replace this implementation with actual async tool calling

@ajbozarth ajbozarth added this pull request to the merge queue May 8, 2026
Merged via the queue into generative-computing:main with commit e522fc7 May 8, 2026
11 checks passed
@ajbozarth ajbozarth deleted the feat/from-callable-async branch May 8, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants