]> BookStack Code Mirror - bookstack/blob - app/Search/Vectors/Services/OpenAiVectorQueryService.php
Vectors: Got basic LLM querying working using vector search context
[bookstack] / app / Search / Vectors / Services / OpenAiVectorQueryService.php
1 <?php
2
3 namespace BookStack\Search\Vectors\Services;
4
5 use BookStack\Http\HttpRequestService;
6
7 class OpenAiVectorQueryService implements VectorQueryService
8 {
9     public function __construct(
10         protected string $endpoint,
11         protected string $key,
12         protected HttpRequestService $http,
13     ) {
14     }
15
16     protected function jsonRequest(string $method, string $uri, array $data): array
17     {
18         $fullUrl = rtrim($this->endpoint, '/') . '/' . ltrim($uri, '/');
19         $client = $this->http->buildClient(10);
20         $request = $this->http->jsonRequest($method, $fullUrl, $data)
21             ->withHeader('Authorization', 'Bearer ' . $this->key);
22
23         $response = $client->sendRequest($request);
24         return json_decode($response->getBody()->getContents(), true);
25     }
26
27     public function generateEmbeddings(string $text): array
28     {
29         $response = $this->jsonRequest('POST', 'v1/embeddings', [
30             'input' => $text,
31             'model' => 'text-embedding-3-small',
32         ]);
33
34         return $response['data'][0]['embedding'];
35     }
36
37     public function query(string $input, array $context): string
38     {
39         $formattedContext = implode("\n", $context);
40
41         $response = $this->jsonRequest('POST', 'v1/chat/completions', [
42             'model' => 'gpt-4o',
43             'messages' => [
44                 [
45                     'role' => 'developer',
46                     'content' => 'You are a helpful assistant providing search query responses. Be specific, factual and to-the-point in response.'
47                 ],
48                 [
49                     'role' => 'user',
50                     'content' => "Provide a response to the below given QUERY using the below given CONTEXT\nQUERY: {$input}\n\nCONTEXT: {$formattedContext}",
51                 ]
52             ],
53         ]);
54
55         return $response['choices'][0]['message']['content'] ?? '';
56     }
57 }