xref: /plugin/aichat/Model/OpenAI/AbstractOpenAIModel.php (revision e8451b21b9ca52de6bf419c0f1a2020e9bcd5276)
1294a9eafSAndreas Gohr<?php
2294a9eafSAndreas Gohr
3294a9eafSAndreas Gohrnamespace dokuwiki\plugin\aichat\Model\OpenAI;
4294a9eafSAndreas Gohr
5294a9eafSAndreas Gohruse dokuwiki\plugin\aichat\Model\AbstractModel;
6294a9eafSAndreas Gohr
7294a9eafSAndreas Gohr/**
8294a9eafSAndreas Gohr * Abstract OpenAI Model
9294a9eafSAndreas Gohr *
10294a9eafSAndreas Gohr * This class provides a basic interface to the OpenAI API
11294a9eafSAndreas Gohr */
12294a9eafSAndreas Gohrabstract class AbstractOpenAIModel extends AbstractModel
13294a9eafSAndreas Gohr{
14294a9eafSAndreas Gohr    /** @inheritdoc */
15dce0dee5SAndreas Gohr    public function __construct(string $name, array $config)
16294a9eafSAndreas Gohr    {
17dce0dee5SAndreas Gohr        parent::__construct($name, $config);
18294a9eafSAndreas Gohr
19*e8451b21SAndreas Gohr        if (empty($config['openai_apikey'])) {
20*e8451b21SAndreas Gohr            throw new \Exception('OpenAI API key not configured');
21*e8451b21SAndreas Gohr        }
22*e8451b21SAndreas Gohr
23*e8451b21SAndreas Gohr        $openAIKey = $config['openai_apikey'];
24e3640be8SAndreas Gohr        $openAIOrg = $config['openai_org'] ?? '';
25294a9eafSAndreas Gohr
26294a9eafSAndreas Gohr        $this->http->headers['Authorization'] = 'Bearer ' . $openAIKey;
27294a9eafSAndreas Gohr        if ($openAIOrg) {
28294a9eafSAndreas Gohr            $this->http->headers['OpenAI-Organization'] = $openAIOrg;
29294a9eafSAndreas Gohr        }
30294a9eafSAndreas Gohr    }
31294a9eafSAndreas Gohr
32294a9eafSAndreas Gohr    /**
33294a9eafSAndreas Gohr     * Send a request to the OpenAI API
34294a9eafSAndreas Gohr     *
35294a9eafSAndreas Gohr     * @param string $endpoint
36294a9eafSAndreas Gohr     * @param array $data Payload to send
37294a9eafSAndreas Gohr     * @return array API response
38294a9eafSAndreas Gohr     * @throws \Exception
39294a9eafSAndreas Gohr     */
40294a9eafSAndreas Gohr    protected function request($endpoint, $data)
41294a9eafSAndreas Gohr    {
42294a9eafSAndreas Gohr        $url = 'https://api.openai.com/v1/' . $endpoint;
43294a9eafSAndreas Gohr        return $this->sendAPIRequest('POST', $url, $data);
44294a9eafSAndreas Gohr    }
45294a9eafSAndreas Gohr
46294a9eafSAndreas Gohr    /** @inheritdoc */
47294a9eafSAndreas Gohr    protected function parseAPIResponse($response)
48294a9eafSAndreas Gohr    {
49294a9eafSAndreas Gohr        if (isset($response['usage'])) {
5034a1c478SAndreas Gohr            $this->inputTokensUsed += $response['usage']['prompt_tokens'];
5134a1c478SAndreas Gohr            $this->outputTokensUsed += $response['usage']['completion_tokens'] ?? 0;
52294a9eafSAndreas Gohr        }
53294a9eafSAndreas Gohr
54294a9eafSAndreas Gohr        if (isset($response['error'])) {
55294a9eafSAndreas Gohr            throw new \Exception('OpenAI API error: ' . $response['error']['message']);
56294a9eafSAndreas Gohr        }
57294a9eafSAndreas Gohr
58294a9eafSAndreas Gohr        return $response;
59294a9eafSAndreas Gohr    }
60294a9eafSAndreas Gohr
61294a9eafSAndreas Gohr    /**
62294a9eafSAndreas Gohr     * @internal for checking available models
63294a9eafSAndreas Gohr     */
64294a9eafSAndreas Gohr    public function listUpstreamModels()
65294a9eafSAndreas Gohr    {
66294a9eafSAndreas Gohr        $url = 'https://api.openai.com/v1/models';
67294a9eafSAndreas Gohr        return $this->http->get($url);
68294a9eafSAndreas Gohr    }
69294a9eafSAndreas Gohr}
70