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