Issues (34)

src/Adapters/GeminiAdapter.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Squareetlabs\LaravelToon\Adapters;
6
7
use Illuminate\Http\Client\PendingRequest;
8
use Illuminate\Support\Facades\Http;
9
10
class GeminiAdapter extends BaseLLMAdapter
11
{
12
    private ?PendingRequest $client = null;
0 ignored issues
show
The private property $client is not used, and could be removed.
Loading history...
13
14
    public function getName(): string
15
    {
16
        return 'Google Gemini';
17
    }
18
19
    public function isEnabled(): bool
20
    {
21
        return config('laravel-toon.adapters.gemini.enabled', false);
22
    }
23
24
    public function sendMessage(
25
        string $message,
26
        ?string $model = null,
27
        ?array $options = null
28
    ): array {
29
        if (!$this->isEnabled()) {
30
            return ['success' => false, 'error' => 'Gemini adapter not enabled'];
31
        }
32
33
        $model ??= $this->getDefaultModel();
34
        $options ??= [];
35
36
        $toonMessage = $this->compressMessage($message);
37
38
        $payload = array_merge([
39
            'contents' => [
40
                ['role' => 'user', 'parts' => [['text' => $toonMessage]]],
41
            ],
42
        ], $options);
43
44
        try {
45
            $apiKey = config('laravel-toon.adapters.gemini.api_key');
46
            $response = Http::baseUrl('https://generativelanguage.googleapis.com/v1beta/models')
47
                ->withQueryParameters(['key' => $apiKey])
48
                ->post("/{$model}:generateContent", $payload)
49
                ->throw()
50
                ->json();
51
52
            return [
53
                'success' => true,
54
                'adapter' => 'gemini',
55
                'model' => $model,
56
                'original_message_tokens' => $this->tokenAnalyzer->estimate($message),
57
                'compressed_message_tokens' => $this->tokenAnalyzer->estimate($toonMessage),
58
                'response' => $response,
59
                'compressed_message' => $toonMessage,
60
            ];
61
        } catch (\Exception $e) {
62
            return [
63
                'success' => false,
64
                'error' => $e->getMessage(),
65
            ];
66
        }
67
    }
68
69
    public function chat(
70
        array $messages,
71
        ?string $model = null,
72
        ?array $options = null
73
    ): array {
74
        if (!$this->isEnabled()) {
75
            return ['success' => false, 'error' => 'Gemini adapter not enabled'];
76
        }
77
78
        $model ??= $this->getDefaultModel();
79
        $options ??= [];
80
81
        // Compress messages
82
        $compressedMessages = array_map(fn ($msg) => [
83
            'role' => $msg['role'],
84
            'parts' => [['text' => $this->compressMessage($msg['content'])]],
85
        ], $messages);
86
87
        $payload = array_merge([
88
            'contents' => $compressedMessages,
89
        ], $options);
90
91
        try {
92
            $apiKey = config('laravel-toon.adapters.gemini.api_key');
93
            $response = Http::baseUrl('https://generativelanguage.googleapis.com/v1beta/models')
94
                ->withQueryParameters(['key' => $apiKey])
95
                ->post("/{$model}:generateContent", $payload)
96
                ->throw()
97
                ->json();
98
99
            $originalTokens = array_sum(array_map(
100
                fn ($msg) => $this->tokenAnalyzer->estimate($msg['content']),
101
                $messages
102
            ));
103
104
            $compressedTokens = array_sum(array_map(
105
                fn ($msg) => $this->tokenAnalyzer->estimate($msg['content']),
106
                $messages
107
            ));
108
109
            return [
110
                'success' => true,
111
                'adapter' => 'gemini',
112
                'model' => $model,
113
                'messages_count' => count($messages),
114
                'original_tokens' => $originalTokens,
115
                'compressed_tokens' => $compressedTokens,
116
                'tokens_saved' => $originalTokens - $compressedTokens,
117
                'response' => $response,
118
            ];
119
        } catch (\Exception $e) {
120
            return [
121
                'success' => false,
122
                'error' => $e->getMessage(),
123
            ];
124
        }
125
    }
126
127
    public function getDefaultModel(): string
128
    {
129
        return config('laravel-toon.adapters.gemini.default_model', 'gemini-pro');
130
    }
131
132
    public function getAvailableModels(): array
133
    {
134
        return [
135
            'gemini-pro',
136
            'gemini-pro-vision',
137
        ];
138
    }
139
}
140
141