Skip to content

Commit f7cebec

Browse files
committed
Rename attribute to Parallel and apply it on the tools method
1 parent 261fd99 commit f7cebec

4 files changed

Lines changed: 52 additions & 36 deletions

File tree

src/Attributes/Parallel.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Laravel\Ai\Attributes;
4+
5+
use Attribute;
6+
use ReflectionMethod;
7+
8+
#[Attribute(Attribute::TARGET_METHOD)]
9+
final class Parallel
10+
{
11+
public static function isAppliedTo(?object $target): bool
12+
{
13+
return $target !== null
14+
&& method_exists($target, 'tools')
15+
&& (new ReflectionMethod($target, 'tools'))->getAttributes(self::class) !== [];
16+
}
17+
}

src/Attributes/ParallelTools.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/Gateway/TextGenerationOptions.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Laravel\Ai\Attributes\MaxSteps;
66
use Laravel\Ai\Attributes\MaxTokens;
7-
use Laravel\Ai\Attributes\ParallelTools;
7+
use Laravel\Ai\Attributes\Parallel;
88
use Laravel\Ai\Attributes\Temperature;
99
use Laravel\Ai\Attributes\TopP;
1010
use Laravel\Ai\Contracts\Agent;
@@ -45,7 +45,7 @@ public function providerOptions(Lab|string $provider): ?array
4545
*/
4646
public function parallelTools(): bool
4747
{
48-
return ParallelTools::isAppliedTo($this->agent);
48+
return Parallel::isAppliedTo($this->agent);
4949
}
5050

5151
/**

tests/Feature/ParallelToolsTest.php

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
use Illuminate\Support\Arr;
77
use Illuminate\Support\Defer\DeferredCallback;
88
use Illuminate\Support\Facades\Concurrency;
9-
use Laravel\Ai\Attributes\ParallelTools;
9+
use Laravel\Ai\Attributes\Parallel;
1010
use Laravel\Ai\Contracts\Agent;
1111
use Laravel\Ai\Contracts\Gateway\StepTextGateway;
12+
use Laravel\Ai\Contracts\HasTools;
1213
use Laravel\Ai\Contracts\Providers\TextProvider;
1314
use Laravel\Ai\Contracts\Tool;
1415
use Laravel\Ai\Exceptions\NoSuchToolException;
@@ -26,15 +27,19 @@
2627
use Laravel\Ai\Tools\Request;
2728
use 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

3540
test('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

4045
test('parallel tools run together with results in original order and correctly paired events', function () {
@@ -75,7 +80,7 @@
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

@@ -107,7 +112,7 @@
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

374389
class ParallelRecordingTool implements Tool

0 commit comments

Comments
 (0)