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