@besales/mcp 0.48.0 → 1.0.0-beta.2

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 (587) hide show
  1. package/README.md +109 -164
  2. package/README.onprem.ru.md +35 -0
  3. package/bin/besales-mcp-http.js +9 -0
  4. package/bin/besales-onprem.mjs +19 -0
  5. package/dist/auth/connection-store.d.ts +3 -1
  6. package/dist/auth/connection-store.js +9 -3
  7. package/dist/auth/connection-store.js.map +1 -1
  8. package/dist/auth/oauth-client.d.ts +20 -27
  9. package/dist/auth/oauth-client.js +31 -23
  10. package/dist/auth/oauth-client.js.map +1 -1
  11. package/dist/auth/session-workspace.d.ts +1 -0
  12. package/dist/auth/session-workspace.js +10 -1
  13. package/dist/auth/session-workspace.js.map +1 -1
  14. package/dist/auth/token-storage.js +4 -1
  15. package/dist/auth/token-storage.js.map +1 -1
  16. package/dist/cli.d.ts +1 -0
  17. package/dist/cli.js +80 -19
  18. package/dist/cli.js.map +1 -1
  19. package/dist/constants/crm-catalog.d.ts +2 -0
  20. package/dist/constants/crm-catalog.js +3 -0
  21. package/dist/constants/crm-catalog.js.map +1 -0
  22. package/dist/http/api-client.d.ts +52 -7
  23. package/dist/http/api-client.js +131 -66
  24. package/dist/http/api-client.js.map +1 -1
  25. package/dist/http/feedback-document-error.d.ts +26 -0
  26. package/dist/http/feedback-document-error.js +22 -0
  27. package/dist/http/feedback-document-error.js.map +1 -0
  28. package/dist/http-server.d.ts +15 -0
  29. package/dist/http-server.js +378 -0
  30. package/dist/http-server.js.map +1 -0
  31. package/dist/instructions/server-instructions.d.ts +1 -1
  32. package/dist/instructions/server-instructions.js +6 -3
  33. package/dist/instructions/server-instructions.js.map +1 -1
  34. package/dist/network/constants.d.ts +25 -0
  35. package/dist/network/constants.js +26 -0
  36. package/dist/network/constants.js.map +1 -0
  37. package/dist/network/failed-verifications.d.ts +10 -0
  38. package/dist/network/failed-verifications.js +37 -0
  39. package/dist/network/failed-verifications.js.map +1 -0
  40. package/dist/network/http-test-fixture.d.ts +3 -0
  41. package/dist/network/http-test-fixture.js +86 -0
  42. package/dist/network/http-test-fixture.js.map +1 -0
  43. package/dist/network/known-keys.d.ts +10 -0
  44. package/dist/network/known-keys.js +38 -0
  45. package/dist/network/known-keys.js.map +1 -0
  46. package/dist/network/memory-credentials.d.ts +11 -0
  47. package/dist/network/memory-credentials.js +24 -0
  48. package/dist/network/memory-credentials.js.map +1 -0
  49. package/dist/network/rate-limit.d.ts +23 -0
  50. package/dist/network/rate-limit.js +62 -0
  51. package/dist/network/rate-limit.js.map +1 -0
  52. package/dist/network/rejected-keys.d.ts +9 -0
  53. package/dist/network/rejected-keys.js +39 -0
  54. package/dist/network/rejected-keys.js.map +1 -0
  55. package/dist/network/request-work.d.ts +8 -0
  56. package/dist/network/request-work.js +20 -0
  57. package/dist/network/request-work.js.map +1 -0
  58. package/dist/network/successful-keys.d.ts +17 -0
  59. package/dist/network/successful-keys.js +47 -0
  60. package/dist/network/successful-keys.js.map +1 -0
  61. package/dist/resources/concepts/external-execution.md +3 -1
  62. package/dist/resources/concepts/feedback-sheets.md +21 -12
  63. package/dist/resources/concepts/icp.md +8 -1
  64. package/dist/resources/concepts/sandbox.md +15 -6
  65. package/dist/resources/concepts/triggers.md +8 -0
  66. package/dist/resources/concepts/workbook-classification.md +104 -50
  67. package/dist/resources/docs/agent-behavior.md +51 -382
  68. package/dist/resources/docs/campaigns.md +9 -16
  69. package/dist/resources/docs/crm-integration.md +39 -523
  70. package/dist/resources/docs/files-and-uploads.md +23 -286
  71. package/dist/resources/docs/follow-up.md +47 -12
  72. package/dist/resources/docs/knowledge-base.md +52 -521
  73. package/dist/resources/docs/pipeline-builder.md +26 -216
  74. package/dist/resources/docs/pipeline-settings-deep.md +27 -220
  75. package/dist/resources/docs/platforms.md +106 -519
  76. package/dist/resources/docs/prompt-anatomy.md +39 -285
  77. package/dist/resources/docs/routing.md +8 -16
  78. package/dist/resources/docs/trigger-actions.md +40 -24
  79. package/dist/resources/docs/variables.md +8 -12
  80. package/dist/resources/operator-edit.contract.d.ts +7 -0
  81. package/dist/resources/operator-edit.contract.js +8 -0
  82. package/dist/resources/operator-edit.contract.js.map +1 -0
  83. package/dist/resources/registry.js +20 -4
  84. package/dist/resources/registry.js.map +1 -1
  85. package/dist/resources/workflows/audit-dialogues.md +23 -12
  86. package/dist/resources/workflows/compare-models.md +6 -6
  87. package/dist/resources/workflows/connect-crm-from-scratch.md +15 -12
  88. package/dist/resources/workflows/connect-datasource-from-scratch.md +5 -4
  89. package/dist/resources/workflows/extract-from-document.md +8 -6
  90. package/dist/resources/workflows/operator-edit.md +15 -0
  91. package/dist/resources/workflows/platform-setup-from-scratch.md +59 -70
  92. package/dist/resources/workflows/production-readiness-check.md +25 -15
  93. package/dist/schemas/mcp-tools.json +9902 -4734
  94. package/dist/schemas/voice-actions-api.contract.json +248 -0
  95. package/dist/shared/constants/broadcast-reason.constants.d.ts +2 -0
  96. package/dist/shared/constants/broadcast-reason.constants.js +47 -0
  97. package/dist/shared/constants/broadcast-reason.constants.js.map +1 -0
  98. package/dist/shared/constants/crm-stage-pool.constants.d.ts +2 -0
  99. package/dist/shared/constants/crm-stage-pool.constants.js +3 -0
  100. package/dist/shared/constants/crm-stage-pool.constants.js.map +1 -0
  101. package/dist/shared/constants/followup-note.constants.d.ts +3 -0
  102. package/dist/shared/constants/followup-note.constants.js +4 -0
  103. package/dist/shared/constants/followup-note.constants.js.map +1 -0
  104. package/dist/shared/constants/followup-session.constants.d.ts +2 -0
  105. package/dist/shared/constants/followup-session.constants.js +3 -0
  106. package/dist/shared/constants/followup-session.constants.js.map +1 -0
  107. package/dist/shared/constants/funnel-analytics.constants.d.ts +2 -0
  108. package/dist/shared/constants/funnel-analytics.constants.js +3 -0
  109. package/dist/shared/constants/funnel-analytics.constants.js.map +1 -0
  110. package/dist/shared/constants/message-filter.constants.d.ts +7 -0
  111. package/dist/shared/constants/message-filter.constants.js +8 -0
  112. package/dist/shared/constants/message-filter.constants.js.map +1 -0
  113. package/dist/shared/utils/trigger-repeat-mapping.d.ts +72 -0
  114. package/dist/shared/utils/trigger-repeat-mapping.js +53 -0
  115. package/dist/shared/utils/trigger-repeat-mapping.js.map +1 -0
  116. package/dist/skills/besales-dialogue-audit/SKILL.md +31 -20
  117. package/dist/tasks/task-state-store.js +5 -0
  118. package/dist/tasks/task-state-store.js.map +1 -1
  119. package/dist/tools/annotations.js +4 -3
  120. package/dist/tools/annotations.js.map +1 -1
  121. package/dist/tools/definitions/agent-design.d.ts +78 -21
  122. package/dist/tools/definitions/agent-design.js +246 -90
  123. package/dist/tools/definitions/agent-design.js.map +1 -1
  124. package/dist/tools/definitions/agent-model-notice.d.ts +5 -0
  125. package/dist/tools/definitions/agent-model-notice.js +31 -0
  126. package/dist/tools/definitions/agent-model-notice.js.map +1 -0
  127. package/dist/tools/definitions/agent-models.d.ts +5 -0
  128. package/dist/tools/definitions/agent-models.js +26 -0
  129. package/dist/tools/definitions/agent-models.js.map +1 -0
  130. package/dist/tools/definitions/agent-settings.d.ts +85 -0
  131. package/dist/tools/definitions/agent-settings.js +187 -0
  132. package/dist/tools/definitions/agent-settings.js.map +1 -0
  133. package/dist/tools/definitions/ai-costs.d.ts +12 -0
  134. package/dist/tools/definitions/ai-costs.js +142 -0
  135. package/dist/tools/definitions/ai-costs.js.map +1 -0
  136. package/dist/tools/definitions/api-tool-request.d.ts +15 -0
  137. package/dist/tools/definitions/api-tool-request.js +2 -0
  138. package/dist/tools/definitions/api-tool-request.js.map +1 -0
  139. package/dist/tools/definitions/behavior-shipped-form.d.ts +182 -0
  140. package/dist/tools/definitions/behavior-shipped-form.js +185 -0
  141. package/dist/tools/definitions/behavior-shipped-form.js.map +1 -0
  142. package/dist/tools/definitions/broadcast-alerts.d.ts +6 -0
  143. package/dist/tools/definitions/broadcast-alerts.js +72 -0
  144. package/dist/tools/definitions/broadcast-alerts.js.map +1 -0
  145. package/dist/tools/definitions/broadcast-analytics.d.ts +102 -18
  146. package/dist/tools/definitions/broadcast-analytics.js +732 -431
  147. package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
  148. package/dist/tools/definitions/broadcast-scheduler.d.ts +10 -13
  149. package/dist/tools/definitions/broadcast-scheduler.js +196 -154
  150. package/dist/tools/definitions/broadcast-scheduler.js.map +1 -1
  151. package/dist/tools/definitions/call-operator-task.schema.d.ts +11 -0
  152. package/dist/tools/definitions/call-operator-task.schema.js +30 -0
  153. package/dist/tools/definitions/call-operator-task.schema.js.map +1 -0
  154. package/dist/tools/definitions/contacts.d.ts +3 -0
  155. package/dist/tools/definitions/contacts.js +57 -31
  156. package/dist/tools/definitions/contacts.js.map +1 -1
  157. package/dist/tools/definitions/crm-platform.d.ts +28 -41
  158. package/dist/tools/definitions/crm-platform.js +235 -368
  159. package/dist/tools/definitions/crm-platform.js.map +1 -1
  160. package/dist/tools/definitions/crm-stage-pool.messages.d.ts +39 -0
  161. package/dist/tools/definitions/crm-stage-pool.messages.js +43 -0
  162. package/dist/tools/definitions/crm-stage-pool.messages.js.map +1 -0
  163. package/dist/tools/definitions/crm-stage-pool.schema.d.ts +64 -0
  164. package/dist/tools/definitions/crm-stage-pool.schema.js +109 -0
  165. package/dist/tools/definitions/crm-stage-pool.schema.js.map +1 -0
  166. package/dist/tools/definitions/custom-reports.d.ts +12 -0
  167. package/dist/tools/definitions/custom-reports.js +68 -0
  168. package/dist/tools/definitions/custom-reports.js.map +1 -0
  169. package/dist/tools/definitions/datasource.d.ts +2 -1
  170. package/dist/tools/definitions/datasource.js +28 -13
  171. package/dist/tools/definitions/datasource.js.map +1 -1
  172. package/dist/tools/definitions/dialog-review-findings-response.d.ts +14 -0
  173. package/dist/tools/definitions/dialog-review-findings-response.js +23 -0
  174. package/dist/tools/definitions/dialog-review-findings-response.js.map +1 -0
  175. package/dist/tools/definitions/dialog-review-safe-response.d.ts +5 -0
  176. package/dist/tools/definitions/dialog-review-safe-response.js +152 -0
  177. package/dist/tools/definitions/dialog-review-safe-response.js.map +1 -0
  178. package/dist/tools/definitions/dialog-review.d.ts +49 -0
  179. package/dist/tools/definitions/dialog-review.js +383 -0
  180. package/dist/tools/definitions/dialog-review.js.map +1 -0
  181. package/dist/tools/definitions/dialogue-analysis.d.ts +46 -0
  182. package/dist/tools/definitions/dialogue-analysis.js +170 -0
  183. package/dist/tools/definitions/dialogue-analysis.js.map +1 -0
  184. package/dist/tools/definitions/dialogue-audit-agent-scope.d.ts +7 -0
  185. package/dist/tools/definitions/dialogue-audit-agent-scope.js +41 -0
  186. package/dist/tools/definitions/dialogue-audit-agent-scope.js.map +1 -0
  187. package/dist/tools/definitions/dialogue-audit-alias.d.ts +67 -0
  188. package/dist/tools/definitions/dialogue-audit-alias.js +559 -0
  189. package/dist/tools/definitions/dialogue-audit-alias.js.map +1 -0
  190. package/dist/tools/definitions/dialogue-export.d.ts +7 -1
  191. package/dist/tools/definitions/dialogue-export.js +89 -32
  192. package/dist/tools/definitions/dialogue-export.js.map +1 -1
  193. package/dist/tools/definitions/dialogue-followup-state.d.ts +9 -0
  194. package/dist/tools/definitions/dialogue-followup-state.js +69 -0
  195. package/dist/tools/definitions/dialogue-followup-state.js.map +1 -0
  196. package/dist/tools/definitions/edit-version-transport.test-fixtures.d.ts +13 -0
  197. package/dist/tools/definitions/edit-version-transport.test-fixtures.js +292 -0
  198. package/dist/tools/definitions/edit-version-transport.test-fixtures.js.map +1 -0
  199. package/dist/tools/definitions/edit-version.d.ts +5 -0
  200. package/dist/tools/definitions/edit-version.js +20 -0
  201. package/dist/tools/definitions/edit-version.js.map +1 -0
  202. package/dist/tools/definitions/external-api-channels.js +17 -15
  203. package/dist/tools/definitions/external-api-channels.js.map +1 -1
  204. package/dist/tools/definitions/feedback-document-access.d.ts +16 -0
  205. package/dist/tools/definitions/feedback-document-access.js +63 -0
  206. package/dist/tools/definitions/feedback-document-access.js.map +1 -0
  207. package/dist/tools/definitions/fixtures/shipped-setup-status.d.ts +3 -0
  208. package/dist/tools/definitions/fixtures/shipped-setup-status.js +9 -0
  209. package/dist/tools/definitions/fixtures/shipped-setup-status.js.map +1 -0
  210. package/dist/tools/definitions/follow-up-config.d.ts +79 -0
  211. package/dist/tools/definitions/follow-up-config.js +258 -0
  212. package/dist/tools/definitions/follow-up-config.js.map +1 -0
  213. package/dist/tools/definitions/follow-up-funnel-test.d.ts +4 -3
  214. package/dist/tools/definitions/follow-up-funnel-test.js +65 -52
  215. package/dist/tools/definitions/follow-up-funnel-test.js.map +1 -1
  216. package/dist/tools/definitions/follow-up-promotion-instructions.d.ts +2 -0
  217. package/dist/tools/definitions/follow-up-promotion-instructions.js +7 -0
  218. package/dist/tools/definitions/follow-up-promotion-instructions.js.map +1 -0
  219. package/dist/tools/definitions/follow-up-setup.d.ts +4 -28
  220. package/dist/tools/definitions/follow-up-setup.js +20 -87
  221. package/dist/tools/definitions/follow-up-setup.js.map +1 -1
  222. package/dist/tools/definitions/follow-up.d.ts +20 -122
  223. package/dist/tools/definitions/follow-up.js +200 -357
  224. package/dist/tools/definitions/follow-up.js.map +1 -1
  225. package/dist/tools/definitions/followup-getcourse-compat.d.ts +29 -0
  226. package/dist/tools/definitions/followup-getcourse-compat.js +62 -0
  227. package/dist/tools/definitions/followup-getcourse-compat.js.map +1 -0
  228. package/dist/tools/definitions/followup-sequence-config.schema.d.ts +10 -0
  229. package/dist/tools/definitions/followup-sequence-config.schema.js +14 -0
  230. package/dist/tools/definitions/followup-sequence-config.schema.js.map +1 -0
  231. package/dist/tools/definitions/funnel-analytics.d.ts +18 -0
  232. package/dist/tools/definitions/funnel-analytics.js +150 -0
  233. package/dist/tools/definitions/funnel-analytics.js.map +1 -0
  234. package/dist/tools/definitions/getcourse-anchor-refresh.d.ts +5 -9
  235. package/dist/tools/definitions/getcourse-anchor-refresh.js +26 -31
  236. package/dist/tools/definitions/getcourse-anchor-refresh.js.map +1 -1
  237. package/dist/tools/definitions/getcourse-cold-outbound-settings.d.ts +46 -0
  238. package/dist/tools/definitions/getcourse-cold-outbound-settings.js +37 -0
  239. package/dist/tools/definitions/getcourse-cold-outbound-settings.js.map +1 -0
  240. package/dist/tools/definitions/getcourse-cold-welcome.d.ts +14 -29
  241. package/dist/tools/definitions/getcourse-cold-welcome.js +180 -254
  242. package/dist/tools/definitions/getcourse-cold-welcome.js.map +1 -1
  243. package/dist/tools/definitions/getcourse-wave-welcome.messages.d.ts +10 -0
  244. package/dist/tools/definitions/getcourse-wave-welcome.messages.js +17 -0
  245. package/dist/tools/definitions/getcourse-wave-welcome.messages.js.map +1 -0
  246. package/dist/tools/definitions/help.js.map +1 -1
  247. package/dist/tools/definitions/icp-import-source.d.ts +75 -0
  248. package/dist/tools/definitions/icp-import-source.js +88 -0
  249. package/dist/tools/definitions/icp-import-source.js.map +1 -0
  250. package/dist/tools/definitions/inbound-analytics.d.ts +13 -0
  251. package/dist/tools/definitions/inbound-analytics.js +55 -0
  252. package/dist/tools/definitions/inbound-analytics.js.map +1 -0
  253. package/dist/tools/definitions/instagram-comment.templates.d.ts +19 -0
  254. package/dist/tools/definitions/instagram-comment.templates.js +34 -0
  255. package/dist/tools/definitions/instagram-comment.templates.js.map +1 -0
  256. package/dist/tools/definitions/instagram-settings-compat.d.ts +33 -0
  257. package/dist/tools/definitions/instagram-settings-compat.js +7 -0
  258. package/dist/tools/definitions/instagram-settings-compat.js.map +1 -0
  259. package/dist/tools/definitions/knowledge-chunking.d.ts +42 -0
  260. package/dist/tools/definitions/knowledge-chunking.js +83 -0
  261. package/dist/tools/definitions/knowledge-chunking.js.map +1 -0
  262. package/dist/tools/definitions/knowledge-space-search-fields.d.ts +12 -0
  263. package/dist/tools/definitions/knowledge-space-search-fields.js +30 -0
  264. package/dist/tools/definitions/knowledge-space-search-fields.js.map +1 -0
  265. package/dist/tools/definitions/knowledge.d.ts +24 -14
  266. package/dist/tools/definitions/knowledge.js +342 -233
  267. package/dist/tools/definitions/knowledge.js.map +1 -1
  268. package/dist/tools/definitions/legacy-trigger-repeat.d.ts +17 -0
  269. package/dist/tools/definitions/legacy-trigger-repeat.js +53 -0
  270. package/dist/tools/definitions/legacy-trigger-repeat.js.map +1 -0
  271. package/dist/tools/definitions/link-tracking.d.ts +8 -0
  272. package/dist/tools/definitions/link-tracking.js +141 -38
  273. package/dist/tools/definitions/link-tracking.js.map +1 -1
  274. package/dist/tools/definitions/mailing-variant-content.d.ts +75 -0
  275. package/dist/tools/definitions/mailing-variant-content.js +73 -0
  276. package/dist/tools/definitions/mailing-variant-content.js.map +1 -0
  277. package/dist/tools/definitions/model-comparison.d.ts +1 -0
  278. package/dist/tools/definitions/model-comparison.js +4 -5
  279. package/dist/tools/definitions/model-comparison.js.map +1 -1
  280. package/dist/tools/definitions/money-currency.d.ts +5 -0
  281. package/dist/tools/definitions/money-currency.js +10 -0
  282. package/dist/tools/definitions/money-currency.js.map +1 -0
  283. package/dist/tools/definitions/operator-workflow.d.ts +5 -5
  284. package/dist/tools/definitions/operator-workflow.js +80 -27
  285. package/dist/tools/definitions/operator-workflow.js.map +1 -1
  286. package/dist/tools/definitions/platform-funnel-analytics.d.ts +42 -0
  287. package/dist/tools/definitions/platform-funnel-analytics.js +72 -0
  288. package/dist/tools/definitions/platform-funnel-analytics.js.map +1 -0
  289. package/dist/tools/definitions/platform-getcourse-wave-field-bindings.d.ts +42 -0
  290. package/dist/tools/definitions/platform-getcourse-wave-field-bindings.js +51 -0
  291. package/dist/tools/definitions/platform-getcourse-wave-field-bindings.js.map +1 -0
  292. package/dist/tools/definitions/platform-settings-limits.d.ts +5 -0
  293. package/dist/tools/definitions/platform-settings-limits.js +6 -0
  294. package/dist/tools/definitions/platform-settings-limits.js.map +1 -0
  295. package/dist/tools/definitions/platform-settings-shipped-form.d.ts +37 -0
  296. package/dist/tools/definitions/platform-settings-shipped-form.js +310 -0
  297. package/dist/tools/definitions/platform-settings-shipped-form.js.map +1 -0
  298. package/dist/tools/definitions/platform-settings-update.d.ts +300 -0
  299. package/dist/tools/definitions/platform-settings-update.js +134 -0
  300. package/dist/tools/definitions/platform-settings-update.js.map +1 -0
  301. package/dist/tools/definitions/{getcourse-wave.d.ts → platform-setup-wave.d.ts} +75 -6
  302. package/dist/tools/definitions/platform-setup-wave.js +1079 -0
  303. package/dist/tools/definitions/platform-setup-wave.js.map +1 -0
  304. package/dist/tools/definitions/platform-setup.d.ts +686 -224
  305. package/dist/tools/definitions/platform-setup.js +313 -752
  306. package/dist/tools/definitions/platform-setup.js.map +1 -1
  307. package/dist/tools/definitions/platform-widget-page-rules.schema.d.ts +10 -0
  308. package/dist/tools/definitions/platform-widget-page-rules.schema.js +7 -0
  309. package/dist/tools/definitions/platform-widget-page-rules.schema.js.map +1 -0
  310. package/dist/tools/definitions/prompt-authoring.constants.d.ts +2 -0
  311. package/dist/tools/definitions/prompt-authoring.constants.js +3 -0
  312. package/dist/tools/definitions/prompt-authoring.constants.js.map +1 -0
  313. package/dist/tools/definitions/prompt-batch-controls.d.ts +5 -0
  314. package/dist/tools/definitions/prompt-batch-controls.js +40 -0
  315. package/dist/tools/definitions/prompt-batch-controls.js.map +1 -0
  316. package/dist/tools/definitions/prompt-draft-authoring.d.ts +5 -0
  317. package/dist/tools/definitions/prompt-draft-authoring.js +24 -0
  318. package/dist/tools/definitions/prompt-draft-authoring.js.map +1 -0
  319. package/dist/tools/definitions/prompt-text-projection.d.ts +11 -0
  320. package/dist/tools/definitions/prompt-text-projection.js +62 -0
  321. package/dist/tools/definitions/prompt-text-projection.js.map +1 -0
  322. package/dist/tools/definitions/reviewer-paid.d.ts +19 -0
  323. package/dist/tools/definitions/reviewer-paid.js +115 -0
  324. package/dist/tools/definitions/reviewer-paid.js.map +1 -0
  325. package/dist/tools/definitions/routing-condition-projection.d.ts +31 -0
  326. package/dist/tools/definitions/routing-condition-projection.js +97 -0
  327. package/dist/tools/definitions/routing-condition-projection.js.map +1 -0
  328. package/dist/tools/definitions/schedule-selection-hints.d.ts +3 -0
  329. package/dist/tools/definitions/schedule-selection-hints.js +42 -0
  330. package/dist/tools/definitions/schedule-selection-hints.js.map +1 -0
  331. package/dist/tools/definitions/{scheduled-tasks.d.ts → scheduled-task-alias.d.ts} +12 -10
  332. package/dist/tools/definitions/scheduled-task-alias.js +207 -0
  333. package/dist/tools/definitions/scheduled-task-alias.js.map +1 -0
  334. package/dist/tools/definitions/session.js +3 -3
  335. package/dist/tools/definitions/session.js.map +1 -1
  336. package/dist/tools/definitions/setup-init-operation.schema.d.ts +2 -0
  337. package/dist/tools/definitions/setup-init-operation.schema.js +6 -0
  338. package/dist/tools/definitions/setup-init-operation.schema.js.map +1 -0
  339. package/dist/tools/definitions/shared-input.helpers.d.ts +51 -0
  340. package/dist/tools/definitions/shared-input.helpers.js +323 -0
  341. package/dist/tools/definitions/shared-input.helpers.js.map +1 -0
  342. package/dist/tools/definitions/shared.d.ts +396 -307
  343. package/dist/tools/definitions/shared.js +430 -652
  344. package/dist/tools/definitions/shared.js.map +1 -1
  345. package/dist/tools/definitions/shipped-output-names.d.ts +19 -0
  346. package/dist/tools/definitions/shipped-output-names.js +123 -0
  347. package/dist/tools/definitions/shipped-output-names.js.map +1 -0
  348. package/dist/tools/definitions/task-state.d.ts +5 -5
  349. package/dist/tools/definitions/task-state.js +2 -1
  350. package/dist/tools/definitions/task-state.js.map +1 -1
  351. package/dist/tools/definitions/telegram-personal-capacity.d.ts +4 -0
  352. package/dist/tools/definitions/telegram-personal-capacity.js +18 -0
  353. package/dist/tools/definitions/telegram-personal-capacity.js.map +1 -0
  354. package/dist/tools/definitions/telegram-pool-policy.d.ts +8 -0
  355. package/dist/tools/definitions/telegram-pool-policy.js +56 -0
  356. package/dist/tools/definitions/telegram-pool-policy.js.map +1 -0
  357. package/dist/tools/definitions/touch-history-alias.d.ts +4 -0
  358. package/dist/tools/definitions/touch-history-alias.js +99 -0
  359. package/dist/tools/definitions/touch-history-alias.js.map +1 -0
  360. package/dist/tools/definitions/trigger-action-item.schema.d.ts +254 -0
  361. package/dist/tools/definitions/trigger-action-item.schema.js +121 -0
  362. package/dist/tools/definitions/trigger-action-item.schema.js.map +1 -0
  363. package/dist/tools/definitions/trigger-argument.schema.d.ts +14 -0
  364. package/dist/tools/definitions/trigger-argument.schema.js +23 -0
  365. package/dist/tools/definitions/trigger-argument.schema.js.map +1 -0
  366. package/dist/tools/definitions/trigger-claim-alias.d.ts +10 -0
  367. package/dist/tools/definitions/trigger-claim-alias.js +90 -0
  368. package/dist/tools/definitions/trigger-claim-alias.js.map +1 -0
  369. package/dist/tools/definitions/trigger-echo-projection.d.ts +1 -0
  370. package/dist/tools/definitions/trigger-echo-projection.js +41 -0
  371. package/dist/tools/definitions/trigger-echo-projection.js.map +1 -0
  372. package/dist/tools/definitions/trigger-upsert.tool.d.ts +29 -0
  373. package/dist/tools/definitions/trigger-upsert.tool.js +122 -0
  374. package/dist/tools/definitions/trigger-upsert.tool.js.map +1 -0
  375. package/dist/tools/definitions/v15-port-descriptions.d.ts +11 -0
  376. package/dist/tools/definitions/v15-port-descriptions.js +30 -0
  377. package/dist/tools/definitions/v15-port-descriptions.js.map +1 -0
  378. package/dist/tools/definitions/variables.d.ts +44 -0
  379. package/dist/tools/definitions/variables.js +310 -0
  380. package/dist/tools/definitions/variables.js.map +1 -0
  381. package/dist/tools/definitions/voice-action-input.d.ts +9 -0
  382. package/dist/tools/definitions/voice-action-input.js +141 -0
  383. package/dist/tools/definitions/voice-action-input.js.map +1 -0
  384. package/dist/tools/definitions/widget-customization-compat.d.ts +51 -0
  385. package/dist/tools/definitions/widget-customization-compat.js +23 -0
  386. package/dist/tools/definitions/widget-customization-compat.js.map +1 -0
  387. package/dist/tools/definitions.d.ts +1089 -636
  388. package/dist/tools/definitions.js +57 -27
  389. package/dist/tools/definitions.js.map +1 -1
  390. package/dist/tools/description-localization.js +3 -2
  391. package/dist/tools/description-localization.js.map +1 -1
  392. package/dist/tools/follow-up-request.d.ts +19 -0
  393. package/dist/tools/follow-up-request.js +81 -0
  394. package/dist/tools/follow-up-request.js.map +1 -0
  395. package/dist/tools/followup-revision.d.ts +4 -0
  396. package/dist/tools/followup-revision.js +29 -0
  397. package/dist/tools/followup-revision.js.map +1 -0
  398. package/dist/tools/incomplete-list.js +4 -0
  399. package/dist/tools/incomplete-list.js.map +1 -1
  400. package/dist/tools/inventory.js +47 -11
  401. package/dist/tools/inventory.js.map +1 -1
  402. package/dist/tools/operation-recovery.d.ts +4 -0
  403. package/dist/tools/operation-recovery.js +33 -0
  404. package/dist/tools/operation-recovery.js.map +1 -0
  405. package/dist/tools/registry-mapping-primary.cases.d.ts +2 -0
  406. package/dist/tools/registry-mapping-primary.cases.js +753 -0
  407. package/dist/tools/registry-mapping-primary.cases.js.map +1 -0
  408. package/dist/tools/registry-mapping-secondary.cases.d.ts +2 -0
  409. package/dist/tools/registry-mapping-secondary.cases.js +626 -0
  410. package/dist/tools/registry-mapping-secondary.cases.js.map +1 -0
  411. package/dist/tools/registry-mapping.cases.d.ts +8 -0
  412. package/dist/tools/registry-mapping.cases.js +13 -0
  413. package/dist/tools/registry-mapping.cases.js.map +1 -0
  414. package/dist/tools/registry-test-fixtures.d.ts +50 -0
  415. package/dist/tools/registry-test-fixtures.js +120 -0
  416. package/dist/tools/registry-test-fixtures.js.map +1 -0
  417. package/dist/tools/registry.d.ts +2 -0
  418. package/dist/tools/registry.js +82 -52
  419. package/dist/tools/registry.js.map +1 -1
  420. package/dist/tools/result.d.ts +1 -0
  421. package/dist/tools/result.js +90 -22
  422. package/dist/tools/result.js.map +1 -1
  423. package/dist/tools/toolsets.d.ts +16 -0
  424. package/dist/tools/toolsets.js +25 -1
  425. package/dist/tools/toolsets.js.map +1 -1
  426. package/dist/types/api-contract.gen.d.ts +105875 -22205
  427. package/dist/utils/credential-signatures.d.ts +3 -0
  428. package/dist/utils/credential-signatures.js +10 -0
  429. package/dist/utils/credential-signatures.js.map +1 -0
  430. package/dist/utils/data-source-column-name.d.ts +10 -0
  431. package/dist/utils/data-source-column-name.js +36 -0
  432. package/dist/utils/data-source-column-name.js.map +1 -0
  433. package/dist/utils/logger.d.ts +1 -0
  434. package/dist/utils/logger.js +32 -8
  435. package/dist/utils/logger.js.map +1 -1
  436. package/dist/utils/secret-read-boundary.d.ts +2 -0
  437. package/dist/utils/secret-read-boundary.js +88 -0
  438. package/dist/utils/secret-read-boundary.js.map +1 -0
  439. package/dist/utils/setup-secrets.d.ts +4 -0
  440. package/dist/utils/setup-secrets.js +40 -0
  441. package/dist/utils/setup-secrets.js.map +1 -0
  442. package/docs/agent-models.md +9 -0
  443. package/docs/agent-usage-guide.full.ru.md +1 -4
  444. package/docs/analytics-contract.md +67 -0
  445. package/docs/async-operation-lifecycle.md +10 -3
  446. package/docs/connect.ru.md +144 -4
  447. package/docs/contact-company-profile.md +17 -0
  448. package/docs/contact-recommendations.md +7 -0
  449. package/docs/crm-stage-pool.md +73 -0
  450. package/docs/customer-data.md +61 -0
  451. package/docs/edit-versions.md +36 -0
  452. package/docs/failure-semantics.md +17 -9
  453. package/docs/help-navigation.md +15 -42
  454. package/docs/host-compatibility-matrix.md +72 -93
  455. package/docs/host-setup.md +33 -35
  456. package/docs/invariants/public-api-and-contracts.md +16 -0
  457. package/docs/legacy-action-settings.md +21 -0
  458. package/docs/main-transfer-dependencies.md +38 -0
  459. package/docs/mcp2-parity.md +50 -0
  460. package/docs/modules/analytics.md +79 -0
  461. package/docs/modules/besales-mcp.md +137 -0
  462. package/docs/modules/dialog-review-report.md +38 -0
  463. package/docs/modules/dialogue-followup-adapters.md +39 -0
  464. package/docs/modules/message-reactions.md +17 -0
  465. package/docs/modules/network-mode.md +284 -0
  466. package/docs/modules/prompt-batch-and-dialogue-controls.md +69 -0
  467. package/docs/pii-policy.md +21 -16
  468. package/docs/response-size-budget.md +197 -7
  469. package/docs/secret-read-boundary.md +102 -0
  470. package/docs/task-state.md +7 -2
  471. package/docs/telegram-pool-policy.md +19 -0
  472. package/docs/tool-effects.md +15 -9
  473. package/docs/tool-surface.md +205 -4
  474. package/docs/voice-actions-and-inbox.md +95 -0
  475. package/docs/wazzup-instagram-comments.md +26 -0
  476. package/package.json +17 -10
  477. package/scripts/api-source-loader.spec.mjs +40 -0
  478. package/scripts/audit-bridge-controls.mjs +129 -0
  479. package/scripts/audit-revert-mutants.mjs +107 -0
  480. package/scripts/bridge-api-input.spec.mjs +98 -0
  481. package/scripts/bridge-controls-mutants.mjs +130 -0
  482. package/scripts/brx3-shipped-refusals.spec.mjs +149 -0
  483. package/scripts/brx4-ledger-payload.spec.mjs +127 -0
  484. package/scripts/build-onprem.mjs +108 -0
  485. package/scripts/connect-clients.sh +141 -0
  486. package/scripts/connect-scopes.mjs +166 -0
  487. package/scripts/connect-scopes.spec.mjs +83 -0
  488. package/scripts/emit-personal-link-carrier.mjs +31 -0
  489. package/scripts/emit-setup-init-schemas.mjs +24 -0
  490. package/scripts/emit-tool-routes.mjs +878 -0
  491. package/scripts/emit-tool-routes.spec.mjs +300 -0
  492. package/scripts/followup-registry.spec.mjs +107 -0
  493. package/scripts/generate-crm-rotation-contract.mjs +98 -0
  494. package/scripts/generate-followup-session-contract.mjs +16 -0
  495. package/scripts/icp-import-verification/mutate.cjs +70 -0
  496. package/scripts/import-secret-read-contract.mjs +53 -0
  497. package/scripts/install-claude-desktop.js +1 -1
  498. package/scripts/lag-decisions.mjs +37 -0
  499. package/scripts/lag-decisions.spec.mjs +87 -0
  500. package/scripts/lag-open-task-owners.mjs +46 -0
  501. package/scripts/lag-open-task-owners.spec.mjs +78 -0
  502. package/scripts/lag-payload.mjs +10 -0
  503. package/scripts/legacy-action-lag.spec.mjs +22 -0
  504. package/scripts/legacy-field-refusal.shipped.spec.mjs +99 -0
  505. package/scripts/mcpcompat-handler.mjs +34 -0
  506. package/scripts/mcpcompat-loader.mjs +36 -0
  507. package/scripts/mcpcompat-typescript.mjs +3 -0
  508. package/scripts/platform-settings-shipped-parity.spec.mjs +89 -0
  509. package/scripts/prbr-round1-recheck.spec.mjs +605 -0
  510. package/scripts/prbr-shipped-compatibility.spec.mjs +276 -0
  511. package/scripts/publish-mcp-registry.mjs +98 -0
  512. package/scripts/publish-mcp-registry.spec.mjs +68 -0
  513. package/scripts/record-scheduled-task-call.mjs +26 -0
  514. package/scripts/refusal-probe.mjs +17 -0
  515. package/scripts/refusal-probe.spec.mjs +29 -0
  516. package/scripts/registry-diff.mjs +502 -0
  517. package/scripts/registry-diff.spec.mjs +787 -0
  518. package/scripts/request-query.mjs +43 -0
  519. package/scripts/request-query.spec.mjs +82 -0
  520. package/scripts/route-lag.mjs +23 -0
  521. package/scripts/route-lag.spec.mjs +30 -0
  522. package/scripts/sample-args.mjs +174 -0
  523. package/scripts/sample-args.spec.mjs +160 -0
  524. package/scripts/shipped-definitions.mjs +197 -0
  525. package/scripts/shipped-definitions.spec.mjs +57 -0
  526. package/scripts/shipped-inputs.spec.mjs +136 -0
  527. package/scripts/shipped-recordings.spec.mjs +19 -0
  528. package/scripts/shipped-ref.d.mts +5 -0
  529. package/scripts/shipped-ref.mjs +20 -0
  530. package/scripts/shipped-ref.spec.mjs +59 -0
  531. package/scripts/shipped-registry.mjs +107 -0
  532. package/scripts/shipped-sample-candidates.mjs +69 -0
  533. package/scripts/shipped-sample-candidates.spec.mjs +117 -0
  534. package/scripts/shipped-sample.mjs +868 -0
  535. package/scripts/shipped-sample.spec.mjs +451 -0
  536. package/scripts/sync-agent-model-schemas.mjs +72 -0
  537. package/scripts/sync-api-contracts.mjs +85 -0
  538. package/scripts/sync-api-contracts.spec.mjs +144 -0
  539. package/scripts/sync-contract-ledger-schemas.mjs +161 -0
  540. package/scripts/sync-crm-stage-pool-schema.mjs +85 -0
  541. package/scripts/sync-prompt-draft-schema.mjs +92 -0
  542. package/scripts/sync-route-map.mjs +94 -0
  543. package/scripts/sync-schema-descriptions.mjs +25 -0
  544. package/scripts/sync-tool-inventory.mjs +27 -0
  545. package/scripts/sync-trigger-argument-schema.mjs +121 -0
  546. package/scripts/sync-trigger-repeat-mapping.mjs +12 -0
  547. package/scripts/sync-voice-actions-contract.mjs +67 -0
  548. package/scripts/sync-voice-actions-tools.mjs +97 -0
  549. package/scripts/sync-wave-id-schemas.mjs +55 -0
  550. package/scripts/tool-input-schemas.mjs +46 -0
  551. package/scripts/tool-input-schemas.spec.mjs +50 -0
  552. package/scripts/verify-followup-adapters.mjs +235 -0
  553. package/scripts/verify-secret-read-import.mjs +84 -0
  554. package/scripts/verify-secret-read-mutants.mjs +143 -0
  555. package/dist/tools/definitions/analytics.d.ts +0 -40
  556. package/dist/tools/definitions/analytics.js +0 -233
  557. package/dist/tools/definitions/analytics.js.map +0 -1
  558. package/dist/tools/definitions/broadcast-mailing-variants.d.ts +0 -41
  559. package/dist/tools/definitions/broadcast-mailing-variants.js +0 -194
  560. package/dist/tools/definitions/broadcast-mailing-variants.js.map +0 -1
  561. package/dist/tools/definitions/dialogue-audit.d.ts +0 -38
  562. package/dist/tools/definitions/dialogue-audit.js +0 -292
  563. package/dist/tools/definitions/dialogue-audit.js.map +0 -1
  564. package/dist/tools/definitions/getcourse-wave.js +0 -519
  565. package/dist/tools/definitions/getcourse-wave.js.map +0 -1
  566. package/dist/tools/definitions/operational-overview.d.ts +0 -3
  567. package/dist/tools/definitions/operational-overview.js +0 -23
  568. package/dist/tools/definitions/operational-overview.js.map +0 -1
  569. package/dist/tools/definitions/scheduled-tasks.js +0 -173
  570. package/dist/tools/definitions/scheduled-tasks.js.map +0 -1
  571. package/dist/tools/definitions/trigger-contact-claims.d.ts +0 -7
  572. package/dist/tools/definitions/trigger-contact-claims.js +0 -60
  573. package/dist/tools/definitions/trigger-contact-claims.js.map +0 -1
  574. package/dist/tools/registry-mapping-cases-core.d.ts +0 -38
  575. package/dist/tools/registry-mapping-cases-core.js +0 -963
  576. package/dist/tools/registry-mapping-cases-core.js.map +0 -1
  577. package/dist/tools/registry-mapping-cases-platform.d.ts +0 -2
  578. package/dist/tools/registry-mapping-cases-platform.js +0 -1052
  579. package/dist/tools/registry-mapping-cases-platform.js.map +0 -1
  580. package/dist/tools/trigger-action-config.d.ts +0 -49
  581. package/dist/tools/trigger-action-config.js +0 -171
  582. package/dist/tools/trigger-action-config.js.map +0 -1
  583. package/docs/evals/model-behavior-scorecard.md +0 -80
  584. package/docs/operation-coverage.md +0 -114
  585. package/scripts/mock-credentials.js +0 -77
  586. package/scripts/model-eval-server.js +0 -213
  587. package/scripts/run-model-eval.js +0 -447
@@ -1,6 +1,29 @@
1
+ import { icpImportSourceSchema, legacyIcpImportConfigSchema } from './icp-import-source.js';
1
2
  import { z } from 'zod';
2
- import { analysisModeSchema, anyObjectSchema, buildListQuery, compactMetadata, compactObject, defineTool, generatedScenarioSchema, icpAnalysisPersonaSchema, icpAnalysisSegmentSchema, optionalAnyObjectSchema, outcomeSchema, promptAnalysisStageOutputSchema, promptGenerationStageOutputSchema, sandboxFindingSchema, simulationFindingSchema, uuidSchema, withInstructions, } from './shared.js';
3
+ import { assertCompleteList } from '../incomplete-list.js';
4
+ import { PROMPT_LANGUAGE_CODE_MAX_LENGTH } from './prompt-authoring.constants.js';
5
+ import { ICP_SCENARIOS_MAX_PAGE_SIZE, analysisModeSchema, anyObjectSchema, buildListQuery, compactMetadata, compactObject, defineTool, generatedScenarioSchema, icpAnalysisPersonaSchema, icpAnalysisSegmentSchema, knowledgeSpaceIdSchema, optionalAnyObjectSchema, outcomeSchema, promptAnalysisStageOutputSchema, promptGenerationStageOutputSchema, sandboxFindingSchema, simulationFindingSchema, uuidSchema, withInstructions, } from './shared.js';
3
6
  const SANDBOX_TERMINAL_STATUSES = new Set(['COMPLETED', 'FAILED', 'CANCELLED']);
7
+ const ICP_CONTINUATION_INSTRUCTIONS = 'continuationState: AVAILABLE — остаток можно продолжить; FORWARDED — уже создан следующий прогон; EXPIRED — остаток устарел; NONE — продолжения нет. remainderExpiredAt — момент удаления старого остатка уборкой, null — уборка ещё не удаляла строки. ICP_INGEST_CONTINUATION_EXPIRED (409): остаток выборки устарел — начните новый импорт. Не повторяй продолжение автоматически; новый импорт запускай по решению человека с новым request_key и gdpr_confirmed=true.';
8
+ const AUDIO_DATE_FIELDS = {
9
+ bitrix_openlines: { startDate: 'createdFrom', endDate: 'createdTo' },
10
+ onlinepbx_direct: { startDate: 'startedFrom', endDate: 'startedTo' },
11
+ };
12
+ function audioSourceConfig(sourceType, config) {
13
+ if (config === undefined)
14
+ return undefined;
15
+ const fields = AUDIO_DATE_FIELDS[sourceType ?? ''];
16
+ if (fields === undefined)
17
+ return config;
18
+ const result = { ...config };
19
+ for (const [oldName, newName] of Object.entries(fields)) {
20
+ if (Object.hasOwn(result, oldName)) {
21
+ result[newName] = result[oldName];
22
+ delete result[oldName];
23
+ }
24
+ }
25
+ return result;
26
+ }
4
27
  function enhanceSandboxStatus(response) {
5
28
  if (!response || typeof response !== 'object' || Array.isArray(response)) {
6
29
  return response;
@@ -35,9 +58,7 @@ export const agentDesignTools = [
35
58
  workspace_id: uuidSchema.optional(),
36
59
  name: z.string(),
37
60
  description: z.string().optional(),
38
- source: z
39
- .enum(['from_dialogues', 'from_files', 'from_scratch'])
40
- .default('from_scratch'),
61
+ source: z.enum(['from_dialogues', 'from_files', 'from_scratch']).default('from_scratch'),
41
62
  }),
42
63
  createRequest: (input) => ({
43
64
  path: `/workspaces/${input.workspace_id}/icp`,
@@ -51,102 +72,192 @@ export const agentDesignTools = [
51
72
  defineTool({
52
73
  name: 'besales_icp_import_dialogues',
53
74
  // Имя проверки из имени операции не выводится: суффиксы не парные.
54
- verifyWithToolName: 'besales_icp_import_status',
75
+ verifyWithToolName: 'besales_icp_import_start_result',
55
76
  sideEffect: 'spend',
56
- requiredFields: ['icp_id'],
77
+ requiredFields: ['icp_id', 'request_key', 'gdpr_confirmed'],
78
+ /** Канонический источник и обе прежние формы используют один keyed-приём. */
57
79
  schema: z
58
80
  .object({
59
81
  icp_id: uuidSchema,
60
- /**
61
- * mode='text' (default) — импорт сохранённых текстовых диалогов из CRM history.
62
- * mode='audio' — batch audio path через transcription-service: тянем call recordings
63
- * из источника (amocrm_leads / xlsx_upload / onlinepbx_direct), прогоняем через
64
- * Yandex SpeechKit STT, создаём IcpDialogueSample из транскрипта.
65
- */
82
+ request_key: uuidSchema,
83
+ source: icpImportSourceSchema.optional(),
66
84
  mode: z.enum(['text', 'audio']).default('text'),
67
- // --- Text mode (legacy CRM history) ---
68
85
  crm_connection_id: uuidSchema.optional(),
69
- outcome_filter: z.array(outcomeSchema).default(['won', 'lost']),
70
- days_ago: z.number().int().min(1).max(730).default(180),
71
- anonymize: z.boolean().default(true),
72
- gdpr_confirmed: z.boolean().optional(),
73
- // --- Audio mode (Phase 4 + Track B onlinePBX) ---
86
+ outcome_filter: z.array(outcomeSchema).min(1).optional(),
87
+ days_ago: z.number().int().min(1).max(730).optional(),
88
+ gdpr_confirmed: z.literal(true),
89
+ anonymize: z.literal(true).optional(),
74
90
  audio_source_type: z
75
- .enum(['amocrm_leads', 'xlsx_upload', 'onlinepbx_direct', 'bitrix_openlines'])
91
+ .enum([
92
+ 'bitrix_open_lines',
93
+ 'amocrm_calls',
94
+ 'onlinepbx_calls',
95
+ 'xlsx_upload',
96
+ 'bitrix_openlines',
97
+ 'amocrm_leads',
98
+ 'onlinepbx_direct',
99
+ ])
76
100
  .optional(),
101
+ audio_source_config: legacyIcpImportConfigSchema.optional(),
102
+ continuation_run_id: z.string().uuid().optional(),
77
103
  /**
78
- * Конфиг источника аудио — shape зависит от audio_source_type:
79
- * - amocrm_leads: { crmConnectionId, leadIds[], defaultOutcome? }
80
- * - xlsx_upload: { storedFileId, crmConnectionId } (xlsx загрузи через POST /v2/files)
81
- * - onlinepbx_direct: { startDate, endDate, minDurationSec?=60, direction?='all',
82
- * matchToCrm?=true, crmConnectionId?, defaultOutcome?='unknown',
83
- * dryRun?=false, trunkId? } — звонки из onlinePBX за период,
84
- * опц. матчинг к AmoCRM по телефону → outcome. dryRun=true →
85
- * только подсчёт (status=DRY_RUN, totalRefs=count) без запуска STT.
86
- * - bitrix_openlines: { crmConnectionId, startDate, endDate, categoryId?, dryRun? } —
87
- * ТЕКСТОВЫЕ диалоги из Bitrix open-lines (сделки за период), без STT.
88
- * NB: xlsx_drive (Google Drive) НЕ поддерживается бэкендом (MVP) — backend → 400.
104
+ * Язык распознавания записей звонков этой ветки.
105
+ *
106
+ * Набор ЗАКРЫТЫЙ и совпадает с набором сателлита распознавания — тем же, что у
107
+ * отгруженного контракта. Не задан — определение по звуку. Сервер отвергает значение вне
108
+ * набора: сателлит привёл бы незнакомое к автоопределению молча, и опечатка выглядела бы
109
+ * как принятая настройка.
89
110
  */
90
- audio_source_config: optionalAnyObjectSchema,
91
111
  language: z.enum(['ru-RU', 'uz-UZ', 'kk-KZ', 'auto']).optional(),
92
112
  })
93
113
  .superRefine((value, ctx) => {
114
+ if (value.source !== undefined) {
115
+ if (value.audio_source_type !== undefined ||
116
+ value.audio_source_config !== undefined ||
117
+ value.crm_connection_id !== undefined ||
118
+ value.outcome_filter !== undefined ||
119
+ value.days_ago !== undefined)
120
+ ctx.addIssue({
121
+ code: z.ZodIssueCode.custom,
122
+ path: ['source'],
123
+ message: 'Выбери одну форму источника',
124
+ });
125
+ return;
126
+ }
94
127
  if (value.mode === 'audio') {
95
- if (!value.audio_source_type || !value.audio_source_config) {
128
+ const config = value.audio_source_config;
129
+ const fields = AUDIO_DATE_FIELDS[value.audio_source_type ?? ''];
130
+ if (config !== undefined && fields !== undefined) {
131
+ for (const [oldName, newName] of Object.entries(fields)) {
132
+ if (Object.hasOwn(config, oldName) && Object.hasOwn(config, newName)) {
133
+ ctx.addIssue({
134
+ code: z.ZodIssueCode.custom,
135
+ path: ['audio_source_config', oldName],
136
+ message: `Пришли оба имени audio_source_config.${oldName} и audio_source_config.${newName}: оставьте одно`,
137
+ });
138
+ }
139
+ }
140
+ }
141
+ if (value.audio_source_type === undefined) {
96
142
  ctx.addIssue({
97
143
  code: z.ZodIssueCode.custom,
98
- message: 'audio_source_type и audio_source_config обязательны при mode=audio',
144
+ message: 'audio_source_type обязателен при mode=audio',
99
145
  path: ['audio_source_type'],
100
146
  });
101
147
  }
102
- }
103
- else {
104
- if (!value.crm_connection_id || value.gdpr_confirmed !== true) {
148
+ if (value.audio_source_config === undefined) {
105
149
  ctx.addIssue({
106
150
  code: z.ZodIssueCode.custom,
107
- message: 'crm_connection_id и gdpr_confirmed обязательны при mode=text',
108
- path: ['crm_connection_id'],
151
+ message: 'audio_source_config обязателен при mode=audio',
152
+ path: ['audio_source_config'],
109
153
  });
110
154
  }
111
- }
112
- }),
113
- createRequest: (input) => {
114
- if (input.mode === 'audio') {
115
- return {
116
- method: 'POST',
117
- path: `/icp/audio-import-runs`,
118
- body: compactObject({
119
- icpProfileId: input.icp_id,
120
- sourceType: input.audio_source_type,
121
- sourceConfig: input.audio_source_config,
122
- language: input.language,
123
- }),
155
+ const normalized = {
156
+ ...audioSourceConfig(value.audio_source_type, value.audio_source_config),
157
+ kind: {
158
+ bitrix_openlines: 'bitrix_open_lines',
159
+ amocrm_leads: 'amocrm_calls',
160
+ onlinepbx_direct: 'onlinepbx_calls',
161
+ }[value.audio_source_type ?? ''] ?? value.audio_source_type,
124
162
  };
163
+ const parsed = icpImportSourceSchema.safeParse(normalized);
164
+ if (!parsed.success)
165
+ ctx.addIssue({
166
+ code: z.ZodIssueCode.custom,
167
+ path: ['audio_source_config'],
168
+ message: 'Неверный отбор источника',
169
+ });
170
+ return;
125
171
  }
126
- return {
127
- path: `/icp/${input.icp_id}/samples/import-from-crm`,
128
- body: {
129
- crmConnectionId: input.crm_connection_id,
130
- outcomeFilter: input.outcome_filter,
131
- ageFilter: { daysAgo: input.days_ago },
132
- anonymize: input.anonymize,
133
- gdprConfirmed: input.gdpr_confirmed,
134
- },
135
- };
136
- },
137
- enhanceResponse: (response, input) => {
138
- if (input.mode === 'audio') {
139
- return withInstructions(response, [
140
- 'Audio import — асинхронный. Получи runId из response.',
141
- 'onlinepbx_direct + dryRun=true → response.status=DRY_RUN, totalRefs=число звонков ' +
142
- 'после фильтра (Run НЕ создан). Подтверди объём и повтори с dryRun=false для импорта.',
143
- 'Опрашивай статус через besales_icp_import_status каждые 30-60 сек.',
144
- 'Терминальные статусы: COMPLETED, PARTIAL, FAILED.',
145
- 'При PARTIAL — часть items expired/failed, но успешные диалоги уже в IcpDialogueSample.',
146
- ]);
172
+ if (value.crm_connection_id === undefined) {
173
+ ctx.addIssue({
174
+ code: z.ZodIssueCode.custom,
175
+ message: 'crm_connection_id обязателен при mode=text',
176
+ path: ['crm_connection_id'],
177
+ });
147
178
  }
148
- return response;
149
- },
179
+ if (value.gdpr_confirmed !== true) {
180
+ ctx.addIssue({
181
+ code: z.ZodIssueCode.custom,
182
+ message: 'gdpr_confirmed должен быть true для импорта диалогов',
183
+ path: ['gdpr_confirmed'],
184
+ });
185
+ }
186
+ }),
187
+ createRequest: (input) => ({
188
+ path: '/icp/' + input.icp_id + '/import-runs',
189
+ body: compactObject({
190
+ requestKey: input.request_key,
191
+ gdprConfirmed: input.gdpr_confirmed,
192
+ source: input.source ??
193
+ (input.mode === 'audio'
194
+ ? {
195
+ ...audioSourceConfig(input.audio_source_type, input.audio_source_config),
196
+ kind: {
197
+ bitrix_openlines: 'bitrix_open_lines',
198
+ amocrm_leads: 'amocrm_calls',
199
+ onlinepbx_direct: 'onlinepbx_calls',
200
+ }[input.audio_source_type ?? ''] ?? input.audio_source_type,
201
+ }
202
+ : {
203
+ kind: 'stored_crm_dialogues',
204
+ crmConnectionId: input.crm_connection_id,
205
+ outcomeFilter: input.outcome_filter,
206
+ daysAgo: input.days_ago,
207
+ }),
208
+ transcriptionLanguage: input.language,
209
+ continuationRunId: input.continuation_run_id,
210
+ }),
211
+ }),
212
+ enhanceResponse: (response, input) => (input.source === undefined
213
+ ? input.mode === 'audio'
214
+ : input.source.kind !== 'stored_crm_dialogues')
215
+ ? withInstructions(response, [
216
+ ICP_CONTINUATION_INSTRUCTIONS,
217
+ 'При потерянном ответе вызови besales_icp_import_start_result с теми же icp_id/request_key. NOT_FOUND_UNKNOWN не доказывает отказ: повтори исходное намерение с тем же ключом. Ингест асинхронный: перечисление диалогов прошло, содержимое каждого добывается в фоне. Возьми runId из ответа и опрашивай besales_icp_import_status раз в 30-60 сек.',
218
+ 'Неизвестный род источника сервер отвергает, перечисляя построенные в поле availableSourceTypes ответа. Это и есть авторитетный список — угадывать по описанию не нужно.',
219
+ 'sourceCoverage=null означает: полнота источника не измерялась. sourceCoverage.complete=false означает ограничение источника; собственный предел прогона отдельно указан в truncated.',
220
+ 'WINDOW: источник прочитан по coveredTo; следующий запуск начни с этой границы, сохранив requestedTo. PAGES: received из declaredTotal (null — число неизвестно); coveredFrom — самая старая прочитанная дата, информационная граница.',
221
+ 'Bitrix24: при truncated=true передай continuation_run_id из continuationRunId запуска или статуса с прежними настройками: добери сохранённый остаток выборки независимо от пропусков и отказов первых 500. Для продолжения нужны новый request_key и true. Если ответ потерян, повтори те же request_key и continuation_run_id: получишь созданный прогон и восстановишь его задания. Для следующей порции используй курсор ответа продолжения. Повтор ошибок запускается отдельно без continuation_run_id. Затем продолжай с audio_source_config.continuationStart из ограничения PAGES, сохранив прежние даты и категорию; createdTo=coveredFrom не гарантирует добор сделок с одинаковой датой. Если список портала изменился между запусками, повтори исходное окно и проверь покрытие.',
222
+ 'headTruncatedCount — число импортированных диалогов с обрезанным началом; null означает, что это не измерялось. ICP_INGEST_SOURCE_RESPONSE_UNREADABLE означает неизвестную форму ответа источника: повтор без исправления источника не поможет.',
223
+ 'Диалог без опознанного человека не импортируется: образец корпуса стирается через контакт, и без контакта стирать было бы нечем.',
224
+ 'Язык распознавания задаётся полем language (ru-RU / uz-UZ / kk-KZ / auto) и применяется ко всему прогону. Не задан — определение по звуку; для узбекских звонков задавать стоит явно.',
225
+ ])
226
+ : withInstructions(response, [
227
+ ICP_CONTINUATION_INSTRUCTIONS,
228
+ 'При потерянном ответе вызови besales_icp_import_start_result с теми же icp_id/request_key. NOT_FOUND_UNKNOWN не доказывает отказ: повтори исходное намерение с тем же ключом.',
229
+ 'mode=text требует request_key, crm_connection_id и gdpr_confirmed=true; импортируются сохранённые текстовые диалоги CRM.',
230
+ 'Обезличивание обязательно. Для каждой новой работы нужны новый request_key UUID и явный gdpr_confirmed=true; повтор ключа возвращает прежний run.',
231
+ ]),
232
+ }),
233
+ defineTool({
234
+ name: 'besales_icp_import_start_result',
235
+ sideEffect: 'none',
236
+ requiredFields: ['icp_id', 'request_key'],
237
+ schema: z.object({ icp_id: uuidSchema, request_key: uuidSchema }),
238
+ createRequest: (input) => ({
239
+ path: '/icp/' + input.icp_id + '/import-runs/start-result',
240
+ body: { requestKey: input.request_key },
241
+ }),
242
+ enhanceResponse: (response) => withInstructions(response, [ICP_CONTINUATION_INSTRUCTIONS]),
243
+ }),
244
+ defineTool({
245
+ name: 'besales_icp_import_history',
246
+ sideEffect: 'none',
247
+ requiredFields: ['icp_id'],
248
+ schema: z.object({
249
+ icp_id: uuidSchema,
250
+ cursor: z.string().max(512).optional(),
251
+ limit: z.number().int().min(1).max(100).optional(),
252
+ }),
253
+ createRequest: (input) => ({
254
+ method: 'GET',
255
+ path: '/icp/' +
256
+ input.icp_id +
257
+ '/import-runs' +
258
+ buildListQuery({ cursor: input.cursor, limit: input.limit }),
259
+ }),
260
+ enhanceResponse: (response) => withInstructions(response, [ICP_CONTINUATION_INSTRUCTIONS]),
150
261
  }),
151
262
  defineTool({
152
263
  name: 'besales_icp_import_status',
@@ -159,6 +270,13 @@ export const agentDesignTools = [
159
270
  method: 'GET',
160
271
  path: `/icp/audio-import-runs/${input.run_id}`,
161
272
  }),
273
+ enhanceResponse: (response) => withInstructions(response, [
274
+ ICP_CONTINUATION_INSTRUCTIONS,
275
+ 'sourceCoverage=null означает: полнота источника не измерялась. sourceCoverage.complete=false означает ограничение источника; собственный предел прогона отдельно указан в truncated.',
276
+ 'WINDOW: источник прочитан по coveredTo; следующий запуск начни с этой границы, сохранив requestedTo. PAGES: received из declaredTotal (null — число неизвестно); coveredFrom — самая старая прочитанная дата, информационная граница.',
277
+ 'Bitrix24: при truncated=true передай continuation_run_id из continuationRunId запуска или статуса с прежними настройками: добери сохранённый остаток выборки независимо от пропусков и отказов первых 500. Если ответ продолжения потерян или очередь отказала, повтори прежний continuation_run_id: получишь созданный прогон и восстановишь его задания. Для следующей порции используй курсор ответа продолжения. Повтор ошибок запускается отдельно без continuation_run_id. Затем продолжай с audio_source_config.continuationStart из ограничения PAGES, сохранив прежние даты и категорию; createdTo=coveredFrom не гарантирует добор сделок с одинаковой датой. Если список портала изменился между запусками, повтори исходное окно и проверь покрытие.',
278
+ 'headTruncatedCount — число импортированных диалогов с обрезанным началом; null означает, что это не измерялось. ICP_INGEST_SOURCE_RESPONSE_UNREADABLE означает неизвестную форму ответа источника: повтор без исправления источника не поможет.',
279
+ ]),
162
280
  }),
163
281
  defineTool({
164
282
  name: 'besales_icp_analysis_get_instructions',
@@ -261,14 +379,29 @@ export const agentDesignTools = [
261
379
  requiredFields: ['icp_id'],
262
380
  schema: z.object({
263
381
  icp_id: uuidSchema,
382
+ // ⚠️ Без умолчания: раньше отказ по размеру был отказом БЕЗ ВЫХОДА — сузить набор было
383
+ // нечем. Умолчание же сделало бы усечённый набор неотличимым от «сценариев больше нет».
384
+ limit: z.number().int().min(1).max(ICP_SCENARIOS_MAX_PAGE_SIZE).optional(),
385
+ cursor: z.string().min(1).optional(),
264
386
  }),
265
- createRequest: (input) => ({
266
- method: 'GET',
267
- path: `/icp/${input.icp_id}/scenarios`,
387
+ createRequest: (input) => {
388
+ const query = new URLSearchParams();
389
+ if (input.limit !== undefined)
390
+ query.set('limit', String(input.limit));
391
+ if (input.cursor)
392
+ query.set('cursor', input.cursor);
393
+ const suffix = query.size > 0 ? `?${query.toString()}` : '';
394
+ return { method: 'GET', path: `/icp/${input.icp_id}/scenarios${suffix}` };
395
+ },
396
+ enhanceResponse: (response, input) => assertCompleteList(response, {
397
+ pageRequested: input.limit !== undefined || input.cursor !== undefined,
398
+ toolName: 'besales_icp_scenarios_list',
399
+ howToPage: `Позовите снова с limit (до ${ICP_SCENARIOS_MAX_PAGE_SIZE}) и продолжайте по cursor, пока он не станет пустым.`,
268
400
  }),
269
401
  }),
270
402
  defineTool({
271
403
  name: 'besales_icp_sample_messages',
404
+ carriesCustomerData: true,
272
405
  sideEffect: 'none',
273
406
  requiredFields: ['sample_id'],
274
407
  schema: z.object({
@@ -285,6 +418,12 @@ export const agentDesignTools = [
285
418
  requiredFields: ['agent_id'],
286
419
  schema: z.object({
287
420
  agent_id: uuidSchema,
421
+ output_language: z
422
+ .string()
423
+ .regex(/^[a-z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$/u)
424
+ .max(PROMPT_LANGUAGE_CODE_MAX_LENGTH)
425
+ .describe('Язык результата: ru/en/es/id/uz и язык внешнего бота вне пятёрки (например kk). Не задан — язык бота, затем пространства. Не связан с style_hints.language.')
426
+ .optional(),
288
427
  icp_profile_id: uuidSchema.optional(),
289
428
  business_context: optionalAnyObjectSchema,
290
429
  style_hints: z
@@ -292,7 +431,7 @@ export const agentDesignTools = [
292
431
  formality: z.enum(['formal', 'casual', 'friendly']).optional(),
293
432
  verbosity: z.enum(['concise', 'balanced', 'detailed']).optional(),
294
433
  // Язык РАССУЖДЕНИЯ стадий генерации (ru/en) — НЕ язык итогового промпта.
295
- // Язык промпта = то, что ты пишешь в final_content (узбекский и т.д.).
434
+ // Язык результата задаёт output_language, иначе сервер сохраняет язык бота.
296
435
  language: z.enum(['ru', 'en']).default('ru'),
297
436
  message_direction: z.enum(['INBOUND', 'OUTBOUND']).optional(),
298
437
  })
@@ -301,6 +440,7 @@ export const agentDesignTools = [
301
440
  createRequest: (input) => ({
302
441
  path: `/agents/${input.agent_id}/prompt/generate/instructions`,
303
442
  body: compactObject({
443
+ outputLanguage: input.output_language,
304
444
  sourceType: input.icp_profile_id ? 'icp_full' : 'business_context_only',
305
445
  icpProfileId: input.icp_profile_id,
306
446
  businessContext: input.business_context,
@@ -316,9 +456,10 @@ export const agentDesignTools = [
316
456
  }),
317
457
  enhanceResponse: (response) => withInstructions(response, [
318
458
  'Перед генерацией сверься с besales://docs/prompt-anatomy (лимит длины + что система добавляет сама) и besales://docs/prompt-principles (человечность/анти-AI-tell + sales-плейбук + раздел C: майнить реальные диалоги операторов по этапам); форму и тактику бери из этих ресурсов, не из догадок.',
459
+ 'Используй возвращённые input и authoringContext во всех стадиях; покажи directionWarnings пользователю. Необязательное поле icpPortraitOmission означает, что сервер намеренно не включил портрет аудитории: сообщи об этом пользователю и используй доступные материалы. Сервер уже вывел направление из назначения. Явный message_direction меняет нейтральный сценарий; реактивация требует OUTBOUND.',
319
460
  'Выполни 4 stages prompt generation локально: structure_builder, industry_validator, prompt_tester, finalizer.',
320
461
  'Каждая stage должна вернуть JSON по своей schema. Финальный compiled prompt положи в final_content.',
321
- 'Язык итогового промпта = содержимое final_content: пиши его на языке бота (узбекский, казахский и т.д.). style_hints.language (ru/en) задаёт лишь язык рассуждения стадий, не язык промпта.',
462
+ 'Язык результата задан отдельно в output_language, иначе сервер сохраняет язык бота (узбекский, казахский и другие языки вне интерфейсной пятёрки), затем пространства. Соблюдай возвращённый languageContext во всех черновиках и final_content. style_hints.language (ru/en) задаёт только язык служебного рассуждения. Перед применением покажи заданный язык и проверь текст.',
322
463
  'После stages вызови besales_prompt_generate_submit с stages, final_content и metadata.',
323
464
  ]),
324
465
  }),
@@ -365,17 +506,25 @@ export const agentDesignTools = [
365
506
  schema: z.object({
366
507
  agent_id: uuidSchema,
367
508
  version_id: uuidSchema,
509
+ source_language: z
510
+ .string()
511
+ .regex(/^[a-z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$/u)
512
+ .max(PROMPT_LANGUAGE_CODE_MAX_LENGTH)
513
+ .describe('Язык проверяемого текста. Если не передан, берётся язык бота, затем пространства. Не переводит весь черновик.')
514
+ .optional(),
368
515
  modes: z.array(analysisModeSchema).default(['grammar', 'structure', 'contradictions']),
369
516
  }),
370
517
  createRequest: (input) => ({
371
518
  path: `/agents/${input.agent_id}/prompt/analyze/instructions`,
372
519
  body: {
373
520
  versionId: input.version_id,
521
+ ...(input.source_language === undefined ? {} : { sourceLanguage: input.source_language }),
374
522
  modes: input.modes,
375
523
  },
376
524
  }),
377
525
  enhanceResponse: (response) => withInstructions(response, [
378
526
  'Выполни static analysis stages локально: grammar, industry, structure, aggregation.',
527
+ 'Сохрани язык проверяемого текста: returned languageContext задаёт язык замечаний и предлагаемых правок. Не переводи весь черновик; original, targetText и anchorText сохраняй дословно.',
379
528
  'Собери итоговый список issues без дублей и с severity.',
380
529
  'После анализа вызови besales_prompt_analyze_submit с aggregated_issues.',
381
530
  ]),
@@ -423,7 +572,7 @@ export const agentDesignTools = [
423
572
  }),
424
573
  }),
425
574
  enhanceResponse: (response) => withInstructions(response, [
426
- 'Промпт активирован. Перед запуском проверь 3 вещи: 1) greeting — besales_behavior_update.greeting, замени дефолтный «Привет!/Hello» на язык аудитории текстом, БЕЗ кнопок (greeting_buttons — лишь по явному запросу); для INBOUND именно оно открывает диалог; 2) knowledge привязан к каналу; 3) прогон besales_sandbox_run_start.',
575
+ 'Промпт активирован. Перед запуском проверь 3 вещи: 1) greeting — besales_behavior_update.greeting, замени дефолтный «Привет!/Hello» на язык аудитории полем text, БЕЗ кнопок (buttons — лишь по явному запросу); секции у нового канала нет, поэтому первая запись обязана нести text, buttons, keyboard_type и popup_delay_seconds целиком; для INBOUND именно оно открывает диалог; 2) knowledge привязан к каналу; 3) прогон besales_sandbox_run_start.',
427
576
  ]),
428
577
  }),
429
578
  defineTool({
@@ -432,6 +581,9 @@ export const agentDesignTools = [
432
581
  requiredFields: ['agent_id'],
433
582
  schema: z.object({
434
583
  agent_id: uuidSchema,
584
+ // Прогон по ещё не активированному тексту промпта: проверка кандидата ДО того, как он
585
+ // станет промптом агента. Без поля кандидата проверить нечем — приходилось бы активировать
586
+ // черновик на живом агенте.
435
587
  candidate_prompt: z.string().min(10).max(100_000).optional(),
436
588
  scenario_ids: z.array(uuidSchema).optional(),
437
589
  options: z
@@ -473,11 +625,8 @@ export const agentDesignTools = [
473
625
  }),
474
626
  }),
475
627
  verifyWithToolName: 'besales_sandbox_run_get',
476
- enhanceResponse: (response, input) => withInstructions(response, [
628
+ enhanceResponse: (response) => withInstructions(response, [
477
629
  'Сохрани id прогона как run_id. Проверяй только этот прогон через besales_sandbox_run_get.',
478
- input.candidate_prompt
479
- ? 'Проверяется неактивированный candidate_prompt. Он не меняет работающего агента; активировать результат можно только отдельным prompt commit/finalize после проверки актуальности hash.'
480
- : 'Проверяется активный промпт агента. testedConfiguration в detail фиксирует его hash/version на момент постановки.',
481
630
  'Первую проверку делай через 10–30 секунд; повторяй, пока status не станет COMPLETED, FAILED или CANCELLED.',
482
631
  ]),
483
632
  }),
@@ -579,6 +728,9 @@ export const agentDesignTools = [
579
728
  path: `/agents/${input.agent_id}/sandbox/runs/${input.run_id}/findings/${input.operation_id}/submit`,
580
729
  body: {
581
730
  findings: input.findings.map((finding) => compactObject({
731
+ // ⛔ Оба написания принимаются на входе, наружу уходит канон сервера. Поля
732
+ // перечислены ЯВНО: сборка тела — вторая точка потери, где незнакомое поле исчезает
733
+ // молча, уже пережив схему.
582
734
  scenarioId: finding.scenarioId ?? finding.scenario_id,
583
735
  category: finding.category,
584
736
  severity: finding.severity,
@@ -672,8 +824,8 @@ export const agentDesignTools = [
672
824
  .object({
673
825
  agent_id: uuidSchema,
674
826
  operation_id: uuidSchema,
675
- knowledge_space_id: uuidSchema.optional(),
676
- knowledgeSpaceId: uuidSchema.optional(),
827
+ knowledge_space_id: knowledgeSpaceIdSchema.optional(),
828
+ knowledgeSpaceId: knowledgeSpaceIdSchema.optional(),
677
829
  qa_pairs: z
678
830
  .array(z.object({
679
831
  question: z.string(),
@@ -728,7 +880,7 @@ export const agentDesignTools = [
728
880
  }),
729
881
  enhanceResponse: (response) => withInstructions(response, [
730
882
  'Выполни stage scenario_builder локально и верни структурированный JSON.',
731
- 'Уточни у пользователя целевой режим sandbox: изолированный агент (single_agent) или полный workflow с роутером (workflow). Для workflow добавь сценарии, провоцирующие смену агента — сдвиг темы/intent в ходе диалога.',
883
+ 'Без вопроса запускай обычный прогон: mode=single_agent и client_mode=scripted (умолчания схемы) — это дешёвый, воспроизводимый прогон для регрессии и проверки кандидата промпта до публикации (candidate_prompt). Перед запуском спроси пользователя одним коротким вопросом с ценой в одну фразу только если нужен client_mode=simulated (LLM играет клиента — дороже и каждый раз по-разному), оба режима клиента (= два прогона) либо mode=workflow (все агенты канала через роутер — шире и дороже). Для workflow добавь сценарии, провоцирующие смену агента — сдвиг темы/intent в ходе диалога.',
732
884
  'Каждый scenario — sandbox-готовый мультитёрн диалог: МИНИМУМ 4 turns (submit с меньшим количеством вернёт 400), начинать ОБЯЗАТЕЛЬНО с role="client".',
733
885
  'Реплики client пиши КОРОТКО, как в мессенджере (обычно 3-15 слов, можно фрагментами/одним словом) — реальные клиенты не пишут эссе; стиль бери из languageStyle сегмента/persona.',
734
886
  'segment_ids должны ссылаться только на icpContext.segments[].id; не выдумывай UUID.',
@@ -756,11 +908,12 @@ export const agentDesignTools = [
756
908
  name: scenario.name,
757
909
  description: scenario.description,
758
910
  segmentIds: scenario.segment_ids,
759
- // ⚠️ `expect` перечислен ЯВНО: реплики пересобираются по списку полей, и забытый
760
- // ключ не ломает ни сборку, ни схему — ожидания просто не доехали бы до backend.
761
911
  situations: scenario.situations.map((situation) => ({
762
912
  role: situation.role,
763
913
  text: situation.text,
914
+ // ⚠️ `expect` перечислен ЯВНО: реплики пересобираются по списку полей, и забытая
915
+ // рубрика исчезла бы молча — сценарий доехал бы до сервера без проверок, а доля
916
+ // прохождения считалась бы по пустому набору.
764
917
  expect: situation.expect,
765
918
  })),
766
919
  })),
@@ -786,7 +939,10 @@ export const agentDesignTools = [
786
939
  requiredFields: ['agent_id', 'graph'],
787
940
  schema: z.object({
788
941
  agent_id: uuidSchema,
789
- preamble: z.string().optional(),
942
+ // `null` принимается наравне с отсутствием: чтение отдаёт `preamble: null`, и круг
943
+ // «прочитал → поправил граф → отправил тем же телом» обязан замыкаться. Соседние
944
+ // необязательные поля графа устроены так же.
945
+ preamble: z.string().nullable().optional(),
790
946
  graph: z.object({
791
947
  stages: z.array(z.object({ id: z.string(), name: z.string() })),
792
948
  nodes: z.array(z.object({