Методы API в IVA Terra
API для транскрибации мероприятий в режиме онлайн и офлайн
Метод API: POST
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/process
где:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
Параметры запросов
| Имя | Тип | Обязательность | Значение по умолчанию | Описание |
|---|---|---|---|---|
audiofile |
file |
да |
− |
бинарный контент аудиофрагмента. |
conference_id |
UUID |
да |
− |
идентификатор мероприятия (сессии транскрибации) |
lang1 |
string |
нет |
ru |
код языка (ru, en, de, es, fr, pt, ch, zh, ar, fa, id, in, af, xh, ur, th, te, gu, hi, ne, bn, ml, mr, ta, vi, km). Используется как подсказка для транcкрибации |
offline |
boolean |
нет |
true |
сохранение файла для возможности дальнейшей обработки в офлайн-режиме |
online |
boolean |
нет |
false |
если значение true, то в результате выполнения запроса будет возвращен результат транскрибации |
participant_id |
UUID |
да |
− |
UUID спикера |
participant_name |
string |
да |
− |
имя спикера (отображаемое имя участника). Если не указано, может быть установлено значение UNKNOWN |
post_id |
string |
нет |
− |
идентификатор запроса. В ответе при онлайн-транскрибации будет возвращен список идентификаторов, из которых был собран текст |
timestamp_float |
float |
да |
текущее системное время отправителя в формате с.мкс |
метка системного времени создания аудиофрагмента. |
token |
string |
да |
- |
ключ подключения |
Пример запроса
POST https://10.12.2.199:9001/process?conference_id=trash6bb3f34f-b29a-4d62-ba73-8489777a18de&participant_id=58c277ff-9af4-48c7-8d5f-f13e7304a7e9&participant_name=UNKNOWN&lang1=ru&online=true&offline=true&post_id=e474c68b-e96b-4465-af38-fec989a892d7
-----------------------------217261477111538
Content-Disposition: name="token"
ivcs
-----------------------------217261477111538
Content-Disposition: name="audiofile"; filename="trash6bb3f34f-b29a-4d62-ba73-8489777a18de:a-58c277ff-9af4-48c7-8d5f-f13e7304a7e9_20240628_14_20_15_123456.wav"
Content-Type: application/octet-stream
.....
Параметры ответов
Если значение параметра запроса online=false, то система не обрабатывает файл, а только сохраняет для дальнейшей обработки. В этом режиме ответ будет пустой.
Если значение параметра запроса online=true, то в результате выполнения запроса будет возвращен результат транскрибации в формате JSON, представляющий собой массив ArrayOfTextElem, который содержит объекты TextElem.
| Имя атрибута | Значение |
|---|---|
conference_id |
UUID сессии |
duration |
длительность объединенного аудиофрагмента в мс (формат: целое число) |
id |
UUID — уникальный идентификатор ответа, назначается первому аудиофрагменту, входящему в состав объединенного аудиофрагмента |
participant_id |
UUID спикера |
post_ids |
список текстовых идентификаторов запросов (id аудиофрагментов), если они были указаны во входящем запросе |
status |
final — текст окончательный, далее изменяться не будет progress — текст временный, может полностью измениться по мере накопления объединенного аудиофрагмента новыми фрагментами |
text |
текст, распознанный из объединенного аудиофрагмента |
timestamp |
текстовый вид метки времени, которая содержалась в имени отправленного файла |
timestamp_float |
метка времени первого аудиофрагмента из всего объединенного объема аудио, по которому распознан текст (формат: с.мкс) |
Пример ответа
[
{
"timestamp":"2024-06-27T21:21:07.782414", − текстовый вид метки времени, которая содержалась в имени отправленного файла
"timestamp_float":1719512467.782414, − та же метка времени, сконвертированная в дробное число (с.мкс)
"duration":2000, − длительность аудиофрагмента в миллисекундах (целое число)
"conference_id":"trash143dc12d-9fa0-45fe-a449-5df04140ed27", − UUID конференции
"participant_id":"659d1a02-1ba2-4e2f-88aa-48bac9481a0a", − UUID спикера
"text":" Всем привет.", − транскрибированный текст
"id":"0310a61b-f7f2-4337-806f-5421b5b69ed1", − сгенерированный уникальный идентификатор, принадлежащий аудиофрагменту, с которого начинается весь распознанный текст
"post_ids":["7bab8ff2-4f31-4f65-b3ca-0ddd1d17284a"], − список идентификаторов посылок аудиофрагментов, если они были не пустые
"status":"progress" − флаг статуса обработки, «progress» -- не конечный результат, будет дополнен и может быть полностью изменен
}
]
В случае завершения одной накопительной комбинации и начала следующей комбинации, список содержит два TextElem:
[
{
"timestamp":"2024-06-27T21:21:07.782414",
"timestamp_float":1719512467.782414,
"duration":30000,
"conference_id":"trash143dc12d-9fa0-45fe-a449-5df04140ed27",
"participant_id":"659d1a02-1ba2-4e2f-88aa-48bac9481a0a",
"text":" Всем привет. Давайте все камеры включим.",
"id":"0310a61b-f7f2-4337-806f-5421b5b69ed1",
"post_ids":
[ # − идентификаторы посылок, из которых был собран аудиофрагмент, транскрибированный в текст
"7bab8ff2-4f31-4f65-b3ca-0ddd1d17284a",
"f8cedb98-200f-4076-8d53-85275e1e935b",
"3a9d9d90-4104-4d80-911f-49dfcfebda2b",
"45836bc1-ce03-465f-885f-9840a76306e6",
"6f22ae04-eed3-4ef6-94c2-a0a4e03f7490",
"6b58f7ac-e776-48d9-b06f-260a025480ce",
"9b94bfc5-2db5-433e-9380-20056852c0ff",
"3834b8cc-2031-4376-a981-c4317842b641",
"d715dd6b-2fab-43c2-9136-7ea2b238315f",
"baa4e4ad-9cfe-48d9-ab01-c4b6f60a7c61",
"4aae99fd-7162-49db-8946-78429232c790",
"a485f89f-cc19-4bb4-be90-ed348dc378a1",
"44aa372c-52a3-4eb9-9249-ce2b77b115c7",
"d1c42456-a694-4b0b-8a53-50aefa205aae",
"55b6d943-c4ac-4008-a6f4-39df4b4e2300"
],
"status":"final"
},
{
"timestamp":"2024-06-27T21:21:37.782414",
"timestamp_float":1719512497.782414,
"duration":2000,
"conference_id":"trash143dc12d-9fa0-45fe-a449-5df04140ed27",
"participant_id":"659d1a02-1ba2-4e2f-88aa-48bac9481a0a",
"text":" Мы подготовили презентацию",
"id":"ffc98483-6cef-4820-9fd3-f1a46e9b6480",
"post_ids":["a2ef5a04-da0f-4382-8c32-2584a4cb629b"],
"status":"progress"
}
]
API для транскрибации ранее загруженных аудиофрагментов
API IVA Terra предоставляет функциональность для офлайн-подготовки протоколов по загруженным материалам одного мероприятия:
-
для запуска транскрибации нужно вызвать соответствующие методы API с параметром offline, который должен отсутствовать или быть установлен в true. Это инициирует обработку загруженных материалов конференции в офлайн-режиме
-
после завершения транскрибации выполнить запрос:
-
метод API: GET
-
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/minutes/{conference_id}?token=<auth_token>где:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
{conference_id} — идентификатор мероприятия
<auth_token> — токен аутентификации для доступа к API
-
Возможные ответы API:
-
если файлы конференции не загружены предварительно:
-
код статуса: 404
-
ответ в формате JSON:
{"detail":"Conference minutes status file not found"}
-
-
если окончательная транскрибация еще не запущена:
-
запрос ставится в очередь на обработку
-
ответ в формате JSON:
{ "status": "queueplacing", "message_en": "Compiling task of minutes has been placed to the Queue", "message_ru": "Задача формирования протокола поставлена в очередь" }
-
-
если транскрибация находится в процессе выполнения, то ответ в формате JSON:
{ "status": "running", "message_en": "Task of compiling of minutes is still under way", "message_ru": "Идет процесс формирования протокола", "timestamp" : float_метка_времени_постановки_в_очередь_на_транскрибацию } -
если транскрибация завершена, возвращается XML-контент, содержащий протокол конференции. В протоколе представлены временные метки, указывающие на момент произнесения фраз, а также указаны спикеры, произносившие каждую фразу
API для перевода текста
Метод API: POST
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/translate_to_any
где:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
Параметры запросов
| Имя | Тип | Обязательность | Значение по умолчанию | Описание |
|---|---|---|---|---|
token |
string |
да |
ivcs |
ключ доступа для подключения |
payload |
list |
да |
− |
список словарей, представляющих посылки для перевода. |
Разметка ключей словаря |
||||
string |
да |
auto |
код языка текста, содержащегося в значении ключа content. |
|
to_lang |
string |
да |
- |
код языка, на который требуется выполнить перевод содержимого content. |
string |
да |
- |
текст, предоставленный для перевода |
|
Пример запроса
'payload': [ {'from_lang': 'auto', 'to_lang': 'en', 'content': 'первое предложение'}, {'from_lang': 'auto', 'to_lang': 'ru', 'content': 'last sentence'}, {'from_lang': 'auto', 'to_lang': 'unknown', 'content': 'last sentence'} ]
Пример ответа
-
код статуса: 200
-
ответ в формате JSON:
'payload': [ {'from_lang': 'ru', 'to_lang': 'en', 'content': 'первое предложение', 'status': 'processed'}, {'from_lang': 'en', 'to_lang': 'ru', 'content': 'last sentence', 'status': 'processed'}, {'from_lang': 'en', 'to_lang': 'unknown', 'content': 'last sentence', 'status': 'not_processed'} ]где:
-
processed — индикатор успешного перевода текста, готового к использованию
-
not_processed — индикатор возврата исходного текста без перевода из-за невозможности обработки
-
Возможные ответы API
-
если в настройках переменных окружения отключено использование переводчика (USE_TRANSLATOR: false) или указан пустой адрес размещения сервиса переводов (TRANSLATOR_URL):
-
код статуса: 404
-
ответ в формате JSON:
"TRANSLATOR DISABLED OR URL IS NOT CONFIGURED"
-
-
если структура запроса не соответствует ожидаемому формату, включая отсутствие обязательных параметров в запросе payload (from_lang, to_lang, content), то клиенту возвращается статус код 400 с ошибкой валидации контента запроса и сообщением с описанием причины
API для синтеза речи (TTS)
Метод API: POST
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/tts
где:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
Параметры запроса
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
text |
string |
да |
текстовый контент для преобразования в звук речи (максимальная длина — 250 символов). Цифры и числа должны быть написаны словами, иначе они не будут преобразованы в речь. Допустим текст только на одном языке. Знак + перед гласными буквами используется для обозначения ударений (например, в+ыдра) |
token |
string |
да |
ключ доступа клиента IVA Terra (формируется в панели администрирования) |
Ограничения сервиса
-
максимальная длина текста: 250 символов
-
скорость создания аудиоконтента: 100 слов в секунду
-
цифры и числа должны быть написаны словами
-
допустим текст только на одном языке
-
если текст содержит слова на нескольких языках, будет обнаружен только один язык (остальные будут пропущены)
-
тайм-аут обработки запроса: 5 секунд
Пример запроса
POST https://10.6.19.23:9001/tts
Content-Type: application/json
{
"text": "Текстовый контент для преобразования в звук речи",
"token": "o193noFnImHx7c3kL3oav9oFyogE0hUL"
}
Пример ответа
При успешном преобразовании текста в речь возвращается:
-
код статуса: 200
-
заголовок ответа: X-Detected-Language — код языка, обнаруженного в предоставленном тексте (поддерживаемые языки: ru, en, de, es, fr)
-
тело ответа: бинарный контент аудиофайла в формате WAV
HTTP/1.1 200 OK
X-Detected-Language: ru
Content-Type: audio/wav
<бинарные данные аудиофайла>
Возможные ответы API
| Код статуса | Заголовок / Сообщение | Описание |
|---|---|---|
200 |
X-Detected-Language: <lang> |
успешное преобразование текста в речь. Аудиофайл возвращается в теле ответа |
403 |
Forbidden |
неверный или отсутствующий токен доступа, или запрос из подсети, недоступной для клиента |
405 |
Method Not Allowed |
неподдерживаемый язык. Поддерживаемые: ru, en, de, es, fr |
410 |
Gone |
превышен тайм-аут обработки запроса (5 секунд). Сообщение: Timeout |
Пример обработки ответа на Python
import requests
TTS_URL = "https://10.6.19.23:9001/tts"
TOKEN = "o193noFnImHx7c3kL3oav9oFyogE0hUL"
data = {"text": "Текстовый контент для преобразования в звук речи", "token": TOKEN}
response = requests.post(TTS_URL, json=data, timeout=5.0, verify=False)
if response.status_code == 200:
lang_code = response.headers.get("X-Detected-Language", "UNKNOWN")
print(f"Получен аудиофайл на языке {lang_code}")
with open("./sound_content.wav", "wb") as f:
f.write(response.content)
API для доступа к сервисам ADP
Методы API предоставляют доступ к сервисам ADP (ADP API Gateway):
-
planner — интеллектуальный анализатор поручений, выделяющий из текста структурированные задачи с идентификацией исполнителей, сроки выполнения и ключевые действия. Сервис автоматически распознает в стенограмме фразы, содержащие указания, требования или делегирование обязанностей, и преобразует их в форматированный список поручений с возможностью последующей интеграции в системы управления задачами
-
summary — сервис автоматического формирования краткого содержания стенограммы: выделение ключевых мыслей, решений и результатов обсуждений, представляя их в связном и лаконичном виде
-
assistant — интеллектуальный диалоговый агент (чат) на основе языковой модели, отвечающий на вопросы пользователя в рамках предоставленного контекста стенограммы. Сервис поддерживает ведение диалоговой сессии с сохранением истории сообщений, что позволяет учитывать предыдущие вопросы и ответы при генерации последующих ответов. Поддерживаются два режима работы:
-
стандартный (no stream) — ответ возвращается целиком после завершения генерации
-
потоковый (stream) — ответ возвращается фрагментами в режиме реального времени по мере генерации текста моделью
-
Запросы направляются на эндпоинты шлюза IVA Terra, который проксирует их к модулю ADP, что позволяет клиентам использовать единый токен аутентификации IVA Terra и исключает необходимость изучения внутренней архитектуры системы.
Для работы методов необходимо:
-
активировать переключатель ADP API шлюз доступен в разделе Настройки → Прием HTTPS API запросов
-
заполнить параметры шлюза (адреса, имя агента, токен доступа к ADP)
-
убедиться, что запрашиваемый сервис присутствует в Списке доступных сервисов ADP API Gateway
POST /adp_services
Эндпоинт /adp_services предназначен для асинхронной обработки запросов к сервисам ADP.
-
метод API: POST
-
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/adp_servicesгде:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
Доступные сервисы ADP:
-
planner — выделение поручений, сроков и исполнителей из текста встречи
-
summary — краткие итоги встречи
-
assistant — генерация ответа на вопрос по контексту
|
Запрос может быть адресован только одному сервису. Для обработки контента несколькими сервисами требуется отправить несколько запросов |
Порядок работы
-
отправка запроса на обработку сообщения (пример:
service: assistant,task: request) -
получение ответа на запрос, который содержит:
-
идентификатор, назначенный запросу (
task_id) -
идентификатор чата для хранения истории контекста (
chat_id) -
статус обработки запроса (
status)
-
-
периодическая отправка запросов на получение результата с использованием полученного
task_id -
при отсутствии готового ответа возвращается статус обработки (
status: in_progressилиstatus: error) -
в случае успешного завершения обработки возвращается текстовый контент ответа в поле
predicted_sp
Параметры запроса (task: request)
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
token |
string |
да |
ключ доступа клиента IVA Terra (формируется в панели администрирования) |
content.service |
string |
да |
имя сервиса: |
content.task |
string |
да |
|
content.message |
string |
да |
текст для обработки (содержимое встречи или вопрос) |
content.lang |
string |
нет |
код языка: |
content.chat_id |
string |
нет |
UUID чата для сохранения истории беседы (только для |
Пример запроса (task: request)
POST https://10.6.19.23:9001/adp_services
Content-Type: application/json
{
"token": "o193noFnImHx7c3kL3oav9oFyogE0hUL",
"content": {
"service": "assistant",
"task": "request",
"message": "Дай краткий совет по продуктивности",
"lang": "ru",
"chat_id": ""
}
}
Пример ответа (task: request)
При успешной постановке задачи в очередь возвращается статус in_progress, а также идентификаторы задачи и чата:
{
"status": "in_progress",
"chat_id": "188d8c0a-3f64-4a30-ab36-869afddb8852",
"task_id": "e5b1f2da-7df1-44f9-b0c1-4825c7928bfc"
}
Параметры запроса (task: response)
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
token |
string |
да |
ключ доступа клиента IVA Terra |
content.service |
string |
да |
имя сервиса (то же, что в запросе) |
content.task |
string |
да |
|
content.task_id |
string |
да |
идентификатор задачи, полученный на этапе |
Пример запроса (task: response)
POST https://10.6.19.23:9001/adp_services
Content-Type: application/json
{
"token": "o193noFnImHx7c3kL3oav9oFyogE0hUL",
"content": {
"service": "assistant",
"task": "response",
"task_id": "e5b1f2da-7df1-44f9-b0c1-4825c7928bfc"
}
}
Возможные ответы (task: response)
-
обработка не завершена:
{
"status": "in_progress"
}
-
ошибка обработки:
{
"status": "error"
}
-
успешное завершение:
{
"predicted_sp": "текстовое содержимое ответа от сервиса ADP"
}
Для сервиса planner ответ возвращается в формате XML с разметкой поручений, сроков и исполнителей.
POST /adp_services_stream
Эндпоинт для потоковой обработки запросов к сервисам ADP. Ответ возвращается порциями по мере генерации, соединение закрывается автоматически после завершения.
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/adp_services_stream
где:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
|
Этот эндпоинт предназначен для сценариев, где требуется отображать ответ по мере его генерации (например, в чат-интерфейсах). Клиент должен поддерживать чтение потоковых данных (text/event-stream) |
Параметры запроса (task: request)
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
token |
string |
да |
ключ доступа клиента IVA Terra (формируется в панели администрирования) |
content.service |
string |
да |
имя сервиса: |
content.task |
string |
да |
|
content.message |
string |
да |
текст для обработки (содержимое встречи или вопрос) |
content.lang |
string |
нет |
код языка: |
content.chat_id |
string |
нет |
UUID чата для сохранения истории беседы (только для |
Пример запроса (task: request)
POST https://10.6.19.23:9001/adp_services
Content-Type: application/json
{
"token": "o193noFnImHx7c3kL3oav9oFyogE0hUL",
"content": {
"service": "assistant",
"task": "request",
"message": "Дай краткий совет по продуктивности",
"lang": "ru",
"chat_id": ""
}
}
Пример ответа (task: request)
При успешной постановке задачи в очередь возвращается статус in_progress, а также идентификаторы задачи и чата:
{
"status": "in_progress",
"chat_id": "188d8c0a-3f64-4a30-ab36-869afddb8852",
"task_id": "e5b1f2da-7df1-44f9-b0c1-4825c7928bfc"
}
Параметры запроса (task: response)
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
token |
string |
да |
ключ доступа клиента IVA Terra |
content.service |
string |
да |
имя сервиса (то же, что в запросе) |
content.task |
string |
да |
|
content.task_id |
string |
да |
идентификатор задачи, полученный на этапе |
Пример запроса (task: response)
POST https://10.6.19.23:9001/adp_services
Content-Type: application/json
{
"token": "o193noFnImHx7c3kL3oav9oFyogE0hUL",
"content": {
"service": "assistant",
"task": "response",
"task_id": "e5b1f2da-7df1-44f9-b0c1-4825c7928bfc"
}
}
Возможные ответы (task: response)
Обработка не завершена:
{
"status": "in_progress"
}
Ошибка обработки:
{
"status": "error"
}
Успешное завершение:
{
"predicted_sp": "текстовое содержимое ответа от сервиса ADP"
}
Для сервиса planner ответ возвращается в формате XML с разметкой поручений, сроков и исполнителей.
POST /adp_services_stream
Эндпоинт для потоковой обработки запросов к сервисам ADP. Ответ возвращается порциями по мере генерации, соединение закрывается сервером автоматически после завершения генерации контента.
-
метод API: POST
-
URL-адрес для API-запросов:
https://<TERRA_IP>:<API_PORT>/adp_services_streamгде:
<TERRA_IP> — IP-адрес или доменное имя сервера IVA Terra
<API_PORT> — порт для доступа к API (по умолчанию 9001)
|
Эндпоинт |
Порядок работы
-
отправка запроса на обработку сообщения (
task: request) -
в заголовках ответа возвращаются
x-inference-id,x-chat-idиx-status -
данные поступают порциями в формате Server-Sent Events (преамбула
data:) -
каждая порция содержит
status(in_progress/done) иchunk(фрагмент ответа) -
соединение закрывается сервером после получения порции с
status: done
Параметры запроса
| Параметр | Тип | Обязательность | Описание |
|---|---|---|---|
token |
string |
да |
ключ доступа клиента IVA Terra (формируется в панели администрирования) |
content.service |
string |
да |
имя сервиса: |
content.task |
string |
да |
|
content.message |
string |
да |
текст для обработки (содержимое встречи или вопрос) |
content.lang |
string |
нет |
код языка: |
content.chat_id |
string |
нет |
UUID чата для сохранения истории беседы (только для |
Пример запроса (curl)
curl -vv -k POST https://10.6.19.23:9001/adp_services_stream \
-H "Content-Type: application/json" \
-d '{
"token": "o193noFnImHx7c3kL3oav9oFyogE0hUL",
"content": {
"task": "request",
"service": "assistant",
"message": "Дай краткий совет по продуктивности",
"lang": "ru"
}
}'
Заголовки ответа
При успешном начале генерации ответа возвращаются следующие заголовки:
| Заголовок | Описание |
|---|---|
x-inference-id |
уникальный идентификатор задачи |
x-chat-id |
идентификатор чата (для сервиса |
x-status |
статус: |
Content-Type |
|
HTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
x-inference-id: 8c7b348d-fe37-46a1-ba83-ffad7d631254
x-chat-id: b122eafc-3ae6-47f0-9cdb-ed7ea1106da9
x-status: started
cache-control: no-cache
Структура потокового ответа
Данные поставляются от сервиса к клиенту порциями, построчно. Каждая порция начинается с преамбулы data: (6 символов), после которой следует JSON с полезным контентом.
Формат порции:
data: {"status": "in_progress", "chunk": "фрагмент текста ответа"}
data: {"status": "done", "chunk": ""}
Поля JSON:
| Поле | Описание |
|---|---|
status |
|
chunk |
текстовый фрагмент ответа (при |
Пример потокового ответа
data: {"status": "in_progress", "chunk": "Сосредоточьтесь"}
data: {"status": "in_progress", "chunk": " на одной задаче"}
data: {"status": "in_progress", "chunk": " за раз. Много"}
data: {"status": "in_progress", "chunk": "задачность часто"}
data: {"status": "in_progress", "chunk": " снижает эффективность."}
data: {"status": "in_progress", "chunk": " Выделите конкретное"}
data: {"status": "in_progress", "chunk": " время для каждой задачи"}
data: {"status": "in_progress", "chunk": " и избегайте отвлечений."}
data: {"status": "done", "chunk": ""}
При получении последней порции с status: done соединение закрывается со стороны сервиса.