xref: /plugin/aichat/remote.php (revision aa6bbe75d15853a1d8cbdfee301c7e380f672a69)
142b2c6e8SAndreas Gohr<?php
242b2c6e8SAndreas Gohr
342b2c6e8SAndreas Gohruse dokuwiki\Extension\RemotePlugin;
4*aa6bbe75SAndreas Gohruse dokuwiki\plugin\aichat\RemoteResponse\Chunk;
542b2c6e8SAndreas Gohruse dokuwiki\plugin\aichat\RemoteResponse\LlmReply;
642b2c6e8SAndreas Gohruse dokuwiki\Remote\AccessDeniedException;
742b2c6e8SAndreas Gohr
842b2c6e8SAndreas Gohr/**
942b2c6e8SAndreas Gohr * DokuWiki Plugin aichat (Action Component)
1042b2c6e8SAndreas Gohr *
1142b2c6e8SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
1242b2c6e8SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de>
1342b2c6e8SAndreas Gohr */
1442b2c6e8SAndreas Gohrclass remote_plugin_aichat extends RemotePlugin
1542b2c6e8SAndreas Gohr{
16*aa6bbe75SAndreas Gohr
1742b2c6e8SAndreas Gohr    /**
18*aa6bbe75SAndreas Gohr     * Initialize the helper and check permissions
1942b2c6e8SAndreas Gohr     *
20*aa6bbe75SAndreas Gohr     * @param string $model
21*aa6bbe75SAndreas Gohr     * @param string $lang
22*aa6bbe75SAndreas Gohr     * @return helper_plugin_aichat
23*aa6bbe75SAndreas Gohr     * @throws AccessDeniedException
2442b2c6e8SAndreas Gohr     */
25*aa6bbe75SAndreas Gohr    protected function initHelper($model = '', $lang = '')
2642b2c6e8SAndreas Gohr    {
2742b2c6e8SAndreas Gohr        /** @var helper_plugin_aichat $helper */
2842b2c6e8SAndreas Gohr        $helper = plugin_load('helper', 'aichat');
2942b2c6e8SAndreas Gohr        if ($model) {
3042b2c6e8SAndreas Gohr            $helper->updateConfig(
3142b2c6e8SAndreas Gohr                ['chatmodel' => $model, 'rephasemodel' => $model]
3242b2c6e8SAndreas Gohr            );
3342b2c6e8SAndreas Gohr        }
3442b2c6e8SAndreas Gohr
3542b2c6e8SAndreas Gohr        if (!$helper->userMayAccess()) {
3642b2c6e8SAndreas Gohr            throw new AccessDeniedException('You are not allowed to use this plugin', 111);
3742b2c6e8SAndreas Gohr        }
3842b2c6e8SAndreas Gohr
3942b2c6e8SAndreas Gohr        if ($lang === 'auto') {
4042b2c6e8SAndreas Gohr            $helper->updateConfig(['preferUIlanguage' => 0]);
4142b2c6e8SAndreas Gohr        } elseif ($lang) {
4242b2c6e8SAndreas Gohr            $helper->updateConfig(['preferUIlanguage' => 1]);
4342b2c6e8SAndreas Gohr            global $conf;
4442b2c6e8SAndreas Gohr            $conf['lang'] = $lang;
4542b2c6e8SAndreas Gohr        }
4642b2c6e8SAndreas Gohr
47*aa6bbe75SAndreas Gohr        return $helper;
48*aa6bbe75SAndreas Gohr    }
49*aa6bbe75SAndreas Gohr
50*aa6bbe75SAndreas Gohr    /**
51*aa6bbe75SAndreas Gohr     * Ask the LLM a question
52*aa6bbe75SAndreas Gohr     *
53*aa6bbe75SAndreas Gohr     * Sends the given question to the LLM and returns the answer, including the used sources.
54*aa6bbe75SAndreas Gohr     *
55*aa6bbe75SAndreas Gohr     * @param string $query The question to ask the LLM
56*aa6bbe75SAndreas Gohr     * @param string $model The model to use, if empty the default model is used
57*aa6bbe75SAndreas Gohr     * @param string $lang Language code to override preferUIlanguage setting. "auto" to force autodetection.
58*aa6bbe75SAndreas Gohr     * @return LlmReply
59*aa6bbe75SAndreas Gohr     * @throws AccessDeniedException
60*aa6bbe75SAndreas Gohr     * @throws Exception
61*aa6bbe75SAndreas Gohr     */
62*aa6bbe75SAndreas Gohr    public function ask($query, $model = '', $lang = '')
63*aa6bbe75SAndreas Gohr    {
64*aa6bbe75SAndreas Gohr        $helper = $this->initHelper($model, $lang);
6542b2c6e8SAndreas Gohr        $result = $helper->askQuestion($query);
6642b2c6e8SAndreas Gohr
6742b2c6e8SAndreas Gohr        return new LlmReply($result);
6842b2c6e8SAndreas Gohr    }
69*aa6bbe75SAndreas Gohr
70*aa6bbe75SAndreas Gohr    /**
71*aa6bbe75SAndreas Gohr     * Get page chunks similar to a given query
72*aa6bbe75SAndreas Gohr     *
73*aa6bbe75SAndreas Gohr     * Uses the given query to find similar pages in the wiki. Returns the most similar chunks.
74*aa6bbe75SAndreas Gohr     *
75*aa6bbe75SAndreas Gohr     * This call returns chunks, not pages. So a page may returned multiple times when different chunks of it
76*aa6bbe75SAndreas Gohr     * are similar to the query.
77*aa6bbe75SAndreas Gohr     *
78*aa6bbe75SAndreas Gohr     * Note that this call may return less results than requested depending on the used vector store.
79*aa6bbe75SAndreas Gohr     *
80*aa6bbe75SAndreas Gohr     * @param string $query
81*aa6bbe75SAndreas Gohr     * @param int $max Maximum number of results to return. -1 for default set in config
82*aa6bbe75SAndreas Gohr     * @param float $threshold Minimum similarity score to return results for. -1 for default set in config
83*aa6bbe75SAndreas Gohr     * @param string $lang Language code to override preferUIlanguage setting. "auto" to force autodetection.
84*aa6bbe75SAndreas Gohr     * @return Chunk[] A list of similar chunks
85*aa6bbe75SAndreas Gohr     * @throws AccessDeniedException
86*aa6bbe75SAndreas Gohr     * @throws Exception
87*aa6bbe75SAndreas Gohr     */
88*aa6bbe75SAndreas Gohr    public function similar($query, $max = -1, $threshold = -1, $lang = '')
89*aa6bbe75SAndreas Gohr    {
90*aa6bbe75SAndreas Gohr        $helper = $this->initHelper('', $lang);
91*aa6bbe75SAndreas Gohr        $langlimit = $helper->getLanguageLimit();
92*aa6bbe75SAndreas Gohr
93*aa6bbe75SAndreas Gohr        $embeddings = $helper->getEmbeddings();
94*aa6bbe75SAndreas Gohr        if ($max !== -1) {
95*aa6bbe75SAndreas Gohr            $embeddings->setConfigContextChunks($max);
96*aa6bbe75SAndreas Gohr        }
97*aa6bbe75SAndreas Gohr        if ($threshold !== -1) {
98*aa6bbe75SAndreas Gohr            $embeddings->setSimilarityThreshold($threshold);
99*aa6bbe75SAndreas Gohr        }
100*aa6bbe75SAndreas Gohr
101*aa6bbe75SAndreas Gohr        $sources = $embeddings->getSimilarChunks($query, $langlimit, false);
102*aa6bbe75SAndreas Gohr
103*aa6bbe75SAndreas Gohr        $results = [];
104*aa6bbe75SAndreas Gohr        foreach ($sources as $source) {
105*aa6bbe75SAndreas Gohr            $results[] = new Chunk($source);
106*aa6bbe75SAndreas Gohr        }
107*aa6bbe75SAndreas Gohr        return $results;
108*aa6bbe75SAndreas Gohr    }
109*aa6bbe75SAndreas Gohr
11042b2c6e8SAndreas Gohr}
111