1
0

BxBaseStudioAgentsAgents.php 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaView UNA Studio Representation classes
  7. * @ingroup UnaStudio
  8. * @{
  9. */
  10. class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
  11. {
  12. protected $_sUrlPage;
  13. protected $_sFieldName;
  14. public function __construct ($aOptions, $oTemplate = false)
  15. {
  16. parent::__construct ($aOptions, $oTemplate);
  17. $this->_sUrlPage = BX_DOL_URL_STUDIO . 'agents.php?page=agents';
  18. $this->_sFieldName = 'name';
  19. }
  20. public function getPageJsObject()
  21. {
  22. return 'oBxDolStudioPageAgents';
  23. }
  24. public function performActionGetAlert()
  25. {
  26. $aAlert = $this->_getAlertPayload(bx_get('alert'));
  27. echoJson([
  28. 'code' => $aAlert ? 200 : 404,
  29. 'desc' => $aAlert ? $this->_oDb->getAlertDesc(bx_get('alert')) : '',
  30. 'payload' => $aAlert,
  31. ]);
  32. }
  33. public function performActionGetFormInputs()
  34. {
  35. $aFormInputs = $this->_getFormInputs(bx_get('form_object'));
  36. if (!$aFormInputs) {
  37. echoJson(['code' => 404, 'msg' => _t('_sys_not_available')]);
  38. return;
  39. }
  40. echoJson([
  41. 'code' => $aFormInputs ? 200 : 404,
  42. 'form_inputs' => $aFormInputs,
  43. ]);
  44. }
  45. public function performActionManual()
  46. {
  47. $iId = $this->_getId();
  48. $aAgent = BxDolAiQuery::getAgentObject($iId);
  49. if (!$aAgent) {
  50. echoJson(['msg' => _t('_sys_txt_error_occured')]);
  51. return;
  52. }
  53. if (!$aAgent['active']) {
  54. echoJson(['msg' => _t('_sys_txt_agent_inactive')]);
  55. return;
  56. }
  57. $oAi = BxDolAi::getInstance();
  58. try {
  59. $sResponse = $oAi->callAgent('manual', $aAgent);
  60. } catch (Throwable $o) {
  61. echoJson(['msg' => $o->getMessage()]);
  62. return;
  63. }
  64. $oParsedown = new Parsedown();
  65. $oParsedown->setSafeMode(true);
  66. $sMessageHtml = $oParsedown->text($sResponse);
  67. $oTemplate = BxDolStudioTemplate::getInstance();
  68. $sHtml = $oTemplate->parseHtmlByName('agents_manual_response.html', [
  69. 'response' => $sMessageHtml
  70. ]);
  71. echoJson(['msg' => $sHtml]);
  72. }
  73. public function performActionWipeChatHistory()
  74. {
  75. $iId = $this->_getId();
  76. $aAgent = BxDolAiQuery::getAgentObject($iId);
  77. if (!$aAgent) {
  78. echoJson(['msg' => _t('_sys_txt_error_occured')]);
  79. return;
  80. }
  81. $oDb = new BxDolAiQuery();
  82. $oDb->wipeAgentChatHistory($aAgent);
  83. $aRes = ['grid' => $this->getCode(false), 'blink' => $iId];
  84. echoJson($aRes);
  85. }
  86. public function performActionAdd()
  87. {
  88. $sAction = 'add';
  89. $oTemplate = BxDolStudioTemplate::getInstance();
  90. $oAI = BxDolAi::getInstance();
  91. $aForm = $this->_getForm($sAction);
  92. $oForm = new BxTemplFormView($aForm);
  93. $oForm->initChecker();
  94. if ($oForm->isSubmitted() && $oForm->getCleanValue('trigger') == 'message') {
  95. $aAgent = $this->_getAgentWithProfile($oForm->getCleanValue('profile_id'));
  96. if ($aAgent) {
  97. $oForm->aInputs['profile_id']['error'] = _t('_sys_agents_form_field_err_profile_has_agent', $aAgent['name']);
  98. $oForm->setValid(false);
  99. }
  100. }
  101. if($oForm->isSubmittedAndValid()) {
  102. $aValsToAdd = [
  103. 'added' => time()
  104. ];
  105. $sName = $oForm->getCleanValue($this->_sFieldName);
  106. $sName = $this->_getUniqName($sName);
  107. BxDolForm::setSubmittedValue($this->_sFieldName, $sName, $oForm->aFormAttrs['method']);
  108. $iProfileId = $oForm->getCleanValue('profile_id');
  109. if(empty($iProfileId)) {
  110. $iProfileId = (int)getParam('sys_agents_profile');
  111. if(empty($iProfileId))
  112. $iProfileId = current(bx_srv('system', 'get_options_agents_profile', [false], 'TemplServices'))['key'];
  113. $aValsToAdd['profile_id'] = $iProfileId;
  114. }
  115. $iModel = $oForm->getCleanValue('model_id');
  116. $sTrigger = $oForm->getCleanValue('trigger');
  117. $sTools = is_array($oForm->getCleanValue('tools')) ? implode(',', $oForm->getCleanValue('tools')) : '';
  118. $aValsToAdd['tools'] = $sTools;
  119. $aValsToAdd['acl_levels'] = (int)$oForm->getCleanValue('acl_levels');
  120. $bIsValid = true;
  121. if($bIsValid) {
  122. if(($iId = $oForm->insert($aValsToAdd)) !== false) {
  123. $this->_oDb->cleanCache('sys_agents_with_alert');
  124. $aRes = ['grid' => $this->getCode(false), 'blink' => $iId];
  125. }
  126. else
  127. $aRes = ['msg' => _t('_sys_txt_error_occured')];
  128. return echoJson($aRes);
  129. }
  130. }
  131. $sFormId = $oForm->getId();
  132. $sContent = BxTemplStudioFunctions::getInstance()->popupBox($sFormId . '_popup', _t('_sys_agents_agents_popup_add'), $this->_oTemplate->parseHtmlByName('agents_agents_form.html', [
  133. 'form_id' => $sFormId,
  134. 'form' => $oForm->getCode(true),
  135. 'object' => $this->_sObject,
  136. 'action' => $sAction
  137. ]));
  138. return echoJson(['popup' => ['html' => $sContent, 'options' => ['closeOnOuterClick' => false]]]);
  139. }
  140. public function performActionEdit()
  141. {
  142. $sAction = 'edit';
  143. $oTemplate = BxDolStudioTemplate::getInstance();
  144. $oAI = BxDolAi::getInstance();
  145. $iId = $this->_getId();
  146. $aAgent = BxDolAiQuery::getAgentObject($iId);
  147. $aForm = $this->_getFormEdit($sAction, $aAgent);
  148. $oForm = new BxTemplFormView($aForm);
  149. $oForm->initChecker();
  150. if ($oForm->isSubmitted() && $oForm->getCleanValue('trigger') == 'message') {
  151. $aAgent = $this->_getAgentWithProfile($oForm->getCleanValue('profile_id'), $iId);
  152. if ($aAgent) {
  153. $oForm->aInputs['profile_id']['error'] = _t('_sys_agents_form_field_err_profile_has_agent', $aAgent['name']);
  154. $oForm->setValid(false);
  155. }
  156. }
  157. if($oForm->isSubmittedAndValid()) {
  158. $aValsToAdd = [];
  159. $sName = $oForm->getCleanValue($this->_sFieldName);
  160. $sName = $this->_getUniqName($sName);
  161. BxDolForm::setSubmittedValue($this->_sFieldName, $sName, $oForm->aFormAttrs['method']);
  162. $iProfileId = $oForm->getCleanValue('profile_id');
  163. if(empty($iProfileId)) {
  164. $iProfileId = (int)getParam('sys_agents_profile');
  165. if(empty($iProfileId))
  166. $iProfileId = current(bx_srv('system', 'get_options_agents_profile', [false], 'TemplServices'))['key'];
  167. $aValsToAdd['profile_id'] = $iProfileId;
  168. }
  169. $iModel = $oForm->getCleanValue('model_id');
  170. $sTrigger = $oForm->getCleanValue('trigger');
  171. $sTools = is_array($oForm->getCleanValue('tools')) ? implode(',', $oForm->getCleanValue('tools')) : '';
  172. $aValsToAdd['tools'] = $sTools;
  173. $aValsToAdd['acl_levels'] = (int)$oForm->getCleanValue('acl_levels');
  174. $bIsValid = true;
  175. if($bIsValid) {
  176. if(($iId = $oForm->update($iId, $aValsToAdd)) !== false) {
  177. $this->_oDb->cleanCache('sys_agents_with_alert');
  178. $aRes = ['grid' => $this->getCode(false), 'blink' => $iId];
  179. }
  180. else
  181. $aRes = ['msg' => _t('_sys_txt_error_occured')];
  182. return echoJson($aRes);
  183. }
  184. }
  185. $sFormId = $oForm->getId();
  186. $sContent = BxTemplStudioFunctions::getInstance()->popupBox($sFormId . '_popup', _t('_sys_agents_agents_popup_edit', $aAgent['name']), $this->_oTemplate->parseHtmlByName('agents_agents_form.html', [
  187. 'form_id' => $sFormId,
  188. 'form' => $oForm->getCode(true),
  189. 'object' => $this->_sObject,
  190. 'action' => $sAction
  191. ]));
  192. return echoJson(['popup' => ['html' => $sContent, 'options' => ['closeOnOuterClick' => false]]]);
  193. }
  194. public function performActionLogs()
  195. {
  196. $iId = $this->_getId();
  197. $aAgent = BxDolAiQuery::getAgentObject($iId);
  198. if (!$aAgent) {
  199. echoJson(['msg' => _t('_sys_txt_error_occured')]);
  200. return;
  201. }
  202. $oGrid = BxDolGrid::getObjectInstance('sys_studio_agents_logs');
  203. $oGrid->addMarkers(['agent_id' => $iId]);
  204. $oGrid->setBrowseParams(['agent_id' => $iId]);
  205. $sGrid = $oGrid->getCode();
  206. $sContent = BxTemplStudioFunctions::getInstance()->popupBox('popup_files_' . $iId, _t('_sys_agents_logs_popup', $aAgent['name']), $this->_oTemplate->parseHtmlByName('agents_popup_grid.html', [
  207. 'grid' => $sGrid,
  208. ]));
  209. return echoJson(['popup' => ['html' => $sContent, 'options' => ['closeOnOuterClick' => false]]]);
  210. }
  211. public function performActionMessage()
  212. {
  213. $iId = $this->_getId();
  214. $aAgent = BxDolAiQuery::getAgentObject($iId);
  215. if (!$aAgent) {
  216. echoJson(['msg' => _t('_sys_txt_error_occured')]);
  217. return;
  218. }
  219. if (!$aAgent['active']) {
  220. echoJson(['msg' => _t('_sys_txt_agent_inactive')]);
  221. return;
  222. }
  223. $sChatId = 'bx-ai-chat-' . $iId;
  224. $sName = !empty($aAgent['title']) ? $aAgent['title'] : $aAgent['name'];
  225. $aThreadsTpl = [];
  226. $oAi = BxDolAi::getInstance();
  227. $aThreads = $oAi ? $oAi->listAgentChatThreads($aAgent) : [];
  228. foreach ($aThreads as $aThread) {
  229. $aThreadsTpl[] = [
  230. 'thread_id' => bx_html_attribute($aThread['thread_id']),
  231. 'writable' => (int)$aThread['writable'],
  232. 'context_pid' => (int)$aThread['context_pid'],
  233. 'title' => bx_process_output($aThread['title']),
  234. 'meta' => bx_process_output($aThread['meta']),
  235. 'class_mine' => $aThread['class_mine'],
  236. ];
  237. }
  238. $sContent = BxTemplStudioFunctions::getInstance()->popupBox('popup_agent_chat_' . $iId, _t('_sys_agents_agents_popup_message', $sName), $this->_oTemplate->parseHtmlByName('agents_popup_chat.html', [
  239. 'chat_id' => $sChatId,
  240. 'agent_id' => (int)$iId,
  241. 'txt_readonly' => _t('_sys_agents_agents_txt_readonly'),
  242. 'txt_chats' => _t('_sys_agents_agents_txt_chats'),
  243. 'bx_repeat:threads' => $aThreadsTpl,
  244. ]));
  245. $aThreadsJs = [];
  246. foreach ($aThreads as $aThread)
  247. $aThreadsJs[] = $this->_agentChatThreadJs($aThread);
  248. $sThreadsJson = json_encode($aThreadsJs, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
  249. if ($sThreadsJson === false)
  250. $sThreadsJson = '[]';
  251. $sJsObject = $this->getPageJsObject();
  252. return echoJson(['popup' => [
  253. 'html' => $sContent,
  254. 'options' => [
  255. 'closeOnOuterClick' => false,
  256. 'onShow' => $sJsObject . ".initAgentChat('#" . $sChatId . "', " . (int)$iId . ", " . $sThreadsJson . ");",
  257. 'onHide' => $sJsObject . ".destroyAgentChat();",
  258. ]
  259. ]]);
  260. }
  261. public function performActionGetChatThreads()
  262. {
  263. $iId = $this->_getId();
  264. $aAgent = BxDolAiQuery::getAgentObject($iId);
  265. if (!$aAgent) {
  266. echoJson(['code' => 404, 'threads' => []]);
  267. return;
  268. }
  269. $aThreadsJs = [];
  270. $oAi = BxDolAi::getInstance();
  271. $aThreads = $oAi ? $oAi->listAgentChatThreads($aAgent) : [];
  272. foreach ($aThreads as $aThread)
  273. $aThreadsJs[] = $this->_agentChatThreadJs($aThread);
  274. echoJson(['code' => 200, 'threads' => $aThreadsJs]);
  275. }
  276. public function performActionGetChatThread()
  277. {
  278. $iId = $this->_getId();
  279. $aAgent = BxDolAiQuery::getAgentObject($iId);
  280. if (!$aAgent) {
  281. echoJson(['code' => 404, 'msg' => _t('_sys_txt_error_occured'), 'messages' => []]);
  282. return;
  283. }
  284. $sThreadId = trim((string)bx_get('thread_id'));
  285. $oAi = BxDolAi::getInstance();
  286. if (!$oAi) {
  287. echoJson(['code' => 503, 'msg' => _t('_sys_txt_error_occured'), 'messages' => []]);
  288. return;
  289. }
  290. $aMessages = $oAi->getChatHistoryUiMessagesByThread($aAgent, $sThreadId);
  291. if ($aMessages === false) {
  292. echoJson(['code' => 404, 'msg' => _t('_sys_txt_error_occured'), 'messages' => []]);
  293. return;
  294. }
  295. echoJson([
  296. 'code' => 200,
  297. 'messages' => $aMessages,
  298. 'writable' => $oAi->isOwnAgentChatThread($aAgent, $sThreadId) ? 1 : 0,
  299. 'artifacts' => $oAi->getChatHistoryArtifactsByThread($aAgent, $sThreadId),
  300. ]);
  301. }
  302. protected function _agentChatThreadJs($aThread)
  303. {
  304. $aArtifacts = [];
  305. if (!empty($aThread['artifacts']) && is_array($aThread['artifacts'])) {
  306. foreach ($aThread['artifacts'] as $aItem) {
  307. if (!is_array($aItem))
  308. continue;
  309. $aArtifacts[] = [
  310. 'field_name' => (string)($aItem['field_name'] ?? ''),
  311. 'field_value' => (string)($aItem['field_value'] ?? ''),
  312. ];
  313. }
  314. }
  315. return [
  316. 'thread_id' => (string)$aThread['thread_id'],
  317. 'writable' => (int)$aThread['writable'],
  318. 'context_pid' => (int)$aThread['context_pid'],
  319. 'title' => (string)$aThread['title'],
  320. 'meta' => (string)$aThread['meta'],
  321. 'status' => (string)($aThread['status'] ?? 'opened'),
  322. 'created_at' => (string)($aThread['created_at'] ?? ''),
  323. 'updated_at' => (string)($aThread['updated_at'] ?? ''),
  324. 'artifacts' => $aArtifacts,
  325. ];
  326. }
  327. protected function _getCellProfileId($mixedValue, $sKey, $aField, $aRow)
  328. {
  329. $mixedValue = BxDolProfile::getInstanceMagic($mixedValue)->getUnit(0, ['template' => 'unit_wo_info']);
  330. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  331. }
  332. protected function _getCellIcon($mixedValue, $sKey, $aField, $aRow)
  333. {
  334. $sIcon = '';
  335. if($mixedValue) {
  336. list($sIcon, $sIconUrl, $sIconA, $sIconHtml, $sIconFontWithHtml) = $this->_oTemplate->getTemplateFunctions()->getIcon($mixedValue, ['class' => 'sys-colored']);
  337. if($sIcon)
  338. $sIcon = $this->_oTemplate->parseIcon(BxDolIconset::getObjectInstance()->getIcon($sIcon));
  339. else if($sIconHtml)
  340. $sIcon = $sIconHtml;
  341. else if($sIconUrl)
  342. $sIcon = '<img src="' . bx_html_attribute($sIconUrl) . '" />';
  343. else if($sIconFontWithHtml)
  344. $sIcon = $sIconFontWithHtml;
  345. }
  346. if (!$sIcon)
  347. $sIcon = '<i class="sys-icon robot"></i>';
  348. return parent::_getCellDefault($sIcon, $sKey, $aField, $aRow);
  349. }
  350. protected function _getCellModelId($mixedValue, $sKey, $aField, $aRow)
  351. {
  352. $aModel = $this->_oDb->getModelsBy(['sample' => 'id', 'id' => $mixedValue]);
  353. if(!empty($aModel) && is_array($aModel)) {
  354. $mixedValue = $aModel['icon'];
  355. if (strpos($mixedValue, '.svg') !== false)
  356. $mixedValue = $this->_oTemplate->getIconContent($mixedValue);
  357. } else {
  358. $mixedValue = '';
  359. }
  360. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  361. }
  362. protected function _getCellTrigger($mixedValue, $sKey, $aField, $aRow)
  363. {
  364. $mixedValue = $this->_oTemplate->getIconContent('agt-trg-' . $mixedValue . '.svg');
  365. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  366. }
  367. protected function _getCellName($mixedValue, $sKey, $aField, $aRow)
  368. {
  369. if (!empty($aRow['title']))
  370. $mixedValue = $aRow['title'];
  371. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  372. }
  373. protected function _delete ($mixedId)
  374. {
  375. $mixedResult = parent::_delete($mixedId);
  376. $this->_oDb->cleanCache('sys_agents_with_alert');
  377. return $mixedResult;
  378. }
  379. protected function _getFormEdit($sAction, $aAgent = [])
  380. {
  381. $aForm = $this->_getForm($sAction, $aAgent);
  382. $aForm['form_attrs']['action'] .= '&id=' . $aAgent['id'];
  383. unset($aForm['inputs']['name']);
  384. return $aForm;
  385. }
  386. protected function _getForm($sAction, $aAgent = [])
  387. {
  388. $sJsObject = $this->getPageJsObject();
  389. $aForm = array(
  390. 'form_attrs' => array(
  391. 'id' => 'bx_std_agents_' . $sAction,
  392. 'action' => BX_DOL_URL_ROOT . 'grid.php?o=sys_studio_agents_agents&a=' . $sAction,
  393. 'method' => 'post',
  394. ),
  395. 'params' => array (
  396. 'db' => array(
  397. 'table' => 'sys_agents_agents',
  398. 'key' => 'id',
  399. 'submit_name' => 'do_submit',
  400. ),
  401. ),
  402. 'inputs' => array(
  403. 'title' => [
  404. 'type' => 'text',
  405. 'name' => 'title',
  406. 'caption' => _t('_sys_agents_field_title'),
  407. 'info' => _t('_sys_agents_field_title_info'),
  408. 'value' => $aAgent['title'] ?? '',
  409. 'required' => '1',
  410. 'checker' => [
  411. 'func' => 'Avail',
  412. 'error' => _t('_sys_agents_form_field_err_enter'),
  413. ],
  414. 'db' => [
  415. 'pass' => 'Xss',
  416. ],
  417. ],
  418. 'name' => [
  419. 'type' => 'text',
  420. 'name' => 'name',
  421. 'caption' => _t('_sys_agents_field_name'),
  422. 'info' => _t('_sys_agents_field_name_info'),
  423. 'value' => isset($aAgent['name']) ? $aAgent['name'] : '',
  424. 'required' => '1',
  425. 'checker' => [
  426. 'func' => 'Avail',
  427. 'error' => _t('_sys_agents_form_field_err_enter'),
  428. ],
  429. 'db' => [
  430. 'pass' => 'Xss',
  431. ],
  432. ],
  433. 'description' => [
  434. 'type' => 'textarea',
  435. 'name' => 'description',
  436. 'caption' => _t('_sys_agents_field_description'),
  437. 'info' => _t('_sys_agents_field_description_info'),
  438. 'value' => $aAgent['description'] ?? '',
  439. 'db' => [
  440. 'pass' => 'Xss',
  441. ],
  442. ],
  443. 'icon' => [
  444. 'type' => 'textarea',
  445. 'name' => 'icon',
  446. 'caption' => _t('_sys_agents_field_icon'),
  447. 'info' => _t('_sys_agents_field_icon_info'),
  448. 'value' => $aAgent['icon'] ?? '',
  449. 'code' => 1,
  450. 'db' => [
  451. 'pass' => 'Xss',
  452. ],
  453. ],
  454. 'model_id' => [
  455. 'type' => 'select',
  456. 'name' => 'model_id',
  457. 'caption' => _t('_sys_agents_field_model_id'),
  458. 'info' => _t('_sys_agents_field_model_id_info'),
  459. 'value' => isset($aAgent['model_id']) ? $aAgent['model_id'] : BxDolAi::getDefaultModel(),
  460. 'values' => $this->_getModelSelectValues(),
  461. 'required' => '1',
  462. 'checker' => [
  463. 'func' => 'Avail',
  464. 'error' => _t('_sys_agents_form_field_err_select'),
  465. ],
  466. 'db' => [
  467. 'pass' => 'Int',
  468. ],
  469. ],
  470. 'profile_id' => [
  471. 'type' => 'select',
  472. 'name' => 'profile_id',
  473. 'caption' => _t('_sys_agents_field_profile_id'),
  474. 'info' => _t('_sys_agents_field_profile_id_inf'),
  475. 'value' => isset($aAgent['profile_id']) ? $aAgent['profile_id'] : 0,
  476. 'values' => $this->_getProfileSelectValues(),
  477. 'required' => '1',
  478. 'required' => '1',
  479. 'checker' => [
  480. 'func' => 'Avail',
  481. 'error' => _t('_sys_agents_form_field_err_select'),
  482. ],
  483. 'db' => [
  484. 'pass' => 'Int',
  485. ]
  486. ],
  487. 'acl_levels' => [
  488. 'type' => 'checkbox_set',
  489. 'name' => 'acl_levels',
  490. 'caption' => _t('_sys_agents_field_acl_levels'),
  491. 'info' => _t('_sys_agents_field_acl_levels_info'),
  492. 'value' => [],
  493. 'values' => [],
  494. 'db' => [
  495. 'pass' => 'Set',
  496. ]
  497. ],
  498. 'trigger' => [
  499. 'type' => 'select',
  500. 'name' => 'trigger',
  501. 'caption' => _t('_sys_agents_field_trigger'),
  502. 'info' => _t('_sys_agents_field_trigger_info'),
  503. 'value' => isset($aAgent['trigger']) ? $aAgent['trigger'] : 0,
  504. 'values' => [
  505. 'alert' => _t('_sys_agents_field_trigger_alert'),
  506. 'scheduler' => _t('_sys_agents_field_trigger_scheduler'),
  507. 'webhook' => _t('_sys_agents_field_trigger_webhook'),
  508. 'manual' => _t('_sys_agents_field_trigger_manual'),
  509. 'agent' => _t('_sys_agents_field_trigger_agent'),
  510. 'message' => _t('_sys_agents_field_trigger_message'),
  511. 'form-input' => _t('_sys_agents_field_trigger_form_input'),
  512. ],
  513. // 'attrs' => [
  514. // 'onchange' => $this->getPageJsObject() . '.onChangeAgentTrigger(this)',
  515. // ],
  516. 'required' => '1',
  517. 'db' => [
  518. 'pass' => 'Xss',
  519. ]
  520. ],
  521. 'async' => [
  522. 'type' => 'checkbox',
  523. 'name' => 'async',
  524. 'caption' => _t('_sys_agents_field_async'),
  525. 'info' => _t('_sys_agents_field_async_inf'),
  526. 'value' => 1,
  527. 'checked' => isset($aAgent['async']) ? $aAgent['async'] : 0,
  528. 'db' => [
  529. 'pass' => 'Int',
  530. ]
  531. ],
  532. 'alert_section' => [
  533. 'type' => 'block_header',
  534. 'caption' => _t('_sys_agents_block_header_alert'),
  535. 'collapsable' => true,
  536. 'collapsed' => true,
  537. ],
  538. 'alert_sample' => [
  539. 'type' => 'custom',
  540. 'name' => 'alert_sample',
  541. 'caption' => _t('_sys_agents_field_alert_sample'),
  542. 'content' => $this->_oTemplate->parseHtmlByName('agents_agents_alerts_payload.html', [
  543. 'text-visibility' => empty($aAgent['alert']) ? 'block' : 'none',
  544. 'text' => _t('_sys_agents_waiting_for_sample_data_alert'),
  545. 'payload-visibility' => !empty($aAgent['alert']) ? 'block' : 'none',
  546. 'desc' => $aAgent ? $this->_oDb->getAlertDesc($aAgent['alert']) : '',
  547. 'payload' => !empty($aAgent['alert']) ? json_encode($this->_getAlertPayload($aAgent['alert']), JSON_PRETTY_PRINT) : '',
  548. ]),
  549. ],
  550. 'alert' => [
  551. 'type' => 'custom',
  552. 'name' => 'alert',
  553. 'caption' => _t('_sys_agents_field_alert'),
  554. 'info' => _t('_sys_agents_field_alert_info'),
  555. 'content' => $this->_oTemplate->parseHtmlByName('agents_agents_alerts_select.html', $this->_getAlertValues(isset($aAgent['alert']) ? $aAgent['alert'] : '')),
  556. 'db' => [
  557. 'pass' => 'Xss',
  558. ],
  559. ],
  560. 'alert_section_end' => [
  561. 'type' => 'block_end',
  562. ],
  563. 'scheduler_section' => [
  564. 'type' => 'block_header',
  565. 'caption' => _t('_sys_agents_block_header_scheduler'),
  566. 'collapsable' => true,
  567. 'collapsed' => true,
  568. ],
  569. 'scheduler_cron' => [
  570. 'type' => 'text',
  571. 'name' => 'scheduler_cron',
  572. 'caption' => _t('_sys_agents_field_scheduler_cron'),
  573. 'info' => _t('_sys_agents_field_scheduler_cron_info'),
  574. 'value' => isset($aAgent['scheduler_cron']) ? $aAgent['scheduler_cron'] : '',
  575. 'db' => [
  576. 'pass' => 'Xss',
  577. ],
  578. ],
  579. 'scheduler_section_end' => [
  580. 'type' => 'block_end',
  581. ],
  582. 'webhook_section' => [
  583. 'type' => 'block_header',
  584. 'caption' => _t('_sys_agents_block_header_webhook'),
  585. 'collapsable' => true,
  586. 'collapsed' => true,
  587. ],
  588. 'webhook_sample' => [
  589. 'type' => 'custom',
  590. 'name' => 'webhook_sample',
  591. 'caption' => _t('_sys_agents_field_webhook_sample'),
  592. 'content' => isset($aAgent['webhook_sample']) ? $aAgent['webhook_sample'] : _t('_sys_agents_waiting_for_sample_data_webhook'),
  593. ],
  594. 'webhook_key' => [
  595. 'type' => 'text',
  596. 'name' => 'webhook_key',
  597. 'caption' => _t('_sys_agents_field_webhook_key'),
  598. 'info' => _t('_sys_agents_field_webhook_key_info'),
  599. 'value' => isset($aAgent['webhook_key']) ? $aAgent['webhook_key'] : '',
  600. 'db' => [
  601. 'pass' => 'Xss',
  602. ],
  603. ],
  604. 'webhook_section_end' => [
  605. 'type' => 'block_end',
  606. ],
  607. 'message_section' => [
  608. 'type' => 'block_header',
  609. 'caption' => _t('_sys_agents_block_header_message'),
  610. 'collapsable' => true,
  611. 'collapsed' => true,
  612. ],
  613. 'message_profile_id' => [
  614. 'type' => 'select',
  615. 'name' => 'message_profile_id',
  616. 'caption' => _t('_sys_agents_field_message_profile'),
  617. 'info' => _t('_sys_agents_field_message_profile_info'),
  618. 'value' => isset($aAgent['message_profile_id']) ? $aAgent['message_profile_id'] : '',
  619. 'values' => $this->_getProfileSelectValues(true, '_adm_nav_txt_items_visible_for_all'),
  620. 'db' => [
  621. 'pass' => 'Xss',
  622. ],
  623. ],
  624. 'message_section_end' => [
  625. 'type' => 'block_end',
  626. ],
  627. 'form_field_section' => [
  628. 'type' => 'block_header',
  629. 'caption' => _t('_sys_agents_block_header_form_input'),
  630. 'collapsable' => true,
  631. 'collapsed' => true,
  632. ],
  633. 'form_object' => [
  634. 'type' => 'custom',
  635. 'name' => 'form_object',
  636. 'caption' => _t('_sys_agents_form_object'),
  637. 'info' => _t('_sys_agents_form_object_info'),
  638. 'content' => $this->_oTemplate->parseHtmlByName('agents_agents_form_object_select.html', $this->_getFormObjectValues(isset($aAgent['form_object']) ? $aAgent['form_object'] : '')),
  639. 'db' => [
  640. 'pass' => 'Xss',
  641. ],
  642. ],
  643. 'form_input' => [
  644. 'type' => 'custom',
  645. 'name' => 'form_input',
  646. 'caption' => _t('_sys_agents_form_input'),
  647. 'info' => _t('_sys_agents_form_input_info'),
  648. 'content' => $this->_oTemplate->parseHtmlByName('agents_agents_form_input_select.html', $this->_getFormInputValues(isset($aAgent['form_object']) ? $aAgent['form_object'] : '', isset($aAgent['form_input']) ? $aAgent['form_input'] : '')),
  649. 'db' => [
  650. 'pass' => 'Xss',
  651. ],
  652. ],
  653. 'form_field_section_end' => array(
  654. 'type' => 'block_end',
  655. ),
  656. 'manual_section' => [
  657. 'type' => 'block_header',
  658. 'caption' => _t('_sys_agents_block_header_manual'),
  659. 'collapsable' => true,
  660. 'collapsed' => true,
  661. ],
  662. 'max_turns' => [
  663. 'type' => 'text',
  664. 'name' => 'max_turns',
  665. 'caption' => _t('_sys_agents_field_manual_max_turns'),
  666. 'info' => _t('_sys_agents_field_manual_max_turns_info'),
  667. 'value' => $aAgent['max_turns'] ?? 0,
  668. 'required' => '1',
  669. 'db' => [
  670. 'pass' => 'Int',
  671. ],
  672. ],
  673. 'chat_ttl_min' => [
  674. 'type' => 'text',
  675. 'name' => 'chat_ttl_min',
  676. 'caption' => _t('_sys_agents_field_manual_chat_ttl_min'),
  677. 'info' => _t('_sys_agents_field_manual_chat_ttl_min_info'),
  678. 'value' => $aAgent['chat_ttl_min'] ?? 0,
  679. 'required' => '1',
  680. 'db' => [
  681. 'pass' => 'Int',
  682. ],
  683. ],
  684. 'limit_message' => [
  685. 'type' => 'textarea',
  686. 'name' => 'limit_message',
  687. 'caption' => _t('_sys_agents_field_manual_limit_message'),
  688. 'info' => _t('_sys_agents_field_manual_limit_message_info'),
  689. 'value' => $aAgent['limit_message'] ?? '',
  690. 'db' => [
  691. 'pass' => 'Xss',
  692. ],
  693. ],
  694. 'max_input_chars' => [
  695. 'type' => 'text',
  696. 'name' => 'max_input_chars',
  697. 'caption' => _t('_sys_agents_field_manual_max_input_chars'),
  698. 'info' => _t('_sys_agents_field_manual_max_input_chars_info'),
  699. 'value' => $aAgent['max_input_chars'] ?? 0,
  700. 'required' => '1',
  701. 'db' => [
  702. 'pass' => 'Int',
  703. ],
  704. ],
  705. 'max_tokens' => [
  706. 'type' => 'text',
  707. 'name' => 'max_tokens',
  708. 'caption' => _t('_sys_agents_field_manual_max_tokens'),
  709. 'info' => _t('_sys_agents_field_manual_max_tokens_info'),
  710. 'value' => $aAgent['max_tokens'] ?? 0,
  711. 'required' => '1',
  712. 'db' => [
  713. 'pass' => 'Int',
  714. ],
  715. ],
  716. 'max_sessions_per_hour' => [
  717. 'type' => 'text',
  718. 'name' => 'max_sessions_per_hour',
  719. 'caption' => _t('_sys_agents_field_manual_max_sessions_per_hour'),
  720. 'info' => _t('_sys_agents_field_manual_max_sessions_per_hour_info'),
  721. 'value' => $aAgent['max_sessions_per_hour'] ?? 3,
  722. 'required' => '1',
  723. 'db' => [
  724. 'pass' => 'Int',
  725. ],
  726. ],
  727. 'max_sessions_per_day' => [
  728. 'type' => 'text',
  729. 'name' => 'max_sessions_per_day',
  730. 'caption' => _t('_sys_agents_field_manual_max_sessions_per_day'),
  731. 'info' => _t('_sys_agents_field_manual_max_sessions_per_day_info'),
  732. 'value' => $aAgent['max_sessions_per_day'] ?? 10,
  733. 'required' => '1',
  734. 'db' => [
  735. 'pass' => 'Int',
  736. ],
  737. ],
  738. 'hidden_first_message' => [
  739. 'type' => 'text',
  740. 'name' => 'hidden_first_message',
  741. 'caption' => _t('_sys_agents_field_manual_hidden_first_message'),
  742. 'info' => _t('_sys_agents_field_manual_hidden_first_message_info'),
  743. 'value' => $aAgent['hidden_first_message'] ?? '',
  744. 'attrs' => ['maxlength' => 64],
  745. 'db' => [
  746. 'pass' => 'Xss',
  747. ],
  748. ],
  749. 'manual_section_end' => [
  750. 'type' => 'block_end',
  751. ],
  752. 'vector_store_id' => [
  753. 'type' => 'select',
  754. 'name' => 'vector_store_id',
  755. 'caption' => _t('_sys_agents_field_vector_store_id'),
  756. 'info' => _t('_sys_agents_field_vector_store_id_info'),
  757. 'value' => isset($aAgent['vector_store_id']) ? $aAgent['vector_store_id'] : 0,
  758. 'values' => $this->_oDb->getVectorStores(),
  759. 'required' => '1',
  760. 'checker' => [
  761. 'func' => 'Avail',
  762. 'error' => _t('_sys_agents_form_field_err_select'),
  763. ],
  764. 'db' => [
  765. 'pass' => 'Xss',
  766. ],
  767. ],
  768. 'chat_history_context' => [
  769. 'type' => 'text',
  770. 'name' => 'chat_history_context',
  771. 'caption' => _t('_sys_agents_field_chat_history_context'),
  772. 'info' => _t('_sys_agents_field_chat_history_context_info'),
  773. 'value' => isset($aAgent['chat_history_context']) ? $aAgent['chat_history_context'] : 50000,
  774. 'db' => [
  775. 'pass' => 'Int',
  776. ],
  777. ],
  778. 'tools' => [
  779. 'type' => 'custom',
  780. 'name' => 'tools',
  781. 'caption' => _t('_sys_agents_field_tools'),
  782. 'info' => _t('_sys_agents_field_tools_info'),
  783. 'value' => '',
  784. ],
  785. 'tools_max_run' => [
  786. 'type' => 'text',
  787. 'name' => 'tools_max_run',
  788. 'caption' => _t('_sys_agents_field_tools_max_run'),
  789. 'info' => _t('_sys_agents_field_tools_max_run_info'),
  790. 'value' => isset($aAgent['tools_max_run']) ? $aAgent['tools_max_run'] : '10',
  791. 'required' => '1',
  792. 'db' => [
  793. 'pass' => 'Int',
  794. ],
  795. ],
  796. 'prompt_system' => [
  797. 'type' => 'textarea',
  798. 'name' => 'prompt_system',
  799. 'caption' => _t('_sys_agents_field_prompt_system'),
  800. 'info' => _t('_sys_agents_field_prompt_system_info'),
  801. 'value' => isset($aAgent['prompt_system']) ? $aAgent['prompt_system'] : '',
  802. 'db' => [
  803. 'pass' => 'Xss',
  804. ],
  805. ],
  806. 'prompts_section' => array(
  807. 'type' => 'block_header',
  808. 'caption' => 'Other prompts',
  809. 'collapsable' => true,
  810. 'collapsed' => true,
  811. ),
  812. 'prompt_steps' => [
  813. 'type' => 'textarea',
  814. 'name' => 'prompt_steps',
  815. 'caption' => _t('_sys_agents_field_prompt_steps'),
  816. 'info' => _t('_sys_agents_field_prompt_steps_info'),
  817. 'value' => isset($aAgent['prompt_steps']) ? $aAgent['prompt_steps'] : '',
  818. 'db' => [
  819. 'pass' => 'Xss',
  820. ],
  821. ],
  822. 'prompt_output' => [
  823. 'type' => 'textarea',
  824. 'name' => 'prompt_output',
  825. 'caption' => _t('_sys_agents_field_prompt_output'),
  826. 'info' => _t('_sys_agents_field_prompt_output_info'),
  827. 'value' => isset($aAgent['prompt_output']) ? $aAgent['prompt_output'] : '',
  828. 'db' => [
  829. 'pass' => 'Xss',
  830. ],
  831. ],
  832. 'prompt_tools' => [
  833. 'type' => 'textarea',
  834. 'name' => 'prompt_tools',
  835. 'caption' => _t('_sys_agents_field_prompt_tools'),
  836. 'info' => _t('_sys_agents_field_prompt_tools_info'),
  837. 'value' => isset($aAgent['prompt_tools']) ? $aAgent['prompt_tools'] : '',
  838. 'db' => [
  839. 'pass' => 'Xss',
  840. ],
  841. ],
  842. 'prompts_section_end' => array(
  843. 'type' => 'block_end',
  844. ),
  845. 'submit' => $this->_getFormControls(),
  846. ),
  847. );
  848. if(($sFldTitle = 'title') && ($sFldName = 'name') && isset($aForm['inputs'][$sFldTitle], $aForm['inputs'][$sFldName])) {
  849. $aMask = array('mask' => "javascript:%s.agentCheckName(this, '%s', '%s');", $sJsObject, 'title', 'name');
  850. if($sAction == 'edit' && ($iAgentId = $aAgent['id'] ?? false)) {
  851. $aMask['mask'] = "javascript:%s.agentCheckName(this, '%s', '%s', %d);";
  852. $aMask[] = (int)$iAgentId;
  853. }
  854. $sOnBlur = call_user_func_array('sprintf', array_values($aMask));
  855. $aForm['inputs'][$sFldTitle]['attrs']['onblur'] = $sOnBlur;
  856. $aForm['inputs'][$sFldName]['attrs']['onblur'] = $sOnBlur;
  857. }
  858. $this->_getMultiField('tools', $aAgent, 'getTools', 'toolAdd', 'agents_agents_form_tools.html', $aForm);
  859. BxDolStudioUtils::getVisibilityValues((int)($aAgent['acl_levels'] ?? 0), $aForm['inputs']['acl_levels']['values'], $aForm['inputs']['acl_levels']['value']);
  860. return $aForm;
  861. }
  862. protected function _getAlertPayload($s)
  863. {
  864. $aAlert = $this->_oDb->getAlert($s);
  865. if (!$aAlert)
  866. return '';
  867. return [
  868. 'object_id' => $aAlert['object'],
  869. 'sender_profile_id' => $aAlert['sender'],
  870. 'extra' => json_decode($aAlert['extra'], true),
  871. 'extra_modifiable_keys' => json_decode($aAlert['extra_refs'], true),
  872. ];
  873. }
  874. protected function _getAlertValues($sValue)
  875. {
  876. $aAlerts = $this->_oDb->getAlerts();
  877. $a = [
  878. 'sys_stat_not_available' => _t('_sys_not_available'),
  879. 'grid_object' => $this->_sObject,
  880. 'bx_repeat:alerts' => [
  881. [
  882. 'name' => _t('_sys_please_select'),
  883. 'value' => '',
  884. 'desc' => '',
  885. 'count' => 0,
  886. 'count_per_req' => 0,
  887. 'bx_if:sel' => [
  888. 'condition' => false,
  889. 'content' => ['sel' => '']
  890. ]
  891. ]
  892. ]
  893. ];
  894. foreach ($aAlerts as $k => $r) {
  895. $a['bx_repeat:alerts'][] = [
  896. 'name' => $r['name'],
  897. 'value' => $r['key'],
  898. 'desc' => bx_html_attribute($r['desc']),
  899. 'count' => bx_html_attribute(_t('_sys_agents_count_today', $r['counter_24h'])),
  900. 'count_per_req' => bx_html_attribute(_t('_sys_agents_count_per_req', $r['counter_per_request'])),
  901. 'bx_if:sel' => [
  902. 'condition' => $sValue == $r['key'],
  903. 'content' => [
  904. 'sel' => $sValue == $r['key'] ? 'selected' : '',
  905. ]
  906. ]
  907. ];
  908. }
  909. return $a;
  910. }
  911. protected function _getFormObjectValues($sValue)
  912. {
  913. $aFormObjects = $this->_oDb->getFormObjects();
  914. // add "Please select" option
  915. $a = [
  916. 'sys_stat_not_available' => _t('_sys_not_available'),
  917. 'grid_object' => $this->_sObject,
  918. 'bx_repeat:form_objects' => [
  919. [
  920. 'title' => _t('_sys_please_select'),
  921. 'title_attr' => _t('_sys_please_select'),
  922. 'value' => '',
  923. 'bx_if:sel' => [
  924. 'condition' => false,
  925. 'content' => ['sel' => '']
  926. ]
  927. ]
  928. ]
  929. ];
  930. // add form objects
  931. $bSelected = false;
  932. foreach ($aFormObjects as $k => $r) {
  933. if ($sValue == $r['form_object'])
  934. $bSelected = true;
  935. $a['bx_repeat:form_objects'][] = [
  936. 'title' => $r['module_title'] . ': ' . $r['form_title'],
  937. 'title_attr' => bx_html_attribute($r['module_title'] . ': ' . $r['form_title']),
  938. 'value' => $r['form_object'],
  939. // 'form_id' => $r['form_id'],
  940. // 'module' => $r['module'],
  941. // 'module_title' => $r['module_title'],
  942. // 'form_title' => $r['form_title'],
  943. 'bx_if:sel' => [
  944. 'condition' => $sValue == $r['form_object'],
  945. 'content' => ['sel' => $sValue == $r['form_object'] ? 'selected' : ''],
  946. ]
  947. ];
  948. }
  949. // add selected form object if not found in form objects
  950. if ($sValue && !$bSelected) {
  951. $a['bx_repeat:form_objects'][] = [
  952. 'title' => $sValue,
  953. 'title_attr' => bx_html_attribute($sValue),
  954. 'value' => $sValue,
  955. 'bx_if:sel' => [
  956. 'condition' => true,
  957. 'content' => ['sel' => 'selected'],
  958. ]
  959. ];
  960. }
  961. return $a;
  962. }
  963. protected function _getFormInputs($sFormObject)
  964. {
  965. $sDisplay = $this->_oDb->getFormDisplay($sFormObject);
  966. $oForm = $sDisplay ? BxDolForm::getObjectInstance($sFormObject, $sDisplay) : null;
  967. $aFormInputs = $oForm ? $oForm->aInputs : [];
  968. if (!$aFormInputs)
  969. return [];
  970. $aRet = [];
  971. foreach ($aFormInputs as $k => $r) {
  972. if ($r['type'] == 'text' || $r['type'] == 'textarea') {
  973. $aRet[$r['name']] = [
  974. 'name' => $r['name'],
  975. 'caption' => $r['caption'],
  976. ];
  977. }
  978. }
  979. return $aRet;
  980. }
  981. protected function _getFormInputValues($sFormObject, $sFormInput)
  982. {
  983. $aFormInputs = $this->_getFormInputs($sFormObject);
  984. // add "Please select" option
  985. $a = [
  986. 'bx_repeat:form_inputs' => [
  987. [
  988. 'title' => _t('_sys_please_select'),
  989. 'title_attr' => _t('_sys_please_select'),
  990. 'value' => '',
  991. 'bx_if:sel' => [
  992. 'condition' => false,
  993. 'content' => ['sel' => '']
  994. ]
  995. ]
  996. ]
  997. ];
  998. // add form inputs
  999. $bSelected = false;
  1000. if ($aFormInputs) {
  1001. foreach ($aFormInputs as $k => $r) {
  1002. if ($sFormInput == $r['name'])
  1003. $bSelected = true;
  1004. $a['bx_repeat:form_inputs'][] = [
  1005. 'title' => $r['name'] . ' - ' . $r['caption'],
  1006. 'title_attr' => bx_html_attribute($r['name'] . (!empty($r['caption']) ? ' - ' . $r['caption'] : '')),
  1007. 'value' => $r['name'],
  1008. 'bx_if:sel' => [
  1009. 'condition' => $sFormInput == $r['name'],
  1010. 'content' => [
  1011. 'sel' => $sFormInput == $r['name'] ? 'selected' : '',
  1012. ]
  1013. ]
  1014. ];
  1015. }
  1016. }
  1017. // add selected input if not found in form inputs
  1018. if ($sFormInput && !$bSelected) {
  1019. $a['bx_repeat:form_inputs'][] = [
  1020. 'title' => $sFormInput,
  1021. 'title_attr' => bx_html_attribute($sFormInput),
  1022. 'value' => $sFormInput,
  1023. 'bx_if:sel' => [
  1024. 'condition' => true,
  1025. 'content' => ['sel' => 'selected'],
  1026. ]
  1027. ];
  1028. }
  1029. return $a;
  1030. }
  1031. protected function _getUniqName($sName)
  1032. {
  1033. return uriGenerate($sName, 'sys_agents_agents', 'name', ['lowercase' => false]);
  1034. }
  1035. protected function _getMultiField($sField, $aAgent, $sGetValuesMethod, $sJsAddMethod, $sTemplateName, &$aForm)
  1036. {
  1037. if(!isset($aForm['inputs']['tools']))
  1038. return;
  1039. $sJsObject = $this->getPageJsObject();
  1040. $oForm = new BxTemplFormView([]);
  1041. $aValues = ['0' => _t('_sys_please_select')];
  1042. $a = $this->_oDb->$sGetValuesMethod();
  1043. foreach ($a as $k => $v) {
  1044. $aValues[$k] = $v;
  1045. }
  1046. $aTmplVars = [];
  1047. if(!empty($aAgent[$sField])) {
  1048. $a = explode(',', $aAgent[$sField]);
  1049. foreach($a as $v) {
  1050. $aInputSelect = [
  1051. 'type' => 'select',
  1052. 'name' => $sField . '[]',
  1053. 'values' => $aValues,
  1054. 'value' => $v,
  1055. 'attrs' => [
  1056. 'class' => 'bx-def-margin-sec-top-auto'
  1057. ]
  1058. ];
  1059. $sInput = $oForm->genInput($aInputSelect);
  1060. $aInputHidden = [
  1061. 'type' => 'hidden',
  1062. 'name' => $sField . '_ids[]',
  1063. 'value' => $v,
  1064. ];
  1065. $sInput .= $oForm->genInput($aInputHidden);
  1066. $aTmplVars[] = ['js_object' => $sJsObject, 'input_select' => $sInput];
  1067. }
  1068. }
  1069. else {
  1070. $aInputSelect = [
  1071. 'type' => 'select',
  1072. 'name' => $sField . '[]',
  1073. 'values' => $aValues,
  1074. 'value' => '',
  1075. 'attrs' => [
  1076. 'class' => 'bx-def-margin-sec-top-auto'
  1077. ]
  1078. ];
  1079. $aTmplVars = [
  1080. ['js_object' => $sJsObject, 'input_select' => $oForm->genInput($aInputSelect)],
  1081. ];
  1082. }
  1083. $aInputButton = [
  1084. 'type' => 'button',
  1085. 'name' => $sField . '_add',
  1086. 'value' => _t('_adm_nav_btn_items_add'),
  1087. 'attrs' => [
  1088. 'class' => 'bx-def-margin-sec-top',
  1089. 'onclick' => $sJsObject . ".$sJsAddMethod(this, '" . $sField . "');"
  1090. ]
  1091. ];
  1092. $aForm['inputs'][$sField]['content'] = $this->_oTemplate->parseHtmlByName($sTemplateName, [
  1093. "bx_repeat:$sField" => $aTmplVars,
  1094. 'btn_add' => $oForm->genInputButton($aInputButton)
  1095. ]);
  1096. }
  1097. protected function _getActionManual ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  1098. {
  1099. if ($aRow['trigger'] != 'manual' && $aRow['trigger'] != 'scheduler')
  1100. return '';
  1101. return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
  1102. }
  1103. protected function _getAgentWithProfile($iProfileId, $iExcludeAgentId = 0)
  1104. {
  1105. $aAgents = BxDolAi::getInstance()->getAgentsByProfileId($iProfileId);
  1106. foreach($aAgents as $aAgent) {
  1107. if($aAgent['id'] != $iExcludeAgentId)
  1108. return $aAgent;
  1109. }
  1110. return null;
  1111. }
  1112. protected function _getModelSelectValues()
  1113. {
  1114. $aParams = ['sample' => 'all_pairs', 'active' => 1];
  1115. $aModels = $this->_oDb->getModelsBy(array_merge($aParams, ['capabilities' => ['chatvlm', 'chatllm']]));
  1116. if(!$aModels || !is_array($aModels))
  1117. $aModels = $this->_oDb->getModelsBy($aParams);
  1118. return ($aModels && is_array($aModels)) ? $aModels : [];
  1119. }
  1120. protected function _getProfileSelectValues($bSelectOne = true, $sSelectOneLangKey = '_Select_one')
  1121. {
  1122. $aProfiles = bx_srv('system', 'get_options_agents_profile', [$bSelectOne, $sSelectOneLangKey], 'TemplServices');
  1123. if($aProfiles && is_array($aProfiles))
  1124. return $aProfiles;
  1125. $aProfiles = bx_srv('system', 'get_options_profile_bot', [], 'TemplServices');
  1126. return ($aProfiles && is_array($aProfiles)) ? $aProfiles : [];
  1127. }
  1128. protected function _addJsCss()
  1129. {
  1130. parent::_addJsCss();
  1131. $this->_oTemplate->addJs(['select2/js/select2.min.js']);
  1132. $this->_oTemplate->addCss([BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'select2/css/|select2.min.css']);
  1133. }
  1134. }
  1135. /** @} */