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