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