Документация LLM Client
🔹 I. Введение и суть нового паттерна с LLMClient
🎯 Что изменилось?
Раньше мы создавали "агента" через объект Agents, устанавливали промпты через setStartInstruction, setFinalInstruction, сохраняли историю и вызывали generateActiveAgentAnswer(...). Этот подход оставался привязанным к структуре агентов как сущностей.
Теперь — всё по-другому.
👉 Вы сами создаете "агента" как сценарий или flow (поток диалога), используя LLMClient, и назначаете ему столько задач, сколько нужно — через разные этапы flow, инструкции и промпты. Каждый шаг — просто JS-код, больше не нужно регистрировать агентов отдельно.
🧠 Что такое LLMClient?
Это универсальный компонент для общения с LLM:
-
формирует список промптов (в нужном порядке),
-
берет промпты как из кода, так и из таблицы (
$name,@common), -
вставляет значения из lead и bot (макропеременные),
-
может подставить историю диалога в нужное место,
-
делает асинхронный запрос (через
MBQuery), -
обрабатывает ответ в этом же скрипте и отправляет дальше.
✅ Почему это лучше?
| 📌 Возможность | Agents |
LLMClient |
|---|---|---|
| Многоагентные шаги (несколько запросов подряд) | ⚠️ Ограничено | ✅ Полностью контролируемо |
| Промпты из таблицы ($name / @common) | ✅ Да | ✅ Да |
| Порядок промптов | ❌ Неявный (в коде разбросано) | ✅ Вы задаёте руками |
| Управление историей | ⚠️ Встроено, не выключается | ✅ Можно включать, отключать, вставлять вручную |
| Асинхронность | ✅ Да | ✅ Да |
| Обработка ошибок | 🔧 Сложно | ✅ Полный контроль на каждом запросе к ИИ |
| Переподключение flow | ⚠️ Привязано к агенту | ✅ Любая логика, любой скрипт |
| Переиспользование компонентов | ⚠️ Мало | ✅ Есть LLMFollowUp, KnowbaseSearch, макросы |
🔹 II. Жизненный цикл работы с LLMClient
🟦 1. Инициализация
|
const LLMClient = require("Common.MetabotAI.LLMClient") const llm = new LLMClient("DetectIntent") // session name |
|---|
Пример подключения gpt-3.5-turbo:
| llm.setModel("gpt-3.5-turbo")llm.setProvider("OpenAI") |
|---|
🟦 2. Добавление промптов
llm.setPromptTable("gpt_prompts", "MyAgent")
llm.addSystemPrompt("$start") // из таблицы (по имени)
llm.addSystemPrompt("@common_instruction") // глобальный prompt
Прямо в коде:
|
llm.addUserPrompt(`Сообщение пользователя: ${user_input}`) llm.addUserPrompt(`Имя пользователя: ${lead.getAttr('name')}`) |
|---|
🟦 3. Макросы и подстановки в таблице промптов
Можно использовать:
{{$lead_attr}}→ из лида{{@bot_attr}}→ из бота
Или можно подставлять значения прямо в коде:
| llm.addUserPrompt(`Город пользователя: ${lead.getAttr('city')}`) |
|---|
🟦 4. История
По умолчанию история включена, но вы можете:
|
llm.disableHistory() // полностью llm.clearHistory() // очиститьllm.addHistoryToPrompts() // вручную подставить историю |
|---|
📌 Важно!
Управляйте порядком промптов прямо в коде:
сначала — system, instruction, потом history, потом user.
Иначе GPT не поймет, что от него хотят.
🟦 5. Подготовка и отправка
|
llm.prepareRequest() // собираем промпты и llm.sendRequest() // отправка асинхронного запроса |
|---|
Можно указать другой скрипт, куда прилетит асинхронный ответ:
| llm.prepareRequest("AgentName:MyFlow") |
|---|
🟦 6. Обработка ответа
Ответ приходит в этот же скрипт, в блоке ниже:
| llm.handleResponse() |
|---|
📌 Не нужно проверять статус — если была ошибка, сработает скрипт обработки ошибки, устанавливаемый через setErrorScript(...), если всё ОК — данные уже подготовлены для дальнейшего использования.
🟦 7. Работа с результатом
|
llm.sendResponse() // показать как llm.sendFormattedResponse() // markdown- llm.nextFlow("MyAgent:NextStep") // перейти на следующий llm.finishFlow() // завершить текущий шаг |
|---|
🔚 Завершение диалога: LLMFollowUp
Для ожидания ответа от пользователя — текстового или кнопочного — используем LLMFollowUp.
Добавьте новую команду JavaScript Callback.
| const LLMFollowUp = require("Common.MetabotAI.LLMFollowUp") |
|---|
🔹 Ожидание текста
| LLMFollowUp.waitForInput("MyAgent:Step2") |
|---|
🔹 С выводом сообщения
| LLMFollowUp.waitForInput("MyAgent:Step2", "Введите ваш номер телефона:") |
|---|
🔹 Подмена поля для ввода
По умолчанию, ввод от пользователя запишется в лида в user_input, но вы можете переопределить это поле (третий параметр):
| LLMFollowUp.waitForInput("MyAgent:Step2", "", "my_user_input") |
|---|
🔹 Ожидание текста или кнопки
-
В скрипте добавьте нужные вам кнопки.
-
В коде:
| LLMFollowUp.waitForInputOrButton("MyAgent:Step2", "Выберите или напишите свой вопрос:") |
|---|
🔹 III. Архитектура команды (скрипта)
Каждый LLM-запрос реализуется в одной JS-команде, которая состоит из 3-х логических блоков:
🟦 1. Инициализация и запуск запроса (вверху)
Это всегда первый запуск команды (isFirstImmediateCall):
|
const LLMClient = require("Common.MetabotAI.LLMClient") const llm = new LLMClient("MyLLMSession") if (isFirstImmediateCall) { llm.setProvider("OpenAI") llm.setModel("gpt-3.5-turbo") llm.setPromptTable("gpt_prompts", "MyAgent") llm.addSystemPrompt("$start") // инструкция llm.addUserPrompt(`Запрос пользователя: ${lead.getAttr("user_input")}`) llm.prepareRequest("MyAgent:MyScript") // указываем этот же скрипт llm.setErrorScript("MyAgent:ErrorFlow")
return llm.sendRequest()} |
|---|
🟦 2. Обработка ответа (ниже, после if (isFirstImmediateCall))
Ответ приходит сюда, автоматически:
|
llm.handleResponse() // Далее логика llm.sendFormattedResponse() llm.nextFlow("MyAgent:NextStep") |
|---|
📌 Если в запросе произошла ошибка, LLMClient автоматически вызовет setErrorScript(...).
Если всё хорошо — handleResponse() сохраняет результат и позволяет продолжить.
🟦 3. UI, кнопки, меню (опционально)
Кнопки настраиваются в этом же скрипте или можете перенаправить в другой скрипт, где настроить кнопки и подключить JavaScript Callback c LLMFollowUp.
📦 Пример структуры скрипта (общее):
|
// ВЕРХ -- запуск запросаif (isFirstImmediateCall) { // ... init return llm.sendRequest()}
// ЦЕНТР -- handleResponse() llm.handleResponse() // НИЖЕ -- логика llm.sendResponse() llm.nextFlow("MyAgent:NextStep") // или если нужно завершить работу с ИИ
// и далее предоставить пользователю выбор llm.finishFlow() |
|---|
🔹 IV. Работа с вводом пользователя и кнопками
После ответа от LLM мы часто хотим:
-
задать уточняющий вопрос пользователю,
-
дождаться текста,
-
или предложить кнопки с вариантами.
Для этого используется мощный компонент:
📦 LLMFollowUp
(из Common.MetabotAI.LLMFollowUp)
🟦 1. Ожидание только текста
|
const LLMFollowUp = require("Common.MetabotAI.LLMFollowUp")
LLMFollowUp.waitForInput( "MyAgent:NextStep", // скрипт, куда перейти "✍️ Введите ваш номер телефона:", // текст-приглашение "user_phone" // атрибут для сохранения) |
|---|
📌 После того, как пользователь напишет, значение попадет в:
| lead.getAttr("user_phone") |
|---|
🟦 2. Ожидание текста или кнопки
Частый сценарий: предложить выбор + оставить возможность ввести свой текст.
|
const LLMFollowUp = require("Common.MetabotAI.LLMFollowUp")
LLMFollowUp.waitForInputOrButton( "MyAgent:HandleCustomInput", // targetScriptCode для текстового ввода "👇 Выберите вопрос или напишите свой:", "user_input") |
|---|
🛎️ А кнопки добавляем в этом же скрипте в меню:
|
Button 1 ("Где мой заказ?", "MyAgent:Flow_OrderStatus") Button 2 ("Связаться с оператором", "MyAgent:Flow_Operator") |
|---|
📎 Примечания
-
Все кнопки работают как меню, определяемое в скрипте.
-
Если пользователь нажал кнопку — мы сразу переходим по скрипту и там запускаем следующий флоу.
-
Если ввел текст — идем в
targetScriptCodeи беремlead.getAttr("user_input")
✅ Резюме
С помощью LLMFollowUp вы:
-
задаёте гибкие формы обратной связи,
-
даёте кнопки без необходимости их отдельно обрабатывать,
-
делаете UX максимально удобным.
Отлично! Ниже — готовый рабочий пример агента из двух flow, реализованного через LLMClient:
🤖 Агент с двумя флоу: INTENT ➜ ANSWER
Сценарий:
-
Пользователь пишет сообщение.
-
Первый flow (
IntentDetect) распознаёт интент и (опционально) ищет в БЗ/таблице. -
Второй flow (
FinalAnswer) формирует финальный ответ на основе результата первого шага и истории.
📁 Структура скриптов:
| MyAgent/├── Start -- Точка входа├── DetectIntent -- Flow 1: извлечение намерения├── FinalAnswer -- Flow 2: генерация ответа├── ErrorFlow -- Обработка ошибок |
|---|
1️⃣ Скрипт: MyAgent:Start
| Запросить значение | Что бы вы хотели узнать или сделать? 👇: [ user_input ] | |
|---|---|---|
| Выполнить JavaScript | // Очищаем историю диалога основного флоу const LLMClient = require("Common.MetabotAI.LLMClient") const dialog = new LLMClient("FinalAnswer") dialog.clearHistory() | |
| Выполнить скрипт | 🔹 Flow 1: Определение интента и KB поиск |
2️⃣ Скрипт: MyAgent:DetectIntent
| Отправить текст | Думаю. Подождите... 🕐 | |
|---|---|---|
| Выполнить асинхронный API-запрос |
const LLMClient = require("Common.MetabotAI.LLMClient")
const llm = new LLMClient("DetectIntent");
llm.setProvider("OpenAI") llm.setModel("gpt-3.5-turbo") llm.setErrorScript("MyAgent:ErrorFlow") llm.setPromptTable("gpt_prompts", "SupportBot")
llm.disableHistory() // Отключаем сохранение истории
if (isFirstImmediateCall) { // Берем историю из следующего флоу
const dialog = new LLMClient("UserDialog")
const history = dialog.getHistory() llm.addSystemPrompt( `По контексту общения и сообщению пользователя, `+ `определи истинное намерение пользователя.\n` + `Контекст общения: ${JSON.stringify(history)}\n` + `Сообщение пользователя: ${lead.getAttr("user_input")}\n` + `Ответь строго в JSON в поле intent в развернутом виде на русском языке.`)
llm.prepareRequest()
return llm.sendRequest()}
llm.handleResponse()
// Обрабатываем ответ от LLM
bot.sendMessage(`Ответ от LLM: ${llm.getResponseText()}`)
// Получаем JSON и излекаем поле intent
const result = llm.getLastJSON()
const userIntent = result?.intentlead.setAttr("user_intent", userIntent)// Если интент есть -- ищем по базе знаний
if (userIntent) { const KnowbaseSearch = require('Common.MetabotAI.KnowbaseSearch')
const kbSearch = new KnowbaseSearch() const chunks = kbSearch.findBestChunks("DefaultKB", userIntent, "rehau")
// Сохраняем все, что нашли в kb_chunks
lead.setJsonAttr("kb_chunks", chunks) bot.sendMessage(`chunks: ${JSON.stringify(chunks)}`)} else {
lead.setJsonAttr("kb_chunks", [])
}// Переходим к следующему
llm.nextFlow("MyAgent:FinalAnswer") |
3️⃣ Скрипт: MyAgent:FinalAnswer
| Выполнить асинхронный API-запрос | const LLMClient = require("Common.MetabotAI.LLMClient")const llm = new LLMClient("FinalAnswer")llm.setProvider("OpenAI")llm.setModel("gpt-3.5-turbo")llm.setErrorScript("MyAgent:ErrorFlow")llm.setPromptTable("gpt_prompts", "SupportBot")if (isFirstImmediateCall) { llm.addSystemPrompt(`Ты должен ответить пользователю, используя найденную информацию из базы знаний.`) llm.addSystemPrompt( `Если в базе знаний будут найдены ссылки на медиа контент, `+ `определи релевантность контента, проанализировав их описание, и включи релевантные ссылки в формате markdown. ` + `Сам ссылки не придумывай!`) llm.addSystemPrompt(`Информация из базы: {{$kb_chunks}}`) llm.addSystemPrompt(`Распознаннный интент: {{$user_intent}}`) llm.addHistoryToPrompts() // Добавляем историю llm.addUserPrompt(`{{$user_input}}`) llm.addSystemPrompt(`$UserDialog:final`) // Промпт агента из таблицы llm.addSystemPrompt(`@общий`) // Общий промпт из таблицы llm.prepareRequest() return llm.sendRequest()}llm.handleResponse()llm.sendFormattedResponse()return llm.finishFlow() // Завершаем | |
|---|---|---|
| Выполнить JavaScript Callback | const LLMFollowUp = require("Common.MetabotAI.LLMFollowUp")// Просто ожидание ввода от пользователя без сообщенияLLMFollowUp.waitForInput("MyAgent:DetectIntent")// СЦЕНАРИЙ 2: Ожидание ввода + кнопки меню//LLMFollowUp.waitForInputOrButton("SupportBot:DetectIntentAndSearch")// СЦЕНАРИЙ 3: Ввод + кнопки + своё сообщение //LLMFollowUp.waitForInputOrButton(// "SupportBot:DetectIntentAndSearch",// "✍️ Можете задать новый вопрос или выбрать из меню:"//)// СЦЕНАРИЙ 4: Используем другую переменную вместо user_input//LLMFollowUp.waitForInputOrButton(// "SupportBot:DetectIntentAndSearch",// "Выберите вариант или напишите свой вопрос:",// "my_user_input"//) |
🛑 Скрипт: MyAgent:ErrorFlow
| Выполнить асинхронный API-запрос | const LLMClient = require("Common.MetabotAI.LLMClient");const llm = new LLMClient("DetectIntent");// Можно дополнительно отправить системное сообщениеbot.sendMessage("⚠️ Произошла ошибка при обращении к ИИ. Давайте попробуем ещё раз!");// Очищаем временные данные (если нужно)lead.setAttr("user_intent", "");lead.setJsonAttr("intent_payload", {});lead.setJsonAttr("kb_chunks", []);// Переходим к начальному этапуllm.nextFlow("SupportBot:DetectIntent") |
|---|
🧠 Почему история не в первом флоу?
- INTENT запрос — технический, он не нужен в памяти диалога. Однако, мы берем историю диалога из второго флоу, чтобы ИИ мог верно определить интент, используя весь контекст диалога.
- История ведется и подставляется во втором флоу, чтобы сохранить корректный контекст общения. Ведь, это те сообщения, которые видит пользователь.
📋 Промпты в таблице gpt_prompts
Промпты вы может указать, как прямо в коде, как в примере выше, так и в таблице, например так:
| agent_name | name | prompt |
|---|---|---|
| MyAgent | start | Ты ассистент техподдержки. Помогай пользователям ясно. |
| MyAgent | intent | Определи намерение пользователя в JSON: {intent, topic}. |
Отлично! Мы уже прошли:
-
Введение
-
Жизненный цикл
LLMClient -
Архитектуру команды
-
Ввод пользователя и кнопки
-
Пример из двух flow ✅
👉 Следующим по плану был:
🔹 V. Замена агентов: теперь всё делается через LLMClient
🧠 Раньше:
Чтобы использовать GPT, приходилось:
-
явно создавать "агента" через
Agents() -
регистрировать имя, провайдера, параметры
-
использовать методы вроде
generateActiveAgentAnswer(...) -
вызывать агентов из конкретных скриптов по имени
-
копить историю автоматически
Это был плотно связанный black-box, не всегда удобный для многошаговых диалогов.
✅ Теперь:
Агент — это просто набор флоу-сценариев, реализованных на LLMClient.
Вы управляете:
-
моделью (
gpt-3.5-turbo,gpt-4, и др.) -
провайдером (
OpenAI,GigaChat, и т.п.) -
промптами (из кода или из таблицы)
-
структурой диалога (разбиваете на флоу)
-
когда и где включать/выключать историю
-
форматированием, ошибками, кнопками, интерактивом
📌 А "агент" — это просто имя сессии и структура ваших флоу.
💡 Пример:
const llm = new LLMClient("SalesAssistant")
// Это и есть "агент", но он нигде не регистрируется
// Вы просто пишете логику под это имя
Вы можете в одном проекте создать десятки таких "агентов", не создавая ни одной сущности в базе.
🛠 Агент = LLMClient + промпты + flow-сценарии
Вы теперь сами:
-
назначаете, какие шаги делает LLM,
-
подсказываете ему через
$prompts, -
вставляете куски истории (или не вставляете),
-
вызываете API, ищете в таблицах, всё вручную комбинируется.
Отлично, поехали 👇
🔹 VI. Варианты источников данных: Knowbase / Таблицы / API
Когда вы строите flow на LLMClient, вы можете дополнительно обогатить ответы LLM:
-
фрагментами из базы знаний (RAG),
-
результатами поиска в таблице,
-
ответами из внешних API,
-
вообще любой своей логикой.
👉 Всё, что вам нужно — вставить результат в system или user prompt.
🧠 1. Поиск в базе знаний (Knowbase)
Если у вас уже загружена база знаний (Knowbase), можно:
| const KnowbaseSearch = require("Common.MetabotAI.KnowbaseSearch")const search = new KnowbaseSearch()const chunks = search.findBestChunks("MyKnowledgeBase", lead.getAttr("user_input"), "domain")const result = chunks.map(c => c.content).join("\n\n")llm.addSystemPrompt(`Вот полезная информация из базы знаний:\n\n${result}`) |
|---|
📌 Не забудь: база знаний должна быть создана и векторизована заранее, например через knowbaseCreate(...).
📦 Альтернатива базе знаний:
Ты не обязан использовать именно Knowbase. Можно:
📊 2. Поиск в таблице (любая логика)
| const items = table.find("product_catalog", ["title", "desc", "price"], [["category", "=", "laptop"]])const top3 = items.slice(0, 3)let txt = top3.map(p => `• ${p.title} -- ${p.price}₽\n${p.desc}`).join("\n\n")llm.addSystemPrompt(`Вот найденные товары:\n\n${txt}`) |
|---|
🌐 3. Обращение к API
| const city = lead.getAttr("user_city")const url = `https://my-api/weather?city=${encodeURIComponent(city)}\`const response = api.getJson(url)const weather = response?.forecast || "Погода недоступна"lead.setAttr("weather_info", weather) |
| :---- |
А затем подставить результат как промпт
| llm.addUserPrompt(`Вот погода для пользователя: ${lead.getAttr("weather_info")}`) |
|---|
🧠 Суть:
Все эти данные (таблицы, API, поиск) не обрабатываются автоматически — вы сами решаете:
-
где выполнить логику,
-
как вставить результат в prompt,
-
стоит ли сохранять это в lead для следующих шагов,
-
нужно ли показывать пользователю или использовать только для генерации.
🔹 VIII. Статусы жизненного цикла LLMClient
Взято напрямую из исходника Common.MetabotAI.LLMClient, в том числе с точным моментом установки каждого статуса.
🧭 Таблица: жизненный цикл и статусы LLMClient
| Статус | Устанавливается после | Что означает |
|---|---|---|
IDLE |
new LLMClient(...) |
Начальное состояние. Клиент создан, но ничего ещё не сделано. |
PREPARED |
prepareRequest() |
Промпты собраны, request готов к отправке. |
WAITING |
sendRequest() |
Запрос ушёл, ожидаем ответ от провайдера. |
SUCCESS |
handleResponse() (200) |
Ответ успешно получен, результат готов для логики. |
ERROR |
handleResponse() (≠200) |
Произошла ошибка при получении ответа. |
ERROR_HANDLED |
handleResponse() → fallback |
Обработчик ошибки сработал (если задан через setErrorScript). |
DONE |
(опционально вручную) | Не используется напрямую — можно установить в логике вручную. |
🛠 Как посмотреть текущий статус?
| llm.getStatus() // вернёт текущий статус, например: "WAITING" |
|---|
✅ Где он хранится?
| lead.getAttr("llm_<sessionName>_status") |
|---|
🔹 IX. Переменные и атрибуты для отладки в LLMClient
Компонент LLMClient автоматически сохраняет множество атрибутов в lead, чтобы вы могли отлаживать поведение прямо внутри скрипта.
🧪 Таблица: отладочные переменные LLMClient
| Переменная | Пример значения | Что хранит / зачем нужна |
|---|---|---|
llm_<session>_status |
WAITING |
Текущий статус запроса |
llm_<session>_provider |
OpenAI |
Название LLM-провайдера |
llm_<session>_params |
{ model: "gpt-3.5-turbo", temperature: 0.7 } |
Параметры модели |
llm_<session>_messages |
[{"role": "system", ...}, ...] |
Все промпты, отправленные в запрос |
llm_<session>_history |
[{"role": "user", ...}, ...] |
История переписки (если включена) |
llm_<session>_callback_script |
MyAgent:NextStep |
Скрипт, куда вернётся ответ от LLM |
llm_<session>_error_script |
MyAgent:Fallback |
Скрипт, куда уйдёт в случае ошибки |
llm_<session>_raw_response |
Вот ваш ответ... |
Текст, возвращённый моделью, до форматирования |
llm_<session>_user_query |
Сколько лет космосу? |
Последний пользовательский запрос (если использован addUserPrompt) |
🔹 X. Таблица методов LLMClient
📦 Версия: Common.MetabotAI.LLMClient v2.0
📌 🔧 Базовые методы управления
| Метод | Назначение |
|---|---|
new LLMClient(session) |
Создание клиента. session — уникальное имя для группы запросов. |
setModel(model) |
Установить модель (например "gpt-3.5-turbo") |
setProvider(provider) |
Установить провайдера ("OpenAI", "GigaChat", и т.д.) |
setModelParams(params) |
Установить параметры модели (temperature, max_tokens, и т.д.) |
🧠 Работа с промптами
| Метод | Назначение |
|---|---|
addSystemPrompt(text) |
Добавить системный промпт (не сохраняется в историю по умолчанию) |
addUserPrompt(text) |
Добавить промпт от пользователя (сохраняется в историю) |
addAssistantPrompt(text) |
Добавить промпт от ассистента (опционально в историю) |
setPromptTable(table, name) |
Назначить таблицу и имя агента для $prompt / @common |
addHistoryToPrompts() |
Добавить сохранённую историю в промпты |
clearPrompts() |
Очистить текущий список промптов |
🕓 Управление историей
| Метод | Назначение |
|---|---|
disableHistory() |
Отключить накопление истории |
clearHistory() |
Очистить историю |
addToHistory(msg) |
Добавить сообщение в историю вручную |
getHistory() |
Получить сохранённую историю |
🚀 Запуск запроса
| Метод | Назначение |
|---|---|
prepareRequest([script]) |
Сохранить промпты и задать callback-скрипт |
sendRequest() |
Отправить асинхронный запрос к LLM через MBQuery |
setErrorScript(script) |
Назначить fallback-скрипт при ошибке |
📥 Ответ и логика
| Метод | Назначение |
|---|---|
handleResponse() |
Обработка ответа от LLM (в этом же скрипте) |
getResponseText() |
Извлечь текст ответа |
getResponseResult() |
Получить весь JSON-ответ |
getLastJSON([text]) |
Извлечь JSON из текста ответа (если там JSON) |
extractTextWithoutJSON() |
Удалить JSON из текста и вернуть только чистый текст |
📦 Постобработка и переход
| Метод | Назначение |
|---|---|
sendResponse() |
Отправить текст ответа пользователю |
sendFormattedResponse() |
Отправить форматированный markdown-ответ |
nextFlow("ScriptName") |
Перейти к следующему скрипту |
finishFlow() |
Завершить текущий flow |
🧩 Внутренние утилиты (для макросов и отладки)
| Метод | Назначение |
|---|---|
_applyMacros(str) |
Подставить макропеременные {{$lead_attr}}, {{@bot_attr}} и т.д. |
setStatus(status) |
Установить статус (WAITING, SUCCESS, и т.д.) |
getStatus() |
Получить текущий статус |