xref: /plugin/aichat/Model/Mistral/AbstractMistralModel.php (revision 42b2c6e864def16df42600c2885e21d4d148fd0c)
1cfd76f4aSAndreas Gohr<?php
2cfd76f4aSAndreas Gohr
3cfd76f4aSAndreas Gohrnamespace dokuwiki\plugin\aichat\Model\Mistral;
4cfd76f4aSAndreas Gohr
5cfd76f4aSAndreas Gohruse dokuwiki\plugin\aichat\Model\AbstractModel;
6cfd76f4aSAndreas Gohr
7cfd76f4aSAndreas Gohr/**
8cfd76f4aSAndreas Gohr * Abstract OpenAI Model
9cfd76f4aSAndreas Gohr *
10cfd76f4aSAndreas Gohr * This class provides a basic interface to the OpenAI API
11cfd76f4aSAndreas Gohr */
12cfd76f4aSAndreas Gohrabstract class AbstractMistralModel extends AbstractModel
13cfd76f4aSAndreas Gohr{
14cfd76f4aSAndreas Gohr    /** @inheritdoc */
15cfd76f4aSAndreas Gohr    public function __construct(string $name, array $config)
16cfd76f4aSAndreas Gohr    {
17cfd76f4aSAndreas Gohr        parent::__construct($name, $config);
18e8451b21SAndreas Gohr        if (empty($config['mistral_apikey'])) {
19*42b2c6e8SAndreas Gohr            throw new \Exception('Mistral API key not configured', 3001);
20e8451b21SAndreas Gohr        }
21e8451b21SAndreas Gohr        $this->http->headers['Authorization'] = 'Bearer ' . $config['mistral_apikey'];
22cfd76f4aSAndreas Gohr    }
23cfd76f4aSAndreas Gohr
24cfd76f4aSAndreas Gohr    /**
25cfd76f4aSAndreas Gohr     * Send a request to the OpenAI API
26cfd76f4aSAndreas Gohr     *
27cfd76f4aSAndreas Gohr     * @param string $endpoint
28cfd76f4aSAndreas Gohr     * @param array $data Payload to send
29cfd76f4aSAndreas Gohr     * @return array API response
30cfd76f4aSAndreas Gohr     * @throws \Exception
31cfd76f4aSAndreas Gohr     */
32cfd76f4aSAndreas Gohr    protected function request($endpoint, $data)
33cfd76f4aSAndreas Gohr    {
34cfd76f4aSAndreas Gohr        $url = 'https://api.mistral.ai/v1/' . $endpoint;
35cfd76f4aSAndreas Gohr        return $this->sendAPIRequest('POST', $url, $data);
36cfd76f4aSAndreas Gohr    }
37cfd76f4aSAndreas Gohr
38cfd76f4aSAndreas Gohr    /** @inheritdoc */
39cfd76f4aSAndreas Gohr    protected function parseAPIResponse($response)
40cfd76f4aSAndreas Gohr    {
41cfd76f4aSAndreas Gohr        if (isset($response['usage'])) {
42cfd76f4aSAndreas Gohr            $this->inputTokensUsed += $response['usage']['prompt_tokens'];
43cfd76f4aSAndreas Gohr            $this->outputTokensUsed += $response['usage']['completion_tokens'] ?? 0;
44cfd76f4aSAndreas Gohr        }
45cfd76f4aSAndreas Gohr
46c2b7a1f7SAndreas Gohr        if (isset($response['object']) && $response['object'] === 'error') {
47*42b2c6e8SAndreas Gohr            throw new \Exception('Mistral API error: ' . $response['message'], 3002);
48cfd76f4aSAndreas Gohr        }
49cfd76f4aSAndreas Gohr
50cfd76f4aSAndreas Gohr        return $response;
51cfd76f4aSAndreas Gohr    }
52cfd76f4aSAndreas Gohr
53cfd76f4aSAndreas Gohr    /**
54cfd76f4aSAndreas Gohr     * @internal for checking available models
55cfd76f4aSAndreas Gohr     */
56cfd76f4aSAndreas Gohr    public function listUpstreamModels()
57cfd76f4aSAndreas Gohr    {
58cfd76f4aSAndreas Gohr        $url = 'https://api.openai.com/v1/models';
59cfd76f4aSAndreas Gohr        return $this->http->get($url);
60cfd76f4aSAndreas Gohr    }
61cfd76f4aSAndreas Gohr}
62