Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1294 lars 1
<?php
2
 
3
namespace Spatie\Ignition\Solutions\OpenAi;
4
 
5
use OpenAI;
6
use Psr\SimpleCache\CacheInterface;
7
use Spatie\Backtrace\Backtrace;
8
use Spatie\Backtrace\Frame;
9
use Spatie\Ignition\Contracts\Solution;
10
use Spatie\Ignition\ErrorPage\Renderer;
11
use Spatie\Ignition\Ignition;
12
use Throwable;
13
 
14
class OpenAiSolution implements Solution
15
{
16
    public bool $aiGenerated = true;
17
 
18
    protected string $prompt;
19
 
20
    protected OpenAiSolutionResponse $openAiSolutionResponse;
21
 
22
    public function __construct(
23
        protected Throwable           $throwable,
24
        protected string              $openAiKey,
25
        protected CacheInterface|null $cache = null,
26
        protected int|null            $cacheTtlInSeconds = 60,
27
        protected string|null         $applicationType = null,
28
        protected string|null         $applicationPath = null,
29
    ) {
30
        $this->prompt = $this->generatePrompt();
31
 
32
        $this->openAiSolutionResponse = $this->getAiSolution();
33
    }
34
 
35
    public function getSolutionTitle(): string
36
    {
37
        return 'AI Generated Solution';
38
    }
39
 
40
    public function getSolutionDescription(): string
41
    {
42
        return $this->openAiSolutionResponse->description();
43
    }
44
 
45
    public function getDocumentationLinks(): array
46
    {
47
        return $this->openAiSolutionResponse->links();
48
    }
49
 
50
    public function getAiSolution(): ?OpenAiSolutionResponse
51
    {
52
        $solution = $this->cache->get($this->getCacheKey());
53
 
54
        if ($solution) {
55
            return new OpenAiSolutionResponse($solution);
56
        }
57
 
58
        $solutionText = OpenAI::client($this->openAiKey)
59
            ->chat()
60
            ->create([
61
                'model' => $this->getModel(),
62
                'messages' => [['role' => 'user', 'content' => $this->prompt]],
63
                'max_tokens' => 1000,
64
                'temperature' => 0,
65
            ])->choices[0]->message->content;
66
 
67
        $this->cache->set($this->getCacheKey(), $solutionText, $this->cacheTtlInSeconds);
68
 
69
        return new OpenAiSolutionResponse($solutionText);
70
    }
71
 
72
    protected function getCacheKey(): string
73
    {
74
        $hash = sha1($this->prompt);
75
 
76
        return "ignition-solution-{$hash}";
77
    }
78
 
79
    protected function generatePrompt(): string
80
    {
81
        $viewPath = Ignition::viewPath('aiPrompt');
82
 
83
        $viewModel = new OpenAiPromptViewModel(
84
            file: $this->throwable->getFile(),
85
            exceptionMessage: $this->throwable->getMessage(),
86
            exceptionClass: get_class($this->throwable),
87
            snippet: $this->getApplicationFrame($this->throwable)->getSnippetAsString(15),
88
            line: $this->throwable->getLine(),
89
            applicationType: $this->applicationType,
90
        );
91
 
92
        return (new Renderer())->renderAsString(
93
            ['viewModel' => $viewModel],
94
            $viewPath,
95
        );
96
    }
97
 
98
    protected function getModel(): string
99
    {
100
        return 'gpt-3.5-turbo';
101
    }
102
 
103
    protected function getApplicationFrame(Throwable $throwable): ?Frame
104
    {
105
        $backtrace = Backtrace::createForThrowable($throwable);
106
 
107
        if ($this->applicationPath) {
108
            $backtrace->applicationPath($this->applicationPath);
109
        }
110
 
111
        $frames = $backtrace->frames();
112
 
113
        return $frames[$backtrace->firstApplicationFrameIndex()] ?? null;
114
    }
115
}