Skip to content

Commit

Permalink
chore(tests): remove obsolete RatAgentChain fixture files 🗑️
Browse files Browse the repository at this point in the history
- Deleted multiple obsolete fixture files under `tests/Fixtures/Saloon/AgentChains/`.
- Cleaned up unnecessary test data and improved project organization.
  • Loading branch information
use-the-fork committed Oct 24, 2024
1 parent 1290b94 commit b2ba6e7
Show file tree
Hide file tree
Showing 47 changed files with 488 additions and 348 deletions.
9 changes: 1 addition & 8 deletions docs/tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@ Tools allow your agent to interact with your application or external APIs. Essen
Tools are inherently part of all agents, but they are not invoked unless the `resolveTools` method returns an array of tools that the agent can use. Below is an example where the `SerperTool` is added to an agent, allowing it to perform Google searches.

```php
use UseTheFork\Synapse\Agent;
use UseTheFork\Synapse\Contracts\Agent\HasOutputSchema;
use UseTheFork\Synapse\Contracts\Integration;
use UseTheFork\Synapse\Contracts\Tool;
use UseTheFork\Synapse\Integrations\OpenAIIntegration;
use UseTheFork\Synapse\Tools\SerperTool;
use UseTheFork\Synapse\Traits\Agent\ValidatesOutputSchema;
use UseTheFork\Synapse\ValueObject\SchemaRule;
use UseTheFork\Synapse\Agent;use UseTheFork\Synapse\Contracts\Agent\HasOutputSchema;use UseTheFork\Synapse\Contracts\Integration;use UseTheFork\Synapse\Integrations\OpenAIIntegration;use UseTheFork\Synapse\Tools\Search\SerperTool;use UseTheFork\Synapse\Traits\Agent\ValidatesOutputSchema;use UseTheFork\Synapse\ValueObject\SchemaRule;

class SerperAgent extends Agent implements HasOutputSchema
{
Expand Down
7 changes: 3 additions & 4 deletions docs/tools/packaged-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ SERPER_API_KEY=
Then, include the `SerperTool` in your agent:

```php
use UseTheFork\Synapse\Tools\SerperTool;
use UseTheFork\Synapse\Tools\Search\SerperTool;

protected function resolveTools(): array
{
Expand All @@ -38,8 +38,7 @@ SERPAPI_API_KEY=
Then, include either the `SerpAPIGoogleSearchTool` or the `SerpAPIGoogleNewsTool` in your agent:

```php
use UseTheFork\Synapse\Tools\SerpAPIGoogleNewsTool;
use UseTheFork\Synapse\Tools\SerpAPIGoogleSearchTool;
use UseTheFork\Synapse\Tools\Search\SerpAPIGoogleNewsTool;use UseTheFork\Synapse\Tools\Search\SerpAPIGoogleSearchTool;

protected function resolveTools(): array
{
Expand All @@ -64,7 +63,7 @@ FIRECRAWL_API_KEY=
Then, include the `FirecrawlTool` in your agent:

```php
use UseTheFork\Synapse\Tools\FirecrawlTool;
use UseTheFork\Synapse\Tools\Scrape\FirecrawlTool;

protected function resolveTools(): array
{
Expand Down
13 changes: 9 additions & 4 deletions resources/views/Prompts/Rat/GetQueryPrompt.blade.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<message type="user">
## User input: {{ $question }}
### Question: {{ $question }}

## Response
### Content
{{ $answer }}

## Instruction
Summarize the content with a focus on the last sentences to create a concise search query for Bing. Use search syntax to make the query specific and relevant for content verification.
### Instruction
I want to verify the content correctness of the given question, especially the last sentences.
Please summarize the content with the corresponding question.
This summarization will be used as a query to search with Bing search engine.
The query should be short but need to be specific to promise Bing can find related knowledge or pages.
You can also use search syntax to make the query short and clear enough for the search engine to find relevant language data.
Try to make the query as relevant as possible to the last few sentences in the content.

@include('synapse::Parts.OutputSchema')
</message>
16 changes: 16 additions & 0 deletions resources/views/Prompts/Rat/ReflectAnswerPrompt.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<message type="user">
### Question: {{ $question }}

### Answer:
{{ $answer }}

### Instruction
Give a title for the answer of the question.
And add a subtitle to each paragraph in the answer and output the final answer using markdown format.
This will make the answer to this question look more structured for better understanding.

**IMPORTANT**
Try to keep the structure (multiple paragraphs with its subtitles) in the response and make it more structural for understanding.

@include('synapse::Parts.OutputSchema')
</message>
25 changes: 25 additions & 0 deletions resources/views/Prompts/Rat/ReviseAnswerPrompt.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<message type="user">
### Existing Text in Wiki Web:
```
{{ $content }}
```

### Question: {{ $question }}

### Answer:
{{ $answer }}

### Instruction
I want to revise the answer according to retrieved related text of the question in WIKI pages.
You need to check whether the answer is correct.
If you find some errors in the answer, revise the answer to make it better.
If you find some necessary details are ignored, add it to make the answer more plausible according to the related text.
If you find the answer is right and do not need to add more details, just output the original answer directly.

**IMPORTANT**
Try to keep the structure (multiple paragraphs with its subtitles) in the revised answer and make it more structural for understanding.
Add more details from retrieved text to the answer.
Split the paragraphs with \n\n characters.

@include('synapse::Parts.OutputSchema')
</message>
58 changes: 2 additions & 56 deletions src/AgentChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,10 @@

namespace UseTheFork\Synapse;

use UseTheFork\Synapse\AgentTask\PendingAgentChain;
use UseTheFork\Synapse\Traits\HasConfig;
use UseTheFork\Synapse\Traits\Makeable;
use UseTheFork\Synapse\ValueObject\Message;

class AgentChain
abstract class AgentChain
{
use Makeable;
use HasConfig;

protected PendingAgentChain $pendingAgentChain;
protected $pipeline;

public function __construct(array $agents)
{
foreach ($agents as $agent) {
if(! ($agent instanceof Agent)){
throw new \Exception("Agent must be an instance of Agent");
}
}

$this->config()->add('persistInputs', []);
$this->config()->add('agents', collect($agents));
$this->pendingAgentChain = $this->createPendingAgentChain();

}

/**
* Create a new PendingAgentTask
*/
public function createPendingAgentChain(): PendingAgentChain
{
return new PendingAgentChain($this);
}

/**
* Handles the user input and extra agent arguments to retrieve the response.
Expand All @@ -48,29 +18,5 @@ public function createPendingAgentChain(): PendingAgentChain
*
* @throws Throwable
*/
public function handle(?array $input): Message
{
$this->config()->add('input', $input);
$this->config()->get('agents')->each(function ($agent) use ($input) {
$input = [
...$this->config()->get('input'),
...$this->config()->get('persistInputs')
];
$response = $agent->handle($input);
$this->config()->add('input', $response->content());
});

return Message::make([
'role' => 'agent',
'finish_reason' => 'stop',
'content' => $this->config()->get('input')
]);
}

public function persistInputs(array $inputs): static
{
$this->config()->add('persistInputs', $inputs);

return $this;
}
abstract public function handle(?array $input, ?array $extraAgentArgs): Message;
}
78 changes: 78 additions & 0 deletions src/AgentChains/RatAgentChain.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace UseTheFork\Synapse\AgentChains;

use UseTheFork\Synapse\AgentChain;
use UseTheFork\Synapse\Agents\Rat\GetQueryAgent;
use UseTheFork\Synapse\Agents\Rat\RatDraftAgent;
use UseTheFork\Synapse\Agents\Rat\RatSplitAnswerAgent;
use UseTheFork\Synapse\Agents\Rat\ReflectAnswerAgent;
use UseTheFork\Synapse\Agents\Rat\ReviseAnswerAgent;
use UseTheFork\Synapse\Contracts\Tool\ScrapeTool;
use UseTheFork\Synapse\Contracts\Tool\SearchTool;
use UseTheFork\Synapse\ValueObject\Message;

/*
* See: https://github.com/CraftJarvis/RAT/tree/main
*/
class RatAgentChain extends AgentChain
{
protected ScrapeTool $scrapeTool;
protected SearchTool $searchTool;

public function __construct(SearchTool $searchTool, ScrapeTool $scrapeTool)
{
$this->searchTool = $searchTool;
$this->scrapeTool = $scrapeTool;
}

public function handle(?array $input, ?array $extraAgentArgs = []): Message
{

$ratDraftAgent = new RatDraftAgent;
$result = $ratDraftAgent->handle($input);

$ratSplitAnswerAgent = new RatSplitAnswerAgent;
$result = $ratSplitAnswerAgent->handle([
...$input,
...$result->content()
]);

$answer = str('');
foreach ($result->content()['paragraphs'] as $value) {

$answer = $answer->append("\n\n", $value);

$getQueryAgent = new GetQueryAgent;
$result = $getQueryAgent->handle([
...$input,
'answer' => $answer->toString()
]);

$searchResult = $this->searchTool->handle($result->content()['query']);
$searchResult = json_decode($searchResult, true);

# Get the first Result scrape page and enhance
if(!empty($searchResult[0])){
$scrapeResult = $this->scrapeTool->handle($searchResult[0]['link']);

$getQueryAgent = new ReviseAnswerAgent;
$result = $getQueryAgent->handle([
...$input,
'content' => $scrapeResult,
'answer' => $answer->toString()
]);
$answer = str($result->content()['answer']);
}

}

$reflectAnswerAgent = new ReflectAnswerAgent;
return $reflectAnswerAgent->handle([
...$input,
'answer' => $answer->toString()
]);
}
}
27 changes: 27 additions & 0 deletions src/Agents/Rat/ReflectAnswerAgent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace UseTheFork\Synapse\Agents\Rat;

use UseTheFork\Synapse\Agent;
use UseTheFork\Synapse\Traits\Agent\ValidatesOutputSchema;
use UseTheFork\Synapse\ValueObject\SchemaRule;

class ReflectAnswerAgent extends Agent
{
use ValidatesOutputSchema;

protected string $promptView = 'synapse::Prompts.Rat.ReflectAnswerPrompt';

public function resolveOutputSchema(): array
{
return [
SchemaRule::make([
'name' => 'answer',
'rules' => 'required|string',
'description' => 'Your answer.',
]),
];
}
}
27 changes: 27 additions & 0 deletions src/Agents/Rat/ReviseAnswerAgent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace UseTheFork\Synapse\Agents\Rat;

use UseTheFork\Synapse\Agent;
use UseTheFork\Synapse\Traits\Agent\ValidatesOutputSchema;
use UseTheFork\Synapse\ValueObject\SchemaRule;

class ReviseAnswerAgent extends Agent
{
use ValidatesOutputSchema;

protected string $promptView = 'synapse::Prompts.Rat.ReviseAnswerPrompt';

public function resolveOutputSchema(): array
{
return [
SchemaRule::make([
'name' => 'answer',
'rules' => 'required|string',
'description' => 'Your answer.',
]),
];
}
}
7 changes: 2 additions & 5 deletions src/Contracts/Tool/SearchTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@

namespace UseTheFork\Synapse\Contracts\Tool;

use UseTheFork\Synapse\Enums\ReturnType;

interface SearchTool
{
public function handle(
string $query,
?string $searchType = 'search',
?int $numberOfResults = 10,
ReturnType $returnType = ReturnType::STRING,
): string|array;
?int $numberOfResults = 10
): string;
}
12 changes: 3 additions & 9 deletions src/Tools/Search/SerpAPIGoogleNewsTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Illuminate\Support\Arr;
use UseTheFork\Synapse\Contracts\Tool;
use UseTheFork\Synapse\Contracts\Tool\SearchTool;
use UseTheFork\Synapse\Enums\ReturnType;
use UseTheFork\Synapse\Exceptions\MissingApiKeyException;
use UseTheFork\Synapse\Services\SerpApi\Requests\SerpApiSearchRequest;
use UseTheFork\Synapse\Services\SerpApi\SerpApiConnector;
Expand All @@ -34,19 +33,14 @@ public function __construct()
public function handle(
string $query,
?string $searchType = 'search',
?int $numberOfResults = 10,
?ReturnType $returnType = ReturnType::STRING,
): string|array {
?int $numberOfResults = 10
): string {

$serpApiConnector = new SerpApiConnector($this->apiKey);
$serpApiSearchRequest = new SerpApiSearchRequest($query, 0, 'google_news');

$results = $serpApiConnector->send($serpApiSearchRequest)->array();

return match ($returnType) {
ReturnType::STRING => $this->parseResults($results),
default => $results
};
return $this->parseResults($results);
}

private function parseResults(array $results): string
Expand Down
11 changes: 3 additions & 8 deletions src/Tools/Search/SerpAPIGoogleSearchTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Illuminate\Support\Str;
use UseTheFork\Synapse\Contracts\Tool;
use UseTheFork\Synapse\Contracts\Tool\SearchTool;
use UseTheFork\Synapse\Enums\ReturnType;
use UseTheFork\Synapse\Exceptions\MissingApiKeyException;
use UseTheFork\Synapse\Services\SerpApi\Requests\SerpApiSearchRequest;
use UseTheFork\Synapse\Services\SerpApi\SerpApiConnector;
Expand Down Expand Up @@ -36,19 +35,15 @@ public function __construct()
public function handle(
string $query,
?string $searchType = 'search',
?int $numberOfResults = 10,
ReturnType $returnType = ReturnType::STRING,
): string|array {
?int $numberOfResults = 10
): string {

$serpApiConnector = new SerpApiConnector($this->apiKey);
$serpApiSearchRequest = new SerpApiSearchRequest($query, $numberOfResults);

$results = $serpApiConnector->send($serpApiSearchRequest)->array();

return match ($returnType) {
ReturnType::STRING => $this->parseResults($results),
default => $results
};
return $this->parseResults($results);
}

private function parseResults(array $results): string
Expand Down
Loading

0 comments on commit b2ba6e7

Please sign in to comment.