1<?php
2
3namespace dokuwiki\plugin\aichatlocal\Model\Local;
4
5use dokuwiki\plugin\aichat\Model\AbstractModel;
6use dokuwiki\plugin\aichat\Model\ChatInterface;
7
8class ChatModel extends AbstractModel implements ChatInterface
9{
10    /** @inheritdoc */
11    public function __construct(string $name, array $config)
12    {
13        parent::__construct($name, $config);
14
15        if (empty($config['local_llm_baseurl'])) {
16            throw new \Exception('Local LLM base URL not configured');
17        }
18
19        $this->http->baseURL = trim($config['local_llm_baseurl'], '/');
20
21        if (!empty($config['local_llm_apikey'])) {
22            $this->http->headers['Authorization'] = 'Bearer ' . $config['local_llm_apikey'];
23        }
24
25        $this->http->headers['Content-Type'] = 'application/json';
26    }
27
28    /** @inheritdoc */
29    public function getAnswer(array $messages): string
30    {
31        $data = [
32            'model' => $this->getModelName(),
33            'messages' => $messages,
34            'max_tokens' => $this->getMaxOutputTokenLength(),
35            'temperature' => 0.7,
36            'stream' => false,
37        ];
38
39        $response = $this->request('chat/completions', $data);
40        return $response['choices'][0]['message']['content'];
41    }
42
43    /**
44     * Send a request to the API
45     *
46     * @param string $endpoint
47     * @param array $data Payload to send
48     * @return array API response
49     * @throws \Exception
50     */
51    protected function request($endpoint, $data)
52    {
53        $url = $this->http->baseURL . '/v1/' . $endpoint;
54        return $this->sendAPIRequest('POST', $url, $data);
55    }
56
57    /** @inheritdoc */
58    protected function parseAPIResponse($response)
59    {
60        if (isset($response['usage'])) {
61            $this->inputTokensUsed += $response['usage']['prompt_tokens'];
62            $this->outputTokensUsed += $response['usage']['completion_tokens'];
63        }
64
65        if (isset($response['error'])) {
66            throw new \Exception('Local LLM API error: ' . $response['error']['message']);
67        }
68
69        return $response;
70    }
71}
72