Sfoglia il codice sorgente

Ticket #4711 - Automations: Assistants.

AntonLV 2 anni fa
parent
commit
23eb24be8b

+ 15 - 0
agents.php

@@ -12,6 +12,8 @@ require_once(BX_DIRECTORY_PATH_INC . "utils.inc.php");
 
 bx_import('BxDolLanguages');
 
+$sTool = bx_process_input(bx_get('t'));
+
 /**
  * Work with Providers
  */
@@ -35,4 +37,17 @@ if(($iProviderId = bx_get('p')) !== false) {
     }
 }
 
+/**
+ * Work with Assistants
+ */
+if($sTool == 'asst' && ($iId = bx_get('id')) !== false) {
+    $oAssistant = BxDolAIAssistant::getObjectInstance((int)$iId);
+
+    if(($sAction = bx_get('a')) !== false) {
+        $sAction = 'processAction' . bx_gen_method_name(bx_process_input($sAction));
+        if(method_exists($oAssistant, $sAction))
+            $oAssistant->$sAction();
+    }
+}
+
 /** @} */

+ 205 - 0
inc/classes/BxDolAIAssistant.php

@@ -0,0 +1,205 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolAIAssistant extends BxDol
+{
+    protected static $_sFileText = 'sys_asst_text.json';
+    protected static $_sFileFaq = 'sys_asst_faq.json';
+
+    protected $_oDb;   
+
+    protected $_iId;
+    protected $_aData;    
+
+    public function __construct($aAssistant)
+    {
+        parent::__construct();
+
+        if(empty($aAssistant) || !is_array($aAssistant))
+            $this->_log("Unexpected value provided for the credentials");
+
+        $this->_oDb = new BxDolAIQuery();
+
+        $this->_iId = (int)$aAssistant['id'];
+        $this->_aData = $aAssistant;
+    }
+
+    /**
+     * Get assistant object instance by ID
+     * @param $iId assistant ID
+     * @return object instance or false on error
+     */
+    public static function getObjectInstance($iId)
+    {
+        $sPrefix = 'BxDolAIAssistant!';
+
+        if(isset($GLOBALS['bxDolClasses'][$sPrefix . $iId]))
+            return $GLOBALS['bxDolClasses'][$sPrefix . $iId];
+
+        $aAssistant = BxDolAIQuery::getAssistantObject($iId);
+        if(!$aAssistant)
+            return false;
+
+        $o = new BxDolAIAssistant($aAssistant);
+        return ($GLOBALS['bxDolClasses'][$sPrefix . $iId] = $o);
+    }
+
+    public function getModelObject()
+    {
+        return BxDolAI::getInstance()->getModelObject($this->_aData['model_id']);
+    }
+
+    public function processActionAddKnowledge()
+    {
+        $sAction = 'add_knowledge';
+        $oTemplate = BxDolTemplate::getInstance();
+
+        $aForm = $this->_getForm($sAction, ['id' => $this->_iId]);
+        $oForm = new BxTemplFormView($aForm);
+        $oForm->initChecker();
+
+        if($oForm->isSubmittedAndValid()) {
+            $oAIModel = $this->getModelObject();
+
+            $sType = $oForm->getCleanValue('type');
+
+            $sFile = self::${'_sFile' . ucfirst($sType)};
+            $aFile = $this->_oDb->getFilesBy(['sample' => 'assistant_id', 'assistant_id' => $this->_iId, 'name' => $sFile]);
+
+            $aContent = [];
+            if(!empty($aFile) && is_array($aFile) && !empty($aFile['ai_file_id'])) {
+                $sContent = $oAIModel->callFilesRetrieveContent($aFile['ai_file_id']);
+                $aContent = json_decode($sContent, true);
+
+                if(!$oAIModel->callVectorStoresFilesDelete($this->_aData['ai_vs_id'], $aFile['ai_file_id']))
+                    return echoJson([]);
+
+                if(!$oAIModel->callFilesDelete($aFile['ai_file_id']))
+                    return echoJson([]);
+
+                $this->_oDb->deleteFiles(['id' => $aFile['id']]);
+            }
+
+            switch($sType) {
+                case 'text':
+                    $aContent[] = bx_process_input($oForm->getCleanValue('text'));
+                    break;
+
+                case 'faq':
+                    $aContent[] = [
+                        'question' => bx_process_input($oForm->getCleanValue('faq_q')),
+                        'answer' => bx_process_input($oForm->getCleanValue('faq_a'))
+                    ];
+                    break;
+            }
+
+            $aFileResponse = $oAIModel->callFiles(['content' => json_encode($aContent), 'name' => $sFile, 'mime' => 'application/json']);
+            if(!$aFileResponse)
+                return echoJson([]);
+
+            if(!$oAIModel->callVectorStoresFiles($this->_aData['ai_vs_id'], ['file_id' => $aFileResponse['id']]))
+                return echoJson([]);
+
+            $this->_oDb->insertFile([
+                'name' => $sFile, 
+                'assistant_id' => $this->_iId, 
+                'added' => time(), 
+                'ai_file_id' => $aFileResponse['id'], 
+                'ai_file_size' => $aFileResponse['bytes']
+            ]);
+
+            return echoJson(['msg' => _t('_sys_agents_assistants_msg_knowledge_added')]);
+        }
+
+        $sFormId = $oForm->getId();
+        $sContent = BxTemplFunctions::getInstance()->popupBox($sFormId . '_popup', _t('_sys_agents_assistants_popup_add_knowledge'), $oTemplate->parseHtmlByName('agents_form.html', [
+            'form_id' => $sFormId,
+            'form' => $oForm->getCode(true),
+        ]));
+
+        return echoJson(['popup' => ['html' => $sContent, 'options' => ['closeOnOuterClick' => false]]]);
+    }
+    
+    protected function _getForm($sAction, $aAssistant = [])
+    {
+        $aForm = [
+            'form_attrs' => [
+                'id' => 'bx_agents_assistants_' . $sAction,
+                'action' => BX_DOL_URL_ROOT . bx_append_url_params('agents.php', ['t' => 'asst', 'a' => $sAction]),
+                'method' => 'post',
+            ],
+            'params' => [
+                'db' => [
+                    'submit_name' => 'do_submit',
+                ],
+            ],
+            'inputs' => [],
+        ];
+
+        switch($sAction) {
+            case 'add_knowledge';
+                $aForm['inputs'] = [
+                    'id' => [
+                        'type' => 'hidden',
+                        'name' => 'id',
+                        'value' => $aAssistant['id'],
+                    ],
+                    'type' => [
+                        'type' => 'select',
+                        'name' => 'type',
+                        'caption' => _t('_sys_agents_assistants_field_kwg_type'),
+                        'value' => '',
+                        'values' => [
+                            ['key' => 'text', 'value' => _t('_sys_agents_assistants_field_kwg_type_text')],
+                            ['key' => 'faq', 'value' => _t('_sys_agents_assistants_field_kwg_type_faq')]
+                        ],
+                        'attrs' => ['onchange' => "javascript:bx_aa_ak_type_change(this)"],
+                    ],
+                    'text' => [
+                        'type' => 'textarea',
+                        'name' => 'text',
+                        'caption' => _t('_sys_agents_assistants_field_kwg_text'),
+                        'value' => '',
+                        'tr_attrs' => ['df' => '1', 'dt' => 'text']
+                    ],
+                    'faq_q' => [
+                        'type' => 'text',
+                        'name' => 'faq_q',
+                        'caption' => _t('_sys_agents_assistants_field_kwg_faq_q'),
+                        'value' => '',
+                        'tr_attrs' => ['df' => '1', 'dt' => 'faq', 'style' => 'display:none']
+                    ],
+                    'faq_a' => [
+                        'type' => 'textarea',
+                        'name' => 'faq_a',
+                        'caption' => _t('_sys_agents_assistants_field_kwg_faq_a'),
+                        'value' => '',
+                        'tr_attrs' => ['df' => '1', 'dt' => 'faq', 'style' => 'display:none']
+                    ],
+                    'submit' => [
+                        'type' => 'input_set',
+                        0 => [
+                            'type' => 'submit',
+                            'name' => 'do_submit',
+                            'value' => _t('_sys_submit'),
+                        ],
+                        1 => [
+                            'type' => 'reset',
+                            'name' => 'close',
+                            'value' => _t('_sys_close'),
+                            'attrs' => ['class' => 'bx-def-margin-sec-left', 'onclick' => '$(\'.bx-popup-applied:visible\').dolPopupHide();'],
+                        ],
+                    ],
+                ];
+                break;
+        }
+
+        return $aForm;
+    }
+}

+ 9 - 0
inc/classes/BxDolAIModelGpt40.php

@@ -21,6 +21,7 @@ class BxDolAIModelGpt40 extends BxDolAIModel
 
     protected $_sEndpointFiles;
     protected $_sEndpointFilesRetrieve;
+    protected $_sEndpointFilesRetrieveContent;
     protected $_sEndpointFilesDelete;
 
     protected $_sEndpointVectorStores;
@@ -48,6 +49,7 @@ class BxDolAIModelGpt40 extends BxDolAIModel
 
         $this->_sEndpointFiles = 'https://api.openai.com/v1/files';
         $this->_sEndpointFilesRetrieve = $this->_sEndpointFiles . '/%s';
+        $this->_sEndpointFilesRetrieveContent = $this->_sEndpointFiles . '/%s/content';
         $this->_sEndpointFilesDelete = $this->_sEndpointFilesRetrieve;
 
         $this->_sEndpointVectorStores = 'https://api.openai.com/v1/vector_stores';
@@ -375,6 +377,13 @@ class BxDolAIModelGpt40 extends BxDolAIModel
         return $mixedResponse;
     }
 
+    public function callFilesRetrieveContent($sFileId)
+    {
+        return bx_file_get_contents(sprintf($this->_sEndpointFilesRetrieveContent, $sFileId), [], 'get', [
+            "Authorization: Bearer " . $this->_sKey
+        ]);
+    }
+
     public function callFilesDelete($sFileId, $aParams = [])
     {
         $aData = [];

+ 19 - 2
inc/classes/BxDolAIQuery.php

@@ -61,6 +61,17 @@ class BxDolAIQuery extends BxDolDb
             'name' => $sName
         ]);
     }
+    
+    static public function getAssistantObject($iId)
+    {
+        $oDb = BxDolDb::getInstance();
+
+        $aAssistant = $oDb->getRow("SELECT * FROM `sys_agents_assistants` WHERE `id` = :id", ['id' => $iId]);
+        if(!$aAssistant || !is_array($aAssistant))
+            return false;
+
+        return $aAssistant;
+    }
 
     public function getModelsBy($aParams = [])
     {
@@ -689,8 +700,14 @@ class BxDolAIQuery extends BxDolDb
                 ];
 
                 $sWhereClause .= " AND `taf`.`assistant_id`=:assistant_id";
-                break;
-                
+
+                if(!empty($aParams['name'])) {
+                    $aMethod['name'] = 'getRow';
+                    $aMethod['params'][1]['name'] = $aParams['name'];
+
+                    $sWhereClause .= " AND `taf`.`name`=:name";
+                }
+                break;                
         }
 
         $aMethod['params'][0] = "SELECT " . $sSelectClause . "

+ 15 - 0
inc/js/functions.js

@@ -1591,4 +1591,19 @@ function bx_redirect_for_external_links_open (sHref)
     window.open(sUrlRoot + 'page.php?i=redirect&url=' + encodeURIComponent(sHref), '_blank').focus();
 }
 
+function bx_agents_action(oElement, sTool, sAction, aParams)
+{
+    var oDate = new Date();
+    var sQueryUrl = sUrlRoot + 'agents.php';
+    var oQueryParams = jQuery.extend({}, {t: sTool, a: sAction, _t:oDate.getTime()}, aParams != undefined ? aParams : {});
+
+    jQuery.post (
+        sQueryUrl,
+        oQueryParams,
+        function(oData) {
+            processJsonData(oData);
+        },
+        'json'
+    );
+}
 /** @} */

+ 5 - 4
install/sql/system.sql

@@ -5482,10 +5482,11 @@ INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable
 
 INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `active`, `order`) VALUES
 ('sys_studio_agents_assistants', 'independent', 'add', '_sys_agents_assistants_btn_add', '', 0, 0, 1, 1),
-('sys_studio_agents_assistants', 'single', 'chats', '_sys_agents_assistants_btn_chats', '', 0, 0, 1, 1),
-('sys_studio_agents_assistants', 'single', 'files', '_sys_agents_assistants_btn_files', '', 0, 0, 1, 2),
-('sys_studio_agents_assistants', 'single', 'edit', '_Edit', 'pencil-alt', 1, 0, 1, 3),
-('sys_studio_agents_assistants', 'single', 'delete', '_Delete', 'remove', 1, 1, 1, 4),
+('sys_studio_agents_assistants', 'single', 'chats', '_sys_agents_assistants_btn_chats', 'comments', 1, 0, 1, 1),
+('sys_studio_agents_assistants', 'single', 'files', '_sys_agents_assistants_btn_files', 'folder', 1, 0, 1, 2),
+('sys_studio_agents_assistants', 'single', 'codes', '_sys_agents_assistants_btn_codes', 'code', 1, 0, 1, 3),
+('sys_studio_agents_assistants', 'single', 'edit', '_Edit', 'pencil-alt', 1, 0, 1, 4),
+('sys_studio_agents_assistants', 'single', 'delete', '_Delete', 'remove', 1, 1, 1, 5),
 ('sys_studio_agents_assistants', 'bulk', 'delete', '_Delete', '', 0, 1, 1, 1);
 
 -- GRID: Agents Assistants Chats

+ 12 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -2236,9 +2236,13 @@
     <string name="_sys_agents_assistants_txt_prompt"><![CDATA[Prompt]]></string>
     <string name="_sys_agents_assistants_txt_added"><![CDATA[Added]]></string>
     <string name="_sys_agents_assistants_txt_assistant"><![CDATA[Assistant]]></string>
+    <string name="_sys_agents_assistants_txt_codes_onclick"><![CDATA[onClick code for a link]]></string>
+    <string name="_sys_agents_assistants_txt_codes_button"><![CDATA[Button HTML code]]></string>
+    <string name="_sys_agents_assistants_txt_add_knowledge"><![CDATA[Add knowledge]]></string>
     <string name="_sys_agents_assistants_btn_add"><![CDATA[Add Assistant]]></string>
     <string name="_sys_agents_assistants_btn_chats"><![CDATA[Chats]]></string>
     <string name="_sys_agents_assistants_btn_files"><![CDATA[Files]]></string>
+    <string name="_sys_agents_assistants_btn_codes"><![CDATA[Get codes]]></string>
     <string name="_sys_agents_assistants_field_name"><![CDATA[Name]]></string>
     <string name="_sys_agents_assistants_field_model_id"><![CDATA[Model]]></string>
     <string name="_sys_agents_assistants_field_profile_id"><![CDATA[Profile]]></string>
@@ -2276,6 +2280,14 @@
     <string name="_sys_agents_assistants_files_btn_delete"><![CDATA[Delete file]]></string>
     <string name="_sys_agents_assistants_files_field_file"><![CDATA[File]]></string>
     <string name="_sys_agents_assistants_files_popup_add"><![CDATA[Add File]]></string>
+    <string name="_sys_agents_assistants_field_kwg_type"><![CDATA[Type]]></string>
+    <string name="_sys_agents_assistants_field_kwg_type_text"><![CDATA[Text]]></string>
+    <string name="_sys_agents_assistants_field_kwg_type_faq"><![CDATA[Question with answer]]></string>
+    <string name="_sys_agents_assistants_field_kwg_text"><![CDATA[Text]]></string>
+    <string name="_sys_agents_assistants_field_kwg_faq_q"><![CDATA[Question]]></string>
+    <string name="_sys_agents_assistants_field_kwg_faq_a"><![CDATA[Answer]]></string>
+    <string name="_sys_agents_assistants_popup_add_knowledge"><![CDATA[Add Knowledge]]></string>
+    <string name="_sys_agents_assistants_msg_knowledge_added"><![CDATA[Knowledge was added.]]></string>
 
   <string name="_sys_audit_content_info_popup_title"><![CDATA[Information]]></string>
   <string name="_sys_audit_action_edit_content"><![CDATA[Content edited]]></string>

+ 12 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -2212,9 +2212,13 @@
         <string name="_sys_agents_assistants_txt_prompt"><![CDATA[Инструкции]]></string>
         <string name="_sys_agents_assistants_txt_added"><![CDATA[Добавлено]]></string>
         <string name="_sys_agents_assistants_txt_assistant"><![CDATA[Ассистент]]></string>
+        <string name="_sys_agents_assistants_txt_codes_onclick"><![CDATA[onClick код для ссылки]]></string>
+        <string name="_sys_agents_assistants_txt_codes_button"><![CDATA[HTML-код кнопки]]></string>
+        <string name="_sys_agents_assistants_txt_add_knowledge"><![CDATA[Добавить знания]]></string>
         <string name="_sys_agents_assistants_btn_add"><![CDATA[Добавить ассистента]]></string>
         <string name="_sys_agents_assistants_btn_chats"><![CDATA[Чаты]]></string>
         <string name="_sys_agents_assistants_btn_files"><![CDATA[Файлы]]></string>
+        <string name="_sys_agents_assistants_btn_codes"><![CDATA[Получить коды]]></string>
         <string name="_sys_agents_assistants_field_name"><![CDATA[Название]]></string>
         <string name="_sys_agents_assistants_field_model_id"><![CDATA[Модель]]></string>
         <string name="_sys_agents_assistants_field_profile_id"><![CDATA[Профиль]]></string>
@@ -2252,6 +2256,14 @@
         <string name="_sys_agents_assistants_files_btn_delete"><![CDATA[Удалить файл]]></string>
         <string name="_sys_agents_assistants_files_field_file"><![CDATA[Файл]]></string>
         <string name="_sys_agents_assistants_files_popup_add"><![CDATA[Добавить файл]]></string>
+        <string name="_sys_agents_assistants_field_kwg_type"><![CDATA[Тип]]></string>
+        <string name="_sys_agents_assistants_field_kwg_type_text"><![CDATA[Текст]]></string>
+        <string name="_sys_agents_assistants_field_kwg_type_faq"><![CDATA[Вопрос с ответом]]></string>
+        <string name="_sys_agents_assistants_field_kwg_text"><![CDATA[Текст]]></string>
+        <string name="_sys_agents_assistants_field_kwg_faq_q"><![CDATA[Вопрос]]></string>
+        <string name="_sys_agents_assistants_field_kwg_faq_a"><![CDATA[Ответ]]></string>
+        <string name="_sys_agents_assistants_popup_add_knowledge"><![CDATA[Добавить знания]]></string>
+        <string name="_sys_agents_assistants_msg_knowledge_added"><![CDATA[Знания были добавлены.]]></string>
 
   <string name="_sys_audit_content_info_popup_title"><![CDATA[Информация]]></string>
   <string name="_sys_audit_action_edit_content"><![CDATA[Контент изменен]]></string>

+ 4 - 1
studio/classes/BxDolStudioAgentsAsstChatsCmts.php

@@ -186,7 +186,10 @@ class BxDolStudioAgentsAsstChatsCmts extends BxTemplCmts
 
     protected function _getActionsBox(&$aCmt, $aBp = [], $aDp = [])
     {
-        return parent::_getActionsBox($aCmt, $aBp, array_merge($aDp, ['view_only' => true]));
+        return $this->_oTemplate->parseLink('javascript:void(0)', _t('_sys_menu_item_title_cmts_item_delete'), [
+            'class' => 'bx-btn bx-btn-small',
+            'onclick' => $this->_sJsObjName . '.cmtRemove(this, ' . $aCmt['cmt_id'] . ')',
+        ]);
     }
 
     protected function _getCountersBox(&$aCmt, $aBp = [], $aDp = [])

+ 10 - 0
studio/template/agents_assistant_codes.html

@@ -0,0 +1,10 @@
+<div class="flex flex-col p-4 gap-4">
+    <div class="flex flex-col gap-2">
+        <div class="font-semibold"><bx_text:_sys_agents_assistants_txt_codes_onclick /></div>
+        <div class="bx-def-vanilla-html"><pre>__code_onclick__</pre></div>
+    </div>
+    <div class="flex flex-col gap-2">
+        <div class="font-semibold"><bx_text:_sys_agents_assistants_txt_codes_button /></div>
+        <div class="bx-def-vanilla-html"><pre>__code_button__</pre></div>
+    </div>
+</div>

+ 1 - 1
studio/template/scripts/BxBaseStudioAgents.php

@@ -191,7 +191,7 @@ class BxBaseStudioAgents extends BxDolStudioAgents
             
             switch($sSubPage) {
                 case 'chats':
-                    $aResult[] = $this->getGrid($this->aGridObjects[BX_DOL_STUDIO_AGENTS_TYPE_ASSISTANTS . '_chats']);
+                    $aResult[] = $this->getGrid($this->aGridObjects[BX_DOL_STUDIO_AGENTS_TYPE_ASSISTANTS . '_chats']);//['caption' => '123', 'content' => $this->getGrid($this->aGridObjects[BX_DOL_STUDIO_AGENTS_TYPE_ASSISTANTS . '_chats'])];
                     break;
 
                 case 'files':

+ 19 - 0
studio/template/scripts/BxBaseStudioAgentsAssistants.php

@@ -127,6 +127,25 @@ class BxBaseStudioAgentsAssistants extends BxDolStudioAgentsAssistants
         return echoJson(['popup' => ['html' => $sContent, 'options' => ['closeOnOuterClick' => false]]]);
     }
 
+    public function performActionCodes()
+    {
+        $sAction = 'codes';
+
+        $iId = $this->_getId();
+
+        $sContent = BxTemplStudioFunctions::getInstance()->transBox('bx_std_agents_assistants_codes', $this->_oTemplate->parseHtmlByName('agents_assistant_codes.html', [
+            'code_onclick' => '{onclick}',
+            'code_button' => htmlspecialchars($this->_oTemplate->parseLink('javascript:void(0)', _t('_sys_agents_assistants_txt_add_knowledge'), [
+                'class' => 'bx-btn', 
+                'onclick' => '{onclick}'
+            ]), ENT_NOQUOTES)
+        ]));        
+        $sContent = bx_replace_markers($sContent, ['onclick' => "javascript:bx_agents_action(this, 'asst', 'add_knowledge', {id: " . $iId . "})"]);
+                
+
+        return echoJson(['popup' => ['html' => $sContent, 'options' => []]]);
+    }
+
     protected function _getCellModelId($mixedValue, $sKey, $aField, $aRow)
     {
         $aModel = $this->_oDb->getModelsBy(['sample' => 'id', 'id' => $mixedValue]);

+ 24 - 0
template/agents_form.html

@@ -0,0 +1,24 @@
+<div class="bx-agents-form">
+    <div class="bx-agents-form-cnt">
+        __form__
+        <script language="javascript">
+            $(document).ready(function () {
+                $("#__form_id__").ajaxForm({ 
+                    dataType: "json",
+                    beforeSubmit: function (formData, jqForm, options) {
+                        bx_loading($("#__form_id__"), true);
+                    },
+                    success: function (data) {
+                        $(".bx-popup-applied:visible").dolPopupHide();
+                        processJsonData(data);
+                    }
+                });
+            });
+
+            function bx_aa_ak_type_change(oElement)
+            {
+                $(oElement).parents(".bx-form-element-wrapper:first").siblings("[df='1']").hide().siblings("[dt='" + $(oElement).val() + "']").show();
+            }
+        </script>
+    </div>
+</div>