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