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