1<?php 2 3use dokuwiki\Extension\RemotePlugin; 4use dokuwiki\plugin\aichat\RemoteResponse\Chunk; 5use dokuwiki\plugin\aichat\RemoteResponse\LlmReply; 6use dokuwiki\Remote\AccessDeniedException; 7 8/** 9 * DokuWiki Plugin aichat (Action Component) 10 * 11 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 12 * @author Andreas Gohr <gohr@cosmocode.de> 13 */ 14class remote_plugin_aichat extends RemotePlugin 15{ 16 17 /** 18 * Initialize the helper and check permissions 19 * 20 * @param string $model 21 * @param string $lang 22 * @return helper_plugin_aichat 23 * @throws AccessDeniedException 24 */ 25 protected function initHelper($model = '', $lang = '') 26 { 27 /** @var helper_plugin_aichat $helper */ 28 $helper = plugin_load('helper', 'aichat'); 29 if ($model) { 30 $helper->updateConfig( 31 ['chatmodel' => $model, 'rephasemodel' => $model] 32 ); 33 } 34 35 if (!$helper->userMayAccess()) { 36 throw new AccessDeniedException('You are not allowed to use this plugin', 111); 37 } 38 39 if ($lang === 'auto') { 40 $helper->updateConfig(['preferUIlanguage' => 0]); 41 } elseif ($lang) { 42 $helper->updateConfig(['preferUIlanguage' => 1]); 43 global $conf; 44 $conf['lang'] = $lang; 45 } 46 47 return $helper; 48 } 49 50 /** 51 * Ask the LLM a question 52 * 53 * Sends the given question to the LLM and returns the answer, including the used sources. 54 * 55 * @param string $query The question to ask the LLM 56 * @param string $model The model to use, if empty the default model is used 57 * @param string $lang Language code to override preferUIlanguage setting. "auto" to force autodetection. 58 * @return LlmReply 59 * @throws AccessDeniedException 60 * @throws Exception 61 */ 62 public function ask($query, $model = '', $lang = '') 63 { 64 $helper = $this->initHelper($model, $lang); 65 $result = $helper->askQuestion($query); 66 67 return new LlmReply($result); 68 } 69 70 /** 71 * Get page chunks similar to a given query 72 * 73 * Uses the given query to find similar pages in the wiki. Returns the most similar chunks. 74 * 75 * This call returns chunks, not pages. So a page may returned multiple times when different chunks of it 76 * are similar to the query. 77 * 78 * Note that this call may return less results than requested depending on the used vector store. 79 * 80 * @param string $query 81 * @param int $max Maximum number of results to return. -1 for default set in config 82 * @param float $threshold Minimum similarity score to return results for. -1 for default set in config 83 * @param string $lang Language code to override preferUIlanguage setting. "auto" to force autodetection. 84 * @return Chunk[] A list of similar chunks 85 * @throws AccessDeniedException 86 * @throws Exception 87 */ 88 public function similar($query, $max = -1, $threshold = -1, $lang = '') 89 { 90 $helper = $this->initHelper('', $lang); 91 $langlimit = $helper->getLanguageLimit(); 92 93 $embeddings = $helper->getEmbeddings(); 94 if ($max !== -1) { 95 $embeddings->setConfigContextChunks($max); 96 } 97 if ($threshold !== -1) { 98 $embeddings->setSimilarityThreshold($threshold); 99 } 100 101 $sources = $embeddings->getSimilarChunks($query, $langlimit, false); 102 103 $results = []; 104 foreach ($sources as $source) { 105 $results[] = new Chunk($source); 106 } 107 return $results; 108 } 109 110} 111