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