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