1010use Cognesy \Agents \Data \AgentState ;
1111use Cognesy \Agents \Data \AgentStep ;
1212use Cognesy \Agents \Data \ToolExecution ;
13+ use Cognesy \Agents \Drivers \CanAcceptToolRuntime ;
1314use Cognesy \Agents \Drivers \CanUseTools ;
1415use Cognesy \Agents \Drivers \ReAct \Actions \MakeReActPrompt ;
1516use Cognesy \Agents \Drivers \ReAct \Actions \MakeToolCalls ;
2223use Cognesy \Agents \Events \InferenceResponseReceived ;
2324use Cognesy \Agents \Events \ValidationFailed ;
2425use Cognesy \Agents \Exceptions \AgentException ;
26+ use Cognesy \Agents \Interception \PassThroughInterceptor ;
27+ use Cognesy \Agents \Tool \ToolExecutor ;
2528use Cognesy \Agents \Tool \Contracts \CanExecuteToolCalls ;
2629use Cognesy \Events \Contracts \CanHandleEvents ;
2730use Cognesy \Events \EventBusResolver ;
5154use Cognesy \Utils \Result \Result ;
5255use DateTimeImmutable ;
5356
54- final class ReActDriver implements CanUseTools, CanAcceptLLMConfig, CanAcceptMessageCompiler
57+ final class ReActDriver implements CanUseTools, CanAcceptToolRuntime, CanAcceptLLMConfig, CanAcceptMessageCompiler
5558{
5659 private LLMProvider $ llm ;
5760 private ?HttpClient $ httpClient = null ;
@@ -66,6 +69,8 @@ final class ReActDriver implements CanUseTools, CanAcceptLLMConfig, CanAcceptMes
6669 private CanHandleEvents $ events ;
6770 private CanCreateInference $ inference ;
6871 private CanCreateStructuredOutput $ structuredOutput ;
72+ private Tools $ tools ;
73+ private CanExecuteToolCalls $ executor ;
6974
7075 public function __construct (
7176 CanCreateInference $ inference ,
@@ -81,6 +86,8 @@ public function __construct(
8186 OutputMode $ mode = OutputMode::Json,
8287 ?CanCompileMessages $ messageCompiler = null ,
8388 ?CanHandleEvents $ events = null ,
89+ ?Tools $ tools = null ,
90+ ?CanExecuteToolCalls $ executor = null ,
8491 ) {
8592 $ this ->inference = $ inference ;
8693 $ this ->structuredOutput = $ structuredOutput ;
@@ -95,13 +102,19 @@ public function __construct(
95102 $ this ->mode = $ mode ;
96103 $ this ->messageCompiler = $ messageCompiler ?? new ConversationWithCurrentToolTrace ();
97104 $ this ->events = EventBusResolver::using ($ events );
105+ $ this ->tools = $ tools ?? new Tools ();
106+ $ this ->executor = $ executor ?? new ToolExecutor (
107+ tools: $ this ->tools ,
108+ events: $ this ->events ,
109+ interceptor: new PassThroughInterceptor (),
110+ );
98111 }
99112
100113 #[\Override]
101- public function useTools (AgentState $ state, Tools $ tools , CanExecuteToolCalls $ executor ): AgentState {
114+ public function useTools (AgentState $ state ): AgentState {
102115 $ state = $ this ->ensureStateLLMConfig ($ state );
103116 $ messages = $ this ->messageCompiler ->compile ($ state );
104- $ system = $ this ->buildSystemPrompt ($ tools );
117+ $ system = $ this ->buildSystemPrompt ($ this -> tools );
105118 $ cachedContext = $ this ->structuredCachedContext ($ state );
106119
107120 $ requestStartedAt = new DateTimeImmutable ();
@@ -131,7 +144,7 @@ public function useTools(AgentState $state, Tools $tools, CanExecuteToolCalls $e
131144 $ this ->emitInferenceResponseReceived ($ state , $ inferenceResponse , $ requestStartedAt );
132145
133146 $ validator = new ReActValidator ();
134- $ validation = $ validator ->validateBasicDecision ($ decision , $ tools ->names ());
147+ $ validation = $ validator ->validateBasicDecision ($ decision , $ this -> tools ->names ());
135148 if ($ validation ->isInvalid ()) {
136149 $ this ->emitValidationFailed (
137150 state: $ state ,
@@ -142,7 +155,7 @@ public function useTools(AgentState $state, Tools $tools, CanExecuteToolCalls $e
142155 return $ state ->withCurrentStep ($ step )->withFailure (new AgentException ($ validation ->getErrorMessage ()));
143156 }
144157
145- $ toolCalls = (new MakeToolCalls ($ tools , $ validator ))($ decision );
158+ $ toolCalls = (new MakeToolCalls ($ this -> tools , $ validator ))($ decision );
146159
147160 $ usage = $ inferenceResponse ->usage ();
148161
@@ -157,7 +170,7 @@ public function useTools(AgentState $state, Tools $tools, CanExecuteToolCalls $e
157170 return $ state ->withCurrentStep ($ step );
158171 }
159172
160- $ executions = $ executor ->executeTools ($ toolCalls , $ state );
173+ $ executions = $ this -> executor ->executeTools ($ toolCalls , $ state );
161174
162175 $ outputMessages = $ this ->makeFollowUps ($ decision , $ executions );
163176 $ responseWithCalls = $ this ->withToolCalls ($ inferenceResponse , $ toolCalls );
@@ -209,6 +222,11 @@ public function withMessageCompiler(CanCompileMessages $compiler): static {
209222 return $ this ->with (messageCompiler: $ compiler );
210223 }
211224
225+ #[\Override]
226+ public function withToolRuntime (Tools $ tools , CanExecuteToolCalls $ executor ): static {
227+ return $ this ->with (tools: $ tools , executor: $ executor );
228+ }
229+
212230 // INTERNAL ////////////////////////////////////////////////////////////////
213231
214232 private function with (
@@ -224,6 +242,8 @@ private function with(
224242 ?CanCompileMessages $ messageCompiler = null ,
225243 ?CanCreateInference $ inference = null ,
226244 ?CanCreateStructuredOutput $ structuredOutput = null ,
245+ ?Tools $ tools = null ,
246+ ?CanExecuteToolCalls $ executor = null ,
227247 ): self {
228248 return new self (
229249 inference: $ inference ?? $ this ->inference ,
@@ -239,6 +259,8 @@ private function with(
239259 mode: $ mode ?? $ this ->mode ,
240260 messageCompiler: $ messageCompiler ?? $ this ->messageCompiler ,
241261 events: $ this ->events ,
262+ tools: $ tools ?? $ this ->tools ,
263+ executor: $ executor ?? $ this ->executor ,
242264 );
243265 }
244266
0 commit comments