-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adding ai based generated solutions (#534)
* feat: adding ai based generated solutions * Fix styling * fix: docs * fix: wip * Fix styling --------- Co-authored-by: binaryk <[email protected]>
- Loading branch information
Showing
8 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
title: AI Solution | ||
menuTitle: AI Solution | ||
description: AI Solution | ||
category: Advanced | ||
position: 14 | ||
--- | ||
|
||
## Generate solution | ||
|
||
Restify can generate an AI based solution to your problem. In order to enable that you need to extend the `App\Exceptions\Handler` with the `Binaryk\LaravelRestify\Exceptions\RestifyHandler`: | ||
|
||
```php | ||
use Binaryk\LaravelRestify\Exceptions\RestifyHandler; | ||
use Throwable; | ||
|
||
class Handler extends RestifyHandler | ||
{ | ||
//... | ||
} | ||
``` | ||
|
||
<alert type="warning"> | ||
This feature is only enabled when the `app.debug` is set to `true`. | ||
</alert> | ||
|
||
|
||
This feature is using the [openai-php/laravel](https://github.com/openai-php/laravel#get-started), you should also publish the config file: | ||
|
||
``` | ||
php artisan vendor:publish --provider="OpenAI\Laravel\ServiceProvider" | ||
``` | ||
|
||
and set the `OPENAI_API_KEY` in the `.env` file. | ||
|
||
The OpenAI key can be obtained from [here](https://platform.openai.com/account/api-keys). | ||
|
||
|
||
Now the solution to your problems will automatically appear in the response: | ||
|
||
```json | ||
{ | ||
"restify-solution": "Line 67 in DocumentRepository.php file has an error because the method `resolveUsingFullPath()` is not defined. The code should look like this:\n```\n->resolveUsingTemporaryUrl($request->boolean('temporary'))\n```\n", | ||
"message": "Call to undefined method Binaryk\\LaravelRestify\\Fields\\File::resolveUsingFullPath()", | ||
"exception": "Error", | ||
"file": "/Users/eduardlupacescu/Sites/binarcode/erp/app/Restify/DocumentRepository.php", | ||
"line": 67, | ||
"trace": [ | ||
... | ||
} | ||
``` | ||
|
||
## Disable solution | ||
|
||
|
||
If you want to disable the solution feature you can set the `restify.ai_solution` to `false` in the `config/restify.php` file so Restify will not call the OpenAI API even you extended the exception handler. This might be useful in automated tests or other environments: | ||
|
||
```php | ||
// config/restify.php | ||
'ai_solutions' => true, | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
You are a very good PHP developer. Use the following context to find a possible fix for the exception message at the end. | ||
|
||
File: /Users/binarcode/Code/ai-errors/app/Documentation.php | ||
Exception: syntax error, unexpected token "{", expecting variable | ||
Line: 193 | ||
|
||
Snippet including line numbers: | ||
192 public static function getDocVersions( | ||
193 { | ||
194 return [ | ||
195 'master' => 'Master', | ||
196 '9.x' => '9.x', | ||
|
||
Possible Fix: | ||
Line 192 in Documentation.php file has a syntax error (missing a closing parenthesis). The code should look like this: `public static function getDocVersions()` | ||
|
||
File: {!! $file !!} | ||
Exception: {!! $exception !!} | ||
Line: {!! $line !!} | ||
|
||
Snippet including line numbers: | ||
{!! $snippet !!} | ||
|
||
Possible Fix: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{!! $solution !!} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace Binaryk\LaravelRestify\Exceptions; | ||
|
||
use Binaryk\LaravelRestify\Exceptions\Solutions\OpenAiSolution; | ||
use Illuminate\Foundation\Exceptions\Handler; | ||
use Throwable; | ||
|
||
class RestifyHandler extends Handler | ||
{ | ||
protected function convertExceptionToArray(Throwable $e): array | ||
{ | ||
$response = parent::convertExceptionToArray($e); | ||
|
||
if (! config('restify.ai_solutions')) { | ||
return $response; | ||
} | ||
|
||
if (! config('app.debug')) { | ||
return $response; | ||
} | ||
|
||
if (! config('openai.api_key')) { | ||
return $response; | ||
} | ||
|
||
$solution = (new OpenAiSolution($e))->getSolutionDescription(); | ||
|
||
return array_merge([ | ||
'restify-solution' => $solution, | ||
], $response); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
|
||
namespace Binaryk\LaravelRestify\Exceptions\Solutions; | ||
|
||
use Illuminate\Support\Facades\Cache; | ||
use OpenAI\Laravel\Facades\OpenAI; | ||
use Spatie\Backtrace\Backtrace; | ||
use Spatie\Backtrace\Frame; | ||
use Throwable; | ||
|
||
class OpenAiSolution | ||
{ | ||
protected string $solution; | ||
|
||
public function __construct(protected Throwable $throwable) | ||
{ | ||
$this->solution = Cache::remember('restify-solution-'.sha1($this->throwable->getTraceAsString()), | ||
now()->addHour(), | ||
fn () => OpenAI::completions()->create([ | ||
'model' => 'text-davinci-003', | ||
'prompt' => $this->generatePrompt($this->throwable), | ||
'max_tokens' => 100, | ||
'temperature' => 0, | ||
])->choices[0]->text | ||
); | ||
} | ||
|
||
public function getSolutionTitle(): string | ||
{ | ||
return 'AI Generated Solution'; | ||
} | ||
|
||
public function getSolutionDescription(): string | ||
{ | ||
return view('restify::prompts.solution', [ | ||
'solution' => $this->solution, | ||
])->render(); | ||
} | ||
|
||
public function getDocumentationLinks(): array | ||
{ | ||
return []; | ||
} | ||
|
||
protected function getApplicationFrame(Throwable $throwable): ?Frame | ||
{ | ||
$backtrace = Backtrace::createForThrowable($throwable)->applicationPath(base_path()); | ||
$frames = $backtrace->frames(); | ||
|
||
return $frames[$backtrace->firstApplicationFrameIndex()] ?? null; | ||
} | ||
|
||
protected function generatePrompt(Throwable $throwable): string | ||
{ | ||
$applicationFrame = $this->getApplicationFrame($throwable); | ||
|
||
$snippet = $applicationFrame->getSnippet(15); | ||
|
||
return (string) view('restify::prompts.prompt', [ | ||
'snippet' => collect($snippet)->map(fn ($line, $number) => $number.' '.$line)->join(PHP_EOL), | ||
'file' => $applicationFrame->file, | ||
'line' => $applicationFrame->lineNumber, | ||
'exception' => $throwable->getMessage(), | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters