66use Illuminate \Support \Arr ;
77use Illuminate \Support \Defer \DeferredCallback ;
88use Illuminate \Support \Facades \Concurrency ;
9- use Laravel \Ai \Attributes \ParallelTools ;
9+ use Laravel \Ai \Attributes \Parallel ;
1010use Laravel \Ai \Contracts \Agent ;
1111use Laravel \Ai \Contracts \Gateway \StepTextGateway ;
12+ use Laravel \Ai \Contracts \HasTools ;
1213use Laravel \Ai \Contracts \Providers \TextProvider ;
1314use Laravel \Ai \Contracts \Tool ;
1415use Laravel \Ai \Exceptions \NoSuchToolException ;
2627use Laravel \Ai \Tools \Request ;
2728use Laravel \SerializableClosure \SerializableClosure ;
2829
29- test ('the parallel tools attribute is detected on an agent ' , function () {
30- expect (ParallelTools::isAppliedTo (new ParallelToolsAgent ))->toBeTrue ()
31- ->and (ParallelTools::isAppliedTo (new SequentialToolsAgent ))->toBeFalse ()
32- ->and (ParallelTools::isAppliedTo (null ))->toBeFalse ();
30+ test ('the parallel attribute is detected on the tools method ' , function () {
31+ expect (Parallel::isAppliedTo (new ParallelAgent ))->toBeTrue ()
32+ ->and (Parallel::isAppliedTo (new SequentialAgent ))->toBeFalse ()
33+ ->and (Parallel::isAppliedTo (new class
34+ {
35+ // An agent without a tools() method is never parallel.
36+ }))->toBeFalse ()
37+ ->and (Parallel::isAppliedTo (null ))->toBeFalse ();
3338});
3439
3540test ('forAgent resolves whether the agent runs its tools in parallel ' , function () {
36- expect (TextGenerationOptions::forAgent (new ParallelToolsAgent )->parallelTools ())->toBeTrue ()
37- ->and (TextGenerationOptions::forAgent (new SequentialToolsAgent )->parallelTools ())->toBeFalse ();
41+ expect (TextGenerationOptions::forAgent (new ParallelAgent )->parallelTools ())->toBeTrue ()
42+ ->and (TextGenerationOptions::forAgent (new SequentialAgent )->parallelTools ())->toBeFalse ();
3843});
3944
4045test ('parallel tools run together with results in original order and correctly paired events ' , function () {
7580 [],
7681 $ tools ,
7782 null ,
78- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
83+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
7984 null ,
8085 );
8186
107112 [],
108113 [new ParallelRecordingTool ('solo ' , $ log , 'S ' )],
109114 null ,
110- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
115+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
111116 null ,
112117 );
113118
@@ -146,7 +151,7 @@ protected function canRunInParallel(): bool
146151 [],
147152 $ tools ,
148153 null ,
149- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
154+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
150155 null ,
151156 );
152157
@@ -178,7 +183,7 @@ protected function canRunInParallel(): bool
178183 [],
179184 $ tools ,
180185 null ,
181- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
186+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
182187 null ,
183188 ))->toThrow (RuntimeException::class, 'boom:bravo ' );
184189});
@@ -202,7 +207,7 @@ protected function canRunInParallel(): bool
202207 [],
203208 [new ParallelRecordingTool ('alpha ' , $ log , 'A ' )],
204209 null ,
205- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
210+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
206211 null ,
207212 ))->toThrow (NoSuchToolException::class)
208213 ->and ($ log ->getArrayCopy ())->toBe ([]);
@@ -234,7 +239,7 @@ protected function canRunInParallel(): bool
234239 [],
235240 $ tools ,
236241 null ,
237- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
242+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
238243 null ,
239244 ));
240245
@@ -271,7 +276,7 @@ protected function canRunInParallel(): bool
271276 [],
272277 $ tools ,
273278 null ,
274- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
279+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
275280 null ,
276281 );
277282
@@ -320,7 +325,7 @@ protected function canRunInParallel(): bool
320325 [],
321326 $ tools ,
322327 null ,
323- new TextGenerationOptions (maxSteps: 2 , agent: new ParallelToolsAgent ),
328+ new TextGenerationOptions (maxSteps: 2 , agent: new ParallelAgent ),
324329 null ,
325330 );
326331
@@ -350,25 +355,35 @@ function parallelToolsGateway(array $steps = [], array $streams = []): ParallelT
350355 return new ParallelToolsFakeGateway ($ steps , $ streams );
351356}
352357
353- #[ParallelTools]
354- class ParallelToolsAgent implements Agent
358+ class ParallelAgent implements Agent, HasTools
355359{
356360 use Promptable;
357361
358362 public function instructions (): string
359363 {
360364 return 'test ' ;
361365 }
366+
367+ #[Parallel]
368+ public function tools (): array
369+ {
370+ return [];
371+ }
362372}
363373
364- class SequentialToolsAgent implements Agent
374+ class SequentialAgent implements Agent, HasTools
365375{
366376 use Promptable;
367377
368378 public function instructions (): string
369379 {
370380 return 'test ' ;
371381 }
382+
383+ public function tools (): array
384+ {
385+ return [];
386+ }
372387}
373388
374389class ParallelRecordingTool implements Tool
0 commit comments