xref: /plugin/aichat/Model/Anthropic/ChatModel.php (revision 9d0b3322235bbe0983565364adb2ee2d670351fd)
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    function loadUnknownModelInfo(): array
23    {
24        $info = parent::loadUnknownModelInfo();
25        $info['outputTokens'] = 32000;
26        return $info;
27    }
28
29    /** @inheritdoc */
30    public function getAnswer(array $messages): string
31    {
32        // system message is separate from the messages array
33        $system = '';
34        $chat = [];
35        foreach ($messages as $message) {
36            if ($message['role'] === 'system') {
37                $system .= $message['content'] . "\n";
38            } else {
39                $chat[] = $message;
40            }
41        }
42
43        $data = [
44            'messages' => $chat,
45            'model' => $this->getModelName(),
46            'max_tokens' => $this->getMaxOutputTokenLength(),
47            'stream' => false,
48            'temperature' => 0.0,
49        ];
50
51        if ($system) {
52            $data['system'] = $system;
53        }
54
55        $response = $this->request('messages', $data);
56        return $response['content'][0]['text'];
57    }
58
59    /**
60     * Send a request to the API
61     *
62     * @param string $endpoint
63     * @param array $data Payload to send
64     * @return array API response
65     * @throws \Exception
66     */
67    protected function request($endpoint, $data)
68    {
69        $url = 'https://api.anthropic.com/v1/' . $endpoint;
70        return $this->sendAPIRequest('POST', $url, $data);
71    }
72
73    /** @inheritdoc */
74    protected function parseAPIResponse($response)
75    {
76        if (isset($response['usage'])) {
77            $this->inputTokensUsed += $response['usage']['input_tokens'];
78            $this->outputTokensUsed += $response['usage']['output_tokens'];
79        }
80
81        if (isset($response['error'])) {
82            throw new ModelException('Anthropic API error: ' . $response['error']['message'], 3002);
83        }
84
85        return $response;
86    }
87}
88