xref: /plugin/aichat/action.php (revision 7017fcea956877cba40d598e4eb414116a75b0a8)
10337f47fSAndreas Gohr<?php
20337f47fSAndreas Gohr
3bddd899cSAndreas Gohruse dokuwiki\ErrorHandler;
4f6ef2e50SAndreas Gohruse dokuwiki\plugin\aichat\Chunk;
5bddd899cSAndreas Gohr
60337f47fSAndreas Gohr/**
70337f47fSAndreas Gohr * DokuWiki Plugin aichat (Action Component)
80337f47fSAndreas Gohr *
90337f47fSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
100337f47fSAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
110337f47fSAndreas Gohr */
120337f47fSAndreas Gohrclass action_plugin_aichat extends \dokuwiki\Extension\ActionPlugin
130337f47fSAndreas Gohr{
140337f47fSAndreas Gohr
150337f47fSAndreas Gohr    /** @inheritDoc */
160337f47fSAndreas Gohr    public function register(Doku_Event_Handler $controller)
170337f47fSAndreas Gohr    {
180337f47fSAndreas Gohr        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleQuestion');
190337f47fSAndreas Gohr    }
200337f47fSAndreas Gohr
210337f47fSAndreas Gohr
220337f47fSAndreas Gohr    /**
230337f47fSAndreas Gohr     * Event handler for AJAX_CALL_UNKNOWN event
240337f47fSAndreas Gohr     *
250337f47fSAndreas Gohr     * @see https://www.dokuwiki.org/devel:events:ajax_call_unknown
260337f47fSAndreas Gohr     * @param Doku_Event $event Event object
270337f47fSAndreas Gohr     * @param mixed $param optional parameter passed when event was registered
280337f47fSAndreas Gohr     * @return void
290337f47fSAndreas Gohr     */
300337f47fSAndreas Gohr    public function handleQuestion(Doku_Event $event, $param)
310337f47fSAndreas Gohr    {
320337f47fSAndreas Gohr        if ($event->data !== 'aichat') return;
330337f47fSAndreas Gohr        $event->preventDefault();
340337f47fSAndreas Gohr        $event->stopPropagation();
350337f47fSAndreas Gohr        global $INPUT;
360337f47fSAndreas Gohr
37c4127b8eSAndreas Gohr        /** @var helper_plugin_aichat $helper */
38c4127b8eSAndreas Gohr        $helper = plugin_load('helper', 'aichat');
39c4127b8eSAndreas Gohr
400337f47fSAndreas Gohr        $question = $INPUT->post->str('question');
410337f47fSAndreas Gohr        $history = json_decode($INPUT->post->str('history'));
42bddd899cSAndreas Gohr        header('Content-Type: application/json');
430337f47fSAndreas Gohr
44c4127b8eSAndreas Gohr        if (!$helper->userMayAccess()) {
45c4127b8eSAndreas Gohr            echo json_encode([
46c4127b8eSAndreas Gohr                'question' => $question,
47c4127b8eSAndreas Gohr                'answer' => $this->getLang('restricted'),
48c4127b8eSAndreas Gohr                'sources' => [],
49c4127b8eSAndreas Gohr            ]);
50c4127b8eSAndreas Gohr            return;
51c4127b8eSAndreas Gohr        }
52c4127b8eSAndreas Gohr
53bddd899cSAndreas Gohr        try {
540337f47fSAndreas Gohr            $result = $helper->askChatQuestion($question, $history);
550337f47fSAndreas Gohr            $sources = [];
560337f47fSAndreas Gohr            foreach ($result['sources'] as $source) {
57bddd899cSAndreas Gohr                /** @var Chunk $source */
58bddd899cSAndreas Gohr                $sources[wl($source->getPage())] = p_get_first_heading($source->getPage()) ?: $source->getPage();
590337f47fSAndreas Gohr            }
60*7017fceaSAndreas Gohr            $parseDown = new Parsedown();
61*7017fceaSAndreas Gohr            $parseDown->setSafeMode(true);
62*7017fceaSAndreas Gohr
630337f47fSAndreas Gohr            echo json_encode([
640337f47fSAndreas Gohr                'question' => $result['question'],
65*7017fceaSAndreas Gohr                'answer' => $parseDown->text($result['answer']),
660337f47fSAndreas Gohr                'sources' => $sources,
670337f47fSAndreas Gohr            ]);
6882d5855eSAndreas Gohr
6982d5855eSAndreas Gohr            if ($this->getConf('logging')) {
7082d5855eSAndreas Gohr                \dokuwiki\Logger::getInstance('aichat')->log(
7182d5855eSAndreas Gohr                    $question,
7282d5855eSAndreas Gohr                    [
7382d5855eSAndreas Gohr                        'interpretation' => $result['question'],
7482d5855eSAndreas Gohr                        'answer' => $result['answer'],
7582d5855eSAndreas Gohr                        'sources' => $sources,
7682d5855eSAndreas Gohr                        'ip' => $INPUT->server->str('REMOTE_ADDR'),
7782d5855eSAndreas Gohr                        'user' => $INPUT->server->str('REMOTE_USER'),
78f6ef2e50SAndreas Gohr                        'stats' => $helper->getModel()->getUsageStats()
7982d5855eSAndreas Gohr                    ]
8082d5855eSAndreas Gohr                );
8182d5855eSAndreas Gohr            }
82bddd899cSAndreas Gohr        } catch (\Exception $e) {
83bddd899cSAndreas Gohr            ErrorHandler::logException($e);
84bddd899cSAndreas Gohr            echo json_encode([
85bddd899cSAndreas Gohr                'question' => $question,
86bddd899cSAndreas Gohr                'answer' => 'An error occurred. More info may be available in the error log. ' . $e->getMessage(),
87bddd899cSAndreas Gohr                'sources' => [],
88bddd899cSAndreas Gohr            ]);
89bddd899cSAndreas Gohr        }
900337f47fSAndreas Gohr    }
910337f47fSAndreas Gohr
920337f47fSAndreas Gohr}
930337f47fSAndreas Gohr
94