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