فهرست منبع

#5406 AI Agents revamp: agents

Aleksandr Trofimov 7 ماه پیش
والد
کامیت
9050d67f3b
6فایلهای تغییر یافته به همراه176 افزوده شده و 86 حذف شده
  1. 33 32
      composer.lock
  2. 86 34
      inc/classes/BxDolAI.php
  3. 2 1
      inc/classes/BxDolAIQuery.php
  4. 21 9
      inc/classes/BxDolAiAgent.php
  5. 7 7
      inc/classes/BxDolDb.php
  6. 27 3
      studio/template/scripts/BxBaseStudioAgentsAgents.php

+ 33 - 32
composer.lock

@@ -207,16 +207,16 @@
         },
         },
         {
         {
             "name": "aws/aws-sdk-php",
             "name": "aws/aws-sdk-php",
-            "version": "3.371.5",
+            "version": "3.373.2",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "d40b962154a146901f71561519f9d9c5a3863a6e"
+                "reference": "483fba51c28b3a0c0647bf5100e0edca82090b18"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d40b962154a146901f71561519f9d9c5a3863a6e",
-                "reference": "d40b962154a146901f71561519f9d9c5a3863a6e",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/483fba51c28b3a0c0647bf5100e0edca82090b18",
+                "reference": "483fba51c28b3a0c0647bf5100e0edca82090b18",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -237,12 +237,12 @@
                 "aws/aws-php-sns-message-validator": "~1.0",
                 "aws/aws-php-sns-message-validator": "~1.0",
                 "behat/behat": "~3.0",
                 "behat/behat": "~3.0",
                 "composer/composer": "^2.7.8",
                 "composer/composer": "^2.7.8",
-                "dms/phpunit-arraysubset-asserts": "^0.4.0",
+                "dms/phpunit-arraysubset-asserts": "^v0.5.0",
                 "doctrine/cache": "~1.4",
                 "doctrine/cache": "~1.4",
                 "ext-dom": "*",
                 "ext-dom": "*",
                 "ext-openssl": "*",
                 "ext-openssl": "*",
                 "ext-sockets": "*",
                 "ext-sockets": "*",
-                "phpunit/phpunit": "^9.6",
+                "phpunit/phpunit": "^10.0",
                 "psr/cache": "^2.0 || ^3.0",
                 "psr/cache": "^2.0 || ^3.0",
                 "psr/simple-cache": "^2.0 || ^3.0",
                 "psr/simple-cache": "^2.0 || ^3.0",
                 "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0",
                 "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0",
@@ -298,9 +298,9 @@
             "support": {
             "support": {
                 "forum": "https://github.com/aws/aws-sdk-php/discussions",
                 "forum": "https://github.com/aws/aws-sdk-php/discussions",
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.371.5"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.373.2"
             },
             },
-            "time": "2026-03-04T19:06:59+00:00"
+            "time": "2026-03-13T18:08:30+00:00"
         },
         },
         {
         {
             "name": "bshaffer/oauth2-server-php",
             "name": "bshaffer/oauth2-server-php",
@@ -1098,16 +1098,16 @@
         },
         },
         {
         {
             "name": "guzzlehttp/psr7",
             "name": "guzzlehttp/psr7",
-            "version": "2.8.0",
+            "version": "2.9.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "21dc724a0583619cd1652f673303492272778051"
+                "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051",
-                "reference": "21dc724a0583619cd1652f673303492272778051",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884",
+                "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -1123,6 +1123,7 @@
             "require-dev": {
             "require-dev": {
                 "bamarni/composer-bin-plugin": "^1.8.2",
                 "bamarni/composer-bin-plugin": "^1.8.2",
                 "http-interop/http-factory-tests": "0.9.0",
                 "http-interop/http-factory-tests": "0.9.0",
+                "jshttp/mime-db": "1.54.0.1",
                 "phpunit/phpunit": "^8.5.44 || ^9.6.25"
                 "phpunit/phpunit": "^8.5.44 || ^9.6.25"
             },
             },
             "suggest": {
             "suggest": {
@@ -1194,7 +1195,7 @@
             ],
             ],
             "support": {
             "support": {
                 "issues": "https://github.com/guzzle/psr7/issues",
                 "issues": "https://github.com/guzzle/psr7/issues",
-                "source": "https://github.com/guzzle/psr7/tree/2.8.0"
+                "source": "https://github.com/guzzle/psr7/tree/2.9.0"
             },
             },
             "funding": [
             "funding": [
                 {
                 {
@@ -1210,7 +1211,7 @@
                     "type": "tidelift"
                     "type": "tidelift"
                 }
                 }
             ],
             ],
-            "time": "2025-08-23T21:21:41+00:00"
+            "time": "2026-03-10T16:41:02+00:00"
         },
         },
         {
         {
             "name": "html2text/html2text",
             "name": "html2text/html2text",
@@ -1832,16 +1833,16 @@
         },
         },
         {
         {
             "name": "neuron-core/neuron-ai",
             "name": "neuron-core/neuron-ai",
-            "version": "3.0.10",
+            "version": "3.2.2",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/neuron-core/neuron-ai.git",
                 "url": "https://github.com/neuron-core/neuron-ai.git",
-                "reference": "4ce74d0a0f0b9e9f95a3875519fb600275f3561a"
+                "reference": "9343ca51a1d0b3ce3b6d5ed3904e807bdcebb941"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/neuron-core/neuron-ai/zipball/4ce74d0a0f0b9e9f95a3875519fb600275f3561a",
-                "reference": "4ce74d0a0f0b9e9f95a3875519fb600275f3561a",
+                "url": "https://api.github.com/repos/neuron-core/neuron-ai/zipball/9343ca51a1d0b3ce3b6d5ed3904e807bdcebb941",
+                "reference": "9343ca51a1d0b3ce3b6d5ed3904e807bdcebb941",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -1892,7 +1893,7 @@
             "description": "The PHP Agentic Framework.",
             "description": "The PHP Agentic Framework.",
             "support": {
             "support": {
                 "issues": "https://github.com/neuron-core/neuron-ai/issues",
                 "issues": "https://github.com/neuron-core/neuron-ai/issues",
-                "source": "https://github.com/neuron-core/neuron-ai/tree/3.0.10"
+                "source": "https://github.com/neuron-core/neuron-ai/tree/3.2.2"
             },
             },
             "funding": [
             "funding": [
                 {
                 {
@@ -1900,7 +1901,7 @@
                     "type": "github"
                     "type": "github"
                 }
                 }
             ],
             ],
-            "time": "2026-03-03T17:34:35+00:00"
+            "time": "2026-03-14T21:53:48+00:00"
         },
         },
         {
         {
             "name": "nyholm/psr7",
             "name": "nyholm/psr7",
@@ -3361,16 +3362,16 @@
         },
         },
         {
         {
             "name": "stripe/stripe-php",
             "name": "stripe/stripe-php",
-            "version": "v19.4.0",
+            "version": "v19.4.1",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/stripe/stripe-php.git",
                 "url": "https://github.com/stripe/stripe-php.git",
-                "reference": "a8c9db819f86ec47e603b92f9be99661e6a62cf4"
+                "reference": "095384404587d07de2ad1154c389c4051c5ed92f"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/a8c9db819f86ec47e603b92f9be99661e6a62cf4",
-                "reference": "a8c9db819f86ec47e603b92f9be99661e6a62cf4",
+                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/095384404587d07de2ad1154c389c4051c5ed92f",
+                "reference": "095384404587d07de2ad1154c389c4051c5ed92f",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -3380,7 +3381,7 @@
                 "php": ">=5.6.0"
                 "php": ">=5.6.0"
             },
             },
             "require-dev": {
             "require-dev": {
-                "friendsofphp/php-cs-fixer": "3.72.0",
+                "friendsofphp/php-cs-fixer": "3.94.0",
                 "phpstan/phpstan": "^1.2",
                 "phpstan/phpstan": "^1.2",
                 "phpunit/phpunit": "^5.7 || ^9.0"
                 "phpunit/phpunit": "^5.7 || ^9.0"
             },
             },
@@ -3414,9 +3415,9 @@
             ],
             ],
             "support": {
             "support": {
                 "issues": "https://github.com/stripe/stripe-php/issues",
                 "issues": "https://github.com/stripe/stripe-php/issues",
-                "source": "https://github.com/stripe/stripe-php/tree/v19.4.0"
+                "source": "https://github.com/stripe/stripe-php/tree/v19.4.1"
             },
             },
-            "time": "2026-02-25T17:46:20+00:00"
+            "time": "2026-03-06T22:53:13+00:00"
         },
         },
         {
         {
             "name": "symfony/deprecation-contracts",
             "name": "symfony/deprecation-contracts",
@@ -4076,16 +4077,16 @@
         },
         },
         {
         {
             "name": "twilio/sdk",
             "name": "twilio/sdk",
-            "version": "8.11.1",
+            "version": "8.11.2",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/twilio/twilio-php",
                 "url": "https://github.com/twilio/twilio-php",
-                "reference": "7061dc4f080787660ae2a442db620e6afad99c5a"
+                "reference": "f4536d588823f1b1e9f4f26cbf7164cb23e07c10"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/twilio/twilio-php/zipball/7061dc4f080787660ae2a442db620e6afad99c5a",
-                "reference": "7061dc4f080787660ae2a442db620e6afad99c5a",
+                "url": "https://api.github.com/repos/twilio/twilio-php/zipball/f4536d588823f1b1e9f4f26cbf7164cb23e07c10",
+                "reference": "f4536d588823f1b1e9f4f26cbf7164cb23e07c10",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -4122,7 +4123,7 @@
                 "sms",
                 "sms",
                 "twilio"
                 "twilio"
             ],
             ],
-            "time": "2026-02-18T08:25:57+00:00"
+            "time": "2026-03-10T08:37:18+00:00"
         },
         },
         {
         {
             "name": "typesense/typesense-php",
             "name": "typesense/typesense-php",

+ 86 - 34
inc/classes/BxDolAI.php

@@ -64,30 +64,32 @@ class BxDolAI extends BxDolFactory implements iBxDolSingleton
     public static function getInstance()
     public static function getInstance()
     {
     {
         if (!isset($GLOBALS['bxDolClasses'][__CLASS__])) {
         if (!isset($GLOBALS['bxDolClasses'][__CLASS__])) {
-            $GLOBALS['bxDolClasses'][__CLASS__] = BxDolDb::getInstance()->isTableExists('sys_agents_automators') ? new BxDolAI() : null;
+            $GLOBALS['bxDolClasses'][__CLASS__] = BxDolDb::getInstance()->isTableExists('sys_agents_agents') ? new BxDolAI() : null;
         }
         }
 
 
         return $GLOBALS['bxDolClasses'][__CLASS__];
         return $GLOBALS['bxDolClasses'][__CLASS__];
     }
     }
 
 
-    public static function getAiProviderInstance(int $iId):NeuronAI\Providers\AIProviderInterface
-    {
-        return self::getInstance()->getAiProviderInstance($iId);
-    }   
-
-    public static function getAiEmbeddingsProviderInstance(int $iId):NeuronAI\RAG\Embeddings\EmbeddingsProviderInterface
-    {
-        return self::getInstance()->getAiProviderInstance($iId);
-    }   
-
     public static function getAgentInstance(int $iId): NeuronAI\Agent\Agent
     public static function getAgentInstance(int $iId): NeuronAI\Agent\Agent
     {
     {
         if (isset($GLOBALS['bxDolClasses'][__CLASS__ . '_Agent_' . $iId]))
         if (isset($GLOBALS['bxDolClasses'][__CLASS__ . '_Agent_' . $iId]))
             return $GLOBALS['bxDolClasses'][__CLASS__ . '_Agent_' . $iId];
             return $GLOBALS['bxDolClasses'][__CLASS__ . '_Agent_' . $iId];
 
 
         $a = BxDolAIQuery::getAgentObject($iId);
         $a = BxDolAIQuery::getAgentObject($iId);
-        if (!$a || !$a['active'] || !$a['prompt_system'] || !$a['model_id']) {
-            return null;
+        if (!$a) {
+            $s = "Agent with id {$iId} not found";
+            bx_log('sys_agents', $s, BX_LOG_ERR);
+            throw new Exception($s);
+        }
+        if (!$a['active']) {
+            $s = "Agent with id {$iId} isn't active";
+            bx_log('sys_agents', $s, BX_LOG_ERR);
+            throw new Exception($s);
+        }
+        if (!$a['prompt_system'] || !$a['model_id']) {
+            $s = "Agent with id {$iId} can't be used because it haven't prompt or AI model";
+            bx_log('sys_agents', $s, BX_LOG_ERR);
+            throw new Exception($s);
         }
         }
 
 
         $o = BxDolAiAgent::make($a);
         $o = BxDolAiAgent::make($a);
@@ -105,6 +107,16 @@ class BxDolAI extends BxDolFactory implements iBxDolSingleton
         return $o;
         return $o;
     }
     }
 
 
+    public static function getAiProviderInstance(int $iId):NeuronAI\Providers\AIProviderInterface
+    {
+        return self::getModelInstance($iId);
+    }   
+
+    public static function getAiEmbeddingsProviderInstance(int $iId):NeuronAI\RAG\Embeddings\EmbeddingsProviderInterface
+    {
+        return self::getModelInstance($iId);
+    }   
+
     public static function getModelInstance(int $iId): NeuronAI\Providers\AIProviderInterface | NeuronAI\RAG\Embeddings\EmbeddingsProviderInterface
     public static function getModelInstance(int $iId): NeuronAI\Providers\AIProviderInterface | NeuronAI\RAG\Embeddings\EmbeddingsProviderInterface
     {
     {
         if (isset($GLOBALS['bxDolClasses'][__CLASS__ . '_Model_' . $iId]))
         if (isset($GLOBALS['bxDolClasses'][__CLASS__ . '_Model_' . $iId]))
@@ -314,71 +326,71 @@ class BxDolAI extends BxDolFactory implements iBxDolSingleton
             case 'pinecon':
             case 'pinecon':
                 $o = new NeuronAI\RAG\VectorStore\PineconeVectorStore(
                 $o = new NeuronAI\RAG\VectorStore\PineconeVectorStore(
                     key: $a['key'],
                     key: $a['key'],
-                    indexUrl: $a['indexUrl'],
+                    indexUrl: $aParameters['indexUrl'],
                     topK: $a['topk'] ?? 4,
                     topK: $a['topk'] ?? 4,
-                    version: $a['version'] ?? '2025-04',
-                    namespace: $a['namespace'] ?? '__default__'
+                    version: $aParameters['version'] ?? '2025-04',
+                    namespace: $aParameters['namespace'] ?? '__default__'
                 );
                 );
                 break;
                 break;
             case 'elasticsearch':
             case 'elasticsearch':
                 $oClient = Elastic\Elasticsearch\ClientBuilder::create()
                 $oClient = Elastic\Elasticsearch\ClientBuilder::create()
-                    ->setHosts([$a['client_params']['endpoint']])
-                    ->setApiKey($a['client_params']['key'])
+                    ->setHosts([$aParameters['client_params']['endpoint']])
+                    ->setApiKey($aParameters['client_params']['key'])
                     ->build();
                     ->build();
                 
                 
                 $o = new NeuronAI\RAG\VectorStore\ElasticsearchVectorStore(
                 $o = new NeuronAI\RAG\VectorStore\ElasticsearchVectorStore(
                     client: $oClient,
                     client: $oClient,
-                    index: $a['index'],
+                    index: $aParameters['index'],
                     topK: $a['topk'] ?? 4
                     topK: $a['topk'] ?? 4
                 );
                 );
                 break;
                 break;
             case 'opensearch':
             case 'opensearch':
                 $oClient = (new OpenSearch\GuzzleClientFactory())->create([
                 $oClient = (new OpenSearch\GuzzleClientFactory())->create([
-                    'base_uri' => $a['client_params']['endpoint'] ?? 'http://localhost:9200',
+                    'base_uri' => $aParameters['client_params']['endpoint'] ?? 'http://localhost:9200',
                 ]);
                 ]);
         
         
                 $o = NeuronAI\RAG\VectorStore\OpenSearchVectorStore(
                 $o = NeuronAI\RAG\VectorStore\OpenSearchVectorStore(
                     client: $oClient,
                     client: $oClient,
-                    index: $a['index'],
+                    index: $aParameters['index'],
                     topK: $a['topk'] ?? 4,
                     topK: $a['topk'] ?? 4,
                 );
                 );
                 break;
                 break;
             case 'typesense':
             case 'typesense':
-                $oClient = new \Typesense\Client($a['client_params']);
+                $oClient = new \Typesense\Client($aParameters['client_params']);
 
 
                 $o = new NeuronAI\RAG\VectorStore\TypesenseVectorStore(
                 $o = new NeuronAI\RAG\VectorStore\TypesenseVectorStore(
                     client: $oClient,
                     client: $oClient,
-                    collection: $a['collection'],
-                    vectorDimension: $a['vectorDimension'] ?? 1024,
+                    collection: $aParameters['collection'],
+                    vectorDimension: $aParameters['vectorDimension'] ?? 1024,
                     topK: $a['topk'] ?? 4,
                     topK: $a['topk'] ?? 4,
                 );
                 );
                 break;
                 break;
             case 'qdrant':
             case 'qdrant':
                 $o = new NeuronAI\RAG\VectorStore\QdrantVectorStore(
                 $o = new NeuronAI\RAG\VectorStore\QdrantVectorStore(
-                    collectionUrl: $a['collectionUrl'],
+                    collectionUrl: $aParameters['collectionUrl'],
                     key: $a['key'],
                     key: $a['key'],
                     topK: $a['topk'] ?? 4,
                     topK: $a['topk'] ?? 4,
-                    dimension: $a['dimension'] ?? 1024
+                    dimension: $aParameters['dimension'] ?? 1024
                 );
                 );
                 break;
                 break;
             case 'chromadb':
             case 'chromadb':
                 $o = new NeuronAI\RAG\VectorStore\ChromaVectorStore(
                 $o = new NeuronAI\RAG\VectorStore\ChromaVectorStore(
-                    collection: $a['collection'],
-                    host: $a['host'] ?? 'http://localhost:8000',
-                    tenant: $a['tenant'] ?? 'default_tenant',
-                    database: $a['database'] ?? 'default_database',
+                    collection: $aParameters['collection'],
+                    host: $aParameters['host'] ?? 'http://localhost:8000',
+                    tenant: $aParameters['tenant'] ?? 'default_tenant',
+                    database: $aParameters['database'] ?? 'default_database',
                     key: $a['key'] ?? null,
                     key: $a['key'] ?? null,
                     topK: $a['topk'] ?? 4
                     topK: $a['topk'] ?? 4
                 );
                 );
                 break;
                 break;
             case 'meilisearch':
             case 'meilisearch':
                 $o = new NeuronAI\RAG\VectorStore\MeilisearchVectorStore(
                 $o = new NeuronAI\RAG\VectorStore\MeilisearchVectorStore(
-                    indexUid: $a['indexUid'],
-                    host: $a['host'] ?? 'http://localhost:8000',
+                    indexUid: $aParameters['indexUid'],
+                    host: $aParameters['host'] ?? 'http://localhost:8000',
                     key: $a['key'] ?? null,
                     key: $a['key'] ?? null,
-                    embedder: $a['embedder'] ?? 'default',
+                    embedder: $aParameters['embedder'] ?? 'default',
                     topK: $a['topk'] ?? 4,
                     topK: $a['topk'] ?? 4,
-                    dimension: $a['dimension'] ?? 1024
+                    dimension: $aParameters['dimension'] ?? 1024
                 );
                 );
                 break;
                 break;
             default:
             default:
@@ -391,6 +403,46 @@ class BxDolAI extends BxDolFactory implements iBxDolSingleton
         return $o;
         return $o;
     }
     }
 
 
+    public static function getToolInstance(int $iId):  NeuronAI\Tools\ToolInterface
+    {
+        if (isset($GLOBALS['bxDolClasses'][__CLASS__ . '_AiAgentTool_' . $iId]))
+            return $GLOBALS['bxDolClasses'][__CLASS__ . '_AiAgentTool_' . $iId];
+
+        $a = BxDolAIQuery::getToolObject($iId);
+        if (!$a) {
+            bx_log('sys_agents', "Tool with id {$iId} not found", BX_LOG_ERR);
+            throw new Exception("Tool with id {$iId} not found");
+        }
+
+        $aParameters = !empty($a['params']) ? json_decode($a['params'], true) : [];
+        
+        switch($a['type']) {
+            case 'mysql_schema':
+                $o = NeuronAI\Tools\Toolkits\MySQL\MySQLSchemaTool::make(
+                    pdo: BxDolDb::getInstance()->getLink(),
+                    tables: $aParameters['tables'] ?? null
+                );
+                break;
+            case 'mysql_select':
+                $o = NeuronAI\Tools\Toolkits\MySQL\MySQLSelectTool::make(
+                    pdo: BxDolDb::getInstance()->getLink(),
+                );
+                break;
+            case 'mysql_write':
+                $o = NeuronAI\Tools\Toolkits\MySQL\MySQLWriteTool::make(
+                    pdo: BxDolDb::getInstance()->getLink(),
+                );
+                break;
+            default:
+                bx_log('sys_agents', "Tool type {$a['type']} is not supported", BX_LOG_ERR);
+                throw new Exception("Tool type {$a['type']} is not supported");
+        }
+
+        $GLOBALS['bxDolClasses'][__CLASS__ . '_AiAgentTool_' . $iId] = $o;
+
+        return $o;
+    }
+
     public static function callHelper($mixedHelper, $sMessage)
     public static function callHelper($mixedHelper, $sMessage)
     {
     {
         $oAI = BxDolAI::getInstance();
         $oAI = BxDolAI::getInstance();

+ 2 - 1
inc/classes/BxDolAIQuery.php

@@ -917,7 +917,8 @@ class BxDolAIQuery extends BxDolDb
 
 
     public function getTools()
     public function getTools()
     {
     {
-        return [];
+        $sQuery = "SELECT `id`, `title` FROM `sys_agents_tools` WHERE `active` = 1 ORDER BY `title` ASC";
+        return $this->getPairs($sQuery, 'id', 'title'); 
     }
     }
 }
 }
 
 

+ 21 - 9
inc/classes/BxDolAiAgent.php

@@ -12,9 +12,11 @@ use NeuronAI\RAG\RAG;
 class BxDolAiAgent extends RAG
 class BxDolAiAgent extends RAG
 {
 {
     public function __construct(protected array $aAgent)
     public function __construct(protected array $aAgent)
-    {}
+    {
+        parent::__construct();
+    }
 
 
-    protected function provider(): AIProviderInterface
+    protected function provider(): NeuronAI\Providers\AIProviderInterface
     {
     {
         return BxDolAi::getModelInstance($this->aAgent['model_id']);
         return BxDolAi::getModelInstance($this->aAgent['model_id']);
     }
     }
@@ -22,10 +24,10 @@ class BxDolAiAgent extends RAG
     protected function instructions(): string
     protected function instructions(): string
     {
     {
         $oPrompt = new NeuronAI\Agent\SystemPrompt(
         $oPrompt = new NeuronAI\Agent\SystemPrompt(
-            background: [$aAgent['prompt_system']],
-            steps: !empty($aAgent['prompt_steps']) ? [$aAgent['prompt_steps']] : [],
-            output: !empty($aAgent['prompt_output']) ? [$aAgent['prompt_output']] : [],
-            toolsUsage: !empty($aAgent['prompt_tools']) ? [$aAgent['prompt_tools']] : []
+            background: [$this->aAgent['prompt_system']],
+            steps: !empty($this->aAgent['prompt_steps']) ? [$this->aAgent['prompt_steps']] : [],
+            output: !empty($this->aAgent['prompt_output']) ? [$this->aAgent['prompt_output']] : [],
+            toolsUsage: !empty($this->aAgent['prompt_tools']) ? [$this->aAgent['prompt_tools']] : []
         );
         );
         return (string) $oPrompt;
         return (string) $oPrompt;
     }
     }
@@ -35,11 +37,21 @@ class BxDolAiAgent extends RAG
      */
      */
     protected function tools(): array
     protected function tools(): array
     {
     {
-        // TODO:
-        return [];
+        if ($this->aAgent['tools']) {
+            $aTools = explode(',', $this->aAgent['tools']);
+            $aToolInstances = [];
+            foreach ($aTools as $iToolId) {
+                $oTool = BxDolAi::getToolInstance($iToolId);
+                $aToolInstances[] = $oTool;                
+            }
+            return $aToolInstances;
+        }
+        else {
+            return [];
+        }
     }
     }
     
     
-    protected function vectorStore(): VectorStoreInterface
+    protected function vectorStore(): NeuronAI\RAG\VectorStore\VectorStoreInterface
     {
     {
         if ($this->aAgent['vector_store_id'])
         if ($this->aAgent['vector_store_id'])
             return BxDolAi::getVectorStoreInstance($this->aAgent['vector_store_id']);
             return BxDolAi::getVectorStoreInstance($this->aAgent['vector_store_id']);

+ 7 - 7
inc/classes/BxDolDb.php

@@ -681,9 +681,9 @@ class BxDolDb extends BxDolFactory implements iBxDolSingleton
         }
         }
 
 
         if((defined('BX_DB_FULL_VISUAL_PROCESSING') && BX_DB_FULL_VISUAL_PROCESSING) || defined('BX_DOL_INSTALL')) {
         if((defined('BX_DB_FULL_VISUAL_PROCESSING') && BX_DB_FULL_VISUAL_PROCESSING) || defined('BX_DOL_INSTALL')) {
-            $sOutput = '<div style="border:2px solid red;padding:4px;width:600px;margin:0px auto;">';
-            $sOutput .= '<div style="text-align:center;background-color:red;color:white;font-weight:bold;">Error</div>';
-            $sOutput .= '<div style="text-align:center;">' . $sErrorType . '</div>';
+            $sOutput = '<div style="border:2px solid red;padding:4px;width:600px;margin:0px auto;">'."\n";
+            $sOutput .= '<div style="text-align:center;background-color:red;color:white;font-weight:bold;">Error</div>'."\n";
+            $sOutput .= '<div style="text-align:center;">' . $sErrorType . '</div>'."\n";
             if((defined('BX_DB_FULL_DEBUG_MODE') && BX_DB_FULL_DEBUG_MODE) || defined('BX_DOL_INSTALL'))
             if((defined('BX_DB_FULL_DEBUG_MODE') && BX_DB_FULL_DEBUG_MODE) || defined('BX_DOL_INSTALL'))
 				$sOutput .= $this->errorOutput($aError);
 				$sOutput .= $this->errorOutput($aError);
             $sOutput .= '</div>';
             $sOutput .= '</div>';
@@ -1370,15 +1370,15 @@ class BxDolDb extends BxDolFactory implements iBxDolSingleton
         $sOutput = '';
         $sOutput = '';
         
         
         if(!empty($aError['query']))
         if(!empty($aError['query']))
-            $sOutput .= '<p><b>Query:</b><br />' . bx_process_output($aError['query']) . '</p>';
+            $sOutput .= '<p><b>Query:</b><br />' . bx_process_output($aError['query']) . '</p>'."\n";
 
 
         if(!empty($aError['message']))
         if(!empty($aError['message']))
-            $sOutput .= '<p><b>Mysql error:</b><br />' . $aError['message'] . '</p>';
+            $sOutput .= '<p><b>Mysql error:</b><br />' . $aError['message'] . '</p>'."\n";
 
 
 		if(!empty($aErrorLocation))
 		if(!empty($aErrorLocation))
-			$sOutput .= '<p><b>Location:</b><br />The error was found in <b>' . $aErrorLocation['function'] . '</b> function in the file <b>' . $aErrorLocation['file'] . '</b> at line <b>' . $aErrorLocation['line'] . '</b>.</p>';
+			$sOutput .= '<p><b>Location:</b><br />The error was found in <b>' . $aErrorLocation['function'] . '</b> function in the file <b>' . $aErrorLocation['file'] . '</b> at line <b>' . $aErrorLocation['line'] . '</b>.</p>'."\n";
 
 
-        $sOutput .= '<p><b>collation_connection:</b><br />' . $this->getOne("SELECT @@collation_connection") . '</p>';
+        $sOutput .= '<p><b>collation_connection:</b><br />' . $this->getOne("SELECT @@collation_connection") . '</p>'."\n";
         
         
 		if(!empty($aError['trace'])) {
 		if(!empty($aError['trace'])) {
             $sBackTrace = print_r($aError['trace'], true);
             $sBackTrace = print_r($aError['trace'], true);

+ 27 - 3
studio/template/scripts/BxBaseStudioAgentsAgents.php

@@ -426,6 +426,9 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     // 'tr_attrs' => [
                     // 'tr_attrs' => [
                     //     'style' => $sType != 'scheduler' ? 'display:none' : ''
                     //     'style' => $sType != 'scheduler' ? 'display:none' : ''
                     // ],
                     // ],
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'webhook_sample' => [
                 'webhook_sample' => [
                     'type' => 'custom',
                     'type' => 'custom',
@@ -445,16 +448,22 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     // 'tr_attrs' => [
                     // 'tr_attrs' => [
                     //     'style' => $sType != 'webhook' ? 'display:none' : ''
                     //     'style' => $sType != 'webhook' ? 'display:none' : ''
                     // ],
                     // ],
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
-                'message_profile_id' => [
+                'message_profile_ids' => [
                     'type' => 'select',
                     'type' => 'select',
-                    'name' => 'message_profile_id',
+                    'name' => 'message_profile_ids',
                     'caption' => _t('_sys_agents_field_message_profile'),
                     'caption' => _t('_sys_agents_field_message_profile'),
                     'info' => _t('_sys_agents_field_message_profile_info'),
                     'info' => _t('_sys_agents_field_message_profile_info'),
-                    'value' => isset($aAgent['message_profile_id']) ? $aAgent['message_profile_id'] : '',
+                    'value' => isset($aAgent['message_profile_ids']) ? $aAgent['message_profile_ids'] : '',
                     // 'tr_attrs' => [
                     // 'tr_attrs' => [
                     //     'style' => $sType != 'message' ? 'display:none' : ''
                     //     'style' => $sType != 'message' ? 'display:none' : ''
                     // ],
                     // ],
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'vector_store_id' => [
                 'vector_store_id' => [
                     'type' => 'select',
                     'type' => 'select',
@@ -463,6 +472,9 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     'info' => _t('_sys_agents_field_vector_store_id_info'),
                     'info' => _t('_sys_agents_field_vector_store_id_info'),
                     'value' => isset($aAgent['vector_store_id']) ? $aAgent['vector_store_id'] : 0,
                     'value' => isset($aAgent['vector_store_id']) ? $aAgent['vector_store_id'] : 0,
                     'values' => $this->_oDb->getVectorStores(),
                     'values' => $this->_oDb->getVectorStores(),
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'tools' => [
                 'tools' => [
                     'type' => 'custom',
                     'type' => 'custom',
@@ -477,6 +489,9 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     'caption' => _t('_sys_agents_field_prompt_system'),
                     'caption' => _t('_sys_agents_field_prompt_system'),
                     'info' => _t('_sys_agents_field_prompt_system_info'),
                     'info' => _t('_sys_agents_field_prompt_system_info'),
                     'value' => isset($aAgent['prompt_system']) ? $aAgent['prompt_system'] : '',
                     'value' => isset($aAgent['prompt_system']) ? $aAgent['prompt_system'] : '',
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'prompt_steps' => [
                 'prompt_steps' => [
                     'type' => 'textarea',
                     'type' => 'textarea',
@@ -484,6 +499,9 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     'caption' => _t('_sys_agents_field_prompt_steps'),
                     'caption' => _t('_sys_agents_field_prompt_steps'),
                     'info' => _t('_sys_agents_field_prompt_steps_info'),
                     'info' => _t('_sys_agents_field_prompt_steps_info'),
                     'value' => isset($aAgent['prompt_steps']) ? $aAgent['prompt_steps'] : '',
                     'value' => isset($aAgent['prompt_steps']) ? $aAgent['prompt_steps'] : '',
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'prompt_output' => [
                 'prompt_output' => [
                     'type' => 'textarea',
                     'type' => 'textarea',
@@ -491,6 +509,9 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     'caption' => _t('_sys_agents_field_prompt_output'),
                     'caption' => _t('_sys_agents_field_prompt_output'),
                     'info' => _t('_sys_agents_field_prompt_output_info'),
                     'info' => _t('_sys_agents_field_prompt_output_info'),
                     'value' => isset($aAgent['prompt_output']) ? $aAgent['prompt_output'] : '',
                     'value' => isset($aAgent['prompt_output']) ? $aAgent['prompt_output'] : '',
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'prompt_tools' => [
                 'prompt_tools' => [
                     'type' => 'textarea',
                     'type' => 'textarea',
@@ -498,6 +519,9 @@ class BxBaseStudioAgentsAgents extends BxDolStudioAgentsAgents
                     'caption' => _t('_sys_agents_field_prompt_tools'),
                     'caption' => _t('_sys_agents_field_prompt_tools'),
                     'info' => _t('_sys_agents_field_prompt_tools_info'),
                     'info' => _t('_sys_agents_field_prompt_tools_info'),
                     'value' => isset($aAgent['prompt_tools']) ? $aAgent['prompt_tools'] : '',
                     'value' => isset($aAgent['prompt_tools']) ? $aAgent['prompt_tools'] : '',
+                    'db' => [
+                        'pass' => 'Xss',
+                    ],
                 ],
                 ],
                 'submit' => $this->_getFormControls(),
                 'submit' => $this->_getFormControls(),