xref: /plugin/aichat/action.php (revision 7017fcea956877cba40d598e4eb414116a75b0a8)
1<?php
2
3use dokuwiki\ErrorHandler;
4use dokuwiki\plugin\aichat\Chunk;
5
6/**
7 * DokuWiki Plugin aichat (Action Component)
8 *
9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
10 * @author  Andreas Gohr <gohr@cosmocode.de>
11 */
12class action_plugin_aichat extends \dokuwiki\Extension\ActionPlugin
13{
14
15    /** @inheritDoc */
16    public function register(Doku_Event_Handler $controller)
17    {
18        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleQuestion');
19    }
20
21
22    /**
23     * Event handler for AJAX_CALL_UNKNOWN event
24     *
25     * @see https://www.dokuwiki.org/devel:events:ajax_call_unknown
26     * @param Doku_Event $event Event object
27     * @param mixed $param optional parameter passed when event was registered
28     * @return void
29     */
30    public function handleQuestion(Doku_Event $event, $param)
31    {
32        if ($event->data !== 'aichat') return;
33        $event->preventDefault();
34        $event->stopPropagation();
35        global $INPUT;
36
37        /** @var helper_plugin_aichat $helper */
38        $helper = plugin_load('helper', 'aichat');
39
40        $question = $INPUT->post->str('question');
41        $history = json_decode($INPUT->post->str('history'));
42        header('Content-Type: application/json');
43
44        if (!$helper->userMayAccess()) {
45            echo json_encode([
46                'question' => $question,
47                'answer' => $this->getLang('restricted'),
48                'sources' => [],
49            ]);
50            return;
51        }
52
53        try {
54            $result = $helper->askChatQuestion($question, $history);
55            $sources = [];
56            foreach ($result['sources'] as $source) {
57                /** @var Chunk $source */
58                $sources[wl($source->getPage())] = p_get_first_heading($source->getPage()) ?: $source->getPage();
59            }
60            $parseDown = new Parsedown();
61            $parseDown->setSafeMode(true);
62
63            echo json_encode([
64                'question' => $result['question'],
65                'answer' => $parseDown->text($result['answer']),
66                'sources' => $sources,
67            ]);
68
69            if ($this->getConf('logging')) {
70                \dokuwiki\Logger::getInstance('aichat')->log(
71                    $question,
72                    [
73                        'interpretation' => $result['question'],
74                        'answer' => $result['answer'],
75                        'sources' => $sources,
76                        'ip' => $INPUT->server->str('REMOTE_ADDR'),
77                        'user' => $INPUT->server->str('REMOTE_USER'),
78                        'stats' => $helper->getModel()->getUsageStats()
79                    ]
80                );
81            }
82        } catch (\Exception $e) {
83            ErrorHandler::logException($e);
84            echo json_encode([
85                'question' => $question,
86                'answer' => 'An error occurred. More info may be available in the error log. ' . $e->getMessage(),
87                'sources' => [],
88            ]);
89        }
90    }
91
92}
93
94