Skip to content

Commit 60e51f4

Browse files
committed
Init project
0 parents  commit 60e51f4

14 files changed

+515
-0
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
/vendor
3+
/.idea

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) llm-agents-php <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Prompt generator for LLM Agents
2+
3+
[![PHP](https://img.shields.io/packagist/php-v/llm-agents-php/agent-site-status-checker.svg?style=flat-square)](https://packagist.org/packages/llm-agents/prompt-generator)
4+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/llm-agents/prompt-generator.svg?style=flat-square)](https://packagist.org/packages/llm-agents/prompt-generator)
5+
[![Total Downloads](https://img.shields.io/packagist/dt/llm-agents/prompt-generator.svg?style=flat-square)](https://packagist.org/packages/llm-agents/prompt-generator)
6+
7+
### Installation
8+
9+
First things first, let's get this package installed:
10+
11+
```bash
12+
composer require llm-agents/prompt-generator
13+
```
14+
15+
### Setup in Spiral Framework
16+
17+
To get the Site Status Checker Agent up and running in your Spiral Framework project, you need to register its
18+
bootloader.
19+
20+
**Here's how:**
21+
22+
1. Open up your `app/src/Application/Kernel.php` file.
23+
2. Add the bootloader like this:
24+
```php
25+
public function defineBootloaders(): array
26+
{
27+
return [
28+
// ... other bootloaders ...
29+
\LLM\Agents\PromptGenerator\Integration\Spiral\PromptGeneratorBootloader::class,
30+
];
31+
}
32+
```
33+
34+
And that's it! Your Spiral app is now ready to use the agent.
35+
36+
## Want to help out? 🤝
37+
38+
We love contributions! If you've got ideas to make this agent even cooler, here's how you can chip in:
39+
40+
1. Fork the repo
41+
2. Make your changes
42+
3. Create a new Pull Request
43+
44+
Just make sure your code is clean, well-commented, and follows PSR-12 coding standards.
45+
46+
## License 📄
47+
48+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
49+
50+
---
51+
52+
That's all, folks! If you've got any questions or run into any trouble, don't hesitate to open an issue.

composer.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "llm-agents/prompt-generator",
3+
"description": "Prompt generator for LLM agents with interceptors",
4+
"license": "MIT",
5+
"require": {
6+
"php": "^8.3",
7+
"llm-agents/agents": "^1.0",
8+
"llm-agents/json-schema-mapper": "^1.0"
9+
},
10+
"require-dev": {
11+
"phpunit/phpunit": "^11.3",
12+
"spiral/boot": "^3.13",
13+
"illuminate/support": "^11.0"
14+
},
15+
"autoload": {
16+
"psr-4": {
17+
"LLM\\Agents\\PromptGenerator\\": "src"
18+
}
19+
},
20+
"autoload-dev": {
21+
"psr-4": {
22+
"LLM\\Agents\\PromptGenerator\\Tests\\": "tests/src"
23+
}
24+
},
25+
"config": {
26+
"sort-packages": true
27+
},
28+
"minimum-stability": "dev",
29+
"prefer-stable": true
30+
}

src/Context.php

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Agents\PromptGenerator;
6+
7+
use LLM\Agents\LLM\PromptContextInterface;
8+
9+
class Context implements PromptContextInterface
10+
{
11+
private array|\JsonSerializable|null $authContext = null;
12+
13+
final public static function new(): self
14+
{
15+
return new self();
16+
}
17+
18+
public function setAuthContext(array|\JsonSerializable $authContext): self
19+
{
20+
$this->authContext = $authContext;
21+
22+
return $this;
23+
}
24+
25+
public function getAuthContext(): array|\JsonSerializable|null
26+
{
27+
return $this->authContext;
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Agents\PromptGenerator\Integration\Spiral;
6+
7+
use LLM\Agents\LLM\AgentPromptGeneratorInterface;
8+
use LLM\Agents\PromptGenerator\PromptGeneratorPipeline;
9+
use LLM\Agents\PromptGenerator\PromptGeneratorPipelineInterface;
10+
use Spiral\Boot\Bootloader\Bootloader;
11+
12+
final class PromptGeneratorBootloader extends Bootloader
13+
{
14+
public function defineSingletons(): array
15+
{
16+
return [
17+
PromptGeneratorPipeline::class => PromptGeneratorPipeline::class,
18+
PromptGeneratorPipelineInterface::class => PromptGeneratorPipeline::class,
19+
AgentPromptGeneratorInterface::class => PromptGeneratorPipeline::class,
20+
];
21+
}
22+
}
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Agents\PromptGenerator\Interceptors;
6+
7+
use LLM\Agents\Agent\AgentInterface;
8+
use LLM\Agents\LLM\AgentPromptGeneratorInterface;
9+
use LLM\Agents\LLM\Prompt\Chat\MessagePrompt;
10+
use LLM\Agents\LLM\Prompt\Chat\Prompt;
11+
use LLM\Agents\LLM\Prompt\Chat\PromptInterface;
12+
use LLM\Agents\LLM\PromptContextInterface;
13+
use LLM\Agents\PromptGenerator\PromptInterceptorInterface;
14+
use LLM\Agents\Solution\SolutionMetadata;
15+
16+
final class AgentMemoryInjector implements PromptInterceptorInterface
17+
{
18+
public function generate(
19+
AgentInterface $agent,
20+
\Stringable|string $userPrompt,
21+
PromptInterface $prompt,
22+
PromptContextInterface $context,
23+
AgentPromptGeneratorInterface $next,
24+
): PromptInterface {
25+
\assert($prompt instanceof Prompt);
26+
27+
return $next->generate(
28+
agent: $agent,
29+
userPrompt: $userPrompt,
30+
context: $context,
31+
prompt: $prompt
32+
->withAddedMessage(
33+
MessagePrompt::system(
34+
prompt: 'Instructions about your experiences, follow them: {memory}. And also {dynamic_memory}',
35+
),
36+
)
37+
->withValues(
38+
values: [
39+
'memory' => \implode(
40+
PHP_EOL,
41+
\array_map(
42+
static fn(SolutionMetadata $metadata) => $metadata->content,
43+
$agent->getMemory(),
44+
),
45+
),
46+
'dynamic_memory' => '',
47+
],
48+
),
49+
);
50+
}
51+
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Agents\PromptGenerator\Interceptors;
6+
7+
use LLM\Agents\Agent\AgentInterface;
8+
use LLM\Agents\LLM\AgentPromptGeneratorInterface;
9+
use LLM\Agents\LLM\Prompt\Chat\MessagePrompt;
10+
use LLM\Agents\LLM\Prompt\Chat\Prompt;
11+
use LLM\Agents\LLM\Prompt\Chat\PromptInterface;
12+
use LLM\Agents\LLM\PromptContextInterface;
13+
use LLM\Agents\PromptGenerator\PromptInterceptorInterface;
14+
15+
final class InstructionGenerator implements PromptInterceptorInterface
16+
{
17+
public function generate(
18+
AgentInterface $agent,
19+
\Stringable|string $userPrompt,
20+
PromptInterface $prompt,
21+
PromptContextInterface $context,
22+
AgentPromptGeneratorInterface $next,
23+
): PromptInterface {
24+
\assert($prompt instanceof Prompt);
25+
26+
return $next->generate(
27+
agent: $agent,
28+
userPrompt: $userPrompt,
29+
context: $context,
30+
prompt: $prompt
31+
->withAddedMessage(
32+
MessagePrompt::system(
33+
prompt: <<<'PROMPT'
34+
{prompt}
35+
Important rules:
36+
- always response in markdown format
37+
- think before responding to user
38+
PROMPT,
39+
),
40+
)
41+
->withValues(
42+
values: [
43+
'prompt' => $agent->getInstruction(),
44+
],
45+
),
46+
);
47+
}
48+
}
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LLM\Agents\PromptGenerator\Interceptors;
6+
7+
use LLM\Agents\Agent\AgentInterface;
8+
use LLM\Agents\Agent\AgentRepositoryInterface;
9+
use LLM\Agents\LLM\AgentPromptGeneratorInterface;
10+
use LLM\Agents\LLM\Prompt\Chat\MessagePrompt;
11+
use LLM\Agents\LLM\Prompt\Chat\Prompt;
12+
use LLM\Agents\LLM\Prompt\Chat\PromptInterface;
13+
use LLM\Agents\LLM\PromptContextInterface;
14+
use LLM\Agents\PromptGenerator\PromptInterceptorInterface;
15+
use LLM\Agents\Solution\AgentLink;
16+
use LLM\Agents\Tool\SchemaMapperInterface;
17+
18+
final readonly class LinkedAgentsInjector implements PromptInterceptorInterface
19+
{
20+
public function __construct(
21+
private AgentRepositoryInterface $agents,
22+
private SchemaMapperInterface $schemaMapper,
23+
) {}
24+
25+
public function generate(
26+
AgentInterface $agent,
27+
\Stringable|string $userPrompt,
28+
PromptInterface $prompt,
29+
PromptContextInterface $context,
30+
AgentPromptGeneratorInterface $next,
31+
): PromptInterface {
32+
\assert($prompt instanceof Prompt);
33+
34+
if (\count($agent->getAgents()) === 0) {
35+
return $next->generate(
36+
agent: $agent,
37+
userPrompt: $userPrompt,
38+
context: $context,
39+
prompt: $prompt,
40+
);
41+
}
42+
43+
$associatedAgents = \array_map(
44+
fn(AgentLink $agent): array => [
45+
'agent' => $this->agents->get($agent->getName()),
46+
'output_schema' => \json_encode($this->schemaMapper->toJsonSchema($agent->outputSchema)),
47+
],
48+
$agent->getAgents(),
49+
);
50+
51+
return $next->generate(
52+
agent: $agent,
53+
userPrompt: $userPrompt,
54+
context: $context,
55+
prompt: $prompt
56+
->withAddedMessage(
57+
MessagePrompt::system(
58+
prompt: <<<'PROMPT'
59+
There are agents {linked_agents} associated with you. You can ask them for help if you need it.
60+
Use the `ask_agent` tool and provide the agent key.
61+
Always follow rules:
62+
- Don't make up the agent key. Use only the ones from the provided list.
63+
PROMPT,
64+
),
65+
)
66+
->withValues(
67+
values: [
68+
'linked_agents' => \implode(
69+
PHP_EOL,
70+
\array_map(
71+
static fn(array $agent): string => \json_encode([
72+
'key' => $agent['agent']->getKey(),
73+
'description' => $agent['agent']->getDescription(),
74+
'output_schema' => $agent['output_schema'],
75+
]),
76+
$associatedAgents,
77+
),
78+
),
79+
],
80+
),
81+
);
82+
}
83+
}

0 commit comments

Comments
 (0)