@besales/mcp 0.37.0 → 0.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/resources/docs/agent-behavior.md +7 -5
  2. package/dist/resources/docs/prompt-anatomy.md +4 -4
  3. package/dist/resources/docs/prompt-principles.md +22 -3
  4. package/dist/schemas/mcp-tools.json +345 -9
  5. package/dist/skills/besales-dialogue-audit/SKILL.md +6 -0
  6. package/dist/tools/definitions/dialogue-audit.d.ts +23 -0
  7. package/dist/tools/definitions/dialogue-audit.js +155 -0
  8. package/dist/tools/definitions/dialogue-audit.js.map +1 -0
  9. package/dist/tools/definitions/follow-up-setup.d.ts +27 -0
  10. package/dist/tools/definitions/follow-up-setup.js +76 -0
  11. package/dist/tools/definitions/follow-up-setup.js.map +1 -0
  12. package/dist/tools/definitions/follow-up.d.ts +19 -0
  13. package/dist/tools/definitions/follow-up.js +81 -3
  14. package/dist/tools/definitions/follow-up.js.map +1 -1
  15. package/dist/tools/definitions/platform-setup.d.ts +23 -16
  16. package/dist/tools/definitions/platform-setup.js +27 -34
  17. package/dist/tools/definitions/platform-setup.js.map +1 -1
  18. package/dist/tools/definitions/scheduled-tasks.d.ts +5 -0
  19. package/dist/tools/definitions/scheduled-tasks.js +35 -0
  20. package/dist/tools/definitions/scheduled-tasks.js.map +1 -1
  21. package/dist/tools/definitions/shared.d.ts +22 -13
  22. package/dist/tools/definitions/shared.js +49 -7
  23. package/dist/tools/definitions/shared.js.map +1 -1
  24. package/dist/tools/definitions.d.ts +55 -16
  25. package/dist/tools/definitions.js +2 -0
  26. package/dist/tools/definitions.js.map +1 -1
  27. package/dist/tools/registry-mapping-cases-core.d.ts +4 -0
  28. package/dist/tools/registry-mapping-cases-core.js.map +1 -1
  29. package/dist/tools/registry-mapping-cases-platform.js +45 -1
  30. package/dist/tools/registry-mapping-cases-platform.js.map +1 -1
  31. package/package.json +2 -2
@@ -205,7 +205,7 @@
205
205
 
206
206
  | Поле | Дефолт | Описание |
207
207
  |---|---|---|
208
- | `botWaitingReturn` | 3 | Сколько часов бот молчит после сообщения оператора. Допустимые: `0`, `1`, `3`, `6`, `12`, `24`. `0` = до команды `/start`. |
208
+ | `botWaitingReturn` | 3 | Сколько часов бот молчит после сообщения оператора. Допустимые: `-1`, `0`, `1`, `3`, `6`, `12`, `24`. `-1` = ответ оператора вообще не отключает бота, `0` = до команды `/start`. |
209
209
  | `followUpWaitingReturn` | -1 | На сколько часов отключить follow-up после оператора. `-1` = не отключать, `0` = навсегда, `1`–`24` — часы. |
210
210
  | `skipTaskCreationOnCallOperator` | false | Если `true` — при `call_operator` система **только** меняет ответственного на оператора, без постановки задачи в CRM. Полезно, когда workflow в CRM ведётся через статусы воронки, а не через task'ы, и лишние «висящие» задачи на оператора засоряют его список дел. |
211
211
  | `anonymizationEnabled` | false | Обратимая PII-анонимизация LLM-пайплайна (per-platform). Если `true` — реальные имя/телефон/email клиента вырезаются из сообщений перед отправкой в LLM (заменяются токенами) и подставляются обратно в ответе и в аргументах tool-call (например, поля CRM). Ставится через секцию `privacy: { anonymization_enabled }` в `besales_behavior_update`. |
@@ -237,17 +237,18 @@
237
237
  | `PROCESS_WITH_LLM` | Запустить vision-модель (gpt-4.1-mini) и интерпретировать изображение в текст для LLM. |
238
238
  | `FIXED_RESPONSE` | Отправить фиксированный текст из `imageFixedResponseText`. |
239
239
 
240
- `PROCESS_WITH_LLM` для изображений запускает vision-модель. Для **видео** `PROCESS_WITH_LLM` обрабатывает **подпись (caption)** как обычный текст через LLM — само видео в модель не отправляется; нет подписи → вызывается оператор; работает на Telegram Bot/Personal, Wazzup, VK, Bitrix24Bot, Salebot, GetCourse (на Avito/Instagram видео → оператор). Для документов/аудио — только `SILENT` или `FIXED_RESPONSE`.
240
+ `PROCESS_WITH_LLM` есть у трёх типов из четырёх, и механика у каждого СВОЯ: изображение уходит в vision-модель; у **видео** обрабатывается **подпись (caption)** как обычный текст (само видео не отправляется, нет подписи → оператор; Telegram Bot/Personal, Wazzup, VK, Bitrix24Bot, Salebot, GetCourse — на Avito/Instagram видео → оператор); у **документа** обрабатывается **извлечённый текст файла** (сам файл не отправляется). У **аудио** этого значения нет вовсе — только `SILENT` или `FIXED_RESPONSE`.
241
241
 
242
242
  ### Видео / Документы / Аудио (`VideoHandlingBehavior`, `DocumentHandlingBehavior`, `AudioHandlingBehavior`)
243
243
 
244
- `DocumentHandlingBehavior` и `AudioHandlingBehavior` имеют значения `SILENT` / `FIXED_RESPONSE`. `VideoHandlingBehavior` дополнительно поддерживает `PROCESS_WITH_LLM`:
244
+ `AudioHandlingBehavior` имеет только `SILENT` / `FIXED_RESPONSE`. `VideoHandlingBehavior` и `DocumentHandlingBehavior` дополнительно поддерживают `PROCESS_WITH_LLM`:
245
245
 
246
246
  | Значение | Что делает |
247
247
  |---|---|
248
248
  | `SILENT` | Промолчать (default). |
249
249
  | `FIXED_RESPONSE` | Отправить фиксированный текст из соответствующего `*FixedResponseText`. |
250
- | `PROCESS_WITH_LLM` *(только video)* | Обработать **подпись** видео как текст через LLM (само видео не отправляется; нет подписи → оператор; Telegram/Wazzup/VK/Bitrix24/Salebot/GetCourse, кроме Avito/Instagram). |
250
+ | `PROCESS_WITH_LLM` *(video)* | Обработать **подпись** видео как текст через LLM (само видео не отправляется; нет подписи → оператор; Telegram/Wazzup/VK/Bitrix24/Salebot/GetCourse, кроме Avito/Instagram). |
251
+ | `PROCESS_WITH_LLM` *(document)* | Извлечь текст файла (PDF, DOCX, DOC, XLSX, XLS, CSV, TSV, TXT, MD) и обработать как обычное сообщение. Сам файл в модель не отправляется. Длинный документ передаётся не целиком — модель предупреждается об усечении. Скан без текстового слоя, неподдерживаемый формат и файл >20 МБ → оператор. На Avito документ приходит голой ссылкой: без расширения в ней разбор невозможен → оператор. |
251
252
 
252
253
  ```json
253
254
  {
@@ -376,11 +377,12 @@
376
377
  | `messageOpenDelay` только для Telegram Personal | На обычных Telegram Bot ничего не даёт. |
377
378
  | `messageDevide=true` без `messageChunkSeparator` | Не работает — нужен явный разделитель. |
378
379
  | LLM должен знать про `messageChunkSeparator` | Если включаете `messageDevide`, добавьте в `baseSystemPrompt` инструкцию: «Когда нужно разделить ответ на части, ставь между частями `%%%`». |
379
- | `imageHandlingBehavior=PROCESS_WITH_LLM` | Только для изображений (vision). Для видео/доков/аудио — `SILENT` или `FIXED_RESPONSE`. |
380
+ | `audioHandlingBehavior=PROCESS_WITH_LLM` | Такого значения нет — только `SILENT` или `FIXED_RESPONSE`, иначе 400. У image/video/document разбор есть, но механика у каждого своя (vision / подпись / текст файла). |
380
381
  | `urlHandlingBehavior=PROCESS_WITH_CRAWLER` | Может тормозить (внешний запрос). Не включать массово. |
381
382
  | `messageFilters` — до 20 правил | Применяются по `order`. |
382
383
  | `greetingButtons` — до 10 кнопок | Платформенный лимит. |
383
384
  | `botWaitingReturn=0` | Бот не вернётся автоматически — нужно явное `/start` от оператора. |
385
+ | `botWaitingReturn=-1` | Бот отвечает поверх оператора — берут в суфлёрских/квалификационных каналах. Стадию CRM «оператор перехватил» настройка НЕ отменяет: если у этой стадии выключен `isBotActive`, бот всё равно замолчит по стадийному гейту. |
384
386
  | `operatorSchedule.enabled=false` | Оператор «всегда доступен» — не блокировать `call_operator`. |
385
387
  | `aiErrorTargetStageId=null` | Не критично — система переведёт на первый этап. |
386
388
  | `skipTaskCreationOnCallOperator=true` | Только смена ответственного, без постановки задачи в CRM (для AmoCRM/Bitrix24). |
@@ -188,7 +188,7 @@ AI-сервис генерирует только **`baseSystemPrompt`**. Всё
188
188
  Доступные инструменты: ← LLM получает их через tools API
189
189
  - call_operator(reason)
190
190
  - handle_want_buy(productOrService, intent)
191
- - save_user_info(firstName, lastName, ...)
191
+ - save_user_info(name, surname, city, insight)
192
192
 
193
193
  Если клиент сказал «хочу купить» — вызови ← триггеры подставляются отдельно
194
194
  run_trigger с triggerId="abc-123".
@@ -224,11 +224,11 @@ run_trigger с triggerId="abc-123".
224
224
 
225
225
  | Параметр | Значение |
226
226
  |---|---|
227
- | Максимальная длина одного промпта | 60 000 символов (`PROMPT_LIMITS.MAX_PROMPT_LENGTH`) |
227
+ | Максимальная длина одного промпта | 80 000 символов (`PROMPT_LIMITS.MAX_PROMPT_LENGTH`) |
228
228
  | Максимум триггеров в промпте | 50 |
229
229
  | Максимум длины условия триггера | 500 символов |
230
230
 
231
- За длиной `baseSystemPrompt` следит `PromptLintService`: **warn** при превышении **25 000** символов (`PROMPT_LIMITS.SOFT_PROMPT_LENGTH`) и **hard_fail** (блокирует `prompt_finalize` / `prompt_patch_commit`) при превышении **60 000** (`PROMPT_LIMITS.MAX_PROMPT_LENGTH`). Держи `baseSystemPrompt` компактным — ориентир **20 000–25 000 символов**, вынося факты в Базу знаний (документы / Q&A), чтобы оставить место под системные блоки, RAG-контекст и историю.
231
+ За длиной `baseSystemPrompt` следит `PromptLintService`: **warn** при превышении **40 000** символов (`PROMPT_LIMITS.SOFT_PROMPT_LENGTH`) и **hard_fail** (блокирует `prompt_finalize` / `prompt_patch_commit`) при превышении **80 000** (`PROMPT_LIMITS.MAX_PROMPT_LENGTH`). Держи `baseSystemPrompt` компактным — ориентир **30 000–40 000 символов**, вынося факты в Базу знаний (документы / Q&A), чтобы оставить место под системные блоки, RAG-контекст и историю.
232
232
 
233
233
  ## 12. factualContext — активные факты агента
234
234
 
@@ -255,7 +255,7 @@ run_trigger с triggerId="abc-123".
255
255
  | `runtime_banned_term` | Агент в run-time произнёс §9-запрещённый термин (только post-run, не на prompt-level) | `hard_fail` | Transcript-lint в sandbox |
256
256
  | `agent_banned_term` | Терм из per-agent feedback sheet (`AgentFeedbackSheetLink` → §07 Google Sheets) | `warn` | Prompt-finalize, transcript-lint |
257
257
  | `scope_consistency` | Тон/branches противоречат `AgentChat.agentScope` (S4.12). Например, sale-агент пишет «я не могу помочь с покупкой». Regex-based | `warn` | Prompt-finalize |
258
- | `prompt_length` | Длина `baseSystemPrompt`: warn при > 25 000 символов, hard_fail при > 60 000 (`PROMPT_LIMITS`) | `warn` / `hard_fail` | Prompt-finalize |
258
+ | `prompt_length` | Длина `baseSystemPrompt`: warn при > 40 000 символов, hard_fail при > 80 000 (`PROMPT_LIMITS`) | `warn` / `hard_fail` | Prompt-finalize |
259
259
 
260
260
  ### 13.2. Severity-семантика
261
261
 
@@ -49,9 +49,28 @@
49
49
  - ❌ «по теме сосуды», «осуществляется приём заявок», «в рамках программы»
50
50
  - ✅ «про сосуды», «заявки принимаем», «в программе»
51
51
 
52
- **A4. Имена и бренд — на языке клиента.** Латиница в русском тексте читается как робот.
53
- - ❌ «помощница из Ksamata»
54
- - ✅ «помощница из Ксамата» (домены/URL вроде `site.ru` — исключение, их не переводим)
52
+ **A4. Только язык клиента — и в именах, и в обычных словах.** Латиница в русском тексте читается
53
+ как робот. Два разных случая, и второй опаснее, потому что его не ловит инструкция «отвечай на
54
+ языке клиента»: ответ формально на русском, модель считает это не сменой языка, а выбором точного
55
+ слова.
56
+ - ❌ «помощница из Ksamata» → ✅ «помощница из Ксамата» (имя/бренд)
57
+ - ❌ «куратор поддерживает в переписке **throughout** обучение» (реальный прод-случай 06.08.26)
58
+ → ✅ «куратор на связи в переписке всё время обучения»
59
+
60
+ Запрет на ЛЮБУЮ английскую вставку внутри фразы, даже когда она точнее: `throughout`, `however`,
61
+ `actually`, `basically`, `workflow`, `follow-up`, `mindset`, `check-in`. Механизм всегда один: у
62
+ слова нет однословного русского аналога, и модель тянется к компактности. Нет короткого аналога —
63
+ пиши длиннее обычными словами.
64
+
65
+ Туда же калька терминами вместо простых слов: ❌ «экспертиза», «локация», «коммуницировать» →
66
+ ✅ «опыт», «место», «расскажу». На аудитории 50+ это тот же эффект, что латиница.
67
+
68
+ Исключения обязательно называть в промпте явно, иначе агент начнёт переводить сервисы и ломать
69
+ ссылки: названия сервисов и банков, которые так и пишутся (Telegram, WhatsApp), домены и URL.
70
+
71
+ Проверять глазами бесполезно — одно слово в середине абзаца взгляд пропускает (так прод-случай и
72
+ доехал до заказчика). Гони по репликам агента поиск латиницы, вычитай ссылки и названия сервисов,
73
+ остаток должен быть пуст.
55
74
 
56
75
  **A5. Не повторяй уже сказанное.** Если ты уже описал состав/факт или задал вопрос — не описывай
57
76
  блоки снова и не задавай тот же вопрос второй раз. Каждое сообщение двигает диалог НОВЫМ шагом.
@@ -2849,7 +2849,7 @@
2849
2849
  },
2850
2850
  {
2851
2851
  "name": "besales_routing_rule_upsert",
2852
- "description": "Create or patch one router routing rule. Does not bulk replace the router. Direct agent routing requires explicit_confirmation. For CUSTOM_VARIABLE pass either conditions[] (N conditions joined by condition_logic ALL=AND / ANY=OR) or the legacy custom_variable_id+variable_value pair (single condition).",
2852
+ "description": "Create or patch one router routing rule. Does not bulk replace the router. Direct agent routing requires explicit_confirmation. For CUSTOM_VARIABLE pass either conditions[] (N conditions joined by condition_logic ALL=AND / ANY=OR) or the legacy custom_variable_id+variable_value pair (single condition). Each condition holds a SET of values in variable_values[]: the condition matches when the contact variable equals ANY of them (OR inside the condition). Combined with condition_logic=ALL this expresses AND-of-ORs without nested parentheses, e.g. AI_TOPIC in [dbo] AND WAVE_SEGMENT in [post-web, post-web-2] — use ONE rule with two conditions, not two rules. Legacy single-value form variable_value is still accepted per condition. Editing an existing rule that has multi-value conditions requires conditions[]; the legacy scalar does not replace them and returns 409.",
2853
2853
  "inputSchema": {
2854
2854
  "type": "object",
2855
2855
  "required": [
@@ -2905,14 +2905,21 @@
2905
2905
  "items": {
2906
2906
  "type": "object",
2907
2907
  "required": [
2908
- "custom_variable_id",
2909
- "variable_value"
2908
+ "custom_variable_id"
2910
2909
  ],
2911
2910
  "properties": {
2912
2911
  "custom_variable_id": {
2913
2912
  "type": "string",
2914
2913
  "format": "uuid"
2915
2914
  },
2915
+ "variable_values": {
2916
+ "type": "array",
2917
+ "minItems": 1,
2918
+ "maxItems": 50,
2919
+ "items": {
2920
+ "type": "string"
2921
+ }
2922
+ },
2916
2923
  "variable_value": {
2917
2924
  "type": "string"
2918
2925
  }
@@ -3016,6 +3023,14 @@
3016
3023
  },
3017
3024
  "confirmation_reason": {
3018
3025
  "type": "string"
3026
+ },
3027
+ "allow_repeated_calls": {
3028
+ "type": "boolean",
3029
+ "description": "Повтор ВНУТРИ одного ответа модели."
3030
+ },
3031
+ "run_once_per_contact": {
3032
+ "type": "boolean",
3033
+ "description": "Одно срабатывание на контакт НАВСЕГДА. Другая ось, чем allow_repeated_calls."
3019
3034
  }
3020
3035
  }
3021
3036
  }
@@ -3123,7 +3138,7 @@
3123
3138
  },
3124
3139
  "media_handling": {
3125
3140
  "type": "object",
3126
- "description": "Стратегии обработки image/video/audio/document.",
3141
+ "description": "Стратегии обработки image/video/audio/document. PROCESS_WITH_LLM разбирает вложение по-разному: image → vision-модель, video → подпись как текст, document → извлечённый текст файла (PDF/DOCX/DOC/XLSX/XLS/CSV/TXT; скан без текстового слоя и неподдерживаемый формат уводят на оператора). Для audio его нет вовсе — там только SILENT и FIXED_RESPONSE, иначе бэкенд отвечает 400.",
3127
3142
  "properties": {
3128
3143
  "image": {
3129
3144
  "$ref": "#/$defs/mediaHandler"
@@ -3132,7 +3147,7 @@
3132
3147
  "$ref": "#/$defs/mediaHandler"
3133
3148
  },
3134
3149
  "audio": {
3135
- "$ref": "#/$defs/mediaHandler"
3150
+ "$ref": "#/$defs/plainMediaHandler"
3136
3151
  },
3137
3152
  "document": {
3138
3153
  "$ref": "#/$defs/mediaHandler"
@@ -3207,6 +3222,7 @@
3207
3222
  "bot_waiting_return_hours": {
3208
3223
  "type": "integer",
3209
3224
  "enum": [
3225
+ -1,
3210
3226
  0,
3211
3227
  1,
3212
3228
  3,
@@ -3343,6 +3359,7 @@
3343
3359
  "$defs": {
3344
3360
  "mediaHandler": {
3345
3361
  "type": "object",
3362
+ "description": "Обработчик вложения, поддерживающего разбор моделью (image, video, document).",
3346
3363
  "required": [
3347
3364
  "behavior"
3348
3365
  ],
@@ -3365,6 +3382,31 @@
3365
3382
  "type": "string"
3366
3383
  }
3367
3384
  }
3385
+ },
3386
+ "plainMediaHandler": {
3387
+ "type": "object",
3388
+ "description": "Обработчик вложения без разбора моделью (audio): у AudioHandlingBehavior нет значения PROCESS_WITH_LLM.",
3389
+ "required": [
3390
+ "behavior"
3391
+ ],
3392
+ "properties": {
3393
+ "behavior": {
3394
+ "type": "string",
3395
+ "enum": [
3396
+ "SILENT",
3397
+ "FIXED_RESPONSE"
3398
+ ]
3399
+ },
3400
+ "fixed_response_text": {
3401
+ "type": "string"
3402
+ },
3403
+ "call_operator": {
3404
+ "type": "boolean"
3405
+ },
3406
+ "operator_comment": {
3407
+ "type": "string"
3408
+ }
3409
+ }
3368
3410
  }
3369
3411
  }
3370
3412
  }
@@ -3435,7 +3477,7 @@
3435
3477
  "eventType",
3436
3478
  "variable"
3437
3479
  ],
3438
- "description": "Режим отбора контактов. Неизвестное значение НЕ включает ни один фильтр — цепочка ушла бы всем контактам канала, поэтому бэкенд его отвергает."
3480
+ "description": "БАЗОВЫЙ отбор: по статусу CRM, по типу события платформы либо variable = базового фильтра нет (отбор только по sequenceConditions). Условия по переменным ортогональны и добавляются через И: чтобы ветвить цепочки по варианту рассылки, сохранив отбор по событию, бери eventType и задай sequenceConditions, а НЕ variable. Неизвестное значение НЕ включает ни один фильтр — цепочка ушла бы всем контактам канала, поэтому бэкенд его отвергает."
3439
3481
  },
3440
3482
  "sequenceConditions": {
3441
3483
  "type": "array",
@@ -3475,7 +3517,7 @@
3475
3517
  }
3476
3518
  }
3477
3519
  },
3478
- "description": "Обязателен и непуст при filterMode=variable."
3520
+ "description": "Условия принадлежности контакта цепочке, соединяются через И. Применяются при ЛЮБОМ filterMode (при variable обязателен и непуст, иначе цепочка не выберет никого). Для ветвления по варианту рассылки: переменная WAVE_MAILING_VARIANT, значение — UUID варианта из каталога воркспейса, а НЕ его имя (first-ver будет отвергнут). Отдельные цепочки НЕ взаимоисключающи: прогресс изолирован по sequenceId, поэтому безусловная ловящая цепочка рядом с eq A и eq B не подстрахует, а удвоит отправку. Набор обязан быть строгим разбиением: eq A, eq B и fallback neq A AND neq B (у контакта без переменной eq/in ложно, neq истинно)."
3479
3521
  },
3480
3522
  "steps": {
3481
3523
  "type": "array",
@@ -3595,6 +3637,33 @@
3595
3637
  }
3596
3638
  }
3597
3639
  },
3640
+ {
3641
+ "name": "besales_followup_sequence_clone",
3642
+ "description": "Скопировать follow-up sequence на ТОЙ ЖЕ платформе. Копия всегда создаётся ВЫКЛЮЧЕННОЙ: прогресс изолирован по sequenceId, и включённая копия слала бы те же касания тем же контактам вторым потоком. Копируется только определение (имя, тип, триггер, config) — прогресс контактов, история отправок и запланированные сообщения не копируются. Имя не передано — сервер подберёт свободное (<имя>-copy, <имя>-copy-2, …). Cross-platform не поддерживается: конфиг ссылается на статусы CRM, агентов, файлы и переменные своей платформы.",
3643
+ "inputSchema": {
3644
+ "type": "object",
3645
+ "required": [
3646
+ "platform_id",
3647
+ "sequence_id"
3648
+ ],
3649
+ "properties": {
3650
+ "platform_id": {
3651
+ "type": "string",
3652
+ "format": "uuid",
3653
+ "description": "Платформа источника; копия приземляется на неё же."
3654
+ },
3655
+ "sequence_id": {
3656
+ "type": "string",
3657
+ "format": "uuid",
3658
+ "description": "Исходный FollowUpSequence для копирования."
3659
+ },
3660
+ "name": {
3661
+ "type": "string",
3662
+ "description": "Имя копии. Не передано — сервер подберёт свободное от имени источника; передано и занято — тот же подбор применится к нему."
3663
+ }
3664
+ }
3665
+ }
3666
+ },
3598
3667
  {
3599
3668
  "name": "besales_pipeline_settings_update",
3600
3669
  "description": "Patch allowlisted platform PipelineSettings via typed sections (crm_pipeline_behavior, auto_finish). Phase B (2026-05-27): generic `updates` field удалён — отвергается с 400. CRM stage movement or lead/contact creation fields require explicit_confirmation.",
@@ -8597,6 +8666,77 @@
8597
8666
  }
8598
8667
  }
8599
8668
  },
8669
+ {
8670
+ "name": "besales_followup_reactions",
8671
+ "description": "Read-only аналитика дожимов: на какой шаг follow-up-цепочки контакт реально отреагировал. Метрик ДВЕ — операционная (следует за длиной окна шага, шаги по ней сравнивать нельзя) и сравнительная на равном горизонте (сравнивать можно только при comparableReliable=true). Срезы по сегменту/продукту/мессенджеру доступны только у каналов с рассылками. Scope: read:analytics.",
8672
+ "inputSchema": {
8673
+ "type": "object",
8674
+ "required": [
8675
+ "platform_id",
8676
+ "from",
8677
+ "to"
8678
+ ],
8679
+ "additionalProperties": false,
8680
+ "properties": {
8681
+ "platform_id": {
8682
+ "type": "string",
8683
+ "format": "uuid"
8684
+ },
8685
+ "from": {
8686
+ "type": "string",
8687
+ "format": "date",
8688
+ "description": "Начало периода по дате отправки шага (YYYY-MM-DD, московские сутки)."
8689
+ },
8690
+ "to": {
8691
+ "type": "string",
8692
+ "format": "date",
8693
+ "description": "Конец периода. Период длиннее 366 суток отвергается с 400."
8694
+ },
8695
+ "sequence_id": {
8696
+ "type": "array",
8697
+ "items": {
8698
+ "type": "string",
8699
+ "format": "uuid"
8700
+ },
8701
+ "description": "Фильтр цепочек. НЕ влияет на атрибуцию: окно ответа считается по полной шкале касаний."
8702
+ },
8703
+ "horizon_minutes": {
8704
+ "type": "integer",
8705
+ "enum": [
8706
+ 30,
8707
+ 60,
8708
+ 90,
8709
+ 180,
8710
+ 360,
8711
+ 720,
8712
+ 1440
8713
+ ],
8714
+ "description": "Горизонт сравнительной метрики, минуты. По умолчанию 90."
8715
+ },
8716
+ "segment": {
8717
+ "type": "array",
8718
+ "items": {
8719
+ "type": "string"
8720
+ },
8721
+ "description": "Сегменты волны; доступные значения приходят в ответе (dimensions.segments)."
8722
+ },
8723
+ "product": {
8724
+ "type": "array",
8725
+ "items": {
8726
+ "type": "string"
8727
+ },
8728
+ "description": "Продукты волны (dimensions.products)."
8729
+ },
8730
+ "channel": {
8731
+ "type": "array",
8732
+ "items": {
8733
+ "type": "string"
8734
+ },
8735
+ "description": "Транспорты волны (dimensions.channels): Telegram, WhatsApp, MAX, VK."
8736
+ }
8737
+ }
8738
+ }
8739
+ },
8600
8740
  {
8601
8741
  "name": "besales_scheduled_task_list",
8602
8742
  "description": "Read-only список плановых задач канала (модуль «Задачи»). Единственный тип — DIALOGUE_ANALYSIS (суфлёр: саммари дня + почасовой «Статус коммуникации»). Scope: mcp:platform-setup.",
@@ -8773,6 +8913,39 @@
8773
8913
  },
8774
8914
  "description": "ASSIGNED_BY_ID ответственных Bitrix (не наши id — бери из besales_crm_operator_list). Разбираются ТОЛЬКО перечисленные. Пусто = не выбрано (включённая задача вернёт 400), а НЕ «все»."
8775
8915
  },
8916
+ "stages": {
8917
+ "type": [
8918
+ "array",
8919
+ "null"
8920
+ ],
8921
+ "items": {
8922
+ "type": "object",
8923
+ "additionalProperties": false,
8924
+ "required": [
8925
+ "pipeline_crm_id",
8926
+ "pipeline_id",
8927
+ "status_id"
8928
+ ],
8929
+ "properties": {
8930
+ "pipeline_crm_id": {
8931
+ "type": "string",
8932
+ "format": "uuid",
8933
+ "description": "UUID CRM-интеграции."
8934
+ },
8935
+ "pipeline_id": {
8936
+ "type": "integer",
8937
+ "minimum": 0,
8938
+ "description": "Числовой id воронки CRM."
8939
+ },
8940
+ "status_id": {
8941
+ "type": "integer",
8942
+ "minimum": 0,
8943
+ "description": "Номер колонки внутри воронки."
8944
+ }
8945
+ }
8946
+ },
8947
+ "description": "Колонки ВНУТРИ выбранных воронок, общие для обоих режимов. Семантика пустоты ОБРАТНАЯ воронкам: ключа нет или null — все колонки выбранных воронок, воронка без выбранных колонок идёт целиком. ПУСТОЙ массив у включённой задачи вернёт 400. Стадия — тройка: номер колонки уникален лишь внутри пары (CRM, воронка)."
8948
+ },
8776
8949
  "daily_prompt": {
8777
8950
  "type": [
8778
8951
  "string",
@@ -8927,6 +9100,164 @@
8927
9100
  }
8928
9101
  }
8929
9102
  }
9103
+ },
9104
+ {
9105
+ "name": "besales_dialogue_audit_config_get",
9106
+ "description": "Read-only настройки «Ревизора диалогов» на канале: включён ли плановый разбор, модель, час запуска, инструкции. isConfigured=false — строки конфига ещё нет, значения дефолтные. Запись настроек через MCP не выведена. Scope: read:analytics.",
9107
+ "inputSchema": {
9108
+ "type": "object",
9109
+ "required": [
9110
+ "platform_id"
9111
+ ],
9112
+ "additionalProperties": false,
9113
+ "properties": {
9114
+ "platform_id": {
9115
+ "type": "string",
9116
+ "format": "uuid",
9117
+ "description": "Канал, для которого настроен ревизор."
9118
+ }
9119
+ }
9120
+ }
9121
+ },
9122
+ {
9123
+ "name": "besales_dialogue_audit_runs_list",
9124
+ "description": "История прогонов ревизора на канале, курсорная пагинация (offset показал бы один прогон дважды). Scope: read:analytics.",
9125
+ "inputSchema": {
9126
+ "type": "object",
9127
+ "required": [
9128
+ "platform_id"
9129
+ ],
9130
+ "additionalProperties": false,
9131
+ "properties": {
9132
+ "platform_id": {
9133
+ "type": "string",
9134
+ "format": "uuid",
9135
+ "description": "Канал."
9136
+ },
9137
+ "cursor": {
9138
+ "type": "string",
9139
+ "description": "nextCursor предыдущей страницы."
9140
+ },
9141
+ "limit": {
9142
+ "type": "integer",
9143
+ "minimum": 1,
9144
+ "maximum": 100,
9145
+ "description": "Размер страницы."
9146
+ }
9147
+ }
9148
+ }
9149
+ },
9150
+ {
9151
+ "name": "besales_dialogue_audit_run_get",
9152
+ "description": "Отчёт прогона: статус, счётчики охвата (candidate/audited/failed segments), сводка, причина обрыва. Счётчики зафиксированы и не пересчитываются. Scope: read:analytics.",
9153
+ "inputSchema": {
9154
+ "type": "object",
9155
+ "required": [
9156
+ "run_id"
9157
+ ],
9158
+ "additionalProperties": false,
9159
+ "properties": {
9160
+ "run_id": {
9161
+ "type": "string",
9162
+ "format": "uuid",
9163
+ "description": "Прогон ревизора."
9164
+ }
9165
+ }
9166
+ }
9167
+ },
9168
+ {
9169
+ "name": "besales_dialogue_audit_findings",
9170
+ "description": "Находки прогона — материал для правки промпта. Фильтры: агент, категория, важность, статус разметки человеком (NEW/LIKED/DISLIKED). truncated=true означает обрезанный список. Разметка находок через MCP НЕ выведена: это человеческая оценка работы ревизора. Scope: read:analytics.",
9171
+ "inputSchema": {
9172
+ "type": "object",
9173
+ "required": [
9174
+ "run_id"
9175
+ ],
9176
+ "additionalProperties": false,
9177
+ "properties": {
9178
+ "run_id": {
9179
+ "type": "string",
9180
+ "format": "uuid",
9181
+ "description": "Прогон ревизора."
9182
+ },
9183
+ "agent_id": {
9184
+ "type": "string",
9185
+ "format": "uuid",
9186
+ "description": "Оставить находки одного агента."
9187
+ },
9188
+ "category": {
9189
+ "type": "string",
9190
+ "description": "Категория находки."
9191
+ },
9192
+ "severity": {
9193
+ "type": "string",
9194
+ "description": "Важность находки."
9195
+ },
9196
+ "status": {
9197
+ "type": "string",
9198
+ "enum": [
9199
+ "NEW",
9200
+ "LIKED",
9201
+ "DISLIKED"
9202
+ ],
9203
+ "description": "Разметка человеком. LIKED — ревизор прав, DISLIKED — человек находку отверг (применять её нельзя)."
9204
+ }
9205
+ }
9206
+ }
9207
+ },
9208
+ {
9209
+ "name": "besales_dialogue_audit_run_start",
9210
+ "description": "Запустить разбор сейчас. Durable: ответ приходит сразу с runId, работа идёт в очереди. Уже разобранное заново не оплачивается. 409 — на канале уже идёт прогон. Scope: mcp:platform-setup.",
9211
+ "inputSchema": {
9212
+ "type": "object",
9213
+ "required": [
9214
+ "platform_id"
9215
+ ],
9216
+ "additionalProperties": false,
9217
+ "properties": {
9218
+ "platform_id": {
9219
+ "type": "string",
9220
+ "format": "uuid",
9221
+ "description": "Канал."
9222
+ },
9223
+ "period_from": {
9224
+ "type": "string",
9225
+ "format": "date-time",
9226
+ "description": "Начало периода. Задаётся ВМЕСТЕ с period_to; без них — всё непроверенное."
9227
+ },
9228
+ "period_to": {
9229
+ "type": "string",
9230
+ "format": "date-time",
9231
+ "description": "Конец периода."
9232
+ },
9233
+ "explicit_confirmation": {
9234
+ "type": "boolean",
9235
+ "description": "Обязательно true. Операция тратит (или прерывает уже оплаченную) работу LLM клиента — подтверждается оператором явно."
9236
+ }
9237
+ }
9238
+ }
9239
+ },
9240
+ {
9241
+ "name": "besales_dialogue_audit_run_cancel",
9242
+ "description": "Остановить прогон. Переходит в CANCELLED (это не ошибка), захваченные отрезки возвращаются в пул, недоразобранное подхватит следующий прогон. Scope: mcp:platform-setup.",
9243
+ "inputSchema": {
9244
+ "type": "object",
9245
+ "required": [
9246
+ "run_id"
9247
+ ],
9248
+ "additionalProperties": false,
9249
+ "properties": {
9250
+ "run_id": {
9251
+ "type": "string",
9252
+ "format": "uuid",
9253
+ "description": "Прогон ревизора."
9254
+ },
9255
+ "explicit_confirmation": {
9256
+ "type": "boolean",
9257
+ "description": "Обязательно true. Операция тратит (или прерывает уже оплаченную) работу LLM клиента — подтверждается оператором явно."
9258
+ }
9259
+ }
9260
+ }
8930
9261
  }
8931
9262
  ],
8932
9263
  "resources": [
@@ -9118,7 +9449,7 @@
9118
9449
  }
9119
9450
  ],
9120
9451
  "summary": {
9121
- "total_tools": 169,
9452
+ "total_tools": 177,
9122
9453
  "tools_by_category": {
9123
9454
  "getcourse_wave": 10,
9124
9455
  "files_upload": 3,
@@ -9156,7 +9487,8 @@
9156
9487
  "dialog_script": 2,
9157
9488
  "broadcast_analytics": 2,
9158
9489
  "scheduled_tasks": 2,
9159
- "follow_up_read": 2
9490
+ "follow_up_read": 3,
9491
+ "dialogue_audit": 6
9160
9492
  },
9161
9493
  "external_execution_pairs": [
9162
9494
  "besales_icp_analysis_get_instructions / submit",
@@ -9192,6 +9524,7 @@
9192
9524
  "besales_trigger_upsert",
9193
9525
  "besales_behavior_update",
9194
9526
  "besales_followup_sequence_upsert",
9527
+ "besales_followup_sequence_clone",
9195
9528
  "besales_pipeline_settings_update",
9196
9529
  "besales_platform_settings_update",
9197
9530
  "besales_audit_revert"
@@ -9344,6 +9677,9 @@
9344
9677
  "besales_setup_session_create",
9345
9678
  "besales_setup_session_get",
9346
9679
  "besales_setup_step_submit_output"
9680
+ ],
9681
+ "newly_added_in_followup_reactions": [
9682
+ "besales_followup_reactions"
9347
9683
  ]
9348
9684
  }
9349
9685
  }
@@ -8,6 +8,12 @@ description: Read-only аудит production-переписок BeSales чере
8
8
  Используй только `besales_dialogues_query` и `besales_dialogue_transcript`. Не подключайся
9
9
  к PostgreSQL напрямую и не вызывай mutation-tools.
10
10
 
11
+ > ⚠️ Это НЕ «Ревизор диалогов». Здесь ты разбираешь СЫРЫЕ переписки сам. Ревизор — отдельный
12
+ > ночной прогон платформы: он судит по развёрнутому промпту агента, принципам и журналу действий,
13
+ > ставит якоря на конкретные реплики и накапливает разметку человека. Нужны его находки (например,
14
+ > чтобы починить промпт) — это другие инструменты: `besales_dialogue_audit_runs_list` →
15
+ > `besales_dialogue_audit_findings`. Путать их нельзя: материал и выводы разные.
16
+
11
17
  1. Прочитай MCP resource `besales://workflows/audit-dialogues` и следуй ему как source of truth.
12
18
  2. Если период не задан, возьми последние 7 суток и явно зафиксируй допущение.
13
19
  3. Для точного аудита новых заявок фильтруй `GETCOURSE_CREATE_DEAL` через
@@ -0,0 +1,23 @@
1
+ export declare const dialogueAuditTools: (import("./shared.js").ToolDefinition<{
2
+ platform_id: string;
3
+ }> | import("./shared.js").ToolDefinition<{
4
+ platform_id: string;
5
+ cursor?: string | undefined;
6
+ limit?: number | undefined;
7
+ }> | import("./shared.js").ToolDefinition<{
8
+ run_id: string;
9
+ }> | import("./shared.js").ToolDefinition<{
10
+ run_id: string;
11
+ agent_id?: string | undefined;
12
+ category?: string | undefined;
13
+ severity?: string | undefined;
14
+ status?: "NEW" | "LIKED" | "DISLIKED" | undefined;
15
+ }> | import("./shared.js").ToolDefinition<{
16
+ platform_id: string;
17
+ period_from?: string | undefined;
18
+ period_to?: string | undefined;
19
+ explicit_confirmation?: boolean | undefined;
20
+ }> | import("./shared.js").ToolDefinition<{
21
+ run_id: string;
22
+ explicit_confirmation?: boolean | undefined;
23
+ }>)[];