xref: /plugin/aichat/Model/AbstractModel.php (revision 7ebc78955c65af90e7ee0afbd07adc15271113ba)
1f6ef2e50SAndreas Gohr<?php
2f6ef2e50SAndreas Gohr
3f6ef2e50SAndreas Gohrnamespace dokuwiki\plugin\aichat\Model;
4f6ef2e50SAndreas Gohr
5*7ebc7895Ssplitbrainabstract class AbstractModel
6*7ebc7895Ssplitbrain{
7f6ef2e50SAndreas Gohr    /** @var int total tokens used by this instance */
8f6ef2e50SAndreas Gohr    protected $tokensUsed = 0;
9f6ef2e50SAndreas Gohr    /** @var int total cost used by this instance (multiplied by 1000*10000) */
10f6ef2e50SAndreas Gohr    protected $costEstimate = 0;
11f6ef2e50SAndreas Gohr    /** @var int total time spent in requests by this instance */
12f6ef2e50SAndreas Gohr    protected $timeUsed = 0;
13f6ef2e50SAndreas Gohr    /** @var int total number of requests made by this instance */
14f6ef2e50SAndreas Gohr    protected $requestsMade = 0;
15f6ef2e50SAndreas Gohr
16f6ef2e50SAndreas Gohr
17f6ef2e50SAndreas Gohr    /**
18f6ef2e50SAndreas Gohr     * @param array $authConfig Any configuration this Model/Service may need to authenticate
19f6ef2e50SAndreas Gohr     * @throws \Exception
20f6ef2e50SAndreas Gohr     */
21f6ef2e50SAndreas Gohr    abstract public function __construct($authConfig);
22f6ef2e50SAndreas Gohr
23f6ef2e50SAndreas Gohr    /**
24f6ef2e50SAndreas Gohr     * Maximum size of chunks this model can handle
25f6ef2e50SAndreas Gohr     *
26f6ef2e50SAndreas Gohr     * @return int
27f6ef2e50SAndreas Gohr     */
28f6ef2e50SAndreas Gohr    abstract public function getMaxEmbeddingTokenLength();
29f6ef2e50SAndreas Gohr
30f6ef2e50SAndreas Gohr    /**
31f6ef2e50SAndreas Gohr     * Maximum number of tokens to use when creating context info. Should be smaller than the absolute
32f6ef2e50SAndreas Gohr     * token limit of the model, so that prompts and questions can be added.
33f6ef2e50SAndreas Gohr     *
34f6ef2e50SAndreas Gohr     * @return int
35f6ef2e50SAndreas Gohr     */
36f6ef2e50SAndreas Gohr    abstract public function getMaxContextTokenLength();
37f6ef2e50SAndreas Gohr
38f6ef2e50SAndreas Gohr    /**
39f6ef2e50SAndreas Gohr     * Maximum number of tokens to use as context when rephrasing a question. Should be smaller than the
40f6ef2e50SAndreas Gohr     * absolute token limit of the model, so that prompts and questions can be added.
41f6ef2e50SAndreas Gohr     *
42f6ef2e50SAndreas Gohr     * @return int
43f6ef2e50SAndreas Gohr     */
44*7ebc7895Ssplitbrain    public function getMaxRephrasingTokenLength()
45*7ebc7895Ssplitbrain    {
46f6ef2e50SAndreas Gohr        return $this->getMaxContextTokenLength();
47f6ef2e50SAndreas Gohr    }
48f6ef2e50SAndreas Gohr
49f6ef2e50SAndreas Gohr    /**
50f6ef2e50SAndreas Gohr     * Get the embedding vectors for a given text
51f6ef2e50SAndreas Gohr     *
52f6ef2e50SAndreas Gohr     * @param string $text
53f6ef2e50SAndreas Gohr     * @return float[]
54f6ef2e50SAndreas Gohr     * @throws \Exception
55f6ef2e50SAndreas Gohr     */
56f6ef2e50SAndreas Gohr    abstract public function getEmbedding($text);
57f6ef2e50SAndreas Gohr
58f6ef2e50SAndreas Gohr    /**
59f6ef2e50SAndreas Gohr     * Answer a given question.
60f6ef2e50SAndreas Gohr     *
61f6ef2e50SAndreas Gohr     * Any prompt, chat history, context etc. will already be included in the $messages array.
62f6ef2e50SAndreas Gohr     *
63f6ef2e50SAndreas Gohr     * @param array $messages Messages in OpenAI format (with role and content)
64f6ef2e50SAndreas Gohr     * @return string The answer
65f6ef2e50SAndreas Gohr     * @throws \Exception
66f6ef2e50SAndreas Gohr     */
67f6ef2e50SAndreas Gohr    abstract public function getAnswer($messages);
68f6ef2e50SAndreas Gohr
69f6ef2e50SAndreas Gohr    /**
70f6ef2e50SAndreas Gohr     * This is called to let the LLM rephrase a question using given context
71f6ef2e50SAndreas Gohr     *
72f6ef2e50SAndreas Gohr     * Any prompt, chat history, context etc. will already be included in the $messages array.
73f6ef2e50SAndreas Gohr     * This calls getAnswer() by default, but you may want to use a different model instead.
74f6ef2e50SAndreas Gohr     *
75f6ef2e50SAndreas Gohr     * @param array $messages Messages in OpenAI format (with role and content)
76f6ef2e50SAndreas Gohr     * @return string The new question
77f6ef2e50SAndreas Gohr     * @throws \Exception
78f6ef2e50SAndreas Gohr     */
79*7ebc7895Ssplitbrain    public function getRephrasedQuestion($messages)
80*7ebc7895Ssplitbrain    {
81f6ef2e50SAndreas Gohr        return $this->getAnswer($messages);
82f6ef2e50SAndreas Gohr    }
83f6ef2e50SAndreas Gohr
84f6ef2e50SAndreas Gohr    /**
85f6ef2e50SAndreas Gohr     * Reset the usage statistics
86f6ef2e50SAndreas Gohr     *
87f6ef2e50SAndreas Gohr     * Usually not needed when only handling one operation per request, but useful in CLI
88f6ef2e50SAndreas Gohr     */
89f6ef2e50SAndreas Gohr    public function resetUsageStats()
90f6ef2e50SAndreas Gohr    {
91f6ef2e50SAndreas Gohr        $this->tokensUsed = 0;
92f6ef2e50SAndreas Gohr        $this->costEstimate = 0;
93f6ef2e50SAndreas Gohr        $this->timeUsed = 0;
94f6ef2e50SAndreas Gohr        $this->requestsMade = 0;
95f6ef2e50SAndreas Gohr    }
96f6ef2e50SAndreas Gohr
97f6ef2e50SAndreas Gohr    /**
98f6ef2e50SAndreas Gohr     * Get the usage statistics for this instance
99f6ef2e50SAndreas Gohr     *
100f6ef2e50SAndreas Gohr     * @return string[]
101f6ef2e50SAndreas Gohr     */
102f6ef2e50SAndreas Gohr    public function getUsageStats()
103f6ef2e50SAndreas Gohr    {
104f6ef2e50SAndreas Gohr        return [
105f6ef2e50SAndreas Gohr            'tokens' => $this->tokensUsed,
106f6ef2e50SAndreas Gohr            'cost' => round($this->costEstimate / 1000 / 10000, 4),
107f6ef2e50SAndreas Gohr            'time' => round($this->timeUsed, 2),
108f6ef2e50SAndreas Gohr            'requests' => $this->requestsMade,
109f6ef2e50SAndreas Gohr        ];
110f6ef2e50SAndreas Gohr    }
111f6ef2e50SAndreas Gohr}
112