11# chuk_tool_processor/execution/tool_executor.py
22"""
3- Thin façade that turns a list of :class:`~chuk_tool_processor.models.tool_call.ToolCall`
4- objects into a list of :class:`~chuk_tool_processor.models.tool_result.ToolResult`
5- objects by delegating to an :class:`ExecutionStrategy`.
3+ Async-native tool executor for dispatching tool calls to execution strategies.
64
7- Everything here is **async-native** – no support for synchronous tools.
5+ This module provides the central ToolExecutor class that delegates tool execution
6+ to configured execution strategies.
87"""
98from __future__ import annotations
109
11- from typing import List , Optional
10+ from typing import Any , Dict , List , Optional , Union
1211
1312# Lazy import so test-suites can monkey-patch `InProcessStrategy`
1413import chuk_tool_processor .execution .strategies .inprocess_strategy as _inprocess_mod
1514from chuk_tool_processor .models .execution_strategy import ExecutionStrategy
1615from chuk_tool_processor .models .tool_call import ToolCall
1716from chuk_tool_processor .models .tool_result import ToolResult
1817from chuk_tool_processor .registry .interface import ToolRegistryInterface
18+ from chuk_tool_processor .logging import get_logger
19+
20+ logger = get_logger ("chuk_tool_processor.execution.tool_executor" )
1921
2022
2123class ToolExecutor :
2224 """
23- Convenience wrapper that selects a strategy (in-process by default) and
24- exposes a single async :py:meth:`execute` method.
25+ Async-native executor that selects and uses a strategy for tool execution.
26+
27+ This class provides a unified interface for executing tools using different
28+ execution strategies. By default, it uses the InProcessStrategy.
2529 """
2630
2731 def __init__ (
2832 self ,
29- registry : ToolRegistryInterface ,
30- default_timeout : float = 1.0 ,
31- strategy : ExecutionStrategy | None = None ,
32- * ,
33- strategy_kwargs : dict | None = None ,
33+ registry : Optional [ToolRegistryInterface ] = None ,
34+ default_timeout : float = 10.0 ,
35+ strategy : Optional [ExecutionStrategy ] = None ,
36+ strategy_kwargs : Optional [Dict [str , Any ]] = None ,
3437 ) -> None :
38+ """
39+ Initialize the tool executor.
40+
41+ Args:
42+ registry: Tool registry to use for tool lookups
43+ default_timeout: Default timeout for tool execution
44+ strategy: Optional execution strategy (default: InProcessStrategy)
45+ strategy_kwargs: Additional arguments for the strategy constructor
46+ """
3547 self .registry = registry
48+ self .default_timeout = default_timeout
49+
50+ # Create strategy if not provided
3651 if strategy is None :
52+ if registry is None :
53+ raise ValueError ("Registry must be provided if strategy is not" )
54+
3755 strategy_kwargs = strategy_kwargs or {}
3856 strategy = _inprocess_mod .InProcessStrategy (
3957 registry ,
4058 default_timeout = default_timeout ,
4159 ** strategy_kwargs ,
4260 )
61+
4362 self .strategy = strategy
4463
45- # ------------------------------------------------------------------ #
4664 async def execute (
4765 self ,
4866 calls : List [ToolCall ],
49- timeout : float | None = None ,
67+ timeout : Optional [float ] = None ,
68+ use_cache : bool = True ,
5069 ) -> List [ToolResult ]:
51- """Delegate to the underlying strategy (async)."""
52- return await self .strategy .run (calls , timeout = timeout )
70+ """
71+ Execute tool calls using the configured strategy.
72+
73+ Args:
74+ calls: List of tool calls to execute
75+ timeout: Optional timeout for execution (overrides default_timeout)
76+ use_cache: Whether to use cached results (for caching wrappers)
77+
78+ Returns:
79+ List of tool results in the same order as calls
80+ """
81+ if not calls :
82+ return []
83+
84+ # Use the provided timeout or fall back to default
85+ effective_timeout = timeout if timeout is not None else self .default_timeout
86+
87+ logger .debug (f"Executing { len (calls )} tool calls with timeout { effective_timeout } s" )
88+
89+ # Delegate to the strategy
90+ return await self .strategy .run (calls , timeout = effective_timeout )
0 commit comments