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