BxDolAiAgent.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 UnaCore UNA Core
  7. * @{
  8. */
  9. use NeuronAI\RAG\RAG;
  10. use NeuronAI\Observability\InspectorObserver;
  11. use NeuronAI\Observability\LogObserver;
  12. class BxDolAiAgent extends RAG
  13. {
  14. public function __construct(protected array $aAgent, protected array $aParams = [])
  15. {
  16. parent::__construct();
  17. $sKey = getParam('sys_agents_inspector_key');
  18. if ($sKey) {
  19. $this->observe(InspectorObserver::instance(
  20. key: $sKey,
  21. autoFlush: true,
  22. ));
  23. }
  24. else {
  25. $logger = new BxDolLoggerDb('sys_agents_' . $this->aAgent['id']);
  26. $this->observe(new LogObserver($logger));
  27. }
  28. }
  29. protected function provider(): NeuronAI\Providers\AIProviderInterface
  30. {
  31. return BxDolAIModelFactory::getModelInstance($this->aAgent['model_id']);
  32. }
  33. protected function instructions(): string
  34. {
  35. $aToolsUsage = !empty($this->aAgent['prompt_tools']) ? [$this->aAgent['prompt_tools']] : [];
  36. $aToolsUsage[] = "For any tool that requires `profile_id`:
  37. 1. Check if the user request contains an explicit profile_id.
  38. 2. If yes — use the user-provided profile_id.
  39. 3. If no — use {$this->aAgent['profile_id']}.
  40. Never omit profile_id when the tool supports it. Never use current profile or 0, unless it\'s explicitly requested.";
  41. $oPrompt = new NeuronAI\Agent\SystemPrompt(
  42. background: [$this->aAgent['prompt_system']],
  43. steps: !empty($this->aAgent['prompt_steps']) ? [$this->aAgent['prompt_steps']] : [],
  44. output: !empty($this->aAgent['prompt_output']) ? [$this->aAgent['prompt_output']] : [],
  45. toolsUsage: $aToolsUsage
  46. );
  47. return (string) $oPrompt;
  48. }
  49. /**
  50. * @return \NeuronAI\Tools\ToolInterface[]
  51. */
  52. protected function tools(): array
  53. {
  54. if ($this->aAgent['tools']) {
  55. $aTools = explode(',', $this->aAgent['tools']);
  56. $aToolInstances = [];
  57. foreach ($aTools as $iToolId) {
  58. $oTool = BxDolAIToolFactory::getToolInstance($iToolId);
  59. $aToolInstances[] = $oTool;
  60. }
  61. return $aToolInstances;
  62. }
  63. else {
  64. return [];
  65. }
  66. }
  67. protected function vectorStore(): NeuronAI\RAG\VectorStore\VectorStoreInterface
  68. {
  69. if ($this->aAgent['vector_store_id'])
  70. return BxDolAIVectorStoreFactory::getVectorStoreInstance($this->aAgent['vector_store_id']);
  71. else
  72. return new NeuronAI\RAG\VectorStore\MemoryVectorStore();
  73. }
  74. protected function chatHistory(): NeuronAI\Chat\History\ChatHistoryInterface
  75. {
  76. if ($this->aAgent['chat_history_context']) {
  77. return new NeuronAI\Chat\History\SQLChatHistory(
  78. thread_id: $this->getСhatHistoryThreadId(),
  79. pdo: BxDolDb::getInstance()->getLink(),
  80. table: 'sys_agents_chat_history',
  81. contextWindow: $this->aAgent['chat_history_context']
  82. );
  83. }
  84. else {
  85. return new NeuronAI\Chat\History\InMemoryChatHistory(
  86. contextWindow: 50000
  87. );
  88. }
  89. }
  90. protected function getСhatHistoryThreadId(): string
  91. {
  92. echoDbgLog($this->aParams);
  93. $s = $this->aAgent['trigger'] . ':' . $this->aAgent['id'];
  94. if (isset($this->aParams['chat_history_subindex']))
  95. $s .= ':' . $this->aParams['chat_history_subindex'];
  96. return $s;
  97. }
  98. }