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 */ 127c3b69cbSAndreas Gohr protected function getHttpClient() 13dce0dee5SAndreas Gohr { 147c3b69cbSAndreas Gohr $http = parent::getHttpClient(); 157c3b69cbSAndreas Gohr $http->headers['x-api-key'] = $this->getFromConf('apikey'); 167c3b69cbSAndreas Gohr $http->headers['anthropic-version'] = '2023-06-01'; 177c3b69cbSAndreas Gohr return $http; 18dce0dee5SAndreas Gohr } 19dce0dee5SAndreas Gohr 207c3b69cbSAndreas Gohr 21dce0dee5SAndreas Gohr /** @inheritdoc */ 22*9d0b3322SAndreas Gohr function loadUnknownModelInfo(): array 23*9d0b3322SAndreas Gohr { 24*9d0b3322SAndreas Gohr $info = parent::loadUnknownModelInfo(); 25*9d0b3322SAndreas Gohr $info['outputTokens'] = 32000; 26*9d0b3322SAndreas Gohr return $info; 27*9d0b3322SAndreas Gohr } 28*9d0b3322SAndreas Gohr 29*9d0b3322SAndreas Gohr /** @inheritdoc */ 30dce0dee5SAndreas Gohr public function getAnswer(array $messages): string 31dce0dee5SAndreas Gohr { 325f71c9bbSAndreas Gohr // system message is separate from the messages array 33dce0dee5SAndreas Gohr $system = ''; 34dce0dee5SAndreas Gohr $chat = []; 35dce0dee5SAndreas Gohr foreach ($messages as $message) { 36dce0dee5SAndreas Gohr if ($message['role'] === 'system') { 37dce0dee5SAndreas Gohr $system .= $message['content'] . "\n"; 38dce0dee5SAndreas Gohr } else { 39dce0dee5SAndreas Gohr $chat[] = $message; 40dce0dee5SAndreas Gohr } 41dce0dee5SAndreas Gohr } 42dce0dee5SAndreas Gohr 43dce0dee5SAndreas Gohr $data = [ 44dce0dee5SAndreas Gohr 'messages' => $chat, 45dce0dee5SAndreas Gohr 'model' => $this->getModelName(), 46cfd76f4aSAndreas Gohr 'max_tokens' => $this->getMaxOutputTokenLength(), 47dce0dee5SAndreas Gohr 'stream' => false, 48dce0dee5SAndreas Gohr 'temperature' => 0.0, 49dce0dee5SAndreas Gohr ]; 50dce0dee5SAndreas Gohr 51dce0dee5SAndreas Gohr if ($system) { 52dce0dee5SAndreas Gohr $data['system'] = $system; 53dce0dee5SAndreas Gohr } 54dce0dee5SAndreas Gohr 55dce0dee5SAndreas Gohr $response = $this->request('messages', $data); 56dce0dee5SAndreas Gohr return $response['content'][0]['text']; 57dce0dee5SAndreas Gohr } 58dce0dee5SAndreas Gohr 59dce0dee5SAndreas Gohr /** 60eaa2c59dSAndreas Gohr * Send a request to the API 61dce0dee5SAndreas Gohr * 62dce0dee5SAndreas Gohr * @param string $endpoint 63dce0dee5SAndreas Gohr * @param array $data Payload to send 64dce0dee5SAndreas Gohr * @return array API response 65dce0dee5SAndreas Gohr * @throws \Exception 66dce0dee5SAndreas Gohr */ 67dce0dee5SAndreas Gohr protected function request($endpoint, $data) 68dce0dee5SAndreas Gohr { 69dce0dee5SAndreas Gohr $url = 'https://api.anthropic.com/v1/' . $endpoint; 70dce0dee5SAndreas Gohr return $this->sendAPIRequest('POST', $url, $data); 71dce0dee5SAndreas Gohr } 72dce0dee5SAndreas Gohr 73dce0dee5SAndreas Gohr /** @inheritdoc */ 74dce0dee5SAndreas Gohr protected function parseAPIResponse($response) 75dce0dee5SAndreas Gohr { 76dce0dee5SAndreas Gohr if (isset($response['usage'])) { 775f71c9bbSAndreas Gohr $this->inputTokensUsed += $response['usage']['input_tokens']; 785f71c9bbSAndreas Gohr $this->outputTokensUsed += $response['usage']['output_tokens']; 79dce0dee5SAndreas Gohr } 80dce0dee5SAndreas Gohr 81dce0dee5SAndreas Gohr if (isset($response['error'])) { 822e22aefbSAndreas Gohr throw new ModelException('Anthropic API error: ' . $response['error']['message'], 3002); 83dce0dee5SAndreas Gohr } 84dce0dee5SAndreas Gohr 85dce0dee5SAndreas Gohr return $response; 86dce0dee5SAndreas Gohr } 87dce0dee5SAndreas Gohr} 88