1dce0dee5SAndreas Gohr<?php 2dce0dee5SAndreas Gohr 3dce0dee5SAndreas Gohrnamespace dokuwiki\plugin\aichat\Model\Anthropic; 4dce0dee5SAndreas Gohr 5dce0dee5SAndreas Gohruse dokuwiki\plugin\aichat\Model\AbstractModel; 6dce0dee5SAndreas Gohruse dokuwiki\plugin\aichat\Model\ChatInterface; 72e22aefbSAndreas Gohruse dokuwiki\plugin\aichat\Model\ModelException; 8dce0dee5SAndreas Gohr 9dce0dee5SAndreas Gohrclass ChatModel extends AbstractModel implements ChatInterface 10dce0dee5SAndreas Gohr{ 11dce0dee5SAndreas Gohr /** @inheritdoc */ 12*7c3b69cbSAndreas Gohr protected function getHttpClient() 13dce0dee5SAndreas Gohr { 14*7c3b69cbSAndreas Gohr $http = parent::getHttpClient(); 15*7c3b69cbSAndreas Gohr $http->headers['x-api-key'] = $this->getFromConf('apikey'); 16*7c3b69cbSAndreas Gohr $http->headers['anthropic-version'] = '2023-06-01'; 17*7c3b69cbSAndreas Gohr return $http; 18dce0dee5SAndreas Gohr } 19dce0dee5SAndreas Gohr 20*7c3b69cbSAndreas Gohr 21dce0dee5SAndreas Gohr /** @inheritdoc */ 22dce0dee5SAndreas Gohr public function getAnswer(array $messages): string 23dce0dee5SAndreas Gohr { 245f71c9bbSAndreas Gohr // system message is separate from the messages array 25dce0dee5SAndreas Gohr $system = ''; 26dce0dee5SAndreas Gohr $chat = []; 27dce0dee5SAndreas Gohr foreach ($messages as $message) { 28dce0dee5SAndreas Gohr if ($message['role'] === 'system') { 29dce0dee5SAndreas Gohr $system .= $message['content'] . "\n"; 30dce0dee5SAndreas Gohr } else { 31dce0dee5SAndreas Gohr $chat[] = $message; 32dce0dee5SAndreas Gohr } 33dce0dee5SAndreas Gohr } 34dce0dee5SAndreas Gohr 35dce0dee5SAndreas Gohr $data = [ 36dce0dee5SAndreas Gohr 'messages' => $chat, 37dce0dee5SAndreas Gohr 'model' => $this->getModelName(), 38cfd76f4aSAndreas Gohr 'max_tokens' => $this->getMaxOutputTokenLength(), 39dce0dee5SAndreas Gohr 'stream' => false, 40dce0dee5SAndreas Gohr 'temperature' => 0.0, 41dce0dee5SAndreas Gohr ]; 42dce0dee5SAndreas Gohr 43dce0dee5SAndreas Gohr if ($system) { 44dce0dee5SAndreas Gohr $data['system'] = $system; 45dce0dee5SAndreas Gohr } 46dce0dee5SAndreas Gohr 47dce0dee5SAndreas Gohr $response = $this->request('messages', $data); 48dce0dee5SAndreas Gohr return $response['content'][0]['text']; 49dce0dee5SAndreas Gohr } 50dce0dee5SAndreas Gohr 51dce0dee5SAndreas Gohr /** 52eaa2c59dSAndreas Gohr * Send a request to the API 53dce0dee5SAndreas Gohr * 54dce0dee5SAndreas Gohr * @param string $endpoint 55dce0dee5SAndreas Gohr * @param array $data Payload to send 56dce0dee5SAndreas Gohr * @return array API response 57dce0dee5SAndreas Gohr * @throws \Exception 58dce0dee5SAndreas Gohr */ 59dce0dee5SAndreas Gohr protected function request($endpoint, $data) 60dce0dee5SAndreas Gohr { 61dce0dee5SAndreas Gohr $url = 'https://api.anthropic.com/v1/' . $endpoint; 62dce0dee5SAndreas Gohr return $this->sendAPIRequest('POST', $url, $data); 63dce0dee5SAndreas Gohr } 64dce0dee5SAndreas Gohr 65dce0dee5SAndreas Gohr /** @inheritdoc */ 66dce0dee5SAndreas Gohr protected function parseAPIResponse($response) 67dce0dee5SAndreas Gohr { 68dce0dee5SAndreas Gohr if (isset($response['usage'])) { 695f71c9bbSAndreas Gohr $this->inputTokensUsed += $response['usage']['input_tokens']; 705f71c9bbSAndreas Gohr $this->outputTokensUsed += $response['usage']['output_tokens']; 71dce0dee5SAndreas Gohr } 72dce0dee5SAndreas Gohr 73dce0dee5SAndreas Gohr if (isset($response['error'])) { 742e22aefbSAndreas Gohr throw new ModelException('Anthropic API error: ' . $response['error']['message'], 3002); 75dce0dee5SAndreas Gohr } 76dce0dee5SAndreas Gohr 77dce0dee5SAndreas Gohr return $response; 78dce0dee5SAndreas Gohr } 79dce0dee5SAndreas Gohr} 80