@besales/mcp 0.45.0 → 0.47.0

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 (189) hide show
  1. package/README.md +96 -55
  2. package/dist/auth/connection-store.d.ts +21 -1
  3. package/dist/auth/connection-store.js +46 -2
  4. package/dist/auth/connection-store.js.map +1 -1
  5. package/dist/auth/oauth-client.d.ts +5 -1
  6. package/dist/auth/oauth-client.js +22 -12
  7. package/dist/auth/oauth-client.js.map +1 -1
  8. package/dist/cli.js +14 -5
  9. package/dist/cli.js.map +1 -1
  10. package/dist/http/api-client.d.ts +16 -1
  11. package/dist/http/api-client.js +50 -2
  12. package/dist/http/api-client.js.map +1 -1
  13. package/dist/instructions/server-instructions.d.ts +4 -13
  14. package/dist/instructions/server-instructions.js +68 -274
  15. package/dist/instructions/server-instructions.js.map +1 -1
  16. package/dist/prompts/registry.d.ts +15 -0
  17. package/dist/prompts/registry.js +83 -0
  18. package/dist/prompts/registry.js.map +1 -0
  19. package/dist/resources/concepts/feedback-sheets.md +7 -4
  20. package/dist/resources/concepts/handoff.md +4 -1
  21. package/dist/resources/concepts/sandbox.md +14 -5
  22. package/dist/resources/concepts/triggers.md +6 -2
  23. package/dist/resources/concepts/workbook-classification.md +26 -21
  24. package/dist/resources/docs/campaigns.md +20 -0
  25. package/dist/resources/docs/crm-integration.md +3 -1
  26. package/dist/resources/docs/follow-up.md +19 -0
  27. package/dist/resources/docs/platforms.md +2 -2
  28. package/dist/resources/docs/routing.md +18 -0
  29. package/dist/resources/docs/task-state.md +30 -0
  30. package/dist/resources/docs/trigger-actions.md +28 -0
  31. package/dist/resources/docs/variables.md +18 -0
  32. package/dist/resources/registry.js +51 -2
  33. package/dist/resources/registry.js.map +1 -1
  34. package/dist/resources/workflows/compare-models.md +4 -3
  35. package/dist/resources/workflows/connect-crm-from-scratch.md +8 -0
  36. package/dist/resources/workflows/extract-from-document.md +8 -1
  37. package/dist/resources/workflows/iterate-with-sandbox.md +5 -2
  38. package/dist/resources/workflows/platform-setup-from-scratch.md +90 -2
  39. package/dist/resources/workflows/production-readiness-check.md +22 -18
  40. package/dist/schemas/mcp-tools.json +1537 -177
  41. package/dist/server.d.ts +2 -0
  42. package/dist/server.js +8 -2
  43. package/dist/server.js.map +1 -1
  44. package/dist/tasks/task-state-store.d.ts +68 -0
  45. package/dist/tasks/task-state-store.js +278 -0
  46. package/dist/tasks/task-state-store.js.map +1 -0
  47. package/dist/tools/annotations.d.ts +7 -0
  48. package/dist/tools/annotations.js +16 -0
  49. package/dist/tools/annotations.js.map +1 -0
  50. package/dist/tools/contracts.js +7 -1
  51. package/dist/tools/contracts.js.map +1 -1
  52. package/dist/tools/definitions/agent-design.d.ts +49 -20
  53. package/dist/tools/definitions/agent-design.js +192 -19
  54. package/dist/tools/definitions/agent-design.js.map +1 -1
  55. package/dist/tools/definitions/analytics.d.ts +40 -0
  56. package/dist/tools/definitions/analytics.js +233 -0
  57. package/dist/tools/definitions/analytics.js.map +1 -0
  58. package/dist/tools/definitions/broadcast-analytics.d.ts +5 -4
  59. package/dist/tools/definitions/broadcast-analytics.js +26 -4
  60. package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
  61. package/dist/tools/definitions/broadcast-mailing-variants.d.ts +2 -0
  62. package/dist/tools/definitions/broadcast-mailing-variants.js +10 -0
  63. package/dist/tools/definitions/broadcast-mailing-variants.js.map +1 -1
  64. package/dist/tools/definitions/broadcast-scheduler.d.ts +20 -1
  65. package/dist/tools/definitions/broadcast-scheduler.js +134 -8
  66. package/dist/tools/definitions/broadcast-scheduler.js.map +1 -1
  67. package/dist/tools/definitions/contacts.d.ts +15 -0
  68. package/dist/tools/definitions/contacts.js +84 -0
  69. package/dist/tools/definitions/contacts.js.map +1 -0
  70. package/dist/tools/definitions/crm-platform.d.ts +2 -0
  71. package/dist/tools/definitions/crm-platform.js +95 -5
  72. package/dist/tools/definitions/crm-platform.js.map +1 -1
  73. package/dist/tools/definitions/datasource.d.ts +1 -0
  74. package/dist/tools/definitions/datasource.js +16 -1
  75. package/dist/tools/definitions/datasource.js.map +1 -1
  76. package/dist/tools/definitions/dialogue-audit.d.ts +2 -2
  77. package/dist/tools/definitions/dialogue-audit.js +54 -16
  78. package/dist/tools/definitions/dialogue-audit.js.map +1 -1
  79. package/dist/tools/definitions/dialogue-export.d.ts +1 -1
  80. package/dist/tools/definitions/dialogue-export.js +12 -0
  81. package/dist/tools/definitions/dialogue-export.js.map +1 -1
  82. package/dist/tools/definitions/external-api-channels.js +39 -12
  83. package/dist/tools/definitions/external-api-channels.js.map +1 -1
  84. package/dist/tools/definitions/follow-up-funnel-test.js +4 -0
  85. package/dist/tools/definitions/follow-up-funnel-test.js.map +1 -1
  86. package/dist/tools/definitions/follow-up-setup.js +3 -0
  87. package/dist/tools/definitions/follow-up-setup.js.map +1 -1
  88. package/dist/tools/definitions/follow-up.d.ts +1 -1
  89. package/dist/tools/definitions/follow-up.js +6 -0
  90. package/dist/tools/definitions/follow-up.js.map +1 -1
  91. package/dist/tools/definitions/getcourse-anchor-refresh.d.ts +3 -0
  92. package/dist/tools/definitions/getcourse-anchor-refresh.js +29 -2
  93. package/dist/tools/definitions/getcourse-anchor-refresh.js.map +1 -1
  94. package/dist/tools/definitions/getcourse-cold-welcome.d.ts +20 -2
  95. package/dist/tools/definitions/getcourse-cold-welcome.js +128 -7
  96. package/dist/tools/definitions/getcourse-cold-welcome.js.map +1 -1
  97. package/dist/tools/definitions/getcourse-wave.js +14 -0
  98. package/dist/tools/definitions/getcourse-wave.js.map +1 -1
  99. package/dist/tools/definitions/help.d.ts +8 -0
  100. package/dist/tools/definitions/help.js +219 -0
  101. package/dist/tools/definitions/help.js.map +1 -0
  102. package/dist/tools/definitions/knowledge.d.ts +27 -5
  103. package/dist/tools/definitions/knowledge.js +200 -33
  104. package/dist/tools/definitions/knowledge.js.map +1 -1
  105. package/dist/tools/definitions/link-tracking.js +31 -0
  106. package/dist/tools/definitions/link-tracking.js.map +1 -1
  107. package/dist/tools/definitions/model-comparison.js +12 -3
  108. package/dist/tools/definitions/model-comparison.js.map +1 -1
  109. package/dist/tools/definitions/operational-overview.d.ts +3 -0
  110. package/dist/tools/definitions/operational-overview.js +23 -0
  111. package/dist/tools/definitions/operational-overview.js.map +1 -0
  112. package/dist/tools/definitions/operator-workflow.d.ts +20 -0
  113. package/dist/tools/definitions/operator-workflow.js +114 -0
  114. package/dist/tools/definitions/operator-workflow.js.map +1 -0
  115. package/dist/tools/definitions/platform-setup.d.ts +54 -3
  116. package/dist/tools/definitions/platform-setup.js +211 -5
  117. package/dist/tools/definitions/platform-setup.js.map +1 -1
  118. package/dist/tools/definitions/scheduled-tasks.js +2 -0
  119. package/dist/tools/definitions/scheduled-tasks.js.map +1 -1
  120. package/dist/tools/definitions/session.js +103 -5
  121. package/dist/tools/definitions/session.js.map +1 -1
  122. package/dist/tools/definitions/shared.d.ts +272 -10
  123. package/dist/tools/definitions/shared.js +154 -8
  124. package/dist/tools/definitions/shared.js.map +1 -1
  125. package/dist/tools/definitions/task-state.d.ts +76 -0
  126. package/dist/tools/definitions/task-state.js +301 -0
  127. package/dist/tools/definitions/task-state.js.map +1 -0
  128. package/dist/tools/definitions/trigger-contact-claims.d.ts +7 -0
  129. package/dist/tools/definitions/trigger-contact-claims.js +60 -0
  130. package/dist/tools/definitions/trigger-contact-claims.js.map +1 -0
  131. package/dist/tools/definitions.d.ts +334 -35
  132. package/dist/tools/definitions.js +14 -0
  133. package/dist/tools/definitions.js.map +1 -1
  134. package/dist/tools/description-localization.d.ts +2 -0
  135. package/dist/tools/description-localization.js +46 -0
  136. package/dist/tools/description-localization.js.map +1 -0
  137. package/dist/tools/incomplete-list.d.ts +23 -0
  138. package/dist/tools/incomplete-list.js +39 -0
  139. package/dist/tools/incomplete-list.js.map +1 -0
  140. package/dist/tools/inventory.d.ts +10 -0
  141. package/dist/tools/inventory.js +49 -0
  142. package/dist/tools/inventory.js.map +1 -0
  143. package/dist/tools/registry-mapping-cases-core.js +122 -4
  144. package/dist/tools/registry-mapping-cases-core.js.map +1 -1
  145. package/dist/tools/registry-mapping-cases-platform.js +69 -0
  146. package/dist/tools/registry-mapping-cases-platform.js.map +1 -1
  147. package/dist/tools/registry.d.ts +2 -0
  148. package/dist/tools/registry.js +60 -8
  149. package/dist/tools/registry.js.map +1 -1
  150. package/dist/tools/result-envelope.d.ts +46 -0
  151. package/dist/tools/result-envelope.js +184 -0
  152. package/dist/tools/result-envelope.js.map +1 -0
  153. package/dist/tools/result.d.ts +41 -3
  154. package/dist/tools/result.js +229 -27
  155. package/dist/tools/result.js.map +1 -1
  156. package/dist/tools/tool-title.d.ts +2 -0
  157. package/dist/tools/tool-title.js +12 -0
  158. package/dist/tools/tool-title.js.map +1 -0
  159. package/dist/tools/toolsets.d.ts +37 -0
  160. package/dist/tools/toolsets.js +64 -0
  161. package/dist/tools/toolsets.js.map +1 -0
  162. package/dist/tools/trigger-action-config.js +4 -0
  163. package/dist/tools/trigger-action-config.js.map +1 -1
  164. package/dist/tools/verify-with.d.ts +5 -0
  165. package/dist/tools/verify-with.js +36 -0
  166. package/dist/tools/verify-with.js.map +1 -0
  167. package/dist/types/api-contract.gen.d.ts +2612 -332
  168. package/dist/utils/logger.d.ts +11 -0
  169. package/dist/utils/logger.js +64 -8
  170. package/dist/utils/logger.js.map +1 -1
  171. package/docs/agent-usage-guide.full.ru.md +21 -15
  172. package/docs/agent-usage-guide.ru.md +24 -16
  173. package/docs/async-operation-lifecycle.md +46 -0
  174. package/docs/connect.ru.md +120 -0
  175. package/docs/evals/model-behavior-scorecard.md +80 -0
  176. package/docs/failure-semantics.md +56 -0
  177. package/docs/help-navigation.md +48 -0
  178. package/docs/host-compatibility-matrix.md +153 -0
  179. package/docs/host-setup.md +22 -6
  180. package/docs/operation-coverage.md +114 -0
  181. package/docs/pii-policy.md +46 -0
  182. package/docs/response-size-budget.md +150 -0
  183. package/docs/task-state.md +58 -0
  184. package/docs/tool-effects.md +46 -0
  185. package/docs/tool-surface.md +91 -0
  186. package/package.json +6 -2
  187. package/scripts/model-eval-server.js +213 -0
  188. package/scripts/probe-mcp-protocol.js +134 -0
  189. package/scripts/run-model-eval.js +447 -0
@@ -1,11 +1,13 @@
1
1
  import { z } from 'zod';
2
+ import { assertCompleteList } from '../incomplete-list.js';
2
3
  import { followUpSetupTools } from './follow-up-setup.js';
3
4
  import { getCourseWaveTools } from './getcourse-wave.js';
4
5
  import { normalizeTriggerActions } from '../trigger-action-config.js';
5
- import { agentOutputConfigSchema, agentRuntimeConfigSchema, agentScopeSchema, agentToolPatchSchema, anyObjectSchema, behaviorErrorHandlingSchema, behaviorGreetingSchema, behaviorMediaHandlingSchema, behaviorMessageFilterSchema, behaviorMessageSplittingSchema, behaviorOperatorScheduleSchema, behaviorPrivacySchema, behaviorTypingBehaviorSchema, behaviorUrlHandlingSchema, buildListQuery, compactObject, defineTool, feedbackSheetRowSchema, mapBehaviorErrorHandlingInput, mapBehaviorGreetingInput, mapBehaviorMediaHandlingInput, mapBehaviorOperatorScheduleInput, mapBehaviorTypingInput, mapBehaviorUrlHandlingInput, mapOutputConfigInput, mapPipelineAutoFinishInput, mapPipelineCrmBehaviorInput, mapPlatformAccessControlInput, mapPlatformBitrix24BotSettingsInput, mapPlatformCrmBehaviorInput, mapPlatformGeneralSettingsInput, mapPlatformGetcourseSettingsInput, mapPlatformInstagramCommentInput, mapPlatformSalebotSettingsInput, mapPlatformSmsgorodSettingsInput, mapPlatformVariablesConfigInput, mapPlatformWidgetMarketingInput, mapRuntimeConfigInput, modelLaneSchema, pipelineAutoFinishSchema, pipelineCrmBehaviorSchema, platformAccessControlSchema, platformBitrix24BotSettingsSchema, platformCrmBehaviorSchema, platformGeneralSettingsSchema, platformGetcourseSettingsSchema, platformInstagramCommentSchema, platformSalebotSettingsSchema, platformSetupConfirmationSchema, platformSmsgorodSettingsSchema, platformVariablesConfigSchema, mapPromptPatchOperationInput, platformWidgetMarketingSchema, PROMPT_BATCH_IDEMPOTENCY_KEY_MAX_LENGTH, PROMPT_BATCH_MAX_AGENTS, PROMPT_DIFF_MAX_LINES_LIMIT, promptPatchOperationSchema, routingRuleConditionSchema, routingRuleLeadStatusSchema, routingStrategySchema, setupConfirmation, triggerScopeSchema, uuidSchema, withInstructions, } from './shared.js';
6
+ import { PLATFORM_AGENTS_MAX_PAGE_SIZE, agentOutputConfigSchema, agentRuntimeConfigSchema, agentScopeSchema, agentToolPatchSchema, anyObjectSchema, behaviorErrorHandlingSchema, behaviorGreetingSchema, behaviorMediaHandlingSchema, behaviorMessageFilterSchema, behaviorMessageSplittingSchema, behaviorOperatorScheduleSchema, behaviorPrivacySchema, behaviorTypingBehaviorSchema, behaviorUrlHandlingSchema, buildListQuery, compactObject, defineTool, feedbackSheetRowSchema, mapBehaviorErrorHandlingInput, mapBehaviorGreetingInput, mapBehaviorMediaHandlingInput, mapBehaviorOperatorScheduleInput, mapBehaviorTypingInput, mapBehaviorUrlHandlingInput, mapOutputConfigInput, mapPipelineAutoFinishInput, mapPipelineCrmBehaviorInput, mapPlatformAccessControlInput, mapPlatformBitrix24BotSettingsInput, mapPlatformCrmBehaviorInput, mapPlatformGeneralSettingsInput, mapPlatformGetcourseSettingsInput, mapPlatformFunnelAnalyticsInput, mapPlatformInstagramCommentInput, mapPlatformSalebotSettingsInput, mapPlatformSmsgorodSettingsInput, mapPlatformVariablesConfigInput, mapPlatformWidgetMarketingInput, mapRuntimeConfigInput, modelLaneSchema, pipelineAutoFinishSchema, pipelineCrmBehaviorSchema, platformAccessControlSchema, platformBitrix24BotSettingsSchema, platformCrmBehaviorSchema, platformGeneralSettingsSchema, platformGetcourseSettingsSchema, platformFunnelAnalyticsSchema, platformInstagramCommentSchema, platformSalebotSettingsSchema, platformSetupConfirmationSchema, platformSmsgorodSettingsSchema, platformVariablesConfigSchema, mapPromptPatchOperationInput, platformWidgetMarketingSchema, PROMPT_BATCH_IDEMPOTENCY_KEY_MAX_LENGTH, PROMPT_BATCH_MAX_AGENTS, PROMPT_DIFF_MAX_LINES_LIMIT, promptPatchOperationSchema, routingRuleConditionSchema, routingRuleLeadStatusSchema, routingStrategySchema, setupConfirmation, triggerScopeSchema, uuidSchema, withInstructions, } from './shared.js';
6
7
  export const platformSetupTools = [
7
8
  defineTool({
8
9
  name: 'besales_workspace_overview',
10
+ sideEffect: 'none',
9
11
  requiredFields: [],
10
12
  defaultWorkspaceId: true,
11
13
  schema: z.object({
@@ -22,36 +24,178 @@ export const platformSetupTools = [
22
24
  'После overview перейди на drill-down: `besales_platform_context_get` для конкретной платформы, `besales_agent_list` для агентов внутри неё.',
23
25
  ]),
24
26
  }),
27
+ defineTool({
28
+ name: 'besales_workspace_navigate',
29
+ sideEffect: 'none',
30
+ closedWorld: true,
31
+ requiredFields: ['intent'],
32
+ defaultWorkspaceId: true,
33
+ resultPolicy: { neverTruncate: true },
34
+ schema: z
35
+ .object({
36
+ workspace_id: uuidSchema.optional(),
37
+ intent: z.enum([
38
+ 'CREATE_BOT',
39
+ 'IMPROVE_AGENT',
40
+ 'DIAGNOSE_CONTACT',
41
+ 'AUDIT_DIALOGUES',
42
+ 'CAMPAIGN_REPORT',
43
+ 'CONNECT_CRM',
44
+ 'CONNECT_DATASOURCE',
45
+ 'CONFIGURE_FOLLOWUP',
46
+ 'CONTINUE_TASK',
47
+ 'FREEFORM',
48
+ ]),
49
+ bot_type: z.enum(['FAQ', 'SALES', 'BOOKING', 'OUTBOUND', 'SUPPORT', 'UNKNOWN']).optional(),
50
+ platform_id: uuidSchema.optional(),
51
+ agent_id: uuidSchema.optional(),
52
+ contact_id: uuidSchema.optional(),
53
+ task_id: uuidSchema.optional(),
54
+ question: z.string().trim().min(2).max(500).optional(),
55
+ })
56
+ .strict(),
57
+ createRequest: (input) => ({
58
+ method: 'POST',
59
+ path: `/workspaces/${input.workspace_id}/navigation`,
60
+ body: compactObject({
61
+ intent: input.intent,
62
+ botType: input.bot_type,
63
+ platformId: input.platform_id,
64
+ agentId: input.agent_id,
65
+ contactId: input.contact_id,
66
+ taskId: input.task_id,
67
+ question: input.question,
68
+ }),
69
+ }),
70
+ enhanceResponse: (response) => withInstructions(response, [
71
+ 'next.tool и next.arguments — один адресный следующий шаг; placeholders перечислены в requiredUserInput и не должны угадываться.',
72
+ 'Сохранённый overview — evidence только на момент ответа. Перед записью перечитай выбранный объект, а после записи выполни next.verifyWith.',
73
+ 'CREATE_BOT учитывает bot_type: FAQ не требует ICP/CRM автоматически, SALES/BOOKING/OUTBOUND требуют ICP и условий до доказательства готовности.',
74
+ 'FREEFORM возвращает help route и не запускает обязательный шестишаговый мастер.',
75
+ ]),
76
+ }),
25
77
  defineTool({
26
78
  name: 'besales_platform_context_get',
79
+ sideEffect: 'none',
27
80
  requiredFields: ['platform_id'],
81
+ resultPolicy: {
82
+ neverTruncate: true,
83
+ droppablePaths: ['agents[].baseSystemPrompt'],
84
+ narrowingHint: 'Снимок канала отдаётся целиком и на канале с десятками агентов не помещается в ответ. Работайте по одному агенту: besales_agent_list для перечня, besales_prompt_patch_get для промпта.',
85
+ },
28
86
  schema: z.object({
29
87
  platform_id: uuidSchema,
88
+ sections: z
89
+ .array(z.enum([
90
+ 'platform',
91
+ 'agent_summaries',
92
+ 'agents_full',
93
+ 'router',
94
+ 'behavior',
95
+ 'follow_up',
96
+ 'pipeline_settings',
97
+ 'readiness',
98
+ ]))
99
+ .min(1)
100
+ .optional(),
30
101
  }),
31
102
  createRequest: (input) => ({
32
103
  method: 'GET',
33
- path: `/platforms/${input.platform_id}/setup/context`,
104
+ path: `/platforms/${input.platform_id}/setup/context` +
105
+ (input.sections
106
+ ? `?sections=${encodeURIComponent(input.sections.join(','))}`
107
+ : ''),
34
108
  }),
35
109
  enhanceResponse: (response) => withInstructions(response, [
36
- 'Use this sanitized context first for Platform Setup Bridge flows.',
110
+ 'Для точечного чтения передай sections; agent_summaries не содержит полный промпт, agents_full содержит.',
37
111
  'Read readiness flags, then call targeted mutation tools. Do not ask the user for workspace_id.',
38
112
  'Prompt content changes still go through besales_prompt_* tools and besales_prompt_finalize.',
39
113
  ]),
40
114
  }),
115
+ defineTool({
116
+ name: 'besales_trigger_action_catalog_get',
117
+ sideEffect: 'none',
118
+ requiredFields: ['platform_id'],
119
+ resultPolicy: { neverTruncate: true },
120
+ schema: z.object({
121
+ platform_id: uuidSchema,
122
+ action_type: z.string().trim().min(1).optional(),
123
+ }),
124
+ createRequest: (input) => ({
125
+ method: 'GET',
126
+ path: `/platforms/${input.platform_id}/setup/trigger-action-catalog` +
127
+ (input.action_type ? `?actionType=${encodeURIComponent(input.action_type)}` : ''),
128
+ }),
129
+ enhanceResponse: (response) => withInstructions(response, [
130
+ 'Каталог построен из боевого CreateTriggerActionDto и канона TRIGGER_ACTION_CONFIG.',
131
+ 'Перед созданием нового actionType запроси его отдельно через action_type и используй minimalExample без угадывания имени config-поля.',
132
+ 'После записи выполни verification из записи каталога; перечитывание контекста проверяет сохранение, но не внешний эффект.',
133
+ ]),
134
+ }),
41
135
  defineTool({
42
136
  name: 'besales_agent_list',
137
+ sideEffect: 'none',
43
138
  requiredFields: ['platform_id'],
139
+ resultPolicy: { neverTruncate: true },
44
140
  schema: z.object({
45
141
  platform_id: uuidSchema,
142
+ limit: z.number().int().min(1).max(PLATFORM_AGENTS_MAX_PAGE_SIZE).optional(),
143
+ cursor: z.string().min(1).optional(),
144
+ query: z.string().min(1).optional(),
145
+ }),
146
+ createRequest: (input) => {
147
+ const query = new URLSearchParams();
148
+ if (input.limit !== undefined)
149
+ query.set('limit', String(input.limit));
150
+ if (input.cursor)
151
+ query.set('cursor', input.cursor);
152
+ if (input.query)
153
+ query.set('q', input.query);
154
+ const suffix = query.size > 0 ? `?${query.toString()}` : '';
155
+ return { method: 'GET', path: `/platforms/${input.platform_id}/agents${suffix}` };
156
+ },
157
+ enhanceResponse: (response, input) => assertCompleteList(response, {
158
+ pageRequested: input.limit !== undefined || input.cursor !== undefined,
159
+ toolName: 'besales_agent_list',
160
+ howToPage: `Повтори вызов с limit до ${PLATFORM_AGENTS_MAX_PAGE_SIZE} и cursor из ответа, пока cursor не станет пустым.`,
161
+ }),
162
+ }),
163
+ defineTool({
164
+ name: 'besales_agent_get',
165
+ sideEffect: 'none',
166
+ requiredFields: ['agent_id'],
167
+ resultPolicy: { neverTruncate: true },
168
+ schema: z.object({
169
+ agent_id: uuidSchema,
46
170
  }),
47
171
  createRequest: (input) => ({
48
172
  method: 'GET',
49
- path: `/platforms/${input.platform_id}/agents`,
173
+ path: `/agents/${input.agent_id}`,
50
174
  }),
51
175
  }),
176
+ defineTool({
177
+ name: 'besales_agent_readiness_get',
178
+ sideEffect: 'none',
179
+ closedWorld: true,
180
+ requiredFields: ['agent_id'],
181
+ resultPolicy: { neverTruncate: true },
182
+ schema: z.object({ agent_id: uuidSchema }).strict(),
183
+ createRequest: (input) => ({
184
+ method: 'GET',
185
+ path: `/agents/${input.agent_id}/readiness`,
186
+ }),
187
+ enhanceResponse: (response) => withInstructions(response, [
188
+ 'Сейчас readiness всегда отвечает NOT_PROVEN: API не фиксирует версию зависимых настроек (behavior, routing, triggers, knowledge, ICP), и повтор sandbox этого не снимает. Не обещай пользователю READY.',
189
+ 'Выполни адресные пункты missing и перечитай readiness; promptAndAgentCurrent=true означает только актуальность промпта и записи агента.',
190
+ 'passRate не является quality. Нужны COMPLETED, свежая конфигурация, findings, qualityRate и checksRate с expectations.',
191
+ 'crmAuthorization=NOT_EVALUATED не подтверждает live-доступ CRM; проверяй его отдельной health/authorization операцией, если CRM нужна сценарию.',
192
+ ]),
193
+ }),
52
194
  defineTool({
53
195
  name: 'besales_agent_variable_overrides_get',
196
+ sideEffect: 'none',
54
197
  requiredFields: ['platform_id', 'agent_id'],
198
+ resultPolicy: { neverTruncate: true },
55
199
  schema: z.object({
56
200
  platform_id: uuidSchema,
57
201
  agent_id: uuidSchema,
@@ -68,6 +212,7 @@ export const platformSetupTools = [
68
212
  }),
69
213
  defineTool({
70
214
  name: 'besales_getcourse_departments_list',
215
+ sideEffect: 'none',
71
216
  requiredFields: ['platform_id'],
72
217
  schema: z.object({
73
218
  platform_id: uuidSchema,
@@ -84,6 +229,7 @@ export const platformSetupTools = [
84
229
  ...getCourseWaveTools,
85
230
  defineTool({
86
231
  name: 'besales_wazzup_templates_list',
232
+ sideEffect: 'none',
87
233
  requiredFields: ['platform_id'],
88
234
  defaultWorkspaceId: true,
89
235
  schema: z.object({
@@ -102,6 +248,7 @@ export const platformSetupTools = [
102
248
  }),
103
249
  defineTool({
104
250
  name: 'besales_wazzup_wave_import',
251
+ sideEffect: 'spend',
105
252
  requiredFields: ['platform_id', 'template_guid', 'contacts'],
106
253
  defaultWorkspaceId: true,
107
254
  schema: z
@@ -168,6 +315,7 @@ export const platformSetupTools = [
168
315
  }),
169
316
  defineTool({
170
317
  name: 'besales_wazzup_wave_status',
318
+ sideEffect: 'none',
171
319
  requiredFields: ['job_id'],
172
320
  defaultWorkspaceId: true,
173
321
  schema: z.object({
@@ -187,6 +335,7 @@ export const platformSetupTools = [
187
335
  }),
188
336
  defineTool({
189
337
  name: 'besales_agent_create',
338
+ sideEffect: 'write',
190
339
  requiredFields: ['platform_id', 'name', 'model_lane'],
191
340
  schema: z.object({
192
341
  platform_id: uuidSchema,
@@ -233,6 +382,7 @@ export const platformSetupTools = [
233
382
  }),
234
383
  defineTool({
235
384
  name: 'besales_agent_clone',
385
+ sideEffect: 'write',
236
386
  requiredFields: ['platform_id', 'source_agent_id', 'name'],
237
387
  schema: z.object({
238
388
  // Платформа-источник; клон приземляется на неё же (cross-platform не поддерживается).
@@ -260,6 +410,7 @@ export const platformSetupTools = [
260
410
  }),
261
411
  defineTool({
262
412
  name: 'besales_agent_update',
413
+ sideEffect: 'write',
263
414
  requiredFields: ['platform_id', 'agent_id'],
264
415
  schema: z.object({
265
416
  platform_id: uuidSchema,
@@ -325,6 +476,7 @@ export const platformSetupTools = [
325
476
  // В v2 заменён post_processors (Routing Studio Critic node) + post_processor_bindings.
326
477
  defineTool({
327
478
  name: 'besales_agent_tools_update',
479
+ sideEffect: 'write',
328
480
  requiredFields: ['platform_id', 'agent_id', 'tools'],
329
481
  schema: z.object({
330
482
  platform_id: uuidSchema,
@@ -346,6 +498,7 @@ export const platformSetupTools = [
346
498
  }),
347
499
  defineTool({
348
500
  name: 'besales_router_update',
501
+ sideEffect: 'write',
349
502
  requiredFields: ['platform_id'],
350
503
  schema: z.object({
351
504
  platform_id: uuidSchema,
@@ -377,6 +530,7 @@ export const platformSetupTools = [
377
530
  }),
378
531
  defineTool({
379
532
  name: 'besales_routing_rule_upsert',
533
+ sideEffect: 'write',
380
534
  requiredFields: ['platform_id', 'routing_strategy', 'custom_router_prompt'],
381
535
  schema: z.object({
382
536
  platform_id: uuidSchema,
@@ -437,6 +591,7 @@ export const platformSetupTools = [
437
591
  }),
438
592
  defineTool({
439
593
  name: 'besales_trigger_upsert',
594
+ sideEffect: 'write',
440
595
  requiredFields: ['platform_id', 'agent_id'],
441
596
  schema: z.object({
442
597
  platform_id: uuidSchema,
@@ -530,6 +685,7 @@ export const platformSetupTools = [
530
685
  }),
531
686
  defineTool({
532
687
  name: 'besales_trigger_delete',
688
+ sideEffect: 'write',
533
689
  requiredFields: ['platform_id', 'agent_id', 'trigger_id', 'explicit_confirmation'],
534
690
  schema: z
535
691
  .object({
@@ -552,6 +708,7 @@ export const platformSetupTools = [
552
708
  }),
553
709
  defineTool({
554
710
  name: 'besales_behavior_update',
711
+ sideEffect: 'write',
555
712
  requiredFields: ['platform_id'],
556
713
  schema: z
557
714
  .object({
@@ -615,6 +772,7 @@ export const platformSetupTools = [
615
772
  ...followUpSetupTools,
616
773
  defineTool({
617
774
  name: 'besales_pipeline_settings_update',
775
+ sideEffect: 'write',
618
776
  requiredFields: ['platform_id'],
619
777
  schema: z
620
778
  .object({
@@ -639,6 +797,7 @@ export const platformSetupTools = [
639
797
  }),
640
798
  defineTool({
641
799
  name: 'besales_platform_settings_update',
800
+ sideEffect: 'write',
642
801
  requiredFields: ['platform_id'],
643
802
  schema: z
644
803
  .object({
@@ -655,6 +814,9 @@ export const platformSetupTools = [
655
814
  crm_behavior: platformCrmBehaviorSchema.optional(),
656
815
  widget_marketing: platformWidgetMarketingSchema.optional(),
657
816
  instagram_comment_behavior: platformInstagramCommentSchema.optional(),
817
+ // Настройки раздела «Воронка канала»: ворота решения, цель «Пути до стадии», пороги.
818
+ // Бэкенд делегирует запись сервисам раздела — их валидация не обходится.
819
+ funnel_analytics: platformFunnelAnalyticsSchema.optional(),
658
820
  // v1.5 Increment 4c — per-channel typed sections (hard 400 для unsupported channel type)
659
821
  general_settings: platformGeneralSettingsSchema.optional(),
660
822
  salebot_settings: platformSalebotSettingsSchema.optional(),
@@ -686,6 +848,9 @@ export const platformSetupTools = [
686
848
  instagramCommentBehavior: input.instagram_comment_behavior
687
849
  ? mapPlatformInstagramCommentInput(input.instagram_comment_behavior)
688
850
  : undefined,
851
+ funnelAnalytics: input.funnel_analytics
852
+ ? mapPlatformFunnelAnalyticsInput(input.funnel_analytics)
853
+ : undefined,
689
854
  generalSettings: input.general_settings
690
855
  ? mapPlatformGeneralSettingsInput(input.general_settings)
691
856
  : undefined,
@@ -705,6 +870,9 @@ export const platformSetupTools = [
705
870
  }),
706
871
  }),
707
872
  enhanceResponse: (response) => withInstructions(response, [
873
+ 'funnel_analytics — настройки раздела «Воронка канала»: ворота решения (тройка стадий), целевая стадия «Пути до стадии», пороги. null у ворот и цели — СБРОС, отсутствие поля — «не трогать».',
874
+ '⚠️ Ворота проверяются бэкендом: три стадии обязаны быть РАЗНЫМИ и существовать в каталоге площадки — иначе 400. Совпади «одобрено» с «отклонено», доля одобрения стала бы вечными 50 % при любых данных.',
875
+ '⚠️ Секция НЕ попадает в audit log площадки: besales_audit_revert её НЕ откатит. Чтобы вернуть прежнее, пришлите прежние значения тем же тулом либо сбросьте через null.',
708
876
  'Per-channel typed sections (salebot/smsgorod/bitrix24Bot/getcourse) — hard 400 при mismatched platform.type.',
709
877
  'generalSettings.* — closes Phase B gap для name/offMessage/timezone/isActive; flat fields deprecated через 2 недели.',
710
878
  'Response.warnings[] содержит Phase A soft-warnings для widgetMarketing/instagramCommentBehavior на mismatched channel (hard reject после 2026-06-10).',
@@ -712,6 +880,7 @@ export const platformSetupTools = [
712
880
  }),
713
881
  defineTool({
714
882
  name: 'besales_audit_revert',
883
+ sideEffect: 'write',
715
884
  requiredFields: ['audit_log_id'],
716
885
  defaultWorkspaceId: true,
717
886
  schema: z
@@ -743,6 +912,7 @@ export const platformSetupTools = [
743
912
  }),
744
913
  defineTool({
745
914
  name: 'besales_feedback_sheet_link',
915
+ sideEffect: 'write',
746
916
  requiredFields: ['agent_id', 'source_url'],
747
917
  schema: z.object({
748
918
  agent_id: uuidSchema,
@@ -766,6 +936,7 @@ export const platformSetupTools = [
766
936
  }),
767
937
  defineTool({
768
938
  name: 'besales_feedback_sheet_list',
939
+ sideEffect: 'none',
769
940
  requiredFields: ['agent_id'],
770
941
  schema: z.object({
771
942
  agent_id: uuidSchema,
@@ -777,6 +948,7 @@ export const platformSetupTools = [
777
948
  }),
778
949
  defineTool({
779
950
  name: 'besales_feedback_sheet_read',
951
+ sideEffect: 'none',
780
952
  requiredFields: ['agent_id', 'feedback_sheet_id'],
781
953
  schema: z.object({
782
954
  agent_id: uuidSchema,
@@ -794,6 +966,7 @@ export const platformSetupTools = [
794
966
  }),
795
967
  defineTool({
796
968
  name: 'besales_feedback_sheet_unlink',
969
+ sideEffect: 'write',
797
970
  requiredFields: ['agent_id', 'feedback_sheet_id'],
798
971
  schema: z.object({
799
972
  agent_id: uuidSchema,
@@ -806,6 +979,7 @@ export const platformSetupTools = [
806
979
  }),
807
980
  defineTool({
808
981
  name: 'besales_feedback_sheet_row_update',
982
+ sideEffect: 'write',
809
983
  requiredFields: ['agent_id', 'feedback_sheet_id', 'rows'],
810
984
  schema: z.object({
811
985
  agent_id: uuidSchema,
@@ -837,6 +1011,7 @@ export const platformSetupTools = [
837
1011
  // S4.13 — besales_facts_classify_and_migrate
838
1012
  defineTool({
839
1013
  name: 'besales_facts_classify_and_migrate',
1014
+ sideEffect: 'spend',
840
1015
  requiredFields: ['agent_id'],
841
1016
  schema: z.object({
842
1017
  agent_id: uuidSchema,
@@ -857,6 +1032,7 @@ export const platformSetupTools = [
857
1032
  // S2.5 extra — besales_agent_facts_set
858
1033
  defineTool({
859
1034
  name: 'besales_agent_facts_set',
1035
+ sideEffect: 'write',
860
1036
  requiredFields: ['agent_id', 'factual_context'],
861
1037
  schema: z.object({
862
1038
  agent_id: uuidSchema,
@@ -879,6 +1055,11 @@ export const platformSetupTools = [
879
1055
  // ─────────────────────────────────────────────────────────────────
880
1056
  defineTool({
881
1057
  name: 'besales_prompt_patch_start',
1058
+ // Ответ несёт ПОЛНЫЙ текст промпта — до 80 000 символов по боевой границе платформы, то
1059
+ // есть до ~160 КБ кириллицей. Общий потолок в 64 КБ отказывал бы на штатном промпте, а
1060
+ // текст здесь незаменим: по нему строят якоря правок, и усечённый даёт промах якоря.
1061
+ resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
1062
+ sideEffect: 'write',
882
1063
  requiredFields: ['agent_id'],
883
1064
  schema: z.object({
884
1065
  agent_id: uuidSchema,
@@ -897,6 +1078,11 @@ export const platformSetupTools = [
897
1078
  }),
898
1079
  defineTool({
899
1080
  name: 'besales_prompt_patch_get',
1081
+ // Ответ несёт ПОЛНЫЙ текст промпта — до 80 000 символов по боевой границе платформы, то
1082
+ // есть до ~160 КБ кириллицей. Общий потолок в 64 КБ отказывал бы на штатном промпте, а
1083
+ // текст здесь незаменим: по нему строят якоря правок, и усечённый даёт промах якоря.
1084
+ resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
1085
+ sideEffect: 'none',
900
1086
  requiredFields: ['agent_id', 'draft_id'],
901
1087
  schema: z.object({
902
1088
  agent_id: uuidSchema,
@@ -911,6 +1097,7 @@ export const platformSetupTools = [
911
1097
  // mcp-tools.json (registry.spec проверяет parity), поэтому вставка строго после _patch_get.
912
1098
  defineTool({
913
1099
  name: 'besales_prompt_headroom',
1100
+ sideEffect: 'none',
914
1101
  requiredFields: ['agent_id'],
915
1102
  // .strict() — иначе опечатка `draftId` вместо `draft_id` молча отбрасывается zod'ом,
916
1103
  // и тулза измеряет закоммиченный промпт вместо черновика.
@@ -934,6 +1121,8 @@ export const platformSetupTools = [
934
1121
  }),
935
1122
  defineTool({
936
1123
  name: 'besales_prompt_diff',
1124
+ sideEffect: 'none',
1125
+ closedWorld: true,
937
1126
  requiredFields: ['agent_id', 'compare_agent_id'],
938
1127
  schema: z
939
1128
  .object({
@@ -956,6 +1145,11 @@ export const platformSetupTools = [
956
1145
  }),
957
1146
  defineTool({
958
1147
  name: 'besales_prompt_patch_apply',
1148
+ // Ответ несёт ПОЛНЫЙ текст промпта — до 80 000 символов по боевой границе платформы, то
1149
+ // есть до ~160 КБ кириллицей. Общий потолок в 64 КБ отказывал бы на штатном промпте, а
1150
+ // текст здесь незаменим: по нему строят якоря правок, и усечённый даёт промах якоря.
1151
+ resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
1152
+ sideEffect: 'write',
959
1153
  requiredFields: ['agent_id', 'draft_id', 'operations'],
960
1154
  schema: z.object({
961
1155
  agent_id: uuidSchema,
@@ -972,12 +1166,16 @@ export const platformSetupTools = [
972
1166
  enhanceResponse: (response) => withInstructions(response, [
973
1167
  'Operations применены. `appliedCount` — успешно, `skippedCount` — anchor не найден или growth guard сработал (>30% size).',
974
1168
  'Если `skippedCount > 0` — проверь target_text / anchor_text на точность. matchVariants[] помогает fuzzy-match.',
1169
+ 'Текста черновика в ответе НЕТ — приезжает `diff` (`removedLines`/`addedLines`, `charactersDelta`) и `draft.characters`. Промпт целиком ты уже прочитал на `_start`; перечитать — `besales_prompt_patch_get`.',
1170
+ 'Пустые `removedLines`/`addedLines` — НЕ признак «ничего не применилось»: дифф это разность МНОЖЕСТВ строк, и `move_text_after_text` (как и правка одних пробелов) даёт пустые списки. Факт изменения читай по `diff.contentChanged`, объём — по `charactersDelta`.',
1171
+ '`diff.truncated: true` — изменённых строк больше потолка; тогда сверяйся через `besales_prompt_patch_get`.',
975
1172
  'TTL draft сброшен на 24h.',
976
1173
  'Когда правки готовы — `besales_prompt_patch_commit(draft_id)`.',
977
1174
  ]),
978
1175
  }),
979
1176
  defineTool({
980
1177
  name: 'besales_prompt_patch_commit',
1178
+ sideEffect: 'write',
981
1179
  requiredFields: ['agent_id', 'draft_id'],
982
1180
  schema: z.object({
983
1181
  agent_id: uuidSchema,
@@ -989,6 +1187,7 @@ export const platformSetupTools = [
989
1187
  }),
990
1188
  enhanceResponse: (response) => withInstructions(response, [
991
1189
  'Commit: lint pass → новая PromptVersion в prompt-services → AgentChat.baseSystemPrompt обновлён.',
1190
+ 'В ответе только адресация версии (`newVersion.id`, `newVersion.version`) и метаданные черновика — текст промпта не дублируется.',
992
1191
  'Если ошибка 400 с `lintIssues` — поправь через `_apply` (hard_fail issues блокируют commit).',
993
1192
  'Если ошибка 409 PROMPT_DRAFT_REBASE_REQUIRED — другой commit прошёл первым. Discard этот draft и сделай новый.',
994
1193
  'Server-side hash → клиенту не нужно передавать activePromptContentHash.',
@@ -999,6 +1198,7 @@ export const platformSetupTools = [
999
1198
  }),
1000
1199
  defineTool({
1001
1200
  name: 'besales_prompt_patch_discard',
1201
+ sideEffect: 'write',
1002
1202
  requiredFields: ['agent_id', 'draft_id'],
1003
1203
  schema: z.object({
1004
1204
  agent_id: uuidSchema,
@@ -1013,7 +1213,8 @@ export const platformSetupTools = [
1013
1213
  // mcp-tools.json — registry.spec сверяет имена позиционно.
1014
1214
  defineTool({
1015
1215
  name: 'besales_prompt_batch_start',
1016
- requiredFields: ['agent_ids', 'operations'],
1216
+ sideEffect: 'spend',
1217
+ requiredFields: ['agent_ids', 'operations', 'explicit_confirmation'],
1017
1218
  schema: z
1018
1219
  .object({
1019
1220
  agent_ids: z.array(uuidSchema).min(1).max(PROMPT_BATCH_MAX_AGENTS),
@@ -1021,6 +1222,7 @@ export const platformSetupTools = [
1021
1222
  all_or_nothing: z.boolean().optional(),
1022
1223
  idempotency_key: z.string().max(PROMPT_BATCH_IDEMPOTENCY_KEY_MAX_LENGTH).optional(),
1023
1224
  platform_id: uuidSchema.optional(),
1225
+ explicit_confirmation: z.literal(true),
1024
1226
  })
1025
1227
  .strict(),
1026
1228
  createRequest: (input) => ({
@@ -1043,6 +1245,7 @@ export const platformSetupTools = [
1043
1245
  }),
1044
1246
  defineTool({
1045
1247
  name: 'besales_prompt_batch_status',
1248
+ sideEffect: 'none',
1046
1249
  requiredFields: ['run_id'],
1047
1250
  schema: z.object({ run_id: uuidSchema }).strict(),
1048
1251
  createRequest: (input) => ({
@@ -1052,6 +1255,7 @@ export const platformSetupTools = [
1052
1255
  }),
1053
1256
  defineTool({
1054
1257
  name: 'besales_prompt_batch_resume',
1258
+ sideEffect: 'spend',
1055
1259
  requiredFields: ['run_id'],
1056
1260
  schema: z.object({ run_id: uuidSchema }).strict(),
1057
1261
  createRequest: (input) => ({
@@ -1066,6 +1270,8 @@ export const platformSetupTools = [
1066
1270
  // S2.6 extra — besales_prompt_lint (после patches, чтобы matched catalog order)
1067
1271
  defineTool({
1068
1272
  name: 'besales_prompt_lint',
1273
+ sideEffect: 'none',
1274
+ closedWorld: true,
1069
1275
  requiredFields: ['prompt_text'],
1070
1276
  defaultWorkspaceId: true,
1071
1277
  schema: z.object({