@besales/mcp 0.47.1 → 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 -4
  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 +12061 -6753
  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 -427
  147. package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
  148. package/dist/tools/definitions/broadcast-scheduler.d.ts +19 -13
  149. package/dist/tools/definitions/broadcast-scheduler.js +217 -128
  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 -39
  158. package/dist/tools/definitions/crm-platform.js +235 -344
  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 -354
  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 +17 -29
  241. package/dist/tools/definitions/getcourse-cold-welcome.js +182 -242
  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 +701 -222
  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 +414 -284
  343. package/dist/tools/definitions/shared.js +436 -619
  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 +1105 -621
  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 +105862 -22115
  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 -927
  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,11 +1,17 @@
1
- // Schemas, helpers, snake→camel mappers and the ToolDefinition contract
2
- // shared by all definition modules. Split out of the former monolithic
3
- // definitions.ts to keep each file under the 1200-line project limit.
1
+ import { compactObject } from './shared-input.helpers.js';
2
+ import { instagramCommentTemplatesSchema } from './instagram-comment.templates.js';
3
+ // Общие схемы, перевод snake→camel и контракт ToolDefinition отделены от общего списка определений: единая форма между модулями и ограничение размера каждого файла.
4
4
  import { z } from 'zod';
5
+ import { MESSAGE_FILTER_SOURCE_MAX_LENGTH, MESSAGE_FILTER_TARGET_MAX_LENGTH, } from '../../shared/constants/message-filter.constants.js';
6
+ import { platformGetcourseWaveFieldBindingsSchema } from './platform-getcourse-wave-field-bindings.js';
7
+ import { PLATFORM_FINISH_AUTO_MAX_DAYS } from './platform-settings-limits.js';
8
+ import { platformWidgetPageRulesSchema } from './platform-widget-page-rules.schema.js';
5
9
  export const uuidSchema = z.string().uuid();
10
+ /** Preserved knowledge-space IDs keep hex 8-4-4-4-12 without RFC version/variant constraints. */
11
+ export const knowledgeSpaceIdSchema = z.guid().meta({ format: 'uuid' });
6
12
  export const anyObjectSchema = z.object({}).passthrough();
7
13
  export const optionalAnyObjectSchema = anyObjectSchema.optional();
8
- export const outcomeSchema = z.enum(['won', 'lost', 'in_progress']);
14
+ export const outcomeSchema = z.enum(['won', 'lost', 'in_progress', 'unknown']);
9
15
  export const platformSetupConfirmationSchema = {
10
16
  explicit_confirmation: z.boolean().optional(),
11
17
  confirmation_reason: z.string().optional(),
@@ -20,12 +26,26 @@ export const PROMPT_DIFF_MAX_LINES_LIMIT = 1000;
20
26
  * Больший `limit` сервер отвергнет валидацией, поэтому граница объявлена и здесь.
21
27
  */
22
28
  export const VARIABLES_MAX_PAGE_SIZE = 200;
23
- /** Максимальный размер явно запрошенной страницы списка агентов платформы. */
24
- export const PLATFORM_AGENTS_MAX_PAGE_SIZE = 200;
29
+ /**
30
+ * Верхняя граница страницы перечня агентов канала — совпадает с `CHANNEL_AGENTS_LIST_MAX_LIMIT`
31
+ * бэкенда. Умолчания у самой ручки нет: без `limit` перечень приходит целиком.
32
+ */
33
+ export const CHANNEL_AGENTS_MAX_PAGE_SIZE = 200;
34
+ /** Верхняя граница страницы сценариев ICP — совпадает с `ICP_SCENARIOS_LIST_MAX_LIMIT` бэкенда. */
35
+ export const ICP_SCENARIOS_MAX_PAGE_SIZE = 200;
36
+ /** Верхняя граница страницы воронок и стадий — совпадает с `CRM_PIPELINES_LIST_MAX_LIMIT` бэкенда. */
37
+ export const CRM_PIPELINES_MAX_PAGE_SIZE = 200;
38
+ /** Верхняя граница страницы цепочек дожима — совпадает с `FOLLOWUP_SEQUENCES_LIST_MAX_LIMIT`. */
39
+ export const FOLLOWUP_SEQUENCES_MAX_PAGE_SIZE = 200;
25
40
  /** Потолок агентов в одном пакетном прогоне — должен совпадать с `PROMPT_BATCH_MAX_AGENTS`. */
26
41
  export const PROMPT_BATCH_MAX_AGENTS = 200;
27
42
  /** Длина ключа идемпотентности пакетного прогона — должна совпадать с DTO бэкенда. */
28
43
  export const PROMPT_BATCH_IDEMPOTENCY_KEY_MAX_LENGTH = 200;
44
+ /**
45
+ * Потолок срока доверия ответу школы (сутки). Совпадает с сервером: иначе мост пропустил бы
46
+ * значение, которое сервер отвергает, либо наоборот.
47
+ */
48
+ export const GETCOURSE_REACHABILITY_TTL_DAYS_MAX = 365;
29
49
  /**
30
50
  * Одна patch-операция промпта. Общая для `besales_prompt_patch_apply` и
31
51
  * `besales_prompt_batch_start`: две копии разъехались бы при добавлении нового типа.
@@ -85,9 +105,8 @@ export const apiKeyPlatformTypeSchema = z.enum([
85
105
  ]);
86
106
  // v1.5 Increment 5b Phase 2 — OAuth-каналы (авторизация в браузере, код мимо LLM).
87
107
  export const oauthPlatformTypeSchema = z.enum(['Instagram', 'Avito']);
88
- // v1.5 Increment 5c — CRM provisioning через Setup URL pattern (секреты в браузере).
89
- // GETCOURSE/TELEGRAM — API-key; AMOCRM/BITRIX24 — вставка credentials (5c Phase 2, не OAuth-redirect).
90
- export const provisionableCrmTypeSchema = z.enum(['GETCOURSE', 'TELEGRAM', 'AMOCRM', 'BITRIX24']);
108
+ // CRM provisioning через Setup URL pattern: секреты вводятся только в браузере.
109
+ export const provisionableCrmTypeSchema = z.enum(['GETCOURSE', 'AMOCRM', 'BITRIX24']);
91
110
  export const fieldSpecialPurposeSchema = z.enum([
92
111
  'phone',
93
112
  'telegramId',
@@ -177,18 +196,33 @@ export const icpAnalysisPersonaSchema = z
177
196
  /**
178
197
  * Машинные ожидания реплики: что раннер песочницы обязан увидеть в ответе агента на неё.
179
198
  *
180
- * ⚠️ Без этой схемы поле не просто «не валидируется», а ИСЧЕЗАЕТ: zod стрипает неизвестные ключи
181
- * молча, и ожидания не доехали бы до backend вовсе. Вторая точка потери — маппинг сабмита, где
182
- * реплики пересобираются по явному списку полей.
199
+ * ⚠️ Без схемы поле не просто «не проверяется», а ИСЧЕЗАЕТ: zod молча срезает неизвестные ключи,
200
+ * и рубрика не доехала бы до сервера вовсе. Вторая точка потери — сборка тела отправки, где
201
+ * реплики пересобираются по явному списку полей: там `expect` перечислен отдельно.
202
+ *
203
+ * ⛔ Принимаются ровно ТРИ правила — те, что сервер открывает генератору сценариев
204
+ * (`GENERATED_SCENARIO_EXPECTATION_KEYS`, `additionalProperties: false`): два по тексту ответа и
205
+ * запрет ранней передачи оператору, у которого единственная цель — `call_operator` (песочница
206
+ * проверяет его по сработавшему действию с шагом передачи). Идентификаторов действий и имён
207
+ * инструментов генератор не знает, и выдуманная цель краснела бы на исправном агенте: правила по
208
+ * действиям ставит оператор. Хранилище сервера знает ШЕСТЬ имён — это реестр ХРАНЕНИЯ, а не то,
209
+ * что сервер показывает пишущей стороне.
210
+ *
211
+ * ⚠️ Отгруженный клиент объявляет все шесть, и сервер их принимает; сужение здесь повторяет
212
+ * контракт генератора, а не обещает модели цели, которых она не знает.
183
213
  */
184
- export const scenarioTurnExpectationSchema = z.object({
185
- triggers: z.array(z.string().min(1)).optional(),
186
- noTriggers: z.array(z.string().min(1)).optional(),
187
- tools: z.array(z.string().min(1)).optional(),
188
- noTools: z.array(z.string().min(1)).optional(),
214
+ export const scenarioTurnExpectationSchema = z
215
+ .object({
216
+ noTools: z
217
+ .array(z.enum(['call_operator']))
218
+ .min(1)
219
+ .optional(),
189
220
  answerContains: z.array(z.string().min(1)).optional(),
190
221
  answerNotContains: z.array(z.string().min(1)).optional(),
191
- });
222
+ })
223
+ // ⛔ Строгая: незнакомое правило отвергается С ИМЕНЕМ, а не срезается молча. Молчаливое срезание
224
+ // и есть тот случай, когда пишущая сторона считает правило заданным, а проверять его некому.
225
+ .strict();
192
226
  export const scenarioSituationSchema = z.object({
193
227
  role: z.enum(['client', 'agent']),
194
228
  text: z.string().min(1).max(4000),
@@ -209,7 +243,21 @@ export const generatedScenarioSchema = z
209
243
  ...rest,
210
244
  segment_ids: segment_ids ?? segmentIds,
211
245
  }));
212
- export const sandboxFindingSchema = z.object({
246
+ /**
247
+ * Находка песочницы — КАНОН сервера, а не прежняя форма ветки v2.
248
+ *
249
+ * ⛔ Рубрика — РОВНО семь категорий отгруженного контракта. `missed_trigger` убрана: сервер её
250
+ * отвергает, то есть ветка v2 предлагала модели категорию, на которой вызов падал целиком.
251
+ * `missed_context` добавлена — она в каноне и была недостижима. Прежняя `wrong_pipeline_transition`
252
+ * НЕ рекламируется сознательно: сервер её принимает ради уже сохранённых находок, но его задание
253
+ * называет модели семь категорий, и предлагать восьмую значило бы спорить с этим решением.
254
+ *
255
+ * ⛔ Текст находки называется `description`; прежнее имя `message` принимается тоже, потому что
256
+ * им пользуется отгруженный клиент, стоящий у людей сейчас. Требуется РОВНО ОДНО из двух: без
257
+ * этого правила находка без текста уходила бы на сервер пустой.
258
+ */
259
+ export const sandboxFindingSchema = z
260
+ .object({
213
261
  scenario_id: uuidSchema.optional(),
214
262
  scenarioId: uuidSchema.optional(),
215
263
  category: z.enum([
@@ -229,8 +277,9 @@ export const sandboxFindingSchema = z.object({
229
277
  suggestion: z.string().optional(),
230
278
  turn_index: z.number().int().optional(),
231
279
  turnIndex: z.number().int().optional(),
232
- }).refine((finding) => finding.description !== undefined || finding.message !== undefined, {
233
- message: 'description is required',
280
+ })
281
+ .refine((finding) => finding.description !== undefined || finding.message !== undefined, {
282
+ message: 'Находка обязана нести текст: description (канон) либо message (прежнее имя)',
234
283
  path: ['description'],
235
284
  });
236
285
  export const simulationFindingSchema = z.object({
@@ -260,11 +309,11 @@ export const routingRuleLeadStatusSchema = z.object({
260
309
  // Одно условие правила роутинга «по значению переменной» (CUSTOM_VARIABLE).
261
310
  // Одно правило = N условий, объединяемых condition_logic (ALL=И / ANY=ИЛИ).
262
311
  // Внутри условия значения объединяются по ИЛИ (variable_values) — вместе с condition_logic=ALL
263
- // это даёт «И из ИЛИ»: AI_TOPIC ∈ [дбо] AND WAVE_SEGMENT ∈ [post-web, post-web-2].
264
- // variable_value — legacy-форма на одно значение; ровно одна из двух форм на условие.
265
- // Обе формы принимаются вместе, если СОГЛАСОВАНЫ (скаляр = первое значение набора): ответ API и
266
- // besales_platform_context_get отдают оба поля, поэтому клиент «прочитал → поправил → отправил»
267
- // естественно шлёт оба. Жёсткий XOR ломал бы обычный сценарий правки. Противоречие — отказ.
312
+ // это даёт «И из ИЛИ»: тема ∈ [дбо] AND сегмент ∈ [post-web, post-web-2].
313
+ // variable_value — форма на одно значение; ровно одна из двух форм на условие обязательна.
314
+ // Обе формы принимаются вместе, если СОГЛАСОВАНЫ (скаляр = первое значение набора): ответ API
315
+ // отдаёт оба поля, поэтому клиент «прочитал → поправил → отправил» естественно шлёт оба.
316
+ // Жёсткий выбор одной формы ломал бы обычный сценарий правки. Противоречие — отказ.
268
317
  export const routingRuleConditionSchema = z
269
318
  .object({
270
319
  custom_variable_id: z.string().uuid(),
@@ -276,9 +325,14 @@ export const routingRuleConditionSchema = z
276
325
  })
277
326
  .refine((cond) => cond.variable_values === undefined ||
278
327
  cond.variable_value === undefined ||
279
- cond.variable_values[0]?.trim().toLowerCase() === cond.variable_value.trim().toLowerCase(), {
280
- message: 'variable_value не совпадает с variable_values[0]. Присылайте одну форму либо согласованные',
328
+ // Сравнение идёт с первым НЕПУСТЫМ элементом — тем же, который останется набором после
329
+ // чистки на стороне API. Иначе мост отвергал бы форму, которую API принимает.
330
+ firstMeaningfulValue(cond.variable_values) === cond.variable_value.trim().toLowerCase(), {
331
+ message: 'variable_value не совпадает с первым значением variable_values. Присылайте одну форму либо согласованные',
281
332
  });
333
+ function firstMeaningfulValue(values) {
334
+ return values.map((value) => value.trim().toLowerCase()).find((value) => value !== '');
335
+ }
282
336
  export const agentToolPatchSchema = z.object({
283
337
  tool_id: z.string(),
284
338
  priority: z.number().int().min(1).max(100).optional(),
@@ -303,9 +357,7 @@ export const agentRuntimeConfigSchema = z.object({
303
357
  qa_min_score: z.number().min(0).max(1).optional(),
304
358
  qa_context_limit: z.number().int().min(1).max(10).optional(),
305
359
  max_response_symbols: z.number().int().min(1).optional(),
306
- reasoning_effort: z
307
- .enum(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'])
308
- .optional(),
360
+ reasoning_effort: z.enum(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']).optional(),
309
361
  verbosity: z.enum(['low', 'medium', 'high']).optional(),
310
362
  enable_thinking: z.boolean().optional(),
311
363
  timezone: z.string().optional(),
@@ -338,79 +390,172 @@ export const agentScopeSchema = z.enum([
338
390
  'complaint',
339
391
  'other',
340
392
  ]);
341
- // Behavior typed sections (Group C.1)
342
- export const behaviorGreetingButtonSchema = z.object({
393
+ // Behavior typed sections — КАНОН v2 (spec 02 § 5.2).
394
+ //
395
+ // ⛔ Имена полей = имена Zod-схем секций besales-api, а не отгруженные имена v1.5. Причина не в
396
+ // чистоте: у части полей вместе с именем сменилась ЕДИНИЦА (задержки уехали из секунд в
397
+ // миллисекунды), и сохрани мы старое имя — оператор, задавший 10, получил бы десять миллисекунд
398
+ // вместо десяти секунд, молча и без единой ошибки.
399
+ //
400
+ // ⛔ Все поля НЕОБЯЗАТЕЛЬНЫ, потому что сервер сливает присланное с текущим значением секции.
401
+ // Обязательность зеркалить нельзя: она запретила бы правку одного поля — то самое, ради чего
402
+ // инструмент и существует.
403
+ //
404
+ // ⛔ `schema_version` принимается, но перезаписывается: снимок из besales_platform_context_get его
405
+ // СОДЕРЖИТ, и строгая схема без этого поля отвергла бы собственный же прочитанный снимок.
406
+ const behaviorSchemaVersion = { schema_version: z.literal(1).optional() };
407
+ export const behaviorGreetingButtonSchema = z
408
+ .object({
343
409
  id: z.string(),
344
410
  label: z.string(),
345
411
  text: z.string(),
346
412
  order: z.number().int(),
347
- });
348
- export const behaviorGreetingSchema = z.object({
349
- bot_greeting: z.string().optional(),
350
- greeting_file_id: uuidSchema.nullable().optional(),
351
- greeting_buttons: z.array(behaviorGreetingButtonSchema).optional(),
352
- greeting_buttons_keyboard_type: z.enum(['INLINE', 'REPLY']).optional(),
413
+ })
414
+ .strict();
415
+ export const behaviorGreetingSchema = z
416
+ .object({
417
+ ...behaviorSchemaVersion,
418
+ text: z.string().optional(),
419
+ // null очищает картинку приветствия: сервер удаляет ключ, а не пишет пустоту.
420
+ file_id: z.string().nullable().optional(),
421
+ buttons: z.array(behaviorGreetingButtonSchema).optional(),
422
+ keyboard_type: z.enum(['INLINE', 'REPLY']).optional(),
353
423
  popup_delay_seconds: z.number().int().min(0).optional(),
354
- });
355
- /**
356
- * Набор стратегий у каждого типа вложения свой. `PROCESS_WITH_LLM` разбирает вложение
357
- * по-разному: image → vision-модель, video → подпись как текст, document → извлечённый текст
358
- * файла. У аудио такого значения на бэкенде нет вовсе, и запрос отвергается 400. Общая схема
359
- * на все четыре типа предлагала значение везде, из-за чего агент слал заведомо невалидный
360
- * payload (прод, 2026-08-10).
361
- */
362
- const mediaHandlerCommonFields = {
363
- fixed_response_text: z.string().optional(),
424
+ // Отдаёт ли канал offMessage, когда ИИ выключен. Поле есть в v2 и у него живой читатель;
425
+ // у отгруженного инструмента его не было вовсе.
426
+ send_off_message_when_ai_disabled: z.boolean().optional(),
427
+ })
428
+ .strict();
429
+ const behaviorMediaHandlerFields = {
430
+ fixed_response_text: z.string().nullable().optional(),
364
431
  call_operator: z.boolean().optional(),
365
- operator_comment: z.string().optional(),
432
+ operator_comment: z.string().nullable().optional(),
366
433
  };
367
- export const behaviorMediaHandlerSchema = z.object({
368
- behavior: z.enum(['SILENT', 'PROCESS_WITH_LLM', 'FIXED_RESPONSE']),
369
- ...mediaHandlerCommonFields,
370
- });
371
- export const behaviorPlainMediaHandlerSchema = z.object({
372
- behavior: z.enum(['SILENT', 'FIXED_RESPONSE']),
373
- ...mediaHandlerCommonFields,
374
- });
375
- export const behaviorMediaHandlingSchema = z.object({
434
+ /**
435
+ * Обработчик вложения, у которого есть разбор моделью: картинка (кадр уходит зрячей модели),
436
+ * видео (в модель уходит подпись) и документ (в модель уходит ИЗВЛЕЧЁННЫЙ ТЕКСТ, сам файл — нет).
437
+ *
438
+ * ⚠️ У картинки и документа `PROCESS_WITH_LLM` означает: воркспейс соглашается отправлять в модель
439
+ * содержимое присланных файлов, включая персональные данные ТРЕТЬИХ ЛИЦ. Обезличивание подменяет
440
+ * известные значения контакта и распознаёт имена и контакты эвристикой, но полноты на содержимом
441
+ * чужого файла не гарантирует. Поэтому включение требует `explicit_confirmation`.
442
+ */
443
+ export const behaviorMediaHandlerSchema = z
444
+ .object({
445
+ behavior: z.enum(['SILENT', 'PROCESS_WITH_LLM', 'FIXED_RESPONSE']).optional(),
446
+ ...behaviorMediaHandlerFields,
447
+ })
448
+ .strict();
449
+ /**
450
+ * Обработчик вложения БЕЗ разбора моделью — сегодня это только звук.
451
+ *
452
+ * ⛔ Отдельная схема, а не общая: разбирать в аудиофайле нечего (голосовые обрабатывает
453
+ * распознавание речи), и общий набор значений заставлял бы агента слать заведомо невалидный
454
+ * запрос — сервер отвергает `PROCESS_WITH_LLM` у звука своей схемой.
455
+ */
456
+ export const behaviorPlainMediaHandlerSchema = z
457
+ .object({
458
+ behavior: z.enum(['SILENT', 'FIXED_RESPONSE']).optional(),
459
+ ...behaviorMediaHandlerFields,
460
+ })
461
+ .strict();
462
+ export const behaviorMediaHandlingSchema = z
463
+ .object({
464
+ ...behaviorSchemaVersion,
376
465
  image: behaviorMediaHandlerSchema.optional(),
377
466
  video: behaviorMediaHandlerSchema.optional(),
378
467
  audio: behaviorPlainMediaHandlerSchema.optional(),
379
468
  document: behaviorMediaHandlerSchema.optional(),
380
- });
381
- export const behaviorUrlHandlingSchema = z.object({
382
- behavior: z.enum(['PASS_THROUGH', 'SILENT', 'FIXED_RESPONSE', 'PROCESS_WITH_CRAWLER']),
383
- fixed_response_text: z.string().optional(),
469
+ })
470
+ .strict();
471
+ export const behaviorUnsupportedInputHandlingSchema = z
472
+ .object({
473
+ ...behaviorSchemaVersion,
474
+ behavior: z.enum(['SILENT', 'AS_TEXT', 'FIXED_RESPONSE']).optional(),
475
+ fixed_response_text: z.string().nullable().optional(),
476
+ call_operator: z.boolean().optional(),
477
+ operator_comment: z.string().nullable().optional(),
478
+ })
479
+ .strict();
480
+ export const behaviorUrlHandlingSchema = z
481
+ .object({
482
+ ...behaviorSchemaVersion,
483
+ behavior: z
484
+ .enum(['PASS_THROUGH', 'SILENT', 'FIXED_RESPONSE', 'PROCESS_WITH_CRAWLER'])
485
+ .optional(),
486
+ fixed_response_text: z.string().nullable().optional(),
384
487
  call_operator: z.boolean().optional(),
385
- operator_comment: z.string().optional(),
488
+ operator_comment: z.string().nullable().optional(),
386
489
  use_youtube_data_api: z.boolean().optional(),
387
- });
388
- export const behaviorErrorHandlingSchema = z.object({
490
+ })
491
+ .strict();
492
+ export const behaviorErrorHandlingSchema = z
493
+ .object({
494
+ ...behaviorSchemaVersion,
389
495
  ai_error_behavior: z.enum(['SILENT', 'SEND_ERROR_MESSAGE']).optional(),
390
- ai_error_custom_message: z.string().optional(),
391
- call_operator_with_error: z.boolean().optional(),
392
- ai_error_target_stage_id: z.number().int().nullable().optional(),
393
- });
394
- export const behaviorDayAvailabilitySchema = z.object({
496
+ custom_message: z.string().nullable().optional(),
497
+ call_operator: z.boolean().optional(),
498
+ // Цель сбоя модели: пара «воронка + статус» либо статус без воронки — «стадия с этим кодом в текущей воронке
499
+ // сделки» (так понимала номер прежняя система). null снимает цель.
500
+ ai_error_target: z
501
+ .object({ pipeline_id: z.string().min(1).optional(), status_id: z.string().min(1) })
502
+ .strict()
503
+ .nullable()
504
+ .optional(),
505
+ // Прежнее поле отгруженного моста — номер стадии прежней системы. Переводит его в цель СЕРВЕР (по каталогу
506
+ // подключения CRM канала; неоднозначность и неизвестный номер — отказ с адресом поля); null или 0 снимает цель.
507
+ // Вместе с ai_error_target не присылается.
508
+ ai_error_target_stage_id: z.number().int().nonnegative().nullable().optional(),
509
+ })
510
+ .strict();
511
+ /**
512
+ * ⛔ У РАБОЧЕГО дня обязательны ОБА времени и строго в формате `HH:MM`. Схема хранения приняла бы
513
+ * и `active: true` без времён, и запись вида `9:00` — а читатель расписания на таком дне считает
514
+ * НЕСТРОГИМ всё расписание целиком и объявляет оператора доступным ВСЕГДА. То есть один
515
+ * неаккуратный день молча выключает расписание на всю неделю, без ошибки и без предупреждения.
516
+ */
517
+ export const behaviorDayAvailabilitySchema = z
518
+ .object({
395
519
  active: z.boolean(),
396
- start_time: z.string().optional(),
397
- end_time: z.string().optional(),
398
- });
399
- export const behaviorWeekAvailabilitySchema = z.object({
400
- monday: behaviorDayAvailabilitySchema.optional(),
401
- tuesday: behaviorDayAvailabilitySchema.optional(),
402
- wednesday: behaviorDayAvailabilitySchema.optional(),
403
- thursday: behaviorDayAvailabilitySchema.optional(),
404
- friday: behaviorDayAvailabilitySchema.optional(),
405
- saturday: behaviorDayAvailabilitySchema.optional(),
406
- sunday: behaviorDayAvailabilitySchema.optional(),
520
+ start_time: z
521
+ .string()
522
+ .regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/u)
523
+ .optional(),
524
+ end_time: z
525
+ .string()
526
+ .regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/u)
527
+ .optional(),
528
+ })
529
+ .strict()
530
+ .refine((day) => !day.active || (day.start_time !== undefined && day.end_time !== undefined), {
531
+ message: 'у рабочего дня обязательны start_time и end_time в формате HH:MM',
407
532
  });
408
- export const behaviorOperatorScheduleSchema = z.object({
533
+ /**
534
+ * ⛔ Ключи дня пришпилены к канону `MON..SUN`. Хранилище приняло бы ЛЮБУЮ строку
535
+ * (`z.record(z.string(), …)`), а читатель при чужом ключе объявляет оператора доступным ВСЕГДА —
536
+ * то есть расписание, выставленное с ключами `monday…sunday`, молча не работало бы: ни ошибки,
537
+ * ни предупреждения, ни строки в логе.
538
+ */
539
+ export const behaviorWeekAvailabilitySchema = z
540
+ .object({
541
+ MON: behaviorDayAvailabilitySchema.optional(),
542
+ TUE: behaviorDayAvailabilitySchema.optional(),
543
+ WED: behaviorDayAvailabilitySchema.optional(),
544
+ THU: behaviorDayAvailabilitySchema.optional(),
545
+ FRI: behaviorDayAvailabilitySchema.optional(),
546
+ SAT: behaviorDayAvailabilitySchema.optional(),
547
+ SUN: behaviorDayAvailabilitySchema.optional(),
548
+ })
549
+ .strict();
550
+ export const behaviorOperatorScheduleSchema = z
551
+ .object({
552
+ ...behaviorSchemaVersion,
409
553
  enabled: z.boolean().optional(),
410
554
  availability: behaviorWeekAvailabilitySchema.optional(),
411
- unavailable_message: z.string().optional(),
412
- // -1 — ответ оператора не отключает бота, 0 — молчать до /start, далее часы паузы.
413
- bot_waiting_return_hours: z.union([
555
+ unavailable_message: z.string().nullable().optional(),
556
+ // -1 — ответ оператора НЕ отключает бота; 0 — молчать до /start; далее часы паузы.
557
+ bot_waiting_return_hours: z
558
+ .union([
414
559
  z.literal(-1),
415
560
  z.literal(0),
416
561
  z.literal(1),
@@ -418,32 +563,81 @@ export const behaviorOperatorScheduleSchema = z.object({
418
563
  z.literal(6),
419
564
  z.literal(12),
420
565
  z.literal(24),
421
- ]).optional(),
422
- follow_up_waiting_return_hours: z.number().int().optional(),
423
- skip_task_creation_on_call_operator: z.boolean().optional(),
424
- });
425
- export const behaviorTypingBehaviorSchema = z.object({
566
+ ])
567
+ .optional(),
568
+ followup_waiting_return_hours: z.number().int().optional(),
569
+ // Замолкает ли агент после реплики живого оператора. Отсутствие поля означает КАНОН
570
+ // «замолкать», поэтому выключение требует `explicit_confirmation`.
571
+ pause_agent_on_operator_reply: z.boolean().optional(),
572
+ })
573
+ .strict();
574
+ export const behaviorTypingBehaviorSchema = z
575
+ .object({
576
+ ...behaviorSchemaVersion,
577
+ typing_speed: z.enum(['slow', 'medium', 'fast', 'instant']).optional(),
426
578
  waiting_answer_time: z.number().int().min(0).optional(),
427
579
  can_interrupt: z.boolean().optional(),
428
- message_devide: z.boolean().optional(),
429
- typing_speed: z.enum(['slow', 'medium', 'fast']).optional(),
430
- fake_delay: z.number().int().min(0).optional(),
431
- message_open_delay: z.number().int().min(0).optional(),
432
- go_offline: z.string().optional(),
433
- });
434
- export const behaviorMessageFilterSchema = z.object({
580
+ // ⚠️ Секунды v1.5 стали МИЛЛИСЕКУНДАМИ — единица видна в имени намеренно.
581
+ fake_delay_ms: z.number().int().min(0).optional(),
582
+ message_open_delay_ms: z.number().int().min(0).optional(),
583
+ })
584
+ .strict();
585
+ export const behaviorMessageFilterSchema = z
586
+ .object({
435
587
  id: z.string(),
436
- source: z.string(),
437
- target: z.string(),
588
+ // Границы зеркалят схему хранения.
589
+ source: z.string().min(1).max(MESSAGE_FILTER_SOURCE_MAX_LENGTH),
590
+ target: z.string().max(MESSAGE_FILTER_TARGET_MAX_LENGTH),
438
591
  enabled: z.boolean(),
439
592
  order: z.number().int(),
440
- });
441
- export const behaviorMessageSplittingSchema = z.object({
442
- message_chunk_separator: z.string().optional(),
443
- });
444
- export const behaviorPrivacySchema = z.object({
593
+ })
594
+ .strict();
595
+ export const behaviorMessageFiltersSchema = z
596
+ .object({
597
+ ...behaviorSchemaVersion,
598
+ // Переехало из расписания оператора: в v2 признак живёт здесь.
599
+ skip_task_creation_on_call_operator: z.boolean().optional(),
600
+ rules: z.array(behaviorMessageFilterSchema).optional(),
601
+ })
602
+ .strict();
603
+ export const behaviorMessageSplittingSchema = z
604
+ .object({
605
+ ...behaviorSchemaVersion,
606
+ // Переехало из «печатает»: в v1.5 это было `message_devide`.
607
+ enabled: z.boolean().optional(),
608
+ mode: z.enum(['PARAGRAPH', 'SEPARATOR']).optional(),
609
+ separator: z.string().optional(),
610
+ // Максимум означает «не дробить дополнительно»: у v1.5 отдельного предела не было.
611
+ // Границы зеркалят схему хранения.
612
+ max_chunk_size: z.number().int().min(100).max(100_000).optional(),
613
+ delay_between_ms: z.number().int().min(0).max(60_000).optional(),
614
+ })
615
+ .strict();
616
+ /**
617
+ * CRM-поведение канала в инструменте поведения — только входящий фильтр по сделке GetCourse («бот отвечает только
618
+ * тем, у кого есть подходящая сделка»). Раздел СЛИВАЕТСЯ с сохранённым CRM-поведением канала; у канала без привязанной
619
+ * CRM сливать не с чем, и сервер ответит отказом с перечнем недостающих полей. Полноту включённого фильтра и
620
+ * подтверждение смены включённости и типа держит сервер.
621
+ */
622
+ export const behaviorCrmSchema = z
623
+ .object({
624
+ ...behaviorSchemaVersion,
625
+ inbound_deal_filter: z
626
+ .object({
627
+ enabled: z.boolean(),
628
+ type: z.enum(['NONE', 'TAG', 'CUSTOM_FIELD']),
629
+ value: z.string().nullable().optional(),
630
+ field_id: z.string().nullable().optional(),
631
+ })
632
+ .strict()
633
+ .optional(),
634
+ })
635
+ .strict();
636
+ export const behaviorPrivacySchema = z
637
+ .object({
638
+ ...behaviorSchemaVersion,
445
639
  anonymization_enabled: z.boolean().optional(),
446
- contact_name_personalization_mode: z.enum(['OFF', 'SHADOW', 'ENABLED']).optional(),
640
+ personalization_mode: z.enum(['OFF', 'SHADOW', 'ENABLED']).optional(),
447
641
  // Типы PII, выключенные из анонимизации (отдаются в LLM как есть).
448
642
  // Именные типы всегда защищены и не входят в OFF-список.
449
643
  anonymization_disabled_types: z
@@ -461,7 +655,8 @@ export const behaviorPrivacySchema = z.object({
461
655
  'SOCIAL_ID',
462
656
  ]))
463
657
  .optional(),
464
- });
658
+ })
659
+ .strict();
465
660
  // Pipeline settings typed sections (Group C.3)
466
661
  export const pipelineCrmBehaviorSchema = z.object({
467
662
  active_pipeline_ids: z.array(z.string()).optional(),
@@ -473,19 +668,19 @@ export const pipelineCrmBehaviorSchema = z.object({
473
668
  export const pipelineAutoFinishSchema = z.object({
474
669
  finish_auto_noanswer: z.boolean().optional(),
475
670
  finish_auto_timeout: z.boolean().optional(),
476
- finish_auto_days: z.number().int().min(1).optional(),
671
+ finish_auto_days: z.number().int().min(1).max(PLATFORM_FINISH_AUTO_MAX_DAYS).optional(),
477
672
  send_finish_auto_note_to_crm: z.boolean().optional(),
478
673
  finish_auto_note_template: z.string().nullable().optional(),
479
674
  });
480
675
  // Platform settings typed sections (Group C.2 + Increment 4c per-channel)
676
+ /**
677
+ * Кто из людей вообще доходит до агента.
678
+ *
679
+ * ⛔ Выключатели канала и ответов агента (`is_active`, `is_ai_enabled`) СЮДА НЕ ВХОДЯТ — их дом
680
+ * `general_settings`. Отсюда приёмник их не принимает и отвечал отказом на весь запрос.
681
+ */
481
682
  export const platformAccessControlSchema = z
482
683
  .object({
483
- // У Instagram это НАМЕРЕНИЕ держать канал включённым, а не факт работы: эффективная
484
- // активность = намерение И подтверждённая подписка на вебхуки. Прочитав `is_active` обратно
485
- // через `besales_platform_context_get`, можно увидеть `false` при успешно сохранённом `true` —
486
- // это не отказ операции, а неподтверждённая подписка (лечится resubscribe).
487
- is_active: z.boolean().optional(),
488
- is_ai_enabled: z.boolean().optional(),
489
684
  is_user_filter_enabled: z.boolean().optional(),
490
685
  filtered_user_ids: z.array(z.string()).optional(),
491
686
  // v1.5 Increment 4c — TelegramBot only (hard 400 на других)
@@ -501,6 +696,7 @@ export const platformVariablesConfigSchema = z
501
696
  export const platformCrmBehaviorSchema = z
502
697
  .object({
503
698
  send_to_crm: z.boolean().optional(),
699
+ create_deal_on_first_outbound: z.boolean().optional(),
504
700
  use_cross_platform_history: z.boolean().optional(),
505
701
  responsible_assignee_strategy: z
506
702
  .enum(['ROUND_ROBIN', 'LEAST_BUSY', 'RANDOM', 'FIXED', 'OPERATOR_SPECIFIC'])
@@ -512,82 +708,107 @@ export const platformCrmBehaviorSchema = z
512
708
  failed_note_template: z.string().nullable().optional(),
513
709
  send_operator_takeover_note_to_crm: z.boolean().optional(),
514
710
  operator_takeover_note_template: z.string().nullable().optional(),
711
+ finish_auto_enabled: z.boolean().optional(),
712
+ finish_auto_days: z.number().int().min(1).max(PLATFORM_FINISH_AUTO_MAX_DAYS).optional(),
713
+ send_finish_auto_note_to_crm: z.boolean().optional(),
714
+ finish_auto_note_template: z.string().nullable().optional(),
715
+ getcourse_create_deal_payment_tracking_enabled: z.boolean().optional(),
716
+ getcourse_status_deal_fallback_enabled: z.boolean().optional(),
515
717
  // v1.5 Increment 4c — deal marker (любой CRM-aware channel)
516
718
  deal_marker_type: z.enum(['NONE', 'TAG', 'CUSTOM_FIELD']).optional(),
517
719
  deal_marker_value: z.string().nullable().optional(),
518
720
  deal_marker_field_id: z.string().nullable().optional(),
519
- // Inbound deal-фильтр (GetCourse): агент отвечает только контактам, у которых в активной
520
- // сделке есть поле=значение (CUSTOM_FIELD) или тег (TAG). Для не-GetCourse каналов — no-op.
521
- // Включённый фильтр требует type≠NONE + value (для CUSTOM_FIELD ещё field_id) — иначе 400.
721
+ // Входящий фильтр по сделке (GetCourse) — прежние имена отгруженного моста; сервер хранит его в
722
+ // crm_behavior.inbound_deal_filter. Включённый фильтр обязан быть полным; включённость и тип — опасные поля.
522
723
  inbound_deal_filter_enabled: z.boolean().optional(),
523
724
  inbound_deal_filter_type: z.enum(['NONE', 'TAG', 'CUSTOM_FIELD']).optional(),
524
725
  inbound_deal_filter_value: z.string().nullable().optional(),
525
726
  inbound_deal_filter_field_id: z.string().nullable().optional(),
526
727
  })
527
728
  .strict();
729
+ /**
730
+ * Маркетинговая секция виджета — РОВНО два поля, которые принимает besales-api.
731
+ *
732
+ * ⛔ Список сайтов, лимит обращений, признак «передавать адрес страницы» и оформление ЖИВУТ НЕ
733
+ * ЗДЕСЬ, а в `general_settings`: их приёмник — конфигурация подключения канала, а не поведение.
734
+ * Прежде все шесть полей уезжали сюда под именами `webWidget*`, которых приёмная сторона не знает
735
+ * ни одного, и любое из них давало отказ «удалите неизвестные поля» на ВЕСЬ запрос — то есть ни
736
+ * одна настройка виджета через мост не записывалась.
737
+ *
738
+ * ⛔ `null` здесь не принимается: приёмник объявляет оба поля необязательными, но НЕ нулевыми, а
739
+ * проекция пишет `null` значением, а не удаляет ключ. Мост, принявший `null`, обещал бы очистку,
740
+ * которой не бывает.
741
+ */
528
742
  export const platformWidgetMarketingSchema = z
529
743
  .object({
530
- web_widget_allowed_origins: anyObjectSchema.nullable().optional(),
531
- web_widget_show_page_info: z.boolean().optional(),
532
- web_widget_rate_limit_per_minute: z.number().int().min(1).max(600).optional(),
533
- web_widget_customization: anyObjectSchema.nullable().optional(),
534
- web_widget_marketing_field_mappings: anyObjectSchema.nullable().optional(),
535
- web_widget_entry_url_variable_mapping: anyObjectSchema.nullable().optional(),
744
+ marketing_field_mappings: anyObjectSchema.optional(),
745
+ entry_url_variable_mapping: anyObjectSchema.optional(),
746
+ })
747
+ .strict();
748
+ /**
749
+ * Оформление виджета — одиннадцать разделов ровно теми именами, которыми их принимает
750
+ * `general_settings.customization`.
751
+ *
752
+ * ⚠️ Внутренность раздела мост НЕ переописывает: это был бы второй реестр против схемы хранения
753
+ * besales-api, и он разошёлся бы с ней на первой же правке. Раздел сливается с сохранённым, так
754
+ * что частичное значение законно; пустой объект не сбрасывает ничего.
755
+ */
756
+ export const platformWidgetCustomizationSchema = z
757
+ .object({
758
+ button: anyObjectSchema.optional(),
759
+ window: anyObjectSchema.optional(),
760
+ theme: anyObjectSchema.optional(),
761
+ welcome_state: anyObjectSchema.optional(),
762
+ pre_chat_form: anyObjectSchema.optional(),
763
+ offline_state: anyObjectSchema.optional(),
764
+ languages: anyObjectSchema.optional(),
765
+ widget_ux: anyObjectSchema.optional(),
766
+ gdpr: anyObjectSchema.optional(),
767
+ embed: anyObjectSchema.optional(),
768
+ advanced: anyObjectSchema.optional(),
536
769
  })
537
770
  .strict();
538
771
  export const platformInstagramCommentSchema = z
539
772
  .object({
540
773
  reply_to_instagram_comments: z.boolean().optional(),
541
774
  instagram_comment_handling_mode: z.string().nullable().optional(),
542
- instagram_comment_reply_method: z.string().nullable().optional(),
543
- instagram_comment_keywords: anyObjectSchema.nullable().optional(),
775
+ instagram_comment_reply_method: z
776
+ .enum(['DM_ONLY', 'PUBLIC_REPLY', 'BOTH', 'PUBLIC_AND_DM'])
777
+ .optional(),
778
+ instagram_comment_templates: instagramCommentTemplatesSchema.nullable().optional(),
779
+ instagram_comment_keywords: z.array(z.string()).nullable().optional(),
544
780
  reply_to_story_mentions: z.boolean().optional(),
545
781
  })
546
782
  .strict();
547
783
  /**
548
- * Ссылка на стадию CRM ПОЛНЫМ композитом.
784
+ * Общие настройки канала. Четыре поля справедливы для любого канала, остальные — веб-виджет.
549
785
  *
550
- * ⚠️ Голый `status_id` не годится: статусы 142/143 и одноимённые стадии есть в КАЖДОЙ
551
- * воронке, и выбор по номеру попал бы не туда.
552
- */
553
- export const funnelStageRefSchema = z
554
- .object({
555
- pipeline_crm_id: z.string().min(1),
556
- pipeline_id: z.number().int(),
557
- status_id: z.number().int(),
558
- })
559
- .strict();
560
- /**
561
- * Настройки раздела «Воронка канала».
786
+ * ⛔ Список сайтов — МАССИВ строк, и проверка его формы остаётся на приёмной стороне. Здесь список
787
+ * объявлялся объектом, из-за чего отвергался мостом ещё до отправки. Элементом законны голый домен
788
+ * (`site.ru`), домен с портом (`site.ru:8443`), полный адрес (`https://site.ru`) и `*`, поэтому
789
+ * проверка «это URL» была бы ошибкой — она отвергла бы три законные формы из четырёх.
790
+ *
791
+ * ⚠️ Пустой список — законное значение со смыслом «не работать нигде»; приёмник его принимает, и
792
+ * мост не вправе быть строже.
562
793
  *
563
- * ⚠️ `null` у `decision_gate`/`path_target_stage` — СБРОС; отсутствие поля — «не трогать».
564
- * Бэкенд ДЕЛЕГИРУЕТ запись сервисам раздела, поэтому здесь нет своей валидации стадий:
565
- * «стадии разные» и «стадия есть в каталоге площадки» проверяет он, и второй набор правил
566
- * рядом разошёлся бы с первым.
794
+ * Лимит обращений — целое число от 1 до 600, как на приёмной стороне.
567
795
  */
568
- export const platformFunnelAnalyticsSchema = z
569
- .object({
570
- decision_gate: z
571
- .object({
572
- submitted: funnelStageRefSchema,
573
- approved: funnelStageRefSchema,
574
- rejected: funnelStageRefSchema,
575
- })
576
- .strict()
577
- .nullable()
578
- .optional(),
579
- path_target_stage: funnelStageRefSchema.nullable().optional(),
580
- engaged_inbound_count: z.number().int().min(2).max(20).nullable().optional(),
581
- stuck_threshold_hours: z.number().int().min(1).max(720).nullable().optional(),
582
- })
583
- .strict();
584
- // v1.5 Increment 4c — per-channel typed sections
585
796
  export const platformGeneralSettingsSchema = z
586
797
  .object({
587
798
  name: z.string().nullable().optional(),
588
799
  off_message: z.string().nullable().optional(),
589
800
  timezone: z.string().optional(),
590
801
  is_active: z.boolean().optional(),
802
+ // Выключатель ответов агента. Прежде жил в `access_control`, откуда приёмник его не принимает.
803
+ is_ai_enabled: z.boolean().optional(),
804
+ // Реестр поддерживаемых стран принадлежит API; мост передаёт строку либо снимает настройку.
805
+ phone_parsing_country: z.string().nullable().optional(),
806
+ // Веб-виджет.
807
+ allowed_origins: z.array(z.string()).optional(),
808
+ page_rules: platformWidgetPageRulesSchema.nullable().optional(),
809
+ rate_limit: z.number().int().positive().max(600).optional(),
810
+ show_page_info: z.boolean().optional(),
811
+ customization: platformWidgetCustomizationSchema.optional(),
591
812
  })
592
813
  .strict();
593
814
  export const platformSalebotSettingsSchema = z
@@ -616,25 +837,7 @@ export const platformBitrix24BotSettingsSchema = z
616
837
  ignore_crm_stage_gate: z.boolean().optional(),
617
838
  })
618
839
  .strict();
619
- /**
620
- * ⚠️ УСТАРЕЛО с 23.08.2026 и на поведение НЕ влияет. Оставлено, потому что API поле ещё
621
- * принимает, а старые записи его несут; снять можно только вместе с клиентами.
622
- *
623
- * Режим применялся ко ВСЕМУ списку разом: `RESTRICT` умел лишь сужать уже посчитанный выбор, а
624
- * Email/WhatsApp/SMS в него не попадали ни у кого (`bot_link` школы отдаёт vk/telegram/max) — то
625
- * есть их отметка была молчаливым no-op. Теперь список значит «слать сюда», а судьбу КАЖДОГО
626
- * канала решает сервер по фактам о контакте. «Отправить ещё и на почту» = добавить Email в
627
- * `channels` И перечислить мессенджеры явно; предлагать `ADD` больше НЕ нужно.
628
- */
629
- export const coldWelcomeChannelsModeEnum = z.enum(['RESTRICT', 'ADD']);
630
- /**
631
- * Режим правила предохранителя холодных отправок.
632
- *
633
- * OFF — правило выключено; WARN — сработавшее правило только записывается в аудит, отправка
634
- * идёт; BLOCK — отправка останавливается. По умолчанию `active_series` = BLOCK (правило,
635
- * из-за нарушения которого пришла жалоба клиента), остальные = WARN.
636
- */
637
- export const guardModeEnum = z.enum(['OFF', 'WARN', 'BLOCK']);
840
+ // Этот набор сверяется с контрактом в wave-transports.spec.ts; трогая его, смотри туда.
638
841
  export const getcourseTransportEnum = z.enum([
639
842
  'Site',
640
843
  'Email',
@@ -653,22 +856,6 @@ export const platformGetcourseDepartmentSchema = z
653
856
  label: z.string(),
654
857
  })
655
858
  .strict();
656
- const platformGetcourseWaveFieldBindingSchema = z
657
- .object({
658
- field_id: z.number().int().positive().max(2_147_483_647),
659
- field_label: z.string().trim().min(1),
660
- })
661
- .strict();
662
- const platformGetcourseWaveFieldBindingsSchema = z
663
- .object({
664
- product_value_source: z.enum(['CODE', 'NAME']),
665
- launch_type: platformGetcourseWaveFieldBindingSchema.optional(),
666
- product: platformGetcourseWaveFieldBindingSchema.optional(),
667
- segment: platformGetcourseWaveFieldBindingSchema.optional(),
668
- funnel: platformGetcourseWaveFieldBindingSchema.optional(),
669
- channels: platformGetcourseWaveFieldBindingSchema.optional(),
670
- })
671
- .strict();
672
859
  export const platformGetcourseSettingsSchema = z
673
860
  .object({
674
861
  account_domain: z.string().nullable().optional(),
@@ -678,8 +865,8 @@ export const platformGetcourseSettingsSchema = z
678
865
  departments: z.array(platformGetcourseDepartmentSchema).nullable().optional(),
679
866
  template_user_id: z.number().int().nullable().optional(),
680
867
  template_deal_id: z.number().int().nullable().optional(),
681
- // School-scoped bindings: роль durable-волны → custom field ID сделки GetCourse.
682
- // null очищает все bindings; undefined оставляет текущую настройку без изменений.
868
+ // Привязки ролей волны к полям сделки: объект ЗАМЕНЯЕТ сохранённые привязки целиком, null
869
+ // снимает все, отсутствие поля — «не трогать».
683
870
  wave_field_bindings: platformGetcourseWaveFieldBindingsSchema.nullable().optional(),
684
871
  // Phase 2 — маппинг «поле сделки GetCourse → платформенная переменная»: значение поля активной
685
872
  // сделки контакта читается в per-contact переменную (напр. AI_TOPIC → webinar_topic).
@@ -695,32 +882,36 @@ export const platformGetcourseSettingsSchema = z
695
882
  // Department-routing: id отдела GetCourse Inbox для авто-переноса прошедших inbound-фильтр
696
883
  // диалогов (+ авто-размьют filter-muted). null → выключено. Требует inbound-фильтр включённым.
697
884
  target_department_id: z.number().int().positive().nullable().optional(),
885
+ // Отдел ЖИВЫХ ЛЮДЕЙ: туда уезжает диалог, когда его передают человеку. null → передача
886
+ // выключена (ни одного обращения к школе).
887
+ // ⛔ Не путать с `target_department_id`: тот — отдел ВОРОНКИ, куда авто-перенос кладёт диалоги
888
+ // прошедших входящий фильтр сделки. Совпадение значений бэкенд отвергает: авто-перенос
889
+ // положил бы диалог прямо в очередь сотрудников, минуя все гейты передачи человеку.
890
+ operator_department_id: z.number().int().positive().nullable().optional(),
698
891
  // Ночная проверка доставки волн (04:00 МСК): крон читает кастомные поля сделки per-транспорт
699
892
  // (=1 → отправка была); аналитика рассылок платформы при включении учитывает только DELIVERED.
700
893
  delivery_check_enabled: z.boolean().optional(),
701
- // ПРЕДОХРАНИТЕЛИ ХОЛОДНЫХ ОТПРАВОК: не писать посреди вебинарной серии, поверх работы
702
- // менеджера по действующей заявке и оплатившему этот продукт. null → «не настраивали»,
703
- // действующее значение берётся из дефолта (active_series = BLOCK, остальные = WARN).
704
- guard_active_series: guardModeEnum.nullable().optional(),
705
- guard_active_application: guardModeEnum.nullable().optional(),
706
- guard_paid: guardModeEnum.nullable().optional(),
707
894
  /**
708
- * ТИХИЙ ПЕРИОД площадки в сутках: не писать человеку N суток после НАШЕГО касания —
709
- * отправки или шага календарной цепочки. Считается ПО ЧЕЛОВЕКУ; волна школы касанием НЕ
710
- * считается. `null` = «не настраивали», действующее значение 0 (правила нет); рекомендация
711
- * владельца — 7. Расписание судится своим `cooldown_days`, а не этим числом.
895
+ * СРОК ДОВЕРИЯ ОТВЕТУ ШКОЛЫ: сколько суток считать действующим её ответ «выбранными каналами
896
+ * человека не достать». Пока ответ свеж, импорт человека без карточки не заводит и школу о нём
897
+ * не спрашивает. `null` = «не настраивали», действующее значение 7; 0 = спрашивать школу каждый
898
+ * раз. Граница 0…365 — та же, что у сервера.
712
899
  */
713
- quiet_days: z.number().int().min(0).nullable().optional(),
714
- /**
715
- * СРОК ДОВЕРИЯ ОТВЕТУ ШКОЛЫ: сколько суток считать действующим её «привязанных мессенджеров
716
- * нет». Пока ответ свеж, импорт контакт не заводит и школу о нём не дёргает, а отбор
717
- * расписания не берёт его в подачу. `null` = «не настраивали», действующее значение 7;
718
- * 0 = спрашивать школу каждый раз.
719
- */
720
- reachability_ttl_days: z.number().int().min(0).max(365).nullable().optional(),
900
+ reachability_ttl_days: z
901
+ .number()
902
+ .int()
903
+ .min(0)
904
+ .max(GETCOURSE_REACHABILITY_TTL_DAYS_MAX)
905
+ .nullable()
906
+ .optional(),
721
907
  // «Транспорт → точное НАЗВАНИЕ кастомного поля сделки» (id в read-API GetCourse нет):
722
908
  // { "Telegram": "Отправлено ТГ", "VK": "Отправлено ВК" }. Очистка — пустым объектом {}.
723
- delivery_field_map: z.record(getcourseTransportEnum, z.string()).optional(),
909
+ // ⚠️ ИМЕННО `partialRecord`. В zod 4 `record(enum, …)` требует ВСЕ ключи перечисления, поэтому
910
+ // отгруженная версия отвергала и очистку `{}`, и пример из собственного описания
911
+ // (`{"Telegram":"Отправлено ТГ"}`) — десять и девять ошибок соответственно, ещё до HTTP.
912
+ // Поле было недостижимо с момента появления; JSON-схема реестра исчерпывающесть не выражала,
913
+ // поэтому клиент видел «поле необязательное», а мост его отвергал.
914
+ delivery_field_map: z.partialRecord(getcourseTransportEnum, z.string()).optional(),
724
915
  // Ручной мьют бота по контактному полю GetCourse: оператор меняет кастом-поле контакта в GK →
725
916
  // AI молчит (снятие — когда поле снова «вкл»/пусто). manual_mute_field_id = id (числовой строкой)
726
917
  // ИЛИ имя поля; manual_mute_value = стоп-значение(я) через запятую; manual_mute_active_value —
@@ -730,421 +921,47 @@ export const platformGetcourseSettingsSchema = z
730
921
  manual_mute_value: z.string().nullable().optional(),
731
922
  manual_mute_active_value: z.string().nullable().optional(),
732
923
  // Создание отсутствующего заказа в status-волне: контакт БЕЗ единой сделки иначе не получает
733
- // сообщение (поля проставлять некуда). Заказ создаётся по ПРЕДЛОЖЕНИЮ — legacy /pl/api/deals
734
- // иначе заказ не создаёт; бесплатное предложение даёт нулевую сумму. Воронка и этап —
735
- // необязательные уточнения (по умолчанию воронка предложения), внешние id GetCourse.
736
- // Создаёт РЕАЛЬНЫЕ заказы в школе → dangerous, требует explicit_confirmation.
924
+ // сообщение (поля проставлять некуда). Заказ создаётся по ПРЕДЛОЖЕНИЮ; воронка и этап —
925
+ // необязательные уточнения и задаются только парой. Создаёт РЕАЛЬНЫЕ заказы в школе →
926
+ // dangerous, требует explicit_confirmation.
737
927
  create_missing_deal_enabled: z.boolean().optional(),
738
928
  create_missing_deal_offer_id: z.number().int().positive().nullable().optional(),
739
929
  create_missing_deal_funnel_id: z.number().int().positive().nullable().optional(),
740
930
  create_missing_deal_stage_id: z.number().int().positive().nullable().optional(),
741
- // Офферы, оплата заказов с которыми засчитывается нам независимо от автора заказа (агент
742
- // или менеджер руками). Пустой массив = выключить. Набор действует на ШКОЛУ целиком.
743
- // Меняет денежную атрибуцию задним числом → dangerous, требует explicit_confirmation.
931
+ // Деньги канала: набор предложений, оплата которых — выручка ЭТОГО канала (буква в букву как у отгруженного
932
+ // клиента, иначе сравнение схем дало бы новую строку отставания), и момент начала зачёта — поле ветки v2 (у
933
+ // прежней системы дата жила у школы и выставлялась руками). Порядок «сначала дата, потом набор» держит сервер.
934
+ // Меняют деньги задним числом → explicit_confirmation. У канала виджета те же два поля — метка продажи (сервер
935
+ // хранит её своими ключами: метка только добавляет выручку).
744
936
  revenue_offer_ids: z.array(z.number().int().positive()).optional(),
937
+ revenue_offers_paid_since: z.string().datetime({ offset: true }).nullable().optional(),
745
938
  })
746
939
  .strict();
747
940
  // Knowledge tables (Group A.5)
748
- export const knowledgeTableSourceSchema = z.object({
941
+ // ⛔ Отказы живут в СХЕМЕ с путём, а не в конструкторе запроса: отказ без пути не называет поле, и сверка с
942
+ // отгруженным клиентом не может объявить его строкой отставания. `table_schema` прежний сервер лишь резервировал и не
943
+ // читал: принимаем копию, канонический конструктор её не передаёт. NATIVE прежний сервер отвергал сам.
944
+ export const knowledgeTableSourceSchema = z
945
+ .object({
749
946
  kind: z.enum(['GOOGLE_SHEETS', 'NATIVE']),
750
947
  spreadsheet_url: z.string().optional(),
751
948
  table_schema: anyObjectSchema.optional(),
752
- });
753
- export function defineTool(definition) {
754
- return definition;
755
- }
756
- export function compactObject(value) {
757
- return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== undefined));
758
- }
759
- export function compactMetadata(metadata) {
760
- if (!metadata) {
761
- return undefined;
762
- }
763
- const compacted = compactObject({
764
- totalTokens: metadata.total_tokens,
765
- models: metadata.models,
766
- });
767
- return Object.keys(compacted).length === 0 ? undefined : compacted;
768
- }
769
- export function setupConfirmation(input) {
770
- return compactObject({
771
- explicitConfirmation: input.explicit_confirmation,
772
- confirmationReason: input.confirmation_reason,
773
- });
774
- }
775
- export function withInstructions(response, instructions) {
776
- const text = instructions.join('\n');
777
- if (response && typeof response === 'object' && !Array.isArray(response)) {
778
- return {
779
- ...response,
780
- instructions: text,
781
- };
782
- }
783
- return {
784
- result: response,
785
- instructions: text,
786
- };
787
- }
788
- export function buildKnowledgeSpaceListQuery(scopeType, channelId) {
789
- const params = new URLSearchParams();
790
- if (scopeType)
791
- params.set('scope_type', scopeType);
792
- if (channelId)
793
- params.set('channel_id', channelId);
794
- const query = params.toString();
795
- return query.length > 0 ? `?${query}` : '';
796
- }
797
- export function buildListQuery(params) {
798
- const search = new URLSearchParams();
799
- for (const [key, value] of Object.entries(params)) {
800
- if (value === undefined) {
801
- continue;
802
- }
803
- // ⚠️ Массив уходит ПОВТОРЯЮЩИМИСЯ параметрами (`?f=A&f=B`) — именно так его читает бэкенд.
804
- // `String(['A','B'])` дал бы одну строку "A,B", и мультифильтр молча не сматчил бы ничего:
805
- // ответ 200, список пуст, ошибки нет.
806
- if (Array.isArray(value)) {
807
- for (const item of value) {
808
- search.append(key, item);
809
- }
810
- continue;
811
- }
812
- search.set(key, String(value));
813
- }
814
- const query = search.toString();
815
- return query.length > 0 ? `?${query}` : '';
816
- }
817
- export function buildVariableListQuery(scope, platformId, filter, limit, cursor) {
818
- const params = new URLSearchParams();
819
- params.set('scope', scope);
820
- if (platformId) {
821
- params.set('platformId', platformId);
822
- }
823
- if (filter) {
824
- params.set('filter', filter);
825
- }
826
- if (limit !== undefined) {
827
- params.set('limit', String(limit));
828
- }
829
- if (cursor) {
830
- params.set('cursor', cursor);
949
+ })
950
+ .superRefine((source, ctx) => {
951
+ if (source.kind === 'NATIVE') {
952
+ ctx.addIssue({
953
+ code: z.ZodIssueCode.custom,
954
+ path: ['kind'],
955
+ message: 'NATIVE-таблицы пока не поддерживаются v2: используй GOOGLE_SHEETS; поддержка NATIVE придёт отдельным маршрутом.',
956
+ });
831
957
  }
832
- const queryString = params.toString();
833
- return queryString ? `?${queryString}` : '';
834
- }
835
- export function buildVariableScopeQuery(scope, platformId) {
836
- const params = new URLSearchParams();
837
- params.set('scope', scope);
838
- if (platformId) {
839
- params.set('platformId', platformId);
958
+ if (source.kind === 'GOOGLE_SHEETS' && !source.spreadsheet_url) {
959
+ ctx.addIssue({
960
+ code: z.ZodIssueCode.custom,
961
+ path: ['spreadsheet_url'],
962
+ message: 'Для GOOGLE_SHEETS обязателен source.spreadsheet_url.',
963
+ });
840
964
  }
841
- return `?${params.toString()}`;
842
- }
843
- export function buildFileListQuery(input) {
844
- const params = new URLSearchParams();
845
- if (input.file_type)
846
- params.set('file_type', input.file_type);
847
- if (input.source)
848
- params.set('source', input.source);
849
- if (input.section_id !== undefined)
850
- params.set('section_id', input.section_id);
851
- if (input.limit !== undefined)
852
- params.set('limit', String(input.limit));
853
- if (input.offset !== undefined)
854
- params.set('offset', String(input.offset));
855
- const queryString = params.toString();
856
- return queryString ? `?${queryString}` : '';
857
- }
858
- // ============================================================
859
- // v1.5 Increment 3 — snake_case → camelCase input mappers
860
- // ============================================================
861
- export function mapRuntimeConfigInput(input) {
862
- return compactObject({
863
- temperature: input.temperature,
864
- maxTokens: input.max_tokens,
865
- memoryHistorySize: input.memory_history_size,
866
- ragTopK: input.rag_top_k,
867
- ragMinScore: input.rag_min_score,
868
- qaMinScore: input.qa_min_score,
869
- qaContextLimit: input.qa_context_limit,
870
- maxResponseSymbols: input.max_response_symbols,
871
- reasoningEffort: input.reasoning_effort,
872
- verbosity: input.verbosity,
873
- enableThinking: input.enable_thinking,
874
- timezone: input.timezone,
875
- languageCode: input.language_code,
876
- summarizeEvery: input.summarize_every,
877
- summaryMaxSize: input.summary_max_size,
878
- useSummary: input.use_summary,
879
- includeCrmFieldsInMemory: input.include_crm_fields_in_memory,
880
- includeTriggerContext: input.include_trigger_context,
881
- });
882
- }
883
- export function mapOutputConfigInput(input) {
884
- const buttonGenerator = input.button_generator;
885
- return compactObject({
886
- displayName: input.display_name,
887
- responseMode: input.response_mode,
888
- buttonGenerator: buttonGenerator
889
- ? compactObject({
890
- enabled: buttonGenerator.enabled,
891
- maxButtons: buttonGenerator.max_buttons,
892
- keyboardType: buttonGenerator.keyboard_type,
893
- dynamic: buttonGenerator.dynamic,
894
- })
895
- : undefined,
896
- });
897
- }
898
- export function mapBehaviorGreetingInput(input) {
899
- return compactObject({
900
- botGreeting: input.bot_greeting,
901
- greetingFileId: input.greeting_file_id,
902
- greetingButtons: input.greeting_buttons,
903
- greetingButtonsKeyboardType: input.greeting_buttons_keyboard_type,
904
- popupDelaySeconds: input.popup_delay_seconds,
905
- });
906
- }
907
- export function mapMediaHandlerInput(input) {
908
- if (!input)
909
- return undefined;
910
- return compactObject({
911
- behavior: input.behavior,
912
- fixedResponseText: input.fixed_response_text,
913
- callOperator: input.call_operator,
914
- operatorComment: input.operator_comment,
915
- });
916
- }
917
- export function mapBehaviorMediaHandlingInput(input) {
918
- return compactObject({
919
- image: mapMediaHandlerInput(input.image),
920
- video: mapMediaHandlerInput(input.video),
921
- audio: mapMediaHandlerInput(input.audio),
922
- document: mapMediaHandlerInput(input.document),
923
- });
924
- }
925
- export function mapBehaviorUrlHandlingInput(input) {
926
- return compactObject({
927
- behavior: input.behavior,
928
- fixedResponseText: input.fixed_response_text,
929
- callOperator: input.call_operator,
930
- operatorComment: input.operator_comment,
931
- useYoutubeDataApi: input.use_youtube_data_api,
932
- });
933
- }
934
- export function mapBehaviorErrorHandlingInput(input) {
935
- return compactObject({
936
- aiErrorBehavior: input.ai_error_behavior,
937
- aiErrorCustomMessage: input.ai_error_custom_message,
938
- callOperatorWithError: input.call_operator_with_error,
939
- aiErrorTargetStageId: input.ai_error_target_stage_id,
940
- });
941
- }
942
- export function mapBehaviorOperatorScheduleInput(input) {
943
- return compactObject({
944
- enabled: input.enabled,
945
- availability: input.availability,
946
- unavailableMessage: input.unavailable_message,
947
- botWaitingReturnHours: input.bot_waiting_return_hours,
948
- followUpWaitingReturnHours: input.follow_up_waiting_return_hours,
949
- skipTaskCreationOnCallOperator: input.skip_task_creation_on_call_operator,
950
- });
951
- }
952
- export function mapBehaviorTypingInput(input) {
953
- return compactObject({
954
- waitingAnswerTime: input.waiting_answer_time,
955
- canInterrupt: input.can_interrupt,
956
- messageDevide: input.message_devide,
957
- typingSpeed: input.typing_speed,
958
- fakeDelay: input.fake_delay,
959
- messageOpenDelay: input.message_open_delay,
960
- goOffline: input.go_offline,
961
- });
962
- }
963
- export function mapPipelineCrmBehaviorInput(input) {
964
- return compactObject({
965
- activePipelineIds: input.active_pipeline_ids,
966
- filterEnabled: input.filter_enabled,
967
- statusMovement: input.status_movement,
968
- createDefaults: input.create_defaults,
969
- global: input.global,
970
- });
971
- }
972
- export function mapPipelineAutoFinishInput(input) {
973
- return compactObject({
974
- finishAutoNoanswer: input.finish_auto_noanswer,
975
- finishAutoTimeout: input.finish_auto_timeout,
976
- finishAutoDays: input.finish_auto_days,
977
- sendFinishAutoNoteToCrm: input.send_finish_auto_note_to_crm,
978
- finishAutoNoteTemplate: input.finish_auto_note_template,
979
- });
980
- }
981
- export function mapPlatformAccessControlInput(input) {
982
- return compactObject({
983
- isActive: input.is_active,
984
- isAiEnabled: input.is_ai_enabled,
985
- isUserFilterEnabled: input.is_user_filter_enabled,
986
- filteredUserIds: input.filtered_user_ids,
987
- // v1.5 Increment 4c
988
- enableCleanupCommands: input.enable_cleanup_commands,
989
- });
990
- }
991
- export function mapPlatformVariablesConfigInput(input) {
992
- return compactObject({
993
- enableDynamicVariables: input.enable_dynamic_variables,
994
- clearDynamicVarsOnHistoryClear: input.clear_dynamic_vars_on_history_clear,
995
- });
996
- }
997
- export function mapPlatformCrmBehaviorInput(input) {
998
- return compactObject({
999
- sendToCrm: input.send_to_crm,
1000
- useCrossPlatformHistory: input.use_cross_platform_history,
1001
- responsibleAssigneeStrategy: input.responsible_assignee_strategy,
1002
- fixedResponsibleId: input.fixed_responsible_id,
1003
- sendStartNoteToCrm: input.send_start_note_to_crm,
1004
- startNoteTemplate: input.start_note_template,
1005
- sendFailedNoteToCrm: input.send_failed_note_to_crm,
1006
- failedNoteTemplate: input.failed_note_template,
1007
- sendOperatorTakeoverNoteToCrm: input.send_operator_takeover_note_to_crm,
1008
- operatorTakeoverNoteTemplate: input.operator_takeover_note_template,
1009
- // v1.5 Increment 4c — deal marker
1010
- dealMarkerType: input.deal_marker_type,
1011
- dealMarkerValue: input.deal_marker_value,
1012
- dealMarkerFieldId: input.deal_marker_field_id,
1013
- // Inbound deal-фильтр (GetCourse)
1014
- inboundDealFilterEnabled: input.inbound_deal_filter_enabled,
1015
- inboundDealFilterType: input.inbound_deal_filter_type,
1016
- inboundDealFilterValue: input.inbound_deal_filter_value,
1017
- inboundDealFilterFieldId: input.inbound_deal_filter_field_id,
1018
- });
1019
- }
1020
- export function mapPlatformWidgetMarketingInput(input) {
1021
- return compactObject({
1022
- webWidgetAllowedOrigins: input.web_widget_allowed_origins,
1023
- webWidgetShowPageInfo: input.web_widget_show_page_info,
1024
- webWidgetRateLimitPerMinute: input.web_widget_rate_limit_per_minute,
1025
- webWidgetCustomization: input.web_widget_customization,
1026
- webWidgetMarketingFieldMappings: input.web_widget_marketing_field_mappings,
1027
- webWidgetEntryUrlVariableMapping: input.web_widget_entry_url_variable_mapping,
1028
- });
1029
- }
1030
- export function mapPlatformInstagramCommentInput(input) {
1031
- return compactObject({
1032
- replyToInstagramComments: input.reply_to_instagram_comments,
1033
- instagramCommentHandlingMode: input.instagram_comment_handling_mode,
1034
- instagramCommentReplyMethod: input.instagram_comment_reply_method,
1035
- instagramCommentKeywords: input.instagram_comment_keywords,
1036
- replyToStoryMentions: input.reply_to_story_mentions,
1037
- });
1038
- }
1039
- const mapFunnelStageRef = (ref) => ref == null
1040
- ? ref
1041
- : {
1042
- pipelineCrmId: ref.pipeline_crm_id,
1043
- pipelineId: ref.pipeline_id,
1044
- statusId: ref.status_id,
1045
- };
1046
- export function mapPlatformFunnelAnalyticsInput(input) {
1047
- // ⚠️ `compactObject` выбрасывает только `undefined`: `null` доезжает до бэкенда и означает
1048
- // СБРОС. Схлопни мы их — «сбросить ворота» стало бы неотличимо от «не трогать их».
1049
- return compactObject({
1050
- decisionGate: input.decision_gate === undefined
1051
- ? undefined
1052
- : input.decision_gate === null
1053
- ? null
1054
- : {
1055
- submitted: mapFunnelStageRef(input.decision_gate.submitted),
1056
- approved: mapFunnelStageRef(input.decision_gate.approved),
1057
- rejected: mapFunnelStageRef(input.decision_gate.rejected),
1058
- },
1059
- pathTargetStage: mapFunnelStageRef(input.path_target_stage),
1060
- engagedInboundCount: input.engaged_inbound_count,
1061
- stuckThresholdHours: input.stuck_threshold_hours,
1062
- });
1063
- }
1064
- // v1.5 Increment 4c — per-channel typed section mappers
1065
- export function mapPlatformGeneralSettingsInput(input) {
1066
- return compactObject({
1067
- name: input.name,
1068
- offMessage: input.off_message,
1069
- timezone: input.timezone,
1070
- isActive: input.is_active,
1071
- });
1072
- }
1073
- export function mapPlatformSalebotSettingsInput(input) {
1074
- return compactObject({
1075
- projectId: input.project_id,
1076
- groupId: input.group_id,
1077
- });
1078
- }
1079
- export function mapPlatformSmsgorodSettingsInput(input) {
1080
- return compactObject({
1081
- channel: input.channel,
1082
- sender: input.sender,
1083
- });
1084
- }
1085
- export function mapPlatformBitrix24BotSettingsInput(input) {
1086
- return compactObject({
1087
- botId: input.bot_id,
1088
- botCode: input.bot_code,
1089
- botName: input.bot_name,
1090
- openLineId: input.open_line_id,
1091
- ignoreCrmStageGate: input.ignore_crm_stage_gate,
1092
- });
1093
- }
1094
- export function mapPlatformGetcourseSettingsInput(input) {
1095
- const mapWaveFieldBinding = (binding) => binding
1096
- ? {
1097
- fieldId: binding.field_id,
1098
- fieldLabel: binding.field_label,
1099
- }
1100
- : undefined;
1101
- return compactObject({
1102
- accountDomain: input.account_domain,
1103
- employeeUserId: input.employee_user_id,
1104
- availableTransports: input.available_transports,
1105
- defaultTransport: input.default_transport,
1106
- departments: input.departments,
1107
- templateUserId: input.template_user_id,
1108
- templateDealId: input.template_deal_id,
1109
- waveFieldBindings: input.wave_field_bindings == null
1110
- ? input.wave_field_bindings
1111
- : compactObject({
1112
- productValueSource: input.wave_field_bindings.product_value_source,
1113
- launchType: mapWaveFieldBinding(input.wave_field_bindings.launch_type),
1114
- product: mapWaveFieldBinding(input.wave_field_bindings.product),
1115
- segment: mapWaveFieldBinding(input.wave_field_bindings.segment),
1116
- funnel: mapWaveFieldBinding(input.wave_field_bindings.funnel),
1117
- channels: mapWaveFieldBinding(input.wave_field_bindings.channels),
1118
- }),
1119
- // null → очистить маппинг; undefined → не трогать (compactObject стрипнет); массив → snake→camel.
1120
- fieldVariableMap: input.field_variable_map == null
1121
- ? input.field_variable_map
1122
- : input.field_variable_map.map((entry) => ({
1123
- getcourseFieldName: entry.getcourse_field_name,
1124
- variableName: entry.variable_name,
1125
- })),
1126
- targetDepartmentId: input.target_department_id,
1127
- deliveryCheckEnabled: input.delivery_check_enabled,
1128
- guardActiveSeries: input.guard_active_series,
1129
- guardActiveApplication: input.guard_active_application,
1130
- guardPaid: input.guard_paid,
1131
- quietDays: input.quiet_days,
1132
- reachabilityTtlDays: input.reachability_ttl_days,
1133
- // Ключи map — значения enum транспортов (совпадают с camelCase-контрактом бэка) → as-is
1134
- deliveryFieldMap: input.delivery_field_map,
1135
- // Ручной мьют GetCourse: null → очистить поле; undefined → не трогать (compactObject стрипнет).
1136
- manualMuteEnabled: input.manual_mute_enabled,
1137
- manualMuteFieldId: input.manual_mute_field_id,
1138
- manualMuteValue: input.manual_mute_value,
1139
- manualMuteActiveValue: input.manual_mute_active_value,
1140
- // Создание отсутствующего заказа: null → очистить, undefined → не трогать
1141
- createMissingDealEnabled: input.create_missing_deal_enabled,
1142
- createMissingDealOfferId: input.create_missing_deal_offer_id,
1143
- createMissingDealFunnelId: input.create_missing_deal_funnel_id,
1144
- createMissingDealStageId: input.create_missing_deal_stage_id,
1145
- // Офферы зачёта выручки: пустой массив — валидное значение «выключить», поэтому передаём
1146
- // как есть; undefined отстрипнет compactObject.
1147
- revenueOfferIds: input.revenue_offer_ids,
1148
- });
1149
- }
965
+ });
966
+ export * from './shared-input.helpers.js';
1150
967
  //# sourceMappingURL=shared.js.map