1<?php
2
3namespace dokuwiki\plugin\aichat\Model\Reka;
4
5use dokuwiki\plugin\aichat\Model\AbstractModel;
6use dokuwiki\plugin\aichat\Model\ChatInterface;
7use dokuwiki\plugin\aichat\Model\ModelException;
8
9class ChatModel extends AbstractModel implements ChatInterface
10{
11    /** @inheritdoc */
12    protected function getHttpClient()
13    {
14        $http = parent::getHttpClient();
15        $http->headers['x-api-key'] = $this->getFromConf('apikey');
16        return $http;
17    }
18
19    /** @inheritdoc */
20    public function getAnswer(array $messages): string
21    {
22        $chat = [];
23        foreach ($messages as $message) {
24            if ($message['role'] === 'user') {
25                $chat[] = [
26                    'type' => 'human',
27                    'text' => $message['content'],
28                ];
29            } elseif ($message['role'] === 'assistant') {
30                $chat[] = [
31                    'type' => 'model',
32                    'text' => $message['content'],
33                ];
34            }
35            // system messages are not supported
36        }
37
38        $data = [
39            'conversation_history' => $chat,
40            'model_name' => $this->getModelName(),
41            'temperature' => 0.0,
42        ];
43
44        $response = $this->request('chat', $data);
45        return $response['text'];
46    }
47
48    /**
49     * Send a request to the API
50     *
51     * @param string $endpoint
52     * @param array $data Payload to send
53     * @return array API response
54     * @throws \Exception
55     */
56    protected function request($endpoint, $data)
57    {
58        $url = 'https://api.reka.ai/' . $endpoint;
59        return $this->sendAPIRequest('POST', $url, $data);
60    }
61
62    /** @inheritdoc */
63    protected function parseAPIResponse($response)
64    {
65        $http = $this->getHttpClient();
66
67        if (((int) $http->status) !== 200) {
68            if (isset($response['detail'])) {
69                throw new ModelException('Reka API error: ' . $response['detail'], 3002);
70            } else {
71                throw new ModelException('Reka API error: ' . $http->status . ' ' . $http->error, 3002);
72            }
73        }
74
75        if (isset($response['metadata'])) {
76            $this->inputTokensUsed += $response['metadata']['input_tokens'];
77            $this->outputTokensUsed += $response['metadata']['generated_tokens'];
78        }
79
80        return $response;
81    }
82}
83