3namespace Bitrix\Im\V2\Integration\AI;
5use Bitrix\AI\Context\Memory\Contract;
6use Bitrix\Im\Model\MessageTable;
7use Bitrix\Im\V2\Integration\AI\Dto\File;
8use Bitrix\Im\V2\Integration\AI\Dto\ForwardInfo;
9use Bitrix\Im\V2\Integration\AI\Dto\Message;
11use Bitrix\Im\V2\Message\Params;
12use Bitrix\Imbot\Bot\CopilotChatBot;
13use Bitrix\Main\Loader;
17 private const DEFAULT_LIMIT = 200;
19 private int $limit = self::DEFAULT_LIMIT;
21 private int $timeInterval;
22 private bool $isMentionListen =
true;
26 $this->chatId = $chatId;
31 $this->limit = $limit;
38 $this->timeInterval = $timeInterval;
45 $this->isMentionListen = $isMentionListen;
58 $fetchMoreContext =
count($messageIdsByOrder) === $this->limit;
59 $messageIdsByOrder = $this->
fillContext($messageIdsByOrder, $fetchMoreContext);
78 if (!$fetchMoreContext)
80 return $mergeMessageIds;
83 $this->limit = (
count($messageIdsByOrder) -
count($mergeMessageIds)) * 2;
85 if ($this->limit === 0)
87 return $mergeMessageIds;
100 $messageParams = $this->messages[
$messageId]->getParams();
102 if ($messageParams->isSet(Params::IS_DELETED))
104 unset($messageIdsByOrder[
$key]);
108 $messageParams->isSet(Params::COMPONENT_PARAMS)
109 && isset($messageParams->get(Params::COMPONENT_PARAMS)->getValue()[
'COPILOT_ERROR'])
112 unset($messageIdsByOrder[
$key]);
115 if ($messageParams->get(Params::COMPONENT_ID)->getValue() ===
'ChatCopilotCreationMessage')
117 unset($messageIdsByOrder[
$key]);
120 $messageText = $this->messages[
$messageId]->getMessage();
121 if (!$this->isMentionListen && self::checkMessageMentions($this->chatId, $messageText))
123 unset($messageIdsByOrder[
$key]);
127 return $messageIdsByOrder;
134 if (!isset($this->timeInterval))
136 return $messageIdsByOrder;
144 $currentMessage = $this->messages[
$messageId];
148 $userId = $currentMessage->getAuthorId();
154 $lastMessage = $this->messages[$lastMessageId];
157 $currentMessage->getAuthorId() !==
$userId
158 || $this->checkEntitiesInMessage($currentMessage)
159 || $this->checkEntitiesInMessage($lastMessage)
160 || ($lastMessage->getDateCreate() ===
null || $currentMessage->getDateCreate() ===
null)
161 || ($lastMessage->getDateCreate()->getTimestamp() - $currentMessage->getDateCreate()->getTimestamp()) > $this->timeInterval
164 $userId = $currentMessage->getAuthorId();
171 $currentMessage->setMessage($currentMessage->getMessage() .
' ' . $lastMessage->getMessage());
173 unset($messageIdsByOrder[$lastKey]);
177 $userId = $currentMessage->getAuthorId();
180 return $messageIdsByOrder;
185 $messageParams =
$message->getParams();
187 return $messageParams->isSet(Params::FORWARD_USER_ID)
188 || $messageParams->isSet(Params::REPLY_ID)
189 || $messageParams->isSet(Params::FILE_ID)
195 $query = MessageTable::query()
197 ->where(
'CHAT_ID', $this->chatId)
198 ->withNonSystemOnly()
199 ->setLimit($this->limit)
201 ->setOrder([
'DATE_CREATE' =>
'DESC',
'ID' =>
'DESC'])
204 if (isset($lastMessageId))
207 ->where(
'ID',
'<=', $lastMessageId);
210 return $query->fetchCollection()->getIdList();
216 $replayedMessageIds = $messages->getReplayedMessageIds();
217 $replayedMessageIds = array_diff($replayedMessageIds, $ids);
219 $replayedMessages->fillParams();
220 $messages->mergeRegistry($replayedMessages);
221 $messages->fillFiles();
223 if ($this->messages ===
null)
225 $this->messages = $messages;
232 if (isset($this->messages[
$message->getMessageId()]))
257 $message->getAuthor()?->getFullName() ??
'',
266 $text = preg_replace(
267 "/-{54}\n(.[^\[\n]+)\s\[(.+?)\].+?\n(.+?)-{54}/s",
268 '[QUOTE][USER]$1[/USER][DATE]$2[/DATE]$3[/QUOTE]',
277 if (!
$message->getParams()->isSet(Params::FORWARD_USER_ID))
282 $originalAuthorId =
$message->getParams()->get(Params::FORWARD_USER_ID)->getValue();
286 $originalAuthor->getName(),
292 $replyId =
$message->getParams()->get(Params::REPLY_ID)->getValue();
306 foreach (
$message->getFiles() as $file)
308 $diskFile = $file->getDiskFile();
310 if (isset($diskFile))
321 if (!Loader::includeModule(
'imbot'))
327 $relations = $chat->getRelations()->getUsers();
330 if (preg_match_all(
"/\[USER=([0-9]+)( REPLACE)?](.*?)\[\/USER]/i",
$message,
$matches))
338 foreach ($relations as $relation)
340 if ($relation->getId() === CopilotChatBot::getBotId())
347 if (in_array(
$userId, $forUsers,
true))
if(! $messageFields||!isset($messageFields['message_id'])||!isset($messageFields['status'])||!CModule::IncludeModule("messageservice")) $messageId
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static getInstance(?int $id)
getForwardInfo(V2\Message $message)
getMessageIdsByOrder(?int $lastMessageId=null)
static checkMessageMentions(int $chatId, string $message)
mergeCommonMessages(array $messageIdsByOrder)
getReply(V2\Message $message)
prepareText(string $text)
fillContext(array $messageIdsByOrder, bool $fetchMoreContext=false)
createMessageDto(int $messageId, bool $withReply=true)
useMentionListeningMode(bool $isMentionListen=false)
useMergeMode(int $timeInterval)
checkEntitiesInMessage(V2\Message $message)
getFiles(V2\Message $message)
filterMessages(array $messageIdsByOrder)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"