@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.
- package/README.md +109 -164
- package/README.onprem.ru.md +35 -0
- package/bin/besales-mcp-http.js +9 -0
- package/bin/besales-onprem.mjs +19 -0
- package/dist/auth/connection-store.d.ts +3 -1
- package/dist/auth/connection-store.js +9 -3
- package/dist/auth/connection-store.js.map +1 -1
- package/dist/auth/oauth-client.d.ts +20 -27
- package/dist/auth/oauth-client.js +31 -23
- package/dist/auth/oauth-client.js.map +1 -1
- package/dist/auth/session-workspace.d.ts +1 -0
- package/dist/auth/session-workspace.js +10 -1
- package/dist/auth/session-workspace.js.map +1 -1
- package/dist/auth/token-storage.js +4 -1
- package/dist/auth/token-storage.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +80 -19
- package/dist/cli.js.map +1 -1
- package/dist/constants/crm-catalog.d.ts +2 -0
- package/dist/constants/crm-catalog.js +3 -0
- package/dist/constants/crm-catalog.js.map +1 -0
- package/dist/http/api-client.d.ts +52 -7
- package/dist/http/api-client.js +131 -66
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/feedback-document-error.d.ts +26 -0
- package/dist/http/feedback-document-error.js +22 -0
- package/dist/http/feedback-document-error.js.map +1 -0
- package/dist/http-server.d.ts +15 -0
- package/dist/http-server.js +378 -0
- package/dist/http-server.js.map +1 -0
- package/dist/instructions/server-instructions.d.ts +1 -1
- package/dist/instructions/server-instructions.js +6 -3
- package/dist/instructions/server-instructions.js.map +1 -1
- package/dist/network/constants.d.ts +25 -0
- package/dist/network/constants.js +26 -0
- package/dist/network/constants.js.map +1 -0
- package/dist/network/failed-verifications.d.ts +10 -0
- package/dist/network/failed-verifications.js +37 -0
- package/dist/network/failed-verifications.js.map +1 -0
- package/dist/network/http-test-fixture.d.ts +3 -0
- package/dist/network/http-test-fixture.js +86 -0
- package/dist/network/http-test-fixture.js.map +1 -0
- package/dist/network/known-keys.d.ts +10 -0
- package/dist/network/known-keys.js +38 -0
- package/dist/network/known-keys.js.map +1 -0
- package/dist/network/memory-credentials.d.ts +11 -0
- package/dist/network/memory-credentials.js +24 -0
- package/dist/network/memory-credentials.js.map +1 -0
- package/dist/network/rate-limit.d.ts +23 -0
- package/dist/network/rate-limit.js +62 -0
- package/dist/network/rate-limit.js.map +1 -0
- package/dist/network/rejected-keys.d.ts +9 -0
- package/dist/network/rejected-keys.js +39 -0
- package/dist/network/rejected-keys.js.map +1 -0
- package/dist/network/request-work.d.ts +8 -0
- package/dist/network/request-work.js +20 -0
- package/dist/network/request-work.js.map +1 -0
- package/dist/network/successful-keys.d.ts +17 -0
- package/dist/network/successful-keys.js +47 -0
- package/dist/network/successful-keys.js.map +1 -0
- package/dist/resources/concepts/external-execution.md +3 -1
- package/dist/resources/concepts/feedback-sheets.md +21 -12
- package/dist/resources/concepts/icp.md +8 -1
- package/dist/resources/concepts/sandbox.md +15 -6
- package/dist/resources/concepts/triggers.md +8 -0
- package/dist/resources/concepts/workbook-classification.md +104 -50
- package/dist/resources/docs/agent-behavior.md +51 -382
- package/dist/resources/docs/campaigns.md +9 -16
- package/dist/resources/docs/crm-integration.md +39 -523
- package/dist/resources/docs/files-and-uploads.md +23 -286
- package/dist/resources/docs/follow-up.md +47 -12
- package/dist/resources/docs/knowledge-base.md +52 -521
- package/dist/resources/docs/pipeline-builder.md +26 -216
- package/dist/resources/docs/pipeline-settings-deep.md +27 -220
- package/dist/resources/docs/platforms.md +106 -519
- package/dist/resources/docs/prompt-anatomy.md +39 -285
- package/dist/resources/docs/routing.md +8 -16
- package/dist/resources/docs/trigger-actions.md +40 -24
- package/dist/resources/docs/variables.md +8 -12
- package/dist/resources/operator-edit.contract.d.ts +7 -0
- package/dist/resources/operator-edit.contract.js +8 -0
- package/dist/resources/operator-edit.contract.js.map +1 -0
- package/dist/resources/registry.js +20 -4
- package/dist/resources/registry.js.map +1 -1
- package/dist/resources/workflows/audit-dialogues.md +23 -12
- package/dist/resources/workflows/compare-models.md +6 -4
- package/dist/resources/workflows/connect-crm-from-scratch.md +15 -12
- package/dist/resources/workflows/connect-datasource-from-scratch.md +5 -4
- package/dist/resources/workflows/extract-from-document.md +8 -6
- package/dist/resources/workflows/operator-edit.md +15 -0
- package/dist/resources/workflows/platform-setup-from-scratch.md +59 -70
- package/dist/resources/workflows/production-readiness-check.md +25 -15
- package/dist/schemas/mcp-tools.json +12061 -6753
- package/dist/schemas/voice-actions-api.contract.json +248 -0
- package/dist/shared/constants/broadcast-reason.constants.d.ts +2 -0
- package/dist/shared/constants/broadcast-reason.constants.js +47 -0
- package/dist/shared/constants/broadcast-reason.constants.js.map +1 -0
- package/dist/shared/constants/crm-stage-pool.constants.d.ts +2 -0
- package/dist/shared/constants/crm-stage-pool.constants.js +3 -0
- package/dist/shared/constants/crm-stage-pool.constants.js.map +1 -0
- package/dist/shared/constants/followup-note.constants.d.ts +3 -0
- package/dist/shared/constants/followup-note.constants.js +4 -0
- package/dist/shared/constants/followup-note.constants.js.map +1 -0
- package/dist/shared/constants/followup-session.constants.d.ts +2 -0
- package/dist/shared/constants/followup-session.constants.js +3 -0
- package/dist/shared/constants/followup-session.constants.js.map +1 -0
- package/dist/shared/constants/funnel-analytics.constants.d.ts +2 -0
- package/dist/shared/constants/funnel-analytics.constants.js +3 -0
- package/dist/shared/constants/funnel-analytics.constants.js.map +1 -0
- package/dist/shared/constants/message-filter.constants.d.ts +7 -0
- package/dist/shared/constants/message-filter.constants.js +8 -0
- package/dist/shared/constants/message-filter.constants.js.map +1 -0
- package/dist/shared/utils/trigger-repeat-mapping.d.ts +72 -0
- package/dist/shared/utils/trigger-repeat-mapping.js +53 -0
- package/dist/shared/utils/trigger-repeat-mapping.js.map +1 -0
- package/dist/skills/besales-dialogue-audit/SKILL.md +31 -20
- package/dist/tasks/task-state-store.js +5 -0
- package/dist/tasks/task-state-store.js.map +1 -1
- package/dist/tools/annotations.js +4 -3
- package/dist/tools/annotations.js.map +1 -1
- package/dist/tools/definitions/agent-design.d.ts +78 -21
- package/dist/tools/definitions/agent-design.js +246 -90
- package/dist/tools/definitions/agent-design.js.map +1 -1
- package/dist/tools/definitions/agent-model-notice.d.ts +5 -0
- package/dist/tools/definitions/agent-model-notice.js +31 -0
- package/dist/tools/definitions/agent-model-notice.js.map +1 -0
- package/dist/tools/definitions/agent-models.d.ts +5 -0
- package/dist/tools/definitions/agent-models.js +26 -0
- package/dist/tools/definitions/agent-models.js.map +1 -0
- package/dist/tools/definitions/agent-settings.d.ts +85 -0
- package/dist/tools/definitions/agent-settings.js +187 -0
- package/dist/tools/definitions/agent-settings.js.map +1 -0
- package/dist/tools/definitions/ai-costs.d.ts +12 -0
- package/dist/tools/definitions/ai-costs.js +142 -0
- package/dist/tools/definitions/ai-costs.js.map +1 -0
- package/dist/tools/definitions/api-tool-request.d.ts +15 -0
- package/dist/tools/definitions/api-tool-request.js +2 -0
- package/dist/tools/definitions/api-tool-request.js.map +1 -0
- package/dist/tools/definitions/behavior-shipped-form.d.ts +182 -0
- package/dist/tools/definitions/behavior-shipped-form.js +185 -0
- package/dist/tools/definitions/behavior-shipped-form.js.map +1 -0
- package/dist/tools/definitions/broadcast-alerts.d.ts +6 -0
- package/dist/tools/definitions/broadcast-alerts.js +72 -0
- package/dist/tools/definitions/broadcast-alerts.js.map +1 -0
- package/dist/tools/definitions/broadcast-analytics.d.ts +102 -18
- package/dist/tools/definitions/broadcast-analytics.js +732 -427
- package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
- package/dist/tools/definitions/broadcast-scheduler.d.ts +19 -13
- package/dist/tools/definitions/broadcast-scheduler.js +217 -128
- package/dist/tools/definitions/broadcast-scheduler.js.map +1 -1
- package/dist/tools/definitions/call-operator-task.schema.d.ts +11 -0
- package/dist/tools/definitions/call-operator-task.schema.js +30 -0
- package/dist/tools/definitions/call-operator-task.schema.js.map +1 -0
- package/dist/tools/definitions/contacts.d.ts +3 -0
- package/dist/tools/definitions/contacts.js +57 -31
- package/dist/tools/definitions/contacts.js.map +1 -1
- package/dist/tools/definitions/crm-platform.d.ts +28 -39
- package/dist/tools/definitions/crm-platform.js +235 -344
- package/dist/tools/definitions/crm-platform.js.map +1 -1
- package/dist/tools/definitions/crm-stage-pool.messages.d.ts +39 -0
- package/dist/tools/definitions/crm-stage-pool.messages.js +43 -0
- package/dist/tools/definitions/crm-stage-pool.messages.js.map +1 -0
- package/dist/tools/definitions/crm-stage-pool.schema.d.ts +64 -0
- package/dist/tools/definitions/crm-stage-pool.schema.js +109 -0
- package/dist/tools/definitions/crm-stage-pool.schema.js.map +1 -0
- package/dist/tools/definitions/custom-reports.d.ts +12 -0
- package/dist/tools/definitions/custom-reports.js +68 -0
- package/dist/tools/definitions/custom-reports.js.map +1 -0
- package/dist/tools/definitions/datasource.d.ts +2 -1
- package/dist/tools/definitions/datasource.js +28 -13
- package/dist/tools/definitions/datasource.js.map +1 -1
- package/dist/tools/definitions/dialog-review-findings-response.d.ts +14 -0
- package/dist/tools/definitions/dialog-review-findings-response.js +23 -0
- package/dist/tools/definitions/dialog-review-findings-response.js.map +1 -0
- package/dist/tools/definitions/dialog-review-safe-response.d.ts +5 -0
- package/dist/tools/definitions/dialog-review-safe-response.js +152 -0
- package/dist/tools/definitions/dialog-review-safe-response.js.map +1 -0
- package/dist/tools/definitions/dialog-review.d.ts +49 -0
- package/dist/tools/definitions/dialog-review.js +383 -0
- package/dist/tools/definitions/dialog-review.js.map +1 -0
- package/dist/tools/definitions/dialogue-analysis.d.ts +46 -0
- package/dist/tools/definitions/dialogue-analysis.js +170 -0
- package/dist/tools/definitions/dialogue-analysis.js.map +1 -0
- package/dist/tools/definitions/dialogue-audit-agent-scope.d.ts +7 -0
- package/dist/tools/definitions/dialogue-audit-agent-scope.js +41 -0
- package/dist/tools/definitions/dialogue-audit-agent-scope.js.map +1 -0
- package/dist/tools/definitions/dialogue-audit-alias.d.ts +67 -0
- package/dist/tools/definitions/dialogue-audit-alias.js +559 -0
- package/dist/tools/definitions/dialogue-audit-alias.js.map +1 -0
- package/dist/tools/definitions/dialogue-export.d.ts +7 -1
- package/dist/tools/definitions/dialogue-export.js +89 -32
- package/dist/tools/definitions/dialogue-export.js.map +1 -1
- package/dist/tools/definitions/dialogue-followup-state.d.ts +9 -0
- package/dist/tools/definitions/dialogue-followup-state.js +69 -0
- package/dist/tools/definitions/dialogue-followup-state.js.map +1 -0
- package/dist/tools/definitions/edit-version-transport.test-fixtures.d.ts +13 -0
- package/dist/tools/definitions/edit-version-transport.test-fixtures.js +292 -0
- package/dist/tools/definitions/edit-version-transport.test-fixtures.js.map +1 -0
- package/dist/tools/definitions/edit-version.d.ts +5 -0
- package/dist/tools/definitions/edit-version.js +20 -0
- package/dist/tools/definitions/edit-version.js.map +1 -0
- package/dist/tools/definitions/external-api-channels.js +17 -15
- package/dist/tools/definitions/external-api-channels.js.map +1 -1
- package/dist/tools/definitions/feedback-document-access.d.ts +16 -0
- package/dist/tools/definitions/feedback-document-access.js +63 -0
- package/dist/tools/definitions/feedback-document-access.js.map +1 -0
- package/dist/tools/definitions/fixtures/shipped-setup-status.d.ts +3 -0
- package/dist/tools/definitions/fixtures/shipped-setup-status.js +9 -0
- package/dist/tools/definitions/fixtures/shipped-setup-status.js.map +1 -0
- package/dist/tools/definitions/follow-up-config.d.ts +79 -0
- package/dist/tools/definitions/follow-up-config.js +258 -0
- package/dist/tools/definitions/follow-up-config.js.map +1 -0
- package/dist/tools/definitions/follow-up-funnel-test.d.ts +4 -3
- package/dist/tools/definitions/follow-up-funnel-test.js +65 -52
- package/dist/tools/definitions/follow-up-funnel-test.js.map +1 -1
- package/dist/tools/definitions/follow-up-promotion-instructions.d.ts +2 -0
- package/dist/tools/definitions/follow-up-promotion-instructions.js +7 -0
- package/dist/tools/definitions/follow-up-promotion-instructions.js.map +1 -0
- package/dist/tools/definitions/follow-up-setup.d.ts +4 -28
- package/dist/tools/definitions/follow-up-setup.js +20 -87
- package/dist/tools/definitions/follow-up-setup.js.map +1 -1
- package/dist/tools/definitions/follow-up.d.ts +20 -122
- package/dist/tools/definitions/follow-up.js +200 -354
- package/dist/tools/definitions/follow-up.js.map +1 -1
- package/dist/tools/definitions/followup-getcourse-compat.d.ts +29 -0
- package/dist/tools/definitions/followup-getcourse-compat.js +62 -0
- package/dist/tools/definitions/followup-getcourse-compat.js.map +1 -0
- package/dist/tools/definitions/followup-sequence-config.schema.d.ts +10 -0
- package/dist/tools/definitions/followup-sequence-config.schema.js +14 -0
- package/dist/tools/definitions/followup-sequence-config.schema.js.map +1 -0
- package/dist/tools/definitions/funnel-analytics.d.ts +18 -0
- package/dist/tools/definitions/funnel-analytics.js +150 -0
- package/dist/tools/definitions/funnel-analytics.js.map +1 -0
- package/dist/tools/definitions/getcourse-anchor-refresh.d.ts +5 -9
- package/dist/tools/definitions/getcourse-anchor-refresh.js +26 -31
- package/dist/tools/definitions/getcourse-anchor-refresh.js.map +1 -1
- package/dist/tools/definitions/getcourse-cold-outbound-settings.d.ts +46 -0
- package/dist/tools/definitions/getcourse-cold-outbound-settings.js +37 -0
- package/dist/tools/definitions/getcourse-cold-outbound-settings.js.map +1 -0
- package/dist/tools/definitions/getcourse-cold-welcome.d.ts +17 -29
- package/dist/tools/definitions/getcourse-cold-welcome.js +182 -242
- package/dist/tools/definitions/getcourse-cold-welcome.js.map +1 -1
- package/dist/tools/definitions/getcourse-wave-welcome.messages.d.ts +10 -0
- package/dist/tools/definitions/getcourse-wave-welcome.messages.js +17 -0
- package/dist/tools/definitions/getcourse-wave-welcome.messages.js.map +1 -0
- package/dist/tools/definitions/help.js.map +1 -1
- package/dist/tools/definitions/icp-import-source.d.ts +75 -0
- package/dist/tools/definitions/icp-import-source.js +88 -0
- package/dist/tools/definitions/icp-import-source.js.map +1 -0
- package/dist/tools/definitions/inbound-analytics.d.ts +13 -0
- package/dist/tools/definitions/inbound-analytics.js +55 -0
- package/dist/tools/definitions/inbound-analytics.js.map +1 -0
- package/dist/tools/definitions/instagram-comment.templates.d.ts +19 -0
- package/dist/tools/definitions/instagram-comment.templates.js +34 -0
- package/dist/tools/definitions/instagram-comment.templates.js.map +1 -0
- package/dist/tools/definitions/instagram-settings-compat.d.ts +33 -0
- package/dist/tools/definitions/instagram-settings-compat.js +7 -0
- package/dist/tools/definitions/instagram-settings-compat.js.map +1 -0
- package/dist/tools/definitions/knowledge-chunking.d.ts +42 -0
- package/dist/tools/definitions/knowledge-chunking.js +83 -0
- package/dist/tools/definitions/knowledge-chunking.js.map +1 -0
- package/dist/tools/definitions/knowledge-space-search-fields.d.ts +12 -0
- package/dist/tools/definitions/knowledge-space-search-fields.js +30 -0
- package/dist/tools/definitions/knowledge-space-search-fields.js.map +1 -0
- package/dist/tools/definitions/knowledge.d.ts +24 -14
- package/dist/tools/definitions/knowledge.js +342 -233
- package/dist/tools/definitions/knowledge.js.map +1 -1
- package/dist/tools/definitions/legacy-trigger-repeat.d.ts +17 -0
- package/dist/tools/definitions/legacy-trigger-repeat.js +53 -0
- package/dist/tools/definitions/legacy-trigger-repeat.js.map +1 -0
- package/dist/tools/definitions/link-tracking.d.ts +8 -0
- package/dist/tools/definitions/link-tracking.js +141 -38
- package/dist/tools/definitions/link-tracking.js.map +1 -1
- package/dist/tools/definitions/mailing-variant-content.d.ts +75 -0
- package/dist/tools/definitions/mailing-variant-content.js +73 -0
- package/dist/tools/definitions/mailing-variant-content.js.map +1 -0
- package/dist/tools/definitions/model-comparison.d.ts +1 -0
- package/dist/tools/definitions/model-comparison.js +4 -5
- package/dist/tools/definitions/model-comparison.js.map +1 -1
- package/dist/tools/definitions/money-currency.d.ts +5 -0
- package/dist/tools/definitions/money-currency.js +10 -0
- package/dist/tools/definitions/money-currency.js.map +1 -0
- package/dist/tools/definitions/operator-workflow.d.ts +5 -5
- package/dist/tools/definitions/operator-workflow.js +80 -27
- package/dist/tools/definitions/operator-workflow.js.map +1 -1
- package/dist/tools/definitions/platform-funnel-analytics.d.ts +42 -0
- package/dist/tools/definitions/platform-funnel-analytics.js +72 -0
- package/dist/tools/definitions/platform-funnel-analytics.js.map +1 -0
- package/dist/tools/definitions/platform-getcourse-wave-field-bindings.d.ts +42 -0
- package/dist/tools/definitions/platform-getcourse-wave-field-bindings.js +51 -0
- package/dist/tools/definitions/platform-getcourse-wave-field-bindings.js.map +1 -0
- package/dist/tools/definitions/platform-settings-limits.d.ts +5 -0
- package/dist/tools/definitions/platform-settings-limits.js +6 -0
- package/dist/tools/definitions/platform-settings-limits.js.map +1 -0
- package/dist/tools/definitions/platform-settings-shipped-form.d.ts +37 -0
- package/dist/tools/definitions/platform-settings-shipped-form.js +310 -0
- package/dist/tools/definitions/platform-settings-shipped-form.js.map +1 -0
- package/dist/tools/definitions/platform-settings-update.d.ts +300 -0
- package/dist/tools/definitions/platform-settings-update.js +134 -0
- package/dist/tools/definitions/platform-settings-update.js.map +1 -0
- package/dist/tools/definitions/{getcourse-wave.d.ts → platform-setup-wave.d.ts} +75 -6
- package/dist/tools/definitions/platform-setup-wave.js +1079 -0
- package/dist/tools/definitions/platform-setup-wave.js.map +1 -0
- package/dist/tools/definitions/platform-setup.d.ts +701 -222
- package/dist/tools/definitions/platform-setup.js +313 -752
- package/dist/tools/definitions/platform-setup.js.map +1 -1
- package/dist/tools/definitions/platform-widget-page-rules.schema.d.ts +10 -0
- package/dist/tools/definitions/platform-widget-page-rules.schema.js +7 -0
- package/dist/tools/definitions/platform-widget-page-rules.schema.js.map +1 -0
- package/dist/tools/definitions/prompt-authoring.constants.d.ts +2 -0
- package/dist/tools/definitions/prompt-authoring.constants.js +3 -0
- package/dist/tools/definitions/prompt-authoring.constants.js.map +1 -0
- package/dist/tools/definitions/prompt-batch-controls.d.ts +5 -0
- package/dist/tools/definitions/prompt-batch-controls.js +40 -0
- package/dist/tools/definitions/prompt-batch-controls.js.map +1 -0
- package/dist/tools/definitions/prompt-draft-authoring.d.ts +5 -0
- package/dist/tools/definitions/prompt-draft-authoring.js +24 -0
- package/dist/tools/definitions/prompt-draft-authoring.js.map +1 -0
- package/dist/tools/definitions/prompt-text-projection.d.ts +11 -0
- package/dist/tools/definitions/prompt-text-projection.js +62 -0
- package/dist/tools/definitions/prompt-text-projection.js.map +1 -0
- package/dist/tools/definitions/reviewer-paid.d.ts +19 -0
- package/dist/tools/definitions/reviewer-paid.js +115 -0
- package/dist/tools/definitions/reviewer-paid.js.map +1 -0
- package/dist/tools/definitions/routing-condition-projection.d.ts +31 -0
- package/dist/tools/definitions/routing-condition-projection.js +97 -0
- package/dist/tools/definitions/routing-condition-projection.js.map +1 -0
- package/dist/tools/definitions/schedule-selection-hints.d.ts +3 -0
- package/dist/tools/definitions/schedule-selection-hints.js +42 -0
- package/dist/tools/definitions/schedule-selection-hints.js.map +1 -0
- package/dist/tools/definitions/{scheduled-tasks.d.ts → scheduled-task-alias.d.ts} +12 -10
- package/dist/tools/definitions/scheduled-task-alias.js +207 -0
- package/dist/tools/definitions/scheduled-task-alias.js.map +1 -0
- package/dist/tools/definitions/session.js +3 -3
- package/dist/tools/definitions/session.js.map +1 -1
- package/dist/tools/definitions/setup-init-operation.schema.d.ts +2 -0
- package/dist/tools/definitions/setup-init-operation.schema.js +6 -0
- package/dist/tools/definitions/setup-init-operation.schema.js.map +1 -0
- package/dist/tools/definitions/shared-input.helpers.d.ts +51 -0
- package/dist/tools/definitions/shared-input.helpers.js +323 -0
- package/dist/tools/definitions/shared-input.helpers.js.map +1 -0
- package/dist/tools/definitions/shared.d.ts +414 -284
- package/dist/tools/definitions/shared.js +436 -619
- package/dist/tools/definitions/shared.js.map +1 -1
- package/dist/tools/definitions/shipped-output-names.d.ts +19 -0
- package/dist/tools/definitions/shipped-output-names.js +123 -0
- package/dist/tools/definitions/shipped-output-names.js.map +1 -0
- package/dist/tools/definitions/task-state.d.ts +5 -5
- package/dist/tools/definitions/task-state.js +2 -1
- package/dist/tools/definitions/task-state.js.map +1 -1
- package/dist/tools/definitions/telegram-personal-capacity.d.ts +4 -0
- package/dist/tools/definitions/telegram-personal-capacity.js +18 -0
- package/dist/tools/definitions/telegram-personal-capacity.js.map +1 -0
- package/dist/tools/definitions/telegram-pool-policy.d.ts +8 -0
- package/dist/tools/definitions/telegram-pool-policy.js +56 -0
- package/dist/tools/definitions/telegram-pool-policy.js.map +1 -0
- package/dist/tools/definitions/touch-history-alias.d.ts +4 -0
- package/dist/tools/definitions/touch-history-alias.js +99 -0
- package/dist/tools/definitions/touch-history-alias.js.map +1 -0
- package/dist/tools/definitions/trigger-action-item.schema.d.ts +254 -0
- package/dist/tools/definitions/trigger-action-item.schema.js +121 -0
- package/dist/tools/definitions/trigger-action-item.schema.js.map +1 -0
- package/dist/tools/definitions/trigger-argument.schema.d.ts +14 -0
- package/dist/tools/definitions/trigger-argument.schema.js +23 -0
- package/dist/tools/definitions/trigger-argument.schema.js.map +1 -0
- package/dist/tools/definitions/trigger-claim-alias.d.ts +10 -0
- package/dist/tools/definitions/trigger-claim-alias.js +90 -0
- package/dist/tools/definitions/trigger-claim-alias.js.map +1 -0
- package/dist/tools/definitions/trigger-echo-projection.d.ts +1 -0
- package/dist/tools/definitions/trigger-echo-projection.js +41 -0
- package/dist/tools/definitions/trigger-echo-projection.js.map +1 -0
- package/dist/tools/definitions/trigger-upsert.tool.d.ts +29 -0
- package/dist/tools/definitions/trigger-upsert.tool.js +122 -0
- package/dist/tools/definitions/trigger-upsert.tool.js.map +1 -0
- package/dist/tools/definitions/v15-port-descriptions.d.ts +11 -0
- package/dist/tools/definitions/v15-port-descriptions.js +30 -0
- package/dist/tools/definitions/v15-port-descriptions.js.map +1 -0
- package/dist/tools/definitions/variables.d.ts +44 -0
- package/dist/tools/definitions/variables.js +310 -0
- package/dist/tools/definitions/variables.js.map +1 -0
- package/dist/tools/definitions/voice-action-input.d.ts +9 -0
- package/dist/tools/definitions/voice-action-input.js +141 -0
- package/dist/tools/definitions/voice-action-input.js.map +1 -0
- package/dist/tools/definitions/widget-customization-compat.d.ts +51 -0
- package/dist/tools/definitions/widget-customization-compat.js +23 -0
- package/dist/tools/definitions/widget-customization-compat.js.map +1 -0
- package/dist/tools/definitions.d.ts +1105 -621
- package/dist/tools/definitions.js +57 -27
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/description-localization.js +3 -2
- package/dist/tools/description-localization.js.map +1 -1
- package/dist/tools/follow-up-request.d.ts +19 -0
- package/dist/tools/follow-up-request.js +81 -0
- package/dist/tools/follow-up-request.js.map +1 -0
- package/dist/tools/followup-revision.d.ts +4 -0
- package/dist/tools/followup-revision.js +29 -0
- package/dist/tools/followup-revision.js.map +1 -0
- package/dist/tools/incomplete-list.js +4 -0
- package/dist/tools/incomplete-list.js.map +1 -1
- package/dist/tools/inventory.js +47 -11
- package/dist/tools/inventory.js.map +1 -1
- package/dist/tools/operation-recovery.d.ts +4 -0
- package/dist/tools/operation-recovery.js +33 -0
- package/dist/tools/operation-recovery.js.map +1 -0
- package/dist/tools/registry-mapping-primary.cases.d.ts +2 -0
- package/dist/tools/registry-mapping-primary.cases.js +753 -0
- package/dist/tools/registry-mapping-primary.cases.js.map +1 -0
- package/dist/tools/registry-mapping-secondary.cases.d.ts +2 -0
- package/dist/tools/registry-mapping-secondary.cases.js +626 -0
- package/dist/tools/registry-mapping-secondary.cases.js.map +1 -0
- package/dist/tools/registry-mapping.cases.d.ts +8 -0
- package/dist/tools/registry-mapping.cases.js +13 -0
- package/dist/tools/registry-mapping.cases.js.map +1 -0
- package/dist/tools/registry-test-fixtures.d.ts +50 -0
- package/dist/tools/registry-test-fixtures.js +120 -0
- package/dist/tools/registry-test-fixtures.js.map +1 -0
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.js +82 -52
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/result.d.ts +1 -0
- package/dist/tools/result.js +90 -22
- package/dist/tools/result.js.map +1 -1
- package/dist/tools/toolsets.d.ts +16 -0
- package/dist/tools/toolsets.js +25 -1
- package/dist/tools/toolsets.js.map +1 -1
- package/dist/types/api-contract.gen.d.ts +105862 -22115
- package/dist/utils/credential-signatures.d.ts +3 -0
- package/dist/utils/credential-signatures.js +10 -0
- package/dist/utils/credential-signatures.js.map +1 -0
- package/dist/utils/data-source-column-name.d.ts +10 -0
- package/dist/utils/data-source-column-name.js +36 -0
- package/dist/utils/data-source-column-name.js.map +1 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.js +32 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/secret-read-boundary.d.ts +2 -0
- package/dist/utils/secret-read-boundary.js +88 -0
- package/dist/utils/secret-read-boundary.js.map +1 -0
- package/dist/utils/setup-secrets.d.ts +4 -0
- package/dist/utils/setup-secrets.js +40 -0
- package/dist/utils/setup-secrets.js.map +1 -0
- package/docs/agent-models.md +9 -0
- package/docs/agent-usage-guide.full.ru.md +1 -4
- package/docs/analytics-contract.md +67 -0
- package/docs/async-operation-lifecycle.md +10 -3
- package/docs/connect.ru.md +144 -4
- package/docs/contact-company-profile.md +17 -0
- package/docs/contact-recommendations.md +7 -0
- package/docs/crm-stage-pool.md +73 -0
- package/docs/customer-data.md +61 -0
- package/docs/edit-versions.md +36 -0
- package/docs/failure-semantics.md +17 -9
- package/docs/help-navigation.md +15 -42
- package/docs/host-compatibility-matrix.md +72 -93
- package/docs/host-setup.md +33 -35
- package/docs/invariants/public-api-and-contracts.md +16 -0
- package/docs/legacy-action-settings.md +21 -0
- package/docs/main-transfer-dependencies.md +38 -0
- package/docs/mcp2-parity.md +50 -0
- package/docs/modules/analytics.md +79 -0
- package/docs/modules/besales-mcp.md +137 -0
- package/docs/modules/dialog-review-report.md +38 -0
- package/docs/modules/dialogue-followup-adapters.md +39 -0
- package/docs/modules/message-reactions.md +17 -0
- package/docs/modules/network-mode.md +284 -0
- package/docs/modules/prompt-batch-and-dialogue-controls.md +69 -0
- package/docs/pii-policy.md +21 -16
- package/docs/response-size-budget.md +197 -7
- package/docs/secret-read-boundary.md +102 -0
- package/docs/task-state.md +7 -2
- package/docs/telegram-pool-policy.md +19 -0
- package/docs/tool-effects.md +15 -9
- package/docs/tool-surface.md +205 -4
- package/docs/voice-actions-and-inbox.md +95 -0
- package/docs/wazzup-instagram-comments.md +26 -0
- package/package.json +17 -10
- package/scripts/api-source-loader.spec.mjs +40 -0
- package/scripts/audit-bridge-controls.mjs +129 -0
- package/scripts/audit-revert-mutants.mjs +107 -0
- package/scripts/bridge-api-input.spec.mjs +98 -0
- package/scripts/bridge-controls-mutants.mjs +130 -0
- package/scripts/brx3-shipped-refusals.spec.mjs +149 -0
- package/scripts/brx4-ledger-payload.spec.mjs +127 -0
- package/scripts/build-onprem.mjs +108 -0
- package/scripts/connect-clients.sh +141 -0
- package/scripts/connect-scopes.mjs +166 -0
- package/scripts/connect-scopes.spec.mjs +83 -0
- package/scripts/emit-personal-link-carrier.mjs +31 -0
- package/scripts/emit-setup-init-schemas.mjs +24 -0
- package/scripts/emit-tool-routes.mjs +878 -0
- package/scripts/emit-tool-routes.spec.mjs +300 -0
- package/scripts/followup-registry.spec.mjs +107 -0
- package/scripts/generate-crm-rotation-contract.mjs +98 -0
- package/scripts/generate-followup-session-contract.mjs +16 -0
- package/scripts/icp-import-verification/mutate.cjs +70 -0
- package/scripts/import-secret-read-contract.mjs +53 -0
- package/scripts/install-claude-desktop.js +1 -1
- package/scripts/lag-decisions.mjs +37 -0
- package/scripts/lag-decisions.spec.mjs +87 -0
- package/scripts/lag-open-task-owners.mjs +46 -0
- package/scripts/lag-open-task-owners.spec.mjs +78 -0
- package/scripts/lag-payload.mjs +10 -0
- package/scripts/legacy-action-lag.spec.mjs +22 -0
- package/scripts/legacy-field-refusal.shipped.spec.mjs +99 -0
- package/scripts/mcpcompat-handler.mjs +34 -0
- package/scripts/mcpcompat-loader.mjs +36 -0
- package/scripts/mcpcompat-typescript.mjs +3 -0
- package/scripts/platform-settings-shipped-parity.spec.mjs +89 -0
- package/scripts/prbr-round1-recheck.spec.mjs +605 -0
- package/scripts/prbr-shipped-compatibility.spec.mjs +276 -0
- package/scripts/publish-mcp-registry.mjs +98 -0
- package/scripts/publish-mcp-registry.spec.mjs +68 -0
- package/scripts/record-scheduled-task-call.mjs +26 -0
- package/scripts/refusal-probe.mjs +17 -0
- package/scripts/refusal-probe.spec.mjs +29 -0
- package/scripts/registry-diff.mjs +502 -0
- package/scripts/registry-diff.spec.mjs +787 -0
- package/scripts/request-query.mjs +43 -0
- package/scripts/request-query.spec.mjs +82 -0
- package/scripts/route-lag.mjs +23 -0
- package/scripts/route-lag.spec.mjs +30 -0
- package/scripts/sample-args.mjs +174 -0
- package/scripts/sample-args.spec.mjs +160 -0
- package/scripts/shipped-definitions.mjs +197 -0
- package/scripts/shipped-definitions.spec.mjs +57 -0
- package/scripts/shipped-inputs.spec.mjs +136 -0
- package/scripts/shipped-recordings.spec.mjs +19 -0
- package/scripts/shipped-ref.d.mts +5 -0
- package/scripts/shipped-ref.mjs +20 -0
- package/scripts/shipped-ref.spec.mjs +59 -0
- package/scripts/shipped-registry.mjs +107 -0
- package/scripts/shipped-sample-candidates.mjs +69 -0
- package/scripts/shipped-sample-candidates.spec.mjs +117 -0
- package/scripts/shipped-sample.mjs +868 -0
- package/scripts/shipped-sample.spec.mjs +451 -0
- package/scripts/sync-agent-model-schemas.mjs +72 -0
- package/scripts/sync-api-contracts.mjs +85 -0
- package/scripts/sync-api-contracts.spec.mjs +144 -0
- package/scripts/sync-contract-ledger-schemas.mjs +161 -0
- package/scripts/sync-crm-stage-pool-schema.mjs +85 -0
- package/scripts/sync-prompt-draft-schema.mjs +92 -0
- package/scripts/sync-route-map.mjs +94 -0
- package/scripts/sync-schema-descriptions.mjs +25 -0
- package/scripts/sync-tool-inventory.mjs +27 -0
- package/scripts/sync-trigger-argument-schema.mjs +121 -0
- package/scripts/sync-trigger-repeat-mapping.mjs +12 -0
- package/scripts/sync-voice-actions-contract.mjs +67 -0
- package/scripts/sync-voice-actions-tools.mjs +97 -0
- package/scripts/sync-wave-id-schemas.mjs +55 -0
- package/scripts/tool-input-schemas.mjs +46 -0
- package/scripts/tool-input-schemas.spec.mjs +50 -0
- package/scripts/verify-followup-adapters.mjs +235 -0
- package/scripts/verify-secret-read-import.mjs +84 -0
- package/scripts/verify-secret-read-mutants.mjs +143 -0
- package/dist/tools/definitions/analytics.d.ts +0 -40
- package/dist/tools/definitions/analytics.js +0 -233
- package/dist/tools/definitions/analytics.js.map +0 -1
- package/dist/tools/definitions/broadcast-mailing-variants.d.ts +0 -41
- package/dist/tools/definitions/broadcast-mailing-variants.js +0 -194
- package/dist/tools/definitions/broadcast-mailing-variants.js.map +0 -1
- package/dist/tools/definitions/dialogue-audit.d.ts +0 -38
- package/dist/tools/definitions/dialogue-audit.js +0 -292
- package/dist/tools/definitions/dialogue-audit.js.map +0 -1
- package/dist/tools/definitions/getcourse-wave.js +0 -519
- package/dist/tools/definitions/getcourse-wave.js.map +0 -1
- package/dist/tools/definitions/operational-overview.d.ts +0 -3
- package/dist/tools/definitions/operational-overview.js +0 -23
- package/dist/tools/definitions/operational-overview.js.map +0 -1
- package/dist/tools/definitions/scheduled-tasks.js +0 -173
- package/dist/tools/definitions/scheduled-tasks.js.map +0 -1
- package/dist/tools/definitions/trigger-contact-claims.d.ts +0 -7
- package/dist/tools/definitions/trigger-contact-claims.js +0 -60
- package/dist/tools/definitions/trigger-contact-claims.js.map +0 -1
- package/dist/tools/registry-mapping-cases-core.d.ts +0 -38
- package/dist/tools/registry-mapping-cases-core.js +0 -927
- package/dist/tools/registry-mapping-cases-core.js.map +0 -1
- package/dist/tools/registry-mapping-cases-platform.d.ts +0 -2
- package/dist/tools/registry-mapping-cases-platform.js +0 -1052
- package/dist/tools/registry-mapping-cases-platform.js.map +0 -1
- package/dist/tools/trigger-action-config.d.ts +0 -49
- package/dist/tools/trigger-action-config.js +0 -171
- package/dist/tools/trigger-action-config.js.map +0 -1
- package/docs/evals/model-behavior-scorecard.md +0 -80
- package/docs/operation-coverage.md +0 -114
- package/scripts/mock-credentials.js +0 -77
- package/scripts/model-eval-server.js +0 -213
- package/scripts/run-model-eval.js +0 -447
|
@@ -1,514 +1,45 @@
|
|
|
1
|
+
import { withEditVersionInstructions, editVersionInstruction } from './edit-version.js';
|
|
2
|
+
import { agentSettingsTools } from './agent-settings.js';
|
|
3
|
+
import { triggerSetupActionItemSchema } from './trigger-action-item.schema.js';
|
|
4
|
+
import { followupSequenceConfigSchema as followupCompatSequenceConfigSchema } from './followup-getcourse-compat.js';
|
|
5
|
+
import { followUpPromotionInstructions } from './follow-up-promotion-instructions.js';
|
|
6
|
+
import { triggerUpsertTool } from './trigger-upsert.tool.js';
|
|
1
7
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
8
|
+
import { crmStagePoolMessage } from './crm-stage-pool.messages.js';
|
|
9
|
+
import { refineFollowUpConfig } from './follow-up-config.js';
|
|
3
10
|
import { followUpSetupTools } from './follow-up-setup.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
11
|
+
import { withProjectedRoutingRule } from './routing-condition-projection.js';
|
|
12
|
+
import { withoutDraftPromptText, withoutDuplicatedPromptText } from './prompt-text-projection.js';
|
|
13
|
+
import { droppedShippedFields, shippedFormConflicts, shippedFormErrorHandlingSchema, shippedFormGreetingSchema, shippedFormMessageFiltersSchema, shippedFormMessageSplittingSchema, shippedFormOperatorScheduleSchema, shippedFormPrivacySchema, shippedFormTypingBehaviorSchema, translateShippedBehavior, } from './behavior-shipped-form.js';
|
|
14
|
+
import { behaviorCrmSchema, behaviorMediaHandlingSchema, behaviorUnsupportedInputHandlingSchema, behaviorUrlHandlingSchema, buildListQuery, compactObject, defineTool, feedbackSheetRowSchema, followUpSequenceTypeSchema, followUpTriggerSchema, knowledgeSpaceIdSchema, mapPipelineAutoFinishInput, mapPipelineCrmBehaviorInput, mapPromptPatchOperationInput, pipelineAutoFinishSchema, pipelineCrmBehaviorSchema, platformSetupConfirmationSchema, PROMPT_BATCH_IDEMPOTENCY_KEY_MAX_LENGTH, PROMPT_BATCH_MAX_AGENTS, PROMPT_DIFF_MAX_LINES_LIMIT, promptPatchOperationSchema, routingRuleConditionSchema, routingRuleLeadStatusSchema, routingStrategySchema, setupConfirmation, uuidSchema, withInstructions, withSchemaVersion, } from './shared.js';
|
|
15
|
+
import { platformSettingsSections, platformSettingsUpdateSchema, } from './platform-settings-update.js';
|
|
16
|
+
import { platformSetupWaveTools } from './platform-setup-wave.js';
|
|
17
|
+
import { feedbackDocumentConfirmationSchema } from './feedback-document-access.js';
|
|
7
18
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
19
|
+
* Потолок БАЗЫ имени копии цепочки дожимов. Зеркалит `@MaxLength` DTO v2: без него агент получал
|
|
20
|
+
* бы поздний 400 вместо ранней понятной ошибки.
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ Отгружаемая линия знает 200 — предел индекса v1.5. В v2 имя цепочки ограничено 160 на всей
|
|
23
|
+
* API-границе, поэтому здесь сознательно у́же; сужение объявлено строкой реестра отставания.
|
|
12
24
|
*/
|
|
13
|
-
const
|
|
14
|
-
const
|
|
25
|
+
const FOLLOWUP_CLONE_NAME_MAX_LENGTH = 160;
|
|
26
|
+
export const triggerActionItemSchema = triggerSetupActionItemSchema;
|
|
27
|
+
export const followupSequenceConfigSchema = followupCompatSequenceConfigSchema;
|
|
15
28
|
export const platformSetupTools = [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
sideEffect: 'none',
|
|
19
|
-
requiredFields: [],
|
|
20
|
-
defaultWorkspaceId: true,
|
|
21
|
-
schema: z.object({
|
|
22
|
-
workspace_id: uuidSchema.optional(),
|
|
23
|
-
}),
|
|
24
|
-
createRequest: (input) => ({
|
|
25
|
-
method: 'GET',
|
|
26
|
-
path: `/workspaces/${input.workspace_id}/overview`,
|
|
27
|
-
}),
|
|
28
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
29
|
-
'Single-shot snapshot всего workspace: platforms (с agentsCount), ICP profiles (с segments/samples counts), feedback sheets, MCP connections summary.',
|
|
30
|
-
'Используй ПЕРВЫМ когда user задаёт open-ended вопросы вида "что у меня есть?" / "покажи мою настройку" — заменяет N round-trips.',
|
|
31
|
-
'`setupCompleteness` — readiness-сигнал «что недоделано»: channelsConnected/Pending, crmConnected, hasAnchorAgent, hasKnowledge, knowledgeLinkedToChannel, hasTriggers/Followups, hasIcp, lastSandboxRunAt, suggestedNextPhase. Используй suggestedNextPhase как мягкий hint следующего фокуса (не приказ); продолжай настройку с него, а не с нуля.',
|
|
32
|
-
'После overview перейди на drill-down: `besales_platform_context_get` для конкретной платформы, `besales_agent_list` для агентов внутри неё.',
|
|
33
|
-
]),
|
|
34
|
-
}),
|
|
35
|
-
defineTool({
|
|
36
|
-
name: 'besales_workspace_navigate',
|
|
37
|
-
sideEffect: 'none',
|
|
38
|
-
closedWorld: true,
|
|
39
|
-
requiredFields: ['intent'],
|
|
40
|
-
defaultWorkspaceId: true,
|
|
41
|
-
resultPolicy: { neverTruncate: true },
|
|
42
|
-
schema: z
|
|
43
|
-
.object({
|
|
44
|
-
workspace_id: uuidSchema.optional(),
|
|
45
|
-
intent: z.enum([
|
|
46
|
-
'CREATE_BOT',
|
|
47
|
-
'IMPROVE_AGENT',
|
|
48
|
-
'DIAGNOSE_CONTACT',
|
|
49
|
-
'AUDIT_DIALOGUES',
|
|
50
|
-
'CAMPAIGN_REPORT',
|
|
51
|
-
'CONNECT_CRM',
|
|
52
|
-
'CONNECT_DATASOURCE',
|
|
53
|
-
'CONFIGURE_FOLLOWUP',
|
|
54
|
-
'CONTINUE_TASK',
|
|
55
|
-
'FREEFORM',
|
|
56
|
-
]),
|
|
57
|
-
bot_type: z.enum(['FAQ', 'SALES', 'BOOKING', 'OUTBOUND', 'SUPPORT', 'UNKNOWN']).optional(),
|
|
58
|
-
platform_id: uuidSchema.optional(),
|
|
59
|
-
agent_id: uuidSchema.optional(),
|
|
60
|
-
contact_id: uuidSchema.optional(),
|
|
61
|
-
task_id: uuidSchema.optional(),
|
|
62
|
-
question: z.string().trim().min(2).max(500).optional(),
|
|
63
|
-
})
|
|
64
|
-
.strict(),
|
|
65
|
-
createRequest: (input) => ({
|
|
66
|
-
method: 'POST',
|
|
67
|
-
path: `/workspaces/${input.workspace_id}/navigation`,
|
|
68
|
-
body: compactObject({
|
|
69
|
-
intent: input.intent,
|
|
70
|
-
botType: input.bot_type,
|
|
71
|
-
platformId: input.platform_id,
|
|
72
|
-
agentId: input.agent_id,
|
|
73
|
-
contactId: input.contact_id,
|
|
74
|
-
taskId: input.task_id,
|
|
75
|
-
question: input.question,
|
|
76
|
-
}),
|
|
77
|
-
}),
|
|
78
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
79
|
-
'next.tool и next.arguments — один адресный следующий шаг; placeholders перечислены в requiredUserInput и не должны угадываться.',
|
|
80
|
-
'Сохранённый overview — evidence только на момент ответа. Перед записью перечитай выбранный объект, а после записи выполни next.verifyWith.',
|
|
81
|
-
'CREATE_BOT учитывает bot_type: FAQ не требует ICP/CRM автоматически, SALES/BOOKING/OUTBOUND требуют ICP и условий до доказательства готовности.',
|
|
82
|
-
'FREEFORM возвращает help route и не запускает обязательный шестишаговый мастер.',
|
|
83
|
-
]),
|
|
84
|
-
}),
|
|
85
|
-
defineTool({
|
|
86
|
-
name: 'besales_platform_context_get',
|
|
87
|
-
sideEffect: 'none',
|
|
88
|
-
requiredFields: ['platform_id'],
|
|
89
|
-
resultPolicy: {
|
|
90
|
-
neverTruncate: true,
|
|
91
|
-
droppablePaths: ['agents[].baseSystemPrompt'],
|
|
92
|
-
narrowingHint: 'Снимок канала отдаётся целиком и на канале с десятками агентов не помещается в ответ. Работайте по одному агенту: besales_agent_list для перечня, besales_prompt_patch_get для промпта.',
|
|
93
|
-
},
|
|
94
|
-
schema: z.object({
|
|
95
|
-
platform_id: uuidSchema,
|
|
96
|
-
sections: z
|
|
97
|
-
.array(z.enum([
|
|
98
|
-
'platform',
|
|
99
|
-
'agent_summaries',
|
|
100
|
-
'agents_full',
|
|
101
|
-
'router',
|
|
102
|
-
'behavior',
|
|
103
|
-
'follow_up',
|
|
104
|
-
'pipeline_settings',
|
|
105
|
-
'readiness',
|
|
106
|
-
]))
|
|
107
|
-
.min(1)
|
|
108
|
-
.optional(),
|
|
109
|
-
}),
|
|
110
|
-
createRequest: (input) => ({
|
|
111
|
-
method: 'GET',
|
|
112
|
-
path: `/platforms/${input.platform_id}/setup/context` +
|
|
113
|
-
(input.sections
|
|
114
|
-
? `?sections=${encodeURIComponent(input.sections.join(','))}`
|
|
115
|
-
: ''),
|
|
116
|
-
}),
|
|
117
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
118
|
-
'Для точечного чтения передай sections; agent_summaries не содержит полный промпт, agents_full содержит.',
|
|
119
|
-
'Read readiness flags, then call targeted mutation tools. Do not ask the user for workspace_id.',
|
|
120
|
-
'Prompt content changes still go through besales_prompt_* tools and besales_prompt_finalize.',
|
|
121
|
-
]),
|
|
122
|
-
}),
|
|
123
|
-
defineTool({
|
|
124
|
-
name: 'besales_trigger_action_catalog_get',
|
|
125
|
-
sideEffect: 'none',
|
|
126
|
-
requiredFields: ['platform_id'],
|
|
127
|
-
resultPolicy: { neverTruncate: true },
|
|
128
|
-
schema: z.object({
|
|
129
|
-
platform_id: uuidSchema,
|
|
130
|
-
action_type: z.string().trim().min(1).optional(),
|
|
131
|
-
}),
|
|
132
|
-
createRequest: (input) => ({
|
|
133
|
-
method: 'GET',
|
|
134
|
-
path: `/platforms/${input.platform_id}/setup/trigger-action-catalog` +
|
|
135
|
-
(input.action_type ? `?actionType=${encodeURIComponent(input.action_type)}` : ''),
|
|
136
|
-
}),
|
|
137
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
138
|
-
'Каталог построен из боевого CreateTriggerActionDto и канона TRIGGER_ACTION_CONFIG.',
|
|
139
|
-
'Перед созданием нового actionType запроси его отдельно через action_type и используй minimalExample без угадывания имени config-поля.',
|
|
140
|
-
'После записи выполни verification из записи каталога; перечитывание контекста проверяет сохранение, но не внешний эффект.',
|
|
141
|
-
]),
|
|
142
|
-
}),
|
|
143
|
-
defineTool({
|
|
144
|
-
name: 'besales_agent_list',
|
|
145
|
-
sideEffect: 'none',
|
|
146
|
-
requiredFields: ['platform_id'],
|
|
147
|
-
resultPolicy: { neverTruncate: true },
|
|
148
|
-
schema: z.object({
|
|
149
|
-
platform_id: uuidSchema,
|
|
150
|
-
limit: z.number().int().min(1).max(PLATFORM_AGENTS_MAX_PAGE_SIZE).optional(),
|
|
151
|
-
cursor: z.string().min(1).optional(),
|
|
152
|
-
query: z.string().min(1).optional(),
|
|
153
|
-
}),
|
|
154
|
-
createRequest: (input) => {
|
|
155
|
-
const query = new URLSearchParams();
|
|
156
|
-
if (input.limit !== undefined)
|
|
157
|
-
query.set('limit', String(input.limit));
|
|
158
|
-
if (input.cursor)
|
|
159
|
-
query.set('cursor', input.cursor);
|
|
160
|
-
if (input.query)
|
|
161
|
-
query.set('q', input.query);
|
|
162
|
-
const suffix = query.size > 0 ? `?${query.toString()}` : '';
|
|
163
|
-
return { method: 'GET', path: `/platforms/${input.platform_id}/agents${suffix}` };
|
|
164
|
-
},
|
|
165
|
-
enhanceResponse: (response, input) => assertCompleteList(response, {
|
|
166
|
-
pageRequested: input.limit !== undefined || input.cursor !== undefined,
|
|
167
|
-
toolName: 'besales_agent_list',
|
|
168
|
-
howToPage: `Повтори вызов с limit до ${PLATFORM_AGENTS_MAX_PAGE_SIZE} и cursor из ответа, пока cursor не станет пустым.`,
|
|
169
|
-
}),
|
|
170
|
-
}),
|
|
171
|
-
defineTool({
|
|
172
|
-
name: 'besales_agent_get',
|
|
173
|
-
sideEffect: 'none',
|
|
174
|
-
requiredFields: ['agent_id'],
|
|
175
|
-
resultPolicy: { neverTruncate: true },
|
|
176
|
-
schema: z.object({
|
|
177
|
-
agent_id: uuidSchema,
|
|
178
|
-
}),
|
|
179
|
-
createRequest: (input) => ({
|
|
180
|
-
method: 'GET',
|
|
181
|
-
path: `/agents/${input.agent_id}`,
|
|
182
|
-
}),
|
|
183
|
-
}),
|
|
184
|
-
defineTool({
|
|
185
|
-
name: 'besales_agent_readiness_get',
|
|
186
|
-
sideEffect: 'none',
|
|
187
|
-
closedWorld: true,
|
|
188
|
-
requiredFields: ['agent_id'],
|
|
189
|
-
resultPolicy: { neverTruncate: true },
|
|
190
|
-
schema: z.object({ agent_id: uuidSchema }).strict(),
|
|
191
|
-
createRequest: (input) => ({
|
|
192
|
-
method: 'GET',
|
|
193
|
-
path: `/agents/${input.agent_id}/readiness`,
|
|
194
|
-
}),
|
|
195
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
196
|
-
'Сейчас readiness всегда отвечает NOT_PROVEN: API не фиксирует версию зависимых настроек (behavior, routing, triggers, knowledge, ICP), и повтор sandbox этого не снимает. Не обещай пользователю READY.',
|
|
197
|
-
'Выполни адресные пункты missing и перечитай readiness; promptAndAgentCurrent=true означает только актуальность промпта и записи агента.',
|
|
198
|
-
'passRate не является quality. Нужны COMPLETED, свежая конфигурация, findings, qualityRate и checksRate с expectations.',
|
|
199
|
-
'crmAuthorization=NOT_EVALUATED не подтверждает live-доступ CRM; проверяй его отдельной health/authorization операцией, если CRM нужна сценарию.',
|
|
200
|
-
]),
|
|
201
|
-
}),
|
|
202
|
-
defineTool({
|
|
203
|
-
name: 'besales_agent_variable_overrides_get',
|
|
204
|
-
sideEffect: 'none',
|
|
205
|
-
requiredFields: ['platform_id', 'agent_id'],
|
|
206
|
-
resultPolicy: { neverTruncate: true },
|
|
207
|
-
schema: z.object({
|
|
208
|
-
platform_id: uuidSchema,
|
|
209
|
-
agent_id: uuidSchema,
|
|
210
|
-
}),
|
|
211
|
-
createRequest: (input) => ({
|
|
212
|
-
method: 'GET',
|
|
213
|
-
path: `/platforms/${input.platform_id}/agents/${input.agent_id}/variable-overrides`,
|
|
214
|
-
}),
|
|
215
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
216
|
-
'Read-only: текущие перезаписи переменных агента. `workspaceOverrides[]` — перезаписи WorkspaceVariable ({{{name}}}); `customOverrides[]` — перезаписи платформенной CustomVariable ({name}). Каждая: id переменной + name + type + overrideValue.',
|
|
217
|
-
'Читай ПЕРЕД besales_agent_update: поля agent_workspace_variable_overrides / agent_variable_overrides заменяют набор ЦЕЛИКОМ (delete отсутствующих + upsert присланных). Чтобы не затереть уже выставленную перезапись (напр. registration_link), переотправь её вместе с новыми.',
|
|
218
|
-
'Пустой набор → у агента нет перезаписей, он наследует дефолты переменных воркспейса/платформы.',
|
|
219
|
-
]),
|
|
220
|
-
}),
|
|
221
|
-
defineTool({
|
|
222
|
-
name: 'besales_getcourse_departments_list',
|
|
223
|
-
sideEffect: 'none',
|
|
224
|
-
requiredFields: ['platform_id'],
|
|
225
|
-
schema: z.object({
|
|
226
|
-
platform_id: uuidSchema,
|
|
227
|
-
}),
|
|
228
|
-
createRequest: (input) => ({
|
|
229
|
-
method: 'GET',
|
|
230
|
-
path: `/platforms/${input.platform_id}/getcourse/departments`,
|
|
231
|
-
}),
|
|
232
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
233
|
-
'Живой список отделов GetCourse Inbox школы ({ id, title }).',
|
|
234
|
-
'Используй department.id как target_department_id в besales_platform_settings_update (getcourse_settings) для department-routing.',
|
|
235
|
-
]),
|
|
236
|
-
}),
|
|
237
|
-
...getCourseWaveTools,
|
|
238
|
-
defineTool({
|
|
239
|
-
name: 'besales_wazzup_templates_list',
|
|
240
|
-
sideEffect: 'none',
|
|
241
|
-
requiredFields: ['platform_id'],
|
|
242
|
-
defaultWorkspaceId: true,
|
|
243
|
-
schema: z.object({
|
|
244
|
-
workspace_id: uuidSchema.optional(),
|
|
245
|
-
platform_id: uuidSchema,
|
|
246
|
-
}),
|
|
247
|
-
createRequest: (input) => ({
|
|
248
|
-
method: 'GET',
|
|
249
|
-
path: `/workspaces/${input.workspace_id}/wazzup-waves/templates/${input.platform_id}`,
|
|
250
|
-
}),
|
|
251
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
252
|
-
'Шаблоны WABA платформы Wazzup: templateGuid, title, status модерации Meta, bodyText, variableCount (сколько значений переменных нужно), usable + unsupportedReasons.',
|
|
253
|
-
'В волне используй ТОЛЬКО шаблоны с usable=true. Остальные либо не одобрены Meta, либо содержат медиа-заголовок / переменную в URL-кнопке — там значения ушли бы не в те слоты.',
|
|
254
|
-
'variableCount считается по МАКСИМАЛЬНОМУ индексу {{n}}: «{{1}} … {{2}} … {{1}}» — это 2 значения, а не 3.',
|
|
255
|
-
]),
|
|
256
|
-
}),
|
|
257
|
-
defineTool({
|
|
258
|
-
name: 'besales_wazzup_wave_import',
|
|
259
|
-
sideEffect: 'spend',
|
|
260
|
-
requiredFields: ['platform_id', 'template_guid', 'contacts'],
|
|
261
|
-
defaultWorkspaceId: true,
|
|
262
|
-
schema: z
|
|
263
|
-
.object({
|
|
264
|
-
workspace_id: uuidSchema.optional(),
|
|
265
|
-
platform_id: uuidSchema,
|
|
266
|
-
template_guid: z.string().trim().max(100),
|
|
267
|
-
template_values: z.array(z.string()).max(20).optional(),
|
|
268
|
-
contacts: z
|
|
269
|
-
.array(z.object({
|
|
270
|
-
phone: z.string().trim().max(32),
|
|
271
|
-
name: z.string().max(200).optional(),
|
|
272
|
-
}))
|
|
273
|
-
.min(1)
|
|
274
|
-
.max(500),
|
|
275
|
-
funnel: z.string().max(200).optional(),
|
|
276
|
-
segment: z.string().max(200).optional(),
|
|
277
|
-
product_code: z
|
|
278
|
-
.string()
|
|
279
|
-
.trim()
|
|
280
|
-
.max(100)
|
|
281
|
-
.regex(/^[^\s/]+$/, 'product_code: без пробелов и «/»')
|
|
282
|
-
.optional(),
|
|
283
|
-
product_name: z.string().max(200).optional(),
|
|
284
|
-
cohort_label: z.string().max(200).optional(),
|
|
285
|
-
confirm: z.boolean().optional(),
|
|
286
|
-
/**
|
|
287
|
-
* Обязателен ВМЕСТЕ с confirm=true: волна необратима и платна (каждый WABA-шаблон
|
|
288
|
-
* тарифицируется Meta). Dry-run (без confirm) подтверждения не требует.
|
|
289
|
-
*/
|
|
290
|
-
explicit_confirmation: z.literal(true).optional(),
|
|
291
|
-
confirmation_reason: z.string().optional(),
|
|
292
|
-
})
|
|
293
|
-
.refine((input) => !input.confirm || input.explicit_confirmation === true, {
|
|
294
|
-
message: 'Реальный запуск волны требует explicit_confirmation=true: сообщения платные и необратимые',
|
|
295
|
-
path: ['explicit_confirmation'],
|
|
296
|
-
}),
|
|
297
|
-
createRequest: (input) => ({
|
|
298
|
-
method: 'POST',
|
|
299
|
-
path: `/workspaces/${input.workspace_id}/wazzup-waves/import`,
|
|
300
|
-
body: compactObject({
|
|
301
|
-
platformId: input.platform_id,
|
|
302
|
-
templateGuid: input.template_guid,
|
|
303
|
-
templateValues: input.template_values,
|
|
304
|
-
funnel: input.funnel,
|
|
305
|
-
segment: input.segment,
|
|
306
|
-
productCode: input.product_code,
|
|
307
|
-
productName: input.product_name,
|
|
308
|
-
cohortLabel: input.cohort_label,
|
|
309
|
-
contacts: input.contacts?.map((c) => compactObject({ phone: c.phone, name: c.name })),
|
|
310
|
-
confirm: input.confirm,
|
|
311
|
-
}),
|
|
312
|
-
}),
|
|
313
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
314
|
-
'Волна WhatsApp через Wazzup: одобренный WABA-шаблон уходит по когорте телефонов. Ответы получателей обрабатывает AI-агент платформы, волна видна в «Аналитике рассылок» (канал WhatsApp).',
|
|
315
|
-
'БЕЗ confirm=true — DRY-RUN: прогоняется ПОЛНЫЙ preflight (платформа, живой WABA-канал, шаблон, число значений) и возвращается previewText — НИ ОДНО сообщение не отправляется. Покажи previewText пользователю и запускай реально только с confirm=true.',
|
|
316
|
-
'Реальный запуск требует ОДНОВРЕМЕННО confirm=true и explicit_confirmation=true — второе ставится только после явного согласия пользователя на отправку платных сообщений.',
|
|
317
|
-
'КАЖДОЕ маркетинговое сообщение WhatsApp ПЛАТНОЕ, а Meta ограничивает число уникальных получателей в сутки (на старте 250, дальше растёт после верификации бизнеса). Не запускай большие когорты без явного согласия пользователя.',
|
|
318
|
-
'template_guid бери из besales_wazzup_templates_list (только usable=true). Длина template_values обязана совпасть с variableCount шаблона, иначе запуск отклонят.',
|
|
319
|
-
'Повторная отправка ТОГО ЖЕ шаблона тому же контакту в течение суток пропускается автоматически (защита от двойного списания). Другой шаблон той же когорте не блокируется.',
|
|
320
|
-
'Пропускаются контакты, остановившие бота, ждущие оператора и заблокированные — они попадут в skipped, а не в failed.',
|
|
321
|
-
'В ответе confirm-запуска — jobId. Опрашивай его через besales_wazzup_wave_status до status=COMPLETED (отправки идут с паузами).',
|
|
322
|
-
]),
|
|
323
|
-
}),
|
|
324
|
-
defineTool({
|
|
325
|
-
name: 'besales_wazzup_wave_status',
|
|
326
|
-
sideEffect: 'none',
|
|
327
|
-
requiredFields: ['job_id'],
|
|
328
|
-
defaultWorkspaceId: true,
|
|
329
|
-
schema: z.object({
|
|
330
|
-
workspace_id: uuidSchema.optional(),
|
|
331
|
-
job_id: uuidSchema,
|
|
332
|
-
}),
|
|
333
|
-
createRequest: (input) => ({
|
|
334
|
-
method: 'GET',
|
|
335
|
-
path: `/workspaces/${input.workspace_id}/wazzup-waves/${input.job_id}`,
|
|
336
|
-
}),
|
|
337
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
338
|
-
'Статус волны WhatsApp: status (PROCESSING|COMPLETED), processedRows, sent/failed/skipped, errors (построчные причины).',
|
|
339
|
-
'skipped — сознательные пропуски (клиент остановил бота, ждёт оператора, недавно уже получал этот шаблон). Это НЕ ошибки: сумма sent+failed+skipped равна числу обработанных строк.',
|
|
340
|
-
'Доставка приходит вебхуками WhatsApp и живёт ОТДЕЛЬНО от исхода отправки: delivered/read/deliveryFailed + deliveryErrors (коды). Докладывай их вместе с sent — «отправлено» означает лишь, что Wazzup принял сообщение.',
|
|
341
|
-
'delivered и deliveryFailed взаимоисключающи; read — подмножество delivered. unknownOutcome — строки, занятые под отправку без известного исхода (краш между claim и ответом Wazzup); автоматически они НЕ переотправляются и требуют ручного разбора.',
|
|
342
|
-
]),
|
|
343
|
-
}),
|
|
344
|
-
defineTool({
|
|
345
|
-
name: 'besales_agent_create',
|
|
346
|
-
sideEffect: 'write',
|
|
347
|
-
requiredFields: ['platform_id', 'name', 'model_lane'],
|
|
348
|
-
schema: z.object({
|
|
349
|
-
platform_id: uuidSchema,
|
|
350
|
-
name: z.string(),
|
|
351
|
-
description: z.string().nullable().optional(),
|
|
352
|
-
model_lane: modelLaneSchema,
|
|
353
|
-
// Явный id модели (override). Если задан — побеждает model_lane.
|
|
354
|
-
// Список доступных моделей — besales_model_catalog_list.
|
|
355
|
-
model: z.string().optional(),
|
|
356
|
-
default_icp_profile_id: uuidSchema.optional(),
|
|
357
|
-
// Phase 1 — перезаписи переменных на уровне агента (бьют по CustomVariable платформы).
|
|
358
|
-
agent_variable_overrides: z
|
|
359
|
-
.array(z.object({
|
|
360
|
-
custom_variable_id: uuidSchema,
|
|
361
|
-
override_value: z.union([z.string(), z.number(), z.boolean()]),
|
|
362
|
-
}))
|
|
363
|
-
.optional(),
|
|
364
|
-
// Перезаписи переменных воркспейса на уровне агента (бьют по WorkspaceVariable).
|
|
365
|
-
agent_workspace_variable_overrides: z
|
|
366
|
-
.array(z.object({
|
|
367
|
-
workspace_variable_id: uuidSchema,
|
|
368
|
-
override_value: z.union([z.string(), z.number(), z.boolean()]),
|
|
369
|
-
}))
|
|
370
|
-
.optional(),
|
|
371
|
-
}),
|
|
372
|
-
createRequest: (input) => ({
|
|
373
|
-
path: `/platforms/${input.platform_id}/agents`,
|
|
374
|
-
body: compactObject({
|
|
375
|
-
name: input.name,
|
|
376
|
-
description: input.description,
|
|
377
|
-
modelLane: input.model_lane,
|
|
378
|
-
model: input.model,
|
|
379
|
-
defaultIcpProfileId: input.default_icp_profile_id,
|
|
380
|
-
agentVariableOverrides: input.agent_variable_overrides?.map((o) => ({
|
|
381
|
-
customVariableId: o.custom_variable_id,
|
|
382
|
-
overrideValue: o.override_value,
|
|
383
|
-
})),
|
|
384
|
-
agentWorkspaceVariableOverrides: input.agent_workspace_variable_overrides?.map((o) => ({
|
|
385
|
-
workspaceVariableId: o.workspace_variable_id,
|
|
386
|
-
overrideValue: o.override_value,
|
|
387
|
-
})),
|
|
388
|
-
}),
|
|
389
|
-
}),
|
|
390
|
-
}),
|
|
391
|
-
defineTool({
|
|
392
|
-
name: 'besales_agent_clone',
|
|
393
|
-
sideEffect: 'write',
|
|
394
|
-
requiredFields: ['platform_id', 'source_agent_id', 'name'],
|
|
395
|
-
schema: z.object({
|
|
396
|
-
// Платформа-источник; клон приземляется на неё же (cross-platform не поддерживается).
|
|
397
|
-
platform_id: uuidSchema,
|
|
398
|
-
// Исходный AgentChat для глубокого копирования (обязан принадлежать platform_id).
|
|
399
|
-
source_agent_id: uuidSchema,
|
|
400
|
-
// Системное имя нового агента; при коллизии backend добавит суффикс _N.
|
|
401
|
-
name: z.string(),
|
|
402
|
-
// Отображаемое имя нового агента; если не задано — зеркалит name.
|
|
403
|
-
display_name: z.string().optional(),
|
|
404
|
-
}),
|
|
405
|
-
createRequest: (input) => ({
|
|
406
|
-
method: 'POST',
|
|
407
|
-
path: `/platforms/${input.platform_id}/agents/${input.source_agent_id}/clone`,
|
|
408
|
-
body: compactObject({
|
|
409
|
-
name: input.name,
|
|
410
|
-
displayName: input.display_name,
|
|
411
|
-
}),
|
|
412
|
-
}),
|
|
413
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
414
|
-
'Клон — глубокая копия исходного агента на ТОЙ ЖЕ платформе (platform_id): baseSystemPrompt, knowledge namespaces, модель/model-lane/runtime, tools + builtin tools, перезаписи переменных (agent + workspace), ICP-линки и ВСЕ триггеры+действия скопированы на новый agent id (в ответе agent.id).',
|
|
415
|
-
'НЕ скопированы (осознанно): routing rules (per-router) и per-platform behavior. Клон инертен, пока не привязан к роутеру — добавь routing rule (besales_routing_rule_upsert), чтобы диалоги на него попадали.',
|
|
416
|
-
'Промпт идентичен источнику; PromptHub авто-bootstrap создаст новую версию при первой prompt-операции (besales_prompt_*). Cross-platform клон не поддерживается — для переноса на другую платформу используй besales_platform_clone_*.',
|
|
417
|
-
]),
|
|
418
|
-
}),
|
|
419
|
-
defineTool({
|
|
420
|
-
name: 'besales_agent_update',
|
|
421
|
-
sideEffect: 'write',
|
|
422
|
-
requiredFields: ['platform_id', 'agent_id'],
|
|
423
|
-
schema: z.object({
|
|
424
|
-
platform_id: uuidSchema,
|
|
425
|
-
agent_id: uuidSchema,
|
|
426
|
-
name: z.string().optional(),
|
|
427
|
-
description: z.string().nullable().optional(),
|
|
428
|
-
model_lane: modelLaneSchema.optional(),
|
|
429
|
-
// Явный id модели (override). Если задан — побеждает model_lane.
|
|
430
|
-
// Список доступных моделей — besales_model_catalog_list.
|
|
431
|
-
model: z.string().optional(),
|
|
432
|
-
default_icp_profile_id: uuidSchema.nullable().optional(),
|
|
433
|
-
use_global_history: z.boolean().optional(),
|
|
434
|
-
adapt_to_user_language: z.boolean().optional(),
|
|
435
|
-
// v1.5 Increment 3 Group B — typed sections.
|
|
436
|
-
runtime_config: agentRuntimeConfigSchema.optional(),
|
|
437
|
-
output_config: agentOutputConfigSchema.optional(),
|
|
438
|
-
knowledge_space_ids: z.array(uuidSchema).optional(),
|
|
439
|
-
agent_scope: agentScopeSchema.optional(),
|
|
440
|
-
// Phase 1 — перезаписи переменных на уровне агента (полная замена набора).
|
|
441
|
-
agent_variable_overrides: z
|
|
442
|
-
.array(z.object({
|
|
443
|
-
custom_variable_id: uuidSchema,
|
|
444
|
-
override_value: z.union([z.string(), z.number(), z.boolean()]),
|
|
445
|
-
}))
|
|
446
|
-
.optional(),
|
|
447
|
-
// Перезаписи переменных воркспейса на уровне агента (полная замена набора).
|
|
448
|
-
agent_workspace_variable_overrides: z
|
|
449
|
-
.array(z.object({
|
|
450
|
-
workspace_variable_id: uuidSchema,
|
|
451
|
-
override_value: z.union([z.string(), z.number(), z.boolean()]),
|
|
452
|
-
}))
|
|
453
|
-
.optional(),
|
|
454
|
-
}),
|
|
455
|
-
createRequest: (input) => ({
|
|
456
|
-
method: 'PATCH',
|
|
457
|
-
path: `/platforms/${input.platform_id}/agents/${input.agent_id}`,
|
|
458
|
-
body: compactObject({
|
|
459
|
-
name: input.name,
|
|
460
|
-
description: input.description,
|
|
461
|
-
modelLane: input.model_lane,
|
|
462
|
-
model: input.model,
|
|
463
|
-
defaultIcpProfileId: input.default_icp_profile_id,
|
|
464
|
-
useGlobalHistory: input.use_global_history,
|
|
465
|
-
adaptToUserLanguage: input.adapt_to_user_language,
|
|
466
|
-
runtimeConfig: input.runtime_config
|
|
467
|
-
? mapRuntimeConfigInput(input.runtime_config)
|
|
468
|
-
: undefined,
|
|
469
|
-
outputConfig: input.output_config ? mapOutputConfigInput(input.output_config) : undefined,
|
|
470
|
-
knowledgeSpaceIds: input.knowledge_space_ids,
|
|
471
|
-
agentScope: input.agent_scope,
|
|
472
|
-
agentVariableOverrides: input.agent_variable_overrides?.map((o) => ({
|
|
473
|
-
customVariableId: o.custom_variable_id,
|
|
474
|
-
overrideValue: o.override_value,
|
|
475
|
-
})),
|
|
476
|
-
agentWorkspaceVariableOverrides: input.agent_workspace_variable_overrides?.map((o) => ({
|
|
477
|
-
workspaceVariableId: o.workspace_variable_id,
|
|
478
|
-
overrideValue: o.override_value,
|
|
479
|
-
})),
|
|
480
|
-
}),
|
|
481
|
-
}),
|
|
482
|
-
}),
|
|
29
|
+
...platformSetupWaveTools,
|
|
30
|
+
...agentSettingsTools,
|
|
483
31
|
// Phase B (2026-05-27): `besales_agent_legacy_self_analysis_set` удалён.
|
|
484
32
|
// В v2 заменён post_processors (Routing Studio Critic node) + post_processor_bindings.
|
|
485
|
-
defineTool({
|
|
486
|
-
name: 'besales_agent_tools_update',
|
|
487
|
-
sideEffect: 'write',
|
|
488
|
-
requiredFields: ['platform_id', 'agent_id', 'tools'],
|
|
489
|
-
schema: z.object({
|
|
490
|
-
platform_id: uuidSchema,
|
|
491
|
-
agent_id: uuidSchema,
|
|
492
|
-
tools: z.array(agentToolPatchSchema).min(1),
|
|
493
|
-
}),
|
|
494
|
-
createRequest: (input) => ({
|
|
495
|
-
method: 'PATCH',
|
|
496
|
-
path: `/platforms/${input.platform_id}/agents/${input.agent_id}/tools`,
|
|
497
|
-
body: {
|
|
498
|
-
tools: input.tools.map((tool) => compactObject({
|
|
499
|
-
toolId: tool.tool_id,
|
|
500
|
-
priority: tool.priority,
|
|
501
|
-
isEnabled: tool.is_enabled,
|
|
502
|
-
agentSpecificConditions: tool.agent_specific_conditions,
|
|
503
|
-
})),
|
|
504
|
-
},
|
|
505
|
-
}),
|
|
506
|
-
}),
|
|
507
33
|
defineTool({
|
|
508
34
|
name: 'besales_router_update',
|
|
509
35
|
sideEffect: 'write',
|
|
510
36
|
requiredFields: ['platform_id'],
|
|
511
37
|
schema: z.object({
|
|
38
|
+
expected_version: z
|
|
39
|
+
.string()
|
|
40
|
+
.min(1)
|
|
41
|
+
.regex(/^[A-Za-z0-9_.-]+$/u)
|
|
42
|
+
.optional(),
|
|
512
43
|
platform_id: uuidSchema,
|
|
513
44
|
name: z.string().optional(),
|
|
514
45
|
model: z.string().optional(),
|
|
@@ -522,8 +53,9 @@ export const platformSetupTools = [
|
|
|
522
53
|
}),
|
|
523
54
|
createRequest: (input) => ({
|
|
524
55
|
method: 'PATCH',
|
|
525
|
-
path: `/
|
|
56
|
+
path: `/channels/${input.platform_id}/router`,
|
|
526
57
|
body: compactObject({
|
|
58
|
+
expectedVersion: input.expected_version,
|
|
527
59
|
name: input.name,
|
|
528
60
|
model: input.model,
|
|
529
61
|
temperature: input.temperature,
|
|
@@ -535,12 +67,18 @@ export const platformSetupTools = [
|
|
|
535
67
|
...setupConfirmation(input),
|
|
536
68
|
}),
|
|
537
69
|
}),
|
|
70
|
+
enhanceResponse: withEditVersionInstructions,
|
|
538
71
|
}),
|
|
539
72
|
defineTool({
|
|
540
73
|
name: 'besales_routing_rule_upsert',
|
|
541
74
|
sideEffect: 'write',
|
|
542
75
|
requiredFields: ['platform_id', 'routing_strategy', 'custom_router_prompt'],
|
|
543
76
|
schema: z.object({
|
|
77
|
+
expected_version: z
|
|
78
|
+
.string()
|
|
79
|
+
.min(1)
|
|
80
|
+
.regex(/^[A-Za-z0-9_.-]+$/u)
|
|
81
|
+
.optional(),
|
|
544
82
|
platform_id: uuidSchema,
|
|
545
83
|
routing_rule_id: uuidSchema.optional(),
|
|
546
84
|
routing_strategy: routingStrategySchema,
|
|
@@ -561,26 +99,19 @@ export const platformSetupTools = [
|
|
|
561
99
|
}),
|
|
562
100
|
createRequest: (input) => ({
|
|
563
101
|
method: input.routing_rule_id ? 'PATCH' : 'POST',
|
|
564
|
-
path: `/
|
|
102
|
+
path: `/channels/${input.platform_id}/router/routing-rules`,
|
|
565
103
|
body: compactObject({
|
|
104
|
+
expectedVersion: input.expected_version,
|
|
566
105
|
routingRuleId: input.routing_rule_id,
|
|
567
106
|
routingStrategy: input.routing_strategy,
|
|
568
107
|
dealMode: input.deal_mode,
|
|
569
108
|
customVariableId: input.custom_variable_id,
|
|
570
109
|
variableValue: input.variable_value,
|
|
571
110
|
conditionLogic: input.condition_logic,
|
|
572
|
-
conditions: input.conditions?.map((condition) => ({
|
|
111
|
+
conditions: input.conditions?.map((condition) => compactObject({
|
|
573
112
|
customVariableId: condition.custom_variable_id,
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
// Незаданную форму не отправляем вовсе: явный undefined в теле выглядел бы как
|
|
577
|
-
// «поле передано пустым» и мешал бы взаимоисключающей валидации на стороне API.
|
|
578
|
-
...(condition.variable_values !== undefined
|
|
579
|
-
? { variableValues: condition.variable_values }
|
|
580
|
-
: {}),
|
|
581
|
-
...(condition.variable_value !== undefined
|
|
582
|
-
? { variableValue: condition.variable_value }
|
|
583
|
-
: {}),
|
|
113
|
+
variableValue: condition.variable_value,
|
|
114
|
+
variableValues: condition.variable_values,
|
|
584
115
|
})),
|
|
585
116
|
customRouterPrompt: input.custom_router_prompt,
|
|
586
117
|
isEnabled: input.is_enabled,
|
|
@@ -596,102 +127,9 @@ export const platformSetupTools = [
|
|
|
596
127
|
...setupConfirmation(input),
|
|
597
128
|
}),
|
|
598
129
|
}),
|
|
130
|
+
enhanceResponse: (response) => withEditVersionInstructions(withProjectedRoutingRule(response)),
|
|
599
131
|
}),
|
|
600
|
-
|
|
601
|
-
name: 'besales_trigger_upsert',
|
|
602
|
-
sideEffect: 'write',
|
|
603
|
-
requiredFields: ['platform_id', 'agent_id'],
|
|
604
|
-
schema: z.object({
|
|
605
|
-
platform_id: uuidSchema,
|
|
606
|
-
agent_id: uuidSchema,
|
|
607
|
-
trigger_id: uuidSchema.optional(),
|
|
608
|
-
// `.trim()` — как у формы и бэкенда: строка из пробелов пустая, «Оплата » равна «Оплата».
|
|
609
|
-
name: z.string().trim().min(1).max(TRIGGER_NAME_MAX_LENGTH).optional(),
|
|
610
|
-
condition: z.string().trim().min(1).max(TRIGGER_CONDITION_MAX_LENGTH).optional(),
|
|
611
|
-
is_enabled: z.boolean().optional(),
|
|
612
|
-
priority: z.number().int().min(1).max(100).optional(),
|
|
613
|
-
stop_propagation: z.boolean().optional(),
|
|
614
|
-
/** Повтор ВНУТРИ одного ответа модели. Горизонт — этот ответ, дальше состояние теряется. */
|
|
615
|
-
allow_repeated_calls: z.boolean().optional(),
|
|
616
|
-
/**
|
|
617
|
-
* Одно срабатывание на контакт НАВСЕГДА (право в `agent_trigger_contact_claims`).
|
|
618
|
-
* Ось другая, чем у `allow_repeated_calls`: тот живёт один ответ, этот переживает
|
|
619
|
-
* все следующие сообщения. Для действий, пишущих в чужие системы (заметка в CRM).
|
|
620
|
-
*/
|
|
621
|
-
run_once_per_contact: z.boolean().optional(),
|
|
622
|
-
scope: triggerScopeSchema,
|
|
623
|
-
metadata: anyObjectSchema.optional(),
|
|
624
|
-
/**
|
|
625
|
-
* Действия триггера. Конфиг действия кладётся в поле, ИМЯ которого зависит от actionType:
|
|
626
|
-
* правило `camelCase(actionType) + 'Config'`, но у пяти типов имена легаси
|
|
627
|
-
* (см. `TRIGGER_ACTION_CONFIG_NAMES`). Имя в ОТВЕТЕ API другое — MCP принимает оба.
|
|
628
|
-
*/
|
|
629
|
-
actions: z.array(anyObjectSchema).optional(),
|
|
630
|
-
replace_actions: z.boolean().optional(),
|
|
631
|
-
...platformSetupConfirmationSchema,
|
|
632
|
-
}).superRefine((input, ctx) => {
|
|
633
|
-
if (!input.actions?.length) {
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
for (const issue of normalizeTriggerActions(input.actions)
|
|
637
|
-
.issues) {
|
|
638
|
-
ctx.addIssue({
|
|
639
|
-
code: z.ZodIssueCode.custom,
|
|
640
|
-
path: ['actions', issue.index],
|
|
641
|
-
message: issue.message,
|
|
642
|
-
});
|
|
643
|
-
}
|
|
644
|
-
}),
|
|
645
|
-
createRequest: (input) => ({
|
|
646
|
-
method: input.trigger_id ? 'PATCH' : 'POST',
|
|
647
|
-
path: input.trigger_id
|
|
648
|
-
? `/platforms/${input.platform_id}/agents/${input.agent_id}/triggers/${input.trigger_id}`
|
|
649
|
-
: `/platforms/${input.platform_id}/agents/${input.agent_id}/triggers`,
|
|
650
|
-
body: compactObject({
|
|
651
|
-
name: input.name,
|
|
652
|
-
condition: input.condition,
|
|
653
|
-
isEnabled: input.is_enabled,
|
|
654
|
-
priority: input.priority,
|
|
655
|
-
stopPropagation: input.stop_propagation,
|
|
656
|
-
allowRepeatedCalls: input.allow_repeated_calls,
|
|
657
|
-
runOncePerContact: input.run_once_per_contact,
|
|
658
|
-
scope: input.scope,
|
|
659
|
-
metadata: input.metadata,
|
|
660
|
-
// Конфиг под именем связи (как его отдаёт besales_platform_context_get) переименовывается
|
|
661
|
-
// в ключ входа: бэкенд с forbidNonWhitelisted отверг бы имя ответа как «лишнее свойство».
|
|
662
|
-
actions: input.actions
|
|
663
|
-
? normalizeTriggerActions(input.actions).actions
|
|
664
|
-
: undefined,
|
|
665
|
-
replaceActions: input.replace_actions,
|
|
666
|
-
...setupConfirmation(input),
|
|
667
|
-
}),
|
|
668
|
-
}),
|
|
669
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
670
|
-
'Конфиг действия кладётся в поле, имя которого зависит от actionType: правило ' +
|
|
671
|
-
'camelCase(actionType)+"Config" (CRM_UPDATE_FIELD → crmUpdateFieldConfig). Пять исключений: ' +
|
|
672
|
-
'CRM_MOVE_STAGE → crmConfig, SCHEDULE_FOLLOWUP → scheduleFollowUpConfig, ' +
|
|
673
|
-
'SUMMARIZE_DIALOG → summarizeConfig, SEND_TELEGRAM_CHANNEL_MESSAGE → telegramChannelConfig, ' +
|
|
674
|
-
'CRM_RENAME_DEAL → renameDealConfig. В ОТВЕТЕ тот же конфиг приходит под именем связи ' +
|
|
675
|
-
'(crmMoveStage, summarizeAction, telegramChannelMessage, renameDeal, scheduleFollowUp) — ' +
|
|
676
|
-
'пересылать прочитанное можно как есть: MCP переименует конфиг и снимет поля, которые ' +
|
|
677
|
-
'ответ отдаёт, а вход не принимает (id, triggerId, createdAt, updatedAt, пустые связи).',
|
|
678
|
-
'Действие с обязательным конфигом, отправленное без него, бэкенд отвергает: раньше оно ' +
|
|
679
|
-
'сохранялось пустым, отвечало 200, а отказ всплывал только в живом диалоге.',
|
|
680
|
-
'replace_actions=true заменяет ВЕСЬ набор действий триггера (delete-and-recreate, как в UI) — ' +
|
|
681
|
-
'сперва прочитай текущие действия (besales_platform_context_get) и передай ПОЛНЫЙ желаемый набор, ' +
|
|
682
|
-
'а не дельту, иначе потеряешь не переданные действия.',
|
|
683
|
-
'Без replace_actions передача actions на существующем триггере отклоняется (защита от случайной потери).',
|
|
684
|
-
'SILENT_AI: оси молчания РАЗДЕЛЬНЫЕ (silenceBot — бот перестаёт отвечать; ' +
|
|
685
|
-
'silenceFollowUps — цепочки перестают инициировать касания), и обе включены ПО УМОЛЧАНИЮ. ' +
|
|
686
|
-
'При replace_actions передавай их ЯВНО: пересобрав действие без этих полей, ты молча ' +
|
|
687
|
-
'вернёшь выключенную ось во включённую (дефолт = прежнее поведение экшена, а не ' +
|
|
688
|
-
'«как было»). Обе выключенные отвергаются.',
|
|
689
|
-
'allow_repeated_calls и run_once_per_contact — РАЗНЫЕ оси, не синонимы: первый про повтор ' +
|
|
690
|
-
'внутри одного ответа модели, второй запрещает срабатывание навсегда после первого ' +
|
|
691
|
-
'успешного действия у этого контакта. Для действий, пишущих в чужие системы (заметка в CRM, ' +
|
|
692
|
-
'создание сделки), нужен именно run_once_per_contact.',
|
|
693
|
-
]),
|
|
694
|
-
}),
|
|
132
|
+
triggerUpsertTool,
|
|
695
133
|
defineTool({
|
|
696
134
|
name: 'besales_trigger_delete',
|
|
697
135
|
sideEffect: 'write',
|
|
@@ -707,7 +145,7 @@ export const platformSetupTools = [
|
|
|
707
145
|
.strict(),
|
|
708
146
|
createRequest: (input) => ({
|
|
709
147
|
method: 'DELETE',
|
|
710
|
-
path: `/
|
|
148
|
+
path: `/channels/${input.platform_id}/agents/${input.agent_id}/triggers/${input.trigger_id}`,
|
|
711
149
|
body: setupConfirmation(input),
|
|
712
150
|
}),
|
|
713
151
|
enhanceResponse: (response) => withInstructions(response, [
|
|
@@ -721,62 +159,174 @@ export const platformSetupTools = [
|
|
|
721
159
|
requiredFields: ['platform_id'],
|
|
722
160
|
schema: z
|
|
723
161
|
.object({
|
|
162
|
+
expected_version: z
|
|
163
|
+
.string()
|
|
164
|
+
.min(1)
|
|
165
|
+
.regex(/^[A-Za-z0-9_.-]+$/u)
|
|
166
|
+
.optional(),
|
|
724
167
|
platform_id: uuidSchema,
|
|
725
|
-
//
|
|
726
|
-
greeting:
|
|
168
|
+
// Секции с прежними именами полей принимают и прежнюю форму вызова (перевод — behavior-shipped-form.ts).
|
|
169
|
+
greeting: shippedFormGreetingSchema.optional(),
|
|
727
170
|
media_handling: behaviorMediaHandlingSchema.optional(),
|
|
171
|
+
unsupported_input_handling: behaviorUnsupportedInputHandlingSchema.optional(),
|
|
728
172
|
url_handling: behaviorUrlHandlingSchema.optional(),
|
|
729
|
-
error_handling:
|
|
730
|
-
operator_schedule:
|
|
731
|
-
typing_behavior:
|
|
732
|
-
message_filters:
|
|
733
|
-
message_splitting:
|
|
734
|
-
privacy:
|
|
173
|
+
error_handling: shippedFormErrorHandlingSchema.optional(),
|
|
174
|
+
operator_schedule: shippedFormOperatorScheduleSchema.optional(),
|
|
175
|
+
typing_behavior: shippedFormTypingBehaviorSchema.optional(),
|
|
176
|
+
message_filters: shippedFormMessageFiltersSchema.optional(),
|
|
177
|
+
message_splitting: shippedFormMessageSplittingSchema.optional(),
|
|
178
|
+
privacy: shippedFormPrivacySchema.optional(),
|
|
179
|
+
crm_behavior: behaviorCrmSchema.optional(),
|
|
735
180
|
...platformSetupConfirmationSchema,
|
|
736
181
|
})
|
|
737
|
-
.strict()
|
|
182
|
+
.strict()
|
|
183
|
+
.superRefine((value, context) => {
|
|
184
|
+
for (const conflict of shippedFormConflicts(value)) {
|
|
185
|
+
context.addIssue({
|
|
186
|
+
code: 'custom',
|
|
187
|
+
path: conflict.path,
|
|
188
|
+
message: conflict.message,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}),
|
|
192
|
+
createRequest: (input) => {
|
|
193
|
+
// ⛔ Сервер видит только канон новой версии: прежние имена и форма переводятся ЗДЕСЬ, одной функцией.
|
|
194
|
+
const sections = translateShippedBehavior({
|
|
195
|
+
greeting: input.greeting,
|
|
196
|
+
error_handling: input.error_handling,
|
|
197
|
+
operator_schedule: input.operator_schedule,
|
|
198
|
+
typing_behavior: input.typing_behavior,
|
|
199
|
+
message_filters: input.message_filters,
|
|
200
|
+
message_splitting: input.message_splitting,
|
|
201
|
+
privacy: input.privacy,
|
|
202
|
+
});
|
|
203
|
+
const section = (name) => withSchemaVersion(sections[name]);
|
|
204
|
+
return {
|
|
205
|
+
method: 'PATCH',
|
|
206
|
+
path: `/channels/${input.platform_id}/behavior`,
|
|
207
|
+
body: compactObject({
|
|
208
|
+
expectedVersion: input.expected_version,
|
|
209
|
+
greeting: section('greeting'),
|
|
210
|
+
mediaHandling: withSchemaVersion(input.media_handling),
|
|
211
|
+
unsupportedInputHandling: withSchemaVersion(input.unsupported_input_handling),
|
|
212
|
+
urlHandling: withSchemaVersion(input.url_handling),
|
|
213
|
+
errorHandling: section('error_handling'),
|
|
214
|
+
operatorSchedule: section('operator_schedule'),
|
|
215
|
+
typingBehavior: section('typing_behavior'),
|
|
216
|
+
messageFilters: section('message_filters'),
|
|
217
|
+
messageSplitting: section('message_splitting'),
|
|
218
|
+
privacy: section('privacy'),
|
|
219
|
+
crmBehavior: withSchemaVersion(input.crm_behavior),
|
|
220
|
+
...setupConfirmation(input),
|
|
221
|
+
}),
|
|
222
|
+
};
|
|
223
|
+
},
|
|
224
|
+
enhanceResponse: (response, input) => withInstructions(response, [
|
|
225
|
+
editVersionInstruction(),
|
|
226
|
+
...droppedShippedFields(input).map((field) => `Поле ${field} прежней версии не исполнялось и там, в новой не хранится — значение отброшено.`),
|
|
227
|
+
'Секция СЛИВАЕТСЯ с текущей: присылай только те поля, которые меняешь — соседние сохранятся. null у поля очищает его.',
|
|
228
|
+
'У канала, который ещё не настраивали, сливать не с чем: ПЕРВАЯ запись секции обязана быть полной. Текущее состояние читается besales_platform_context_get (поле behavior).',
|
|
229
|
+
'В message_filters.rules образец source должен быть непустым после trim(), но значимые краевые пробелы сохраняются. Несимволы Unicode запрещены и в source, и в target. Сервер раскрывает в target \\n, \\t, \\r и \\\\ за один проход; чтение экранирует обратную черту, поэтому прочитанное target можно отправить обратно без двойного раскрытия.',
|
|
230
|
+
'⚠️ Требуют explicit_confirmation: смена вызова оператора у вложений/ссылок/ошибок, включение PROCESS_WITH_LLM у картинки или документа (в модель уходит содержимое чужих файлов), выключение паузы после ответа оператора, выключение обезличивания и расширение списка исключённых типов PII, смена включённости и типа входящего фильтра по сделке.',
|
|
231
|
+
'crm_behavior.inbound_deal_filter — входящий фильтр по сделке GetCourse: бот отвечает только тем, у кого есть подходящая сделка (метка TAG либо значение поля CUSTOM_FIELD, для него нужен ещё field_id — ИМЯ поля). Включённый фильтр обязан быть полным, иначе отказ BEHAVIOR_SECTION_INVALID с путём inbound_deal_filter. Раздел сливается с сохранённым CRM-поведением: у канала без привязанной CRM его не записать.',
|
|
232
|
+
]),
|
|
233
|
+
}),
|
|
234
|
+
defineTool({
|
|
235
|
+
name: 'besales_followup_sequence_upsert',
|
|
236
|
+
sideEffect: 'write',
|
|
237
|
+
requiredFields: ['platform_id', 'name', 'type', 'trigger', 'config'],
|
|
238
|
+
schema: z
|
|
239
|
+
.object({
|
|
240
|
+
platform_id: uuidSchema,
|
|
241
|
+
sequence_id: uuidSchema.optional(),
|
|
242
|
+
expected_version: z
|
|
243
|
+
.string()
|
|
244
|
+
.regex(/^[1-9][0-9]{0,9}$/u)
|
|
245
|
+
.optional()
|
|
246
|
+
.describe('expected_version — исходная editRevision открытой формы цепочки; передай её явно для защиты от перезаписи чужих изменений. Без expected_version для PATCH нужны read:workflows и write:workflows: мост читает текущую ревизию перед записью; ошибка чтения отменяет запись. Это защищает только окно между GET и PATCH, но не изменения после открытия формы и до GET. Конфликт 409 возвращается без автоматического повтора.'),
|
|
247
|
+
name: z.string(),
|
|
248
|
+
description: z.string().nullable().optional(),
|
|
249
|
+
type: followUpSequenceTypeSchema,
|
|
250
|
+
enabled: z.boolean().optional(),
|
|
251
|
+
trigger: followUpTriggerSchema,
|
|
252
|
+
config: followupSequenceConfigSchema,
|
|
253
|
+
...platformSetupConfirmationSchema,
|
|
254
|
+
})
|
|
255
|
+
.superRefine(refineFollowUpConfig)
|
|
256
|
+
.superRefine((input, context) => {
|
|
257
|
+
if (input.trigger !== 'USER_INACTIVITY' &&
|
|
258
|
+
input.trigger !== 'LOST_CLIENTS' &&
|
|
259
|
+
(Object.hasOwn(input.config, 'assign_responsible_operator_ids') ||
|
|
260
|
+
Object.hasOwn(input.config, 'assignResponsibleOperatorIds')))
|
|
261
|
+
context.addIssue({
|
|
262
|
+
code: 'custom',
|
|
263
|
+
path: ['config'],
|
|
264
|
+
message: crmStagePoolMessage('unsupported'),
|
|
265
|
+
});
|
|
266
|
+
}),
|
|
738
267
|
createRequest: (input) => ({
|
|
739
|
-
method: 'PATCH',
|
|
740
|
-
path:
|
|
268
|
+
method: input.sequence_id ? 'PATCH' : 'POST',
|
|
269
|
+
path: input.sequence_id
|
|
270
|
+
? `/channels/${input.platform_id}/followup-sequences/${input.sequence_id}`
|
|
271
|
+
: `/channels/${input.platform_id}/followup-sequences`,
|
|
272
|
+
...(input.sequence_id && input.expected_version === undefined
|
|
273
|
+
? {
|
|
274
|
+
followupRevisionLookup: {
|
|
275
|
+
path: `/channels/${input.platform_id}/followup-sequences?sequenceId=${input.sequence_id}`,
|
|
276
|
+
sequenceId: input.sequence_id,
|
|
277
|
+
},
|
|
278
|
+
}
|
|
279
|
+
: {}),
|
|
741
280
|
body: compactObject({
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
errorHandling: input.error_handling
|
|
750
|
-
? mapBehaviorErrorHandlingInput(input.error_handling)
|
|
751
|
-
: undefined,
|
|
752
|
-
operatorSchedule: input.operator_schedule
|
|
753
|
-
? mapBehaviorOperatorScheduleInput(input.operator_schedule)
|
|
754
|
-
: undefined,
|
|
755
|
-
typingBehavior: input.typing_behavior
|
|
756
|
-
? mapBehaviorTypingInput(input.typing_behavior)
|
|
757
|
-
: undefined,
|
|
758
|
-
messageFilters: input.message_filters
|
|
759
|
-
? input.message_filters.map((filter) => ({
|
|
760
|
-
id: filter.id,
|
|
761
|
-
source: filter.source,
|
|
762
|
-
target: filter.target,
|
|
763
|
-
enabled: filter.enabled,
|
|
764
|
-
order: filter.order,
|
|
765
|
-
}))
|
|
766
|
-
: undefined,
|
|
767
|
-
messageSplitting: input.message_splitting
|
|
768
|
-
? { messageChunkSeparator: input.message_splitting.message_chunk_separator }
|
|
769
|
-
: undefined,
|
|
770
|
-
privacy: input.privacy
|
|
771
|
-
? {
|
|
772
|
-
anonymizationEnabled: input.privacy.anonymization_enabled,
|
|
773
|
-
contactNamePersonalizationMode: input.privacy.contact_name_personalization_mode,
|
|
774
|
-
anonymizationDisabledTypes: input.privacy.anonymization_disabled_types,
|
|
775
|
-
}
|
|
776
|
-
: undefined,
|
|
281
|
+
name: input.name,
|
|
282
|
+
description: input.description,
|
|
283
|
+
type: input.type,
|
|
284
|
+
expectedVersion: input.expected_version,
|
|
285
|
+
enabled: input.enabled,
|
|
286
|
+
trigger: input.trigger,
|
|
287
|
+
config: input.config,
|
|
777
288
|
...setupConfirmation(input),
|
|
778
289
|
}),
|
|
779
290
|
}),
|
|
291
|
+
enhanceResponse: (response) => withInstructions(response, [
|
|
292
|
+
crmStagePoolMessage('hint'),
|
|
293
|
+
...followUpPromotionInstructions,
|
|
294
|
+
'Аудитория цепочки задаётся двумя частями: базовым фильтром config.filterMode и условиями config.sequenceConditions, которые СУЖАЮТ его через «И». Поддерживаются три режима: "variable" (базового фильтра нет, условия обязательны) и "eventType" (нужен непустой config.allowedEventTypes из значений START, IN_PROCESS, FINISH_WIN, FINISH_LOST, FAILED, OPERATOR_TAKEOVER, FINISH_AUTO). Режим "status" требует config.allowedStatuses; отсутствие режима отклоняется.',
|
|
295
|
+
'Условие пишется как {variable: "ИМЯ", op: "eq"|"neq"|"in", value}: строка для eq/neq, непустой массив строк для in. Условия соединяются только через «И». Переменная называется ИМЕНЕМ; константа, секрет и одноимённые переменные разных уровней отклоняются.',
|
|
296
|
+
'⚠️ Цепочки НЕ исключают друг друга: у каждой свой прогресс. Набор обязан быть строгим разбиением — «= A», «= B» и подстраховка «≠ A И ≠ B». Безусловная цепочка рядом с точными не подстраховывает, а УДВАИВАЕТ отправку тем, у кого значение есть. У контакта без значения eq/in ложны, neq истинно — именно поэтому подстраховка пишется отрицаниями, а не пустым набором условий.',
|
|
297
|
+
'config.stopOnPayment: true — выключать дожимы у оплатившего: при зачёте оплаты человеку ставится «дожимы выключены навсегда» на каналах, где такая цепочка включена (все его карточки в школе GetCourse и канал, из которого пришёл оплаченный заказ). Только true/false; читается у цепочки бездействия (USER_INACTIVITY), у «пропавших клиентов» не действует. Оператор может включить дожимы обратно — это держится до следующего зачёта оплаты (ночной разбор засчитывает оплату через часы после неё).',
|
|
298
|
+
'Календарная цепочка: у КАЖДОГО шага scheduleMode="clock", anchorMode="variable" и anchorVariable — имя переменной карточки с датой (ГГГГ-ММ-ДД или ДД.ММ.ГГГГ, можно со временем), плюс atTime (ЧЧ:ММ) и dayOffset (от −7 до 30 дней от даты). Такая цепочка запускается датой в карточке и перепиской на канале — в том числе у того, кто только получил наше первое сообщение; ответ клиента её не прерывает; касание сдвигается вместе с датой; опоздавшее дольше validityMinutes (по умолчанию 45) касание пропускается. Варианты одного момента — подряд идущие шаги с одинаковым slotGroup: уходит первый, чьи conditions выполнены. Некалендарный шаг в такой цепочке и finalAction отвергаются; skipIfContactRepliedSincePreviousSlot пропускает касание после ответа на предыдущий отличный момент.',
|
|
299
|
+
'config.contactVariablesOnSend — записка после успешной отправки: объект из 1–10 пар «имя переменной контакта этого канала → непустой текст до 500 кодовых единиц». Подготовь переменную контакта на канале цепочки и одноимённую константу канала рассылки: при холодной отправке значение контакта побеждает константу. Доступно цепочкам молчания и календаря, у потерянных клиентов сервер откажет. null снимает записку; отсутствие поля при полной правке тоже снимет её.',
|
|
300
|
+
'Если description или enabled не переданы, их прежнее значение сохраняется. null или пустая строка очищает описание.',
|
|
301
|
+
'Перенесённая цепочка сохраняет номер по месту исходного шага: добавление в конец даёт следующий номер, вставка или удаление сдвигает номера новых выдач. Уже выданные коды не меняются. Собственная цепочка нумерует группы действий между ожиданиями; номер назначает сервер. У пропавших клиентов номера нет.',
|
|
302
|
+
'Ответ записи может содержать warnings[] с кодом и сообщением о неготовой CRM-стадии. Это предупреждение, а не отказ; проверь состояние CRM до включения цепочки.',
|
|
303
|
+
]),
|
|
304
|
+
}),
|
|
305
|
+
defineTool({
|
|
306
|
+
name: 'besales_followup_sequence_clone',
|
|
307
|
+
sideEffect: 'write',
|
|
308
|
+
requiredFields: ['platform_id', 'sequence_id'],
|
|
309
|
+
schema: z
|
|
310
|
+
.object({
|
|
311
|
+
platform_id: uuidSchema,
|
|
312
|
+
// Источник копирования; обязан принадлежать platform_id (cross-platform не поддерживается).
|
|
313
|
+
sequence_id: uuidSchema,
|
|
314
|
+
// База имени копии. Не передана — берётся имя источника; суффикс добавляется в любом случае.
|
|
315
|
+
name: z.string().max(FOLLOWUP_CLONE_NAME_MAX_LENGTH).optional(),
|
|
316
|
+
})
|
|
317
|
+
.strict(),
|
|
318
|
+
createRequest: (input) => ({
|
|
319
|
+
method: 'POST',
|
|
320
|
+
path: `/channels/${input.platform_id}/followup-sequences/${input.sequence_id}/clone`,
|
|
321
|
+
body: compactObject({ name: input.name }),
|
|
322
|
+
}),
|
|
323
|
+
enhanceResponse: (response) => withInstructions(response, [
|
|
324
|
+
'Копия создана ВЫКЛЮЧЕННОЙ и такой останется, пока её не включат явно: событие «контакт затих» веерится на КАЖДУЮ включённую цепочку канала, поэтому включённая копия слала бы те же касания тем же людям вторым потоком.',
|
|
325
|
+
'Скопировано только ОПРЕДЕЛЕНИЕ (имя, описание, триггер, шаги и переменные последней версии). Прогресс контактов, история отправок и запланированные касания источника не копируются и не затрагиваются.',
|
|
326
|
+
'Перед включением копии убедись, что условия цепочек образуют строгое разбиение (например «= A» / «= B» / «≠ A И ≠ B»). Две цепочки без взаимоисключающих условий удвоят отправку — они выполняются независимо.',
|
|
327
|
+
'Копия остаётся на ТОМ ЖЕ канале. Для переноса на другой канал используй besales_platform_clone_* — определение ссылается на статусы CRM, переменные и файлы своего канала.',
|
|
328
|
+
'⚠️ Повтор вызова НЕ идемпотентен: он создаёт следующую копию (`…-copy-2`, `…-copy-3`). Переданный name — это БАЗА имени, суффикс копии добавляется всегда; свободное имя ищется среди неудалённых цепочек всего воркспейса.',
|
|
329
|
+
]),
|
|
780
330
|
}),
|
|
781
331
|
...followUpSetupTools,
|
|
782
332
|
defineTool({
|
|
@@ -785,6 +335,11 @@ export const platformSetupTools = [
|
|
|
785
335
|
requiredFields: ['platform_id'],
|
|
786
336
|
schema: z
|
|
787
337
|
.object({
|
|
338
|
+
expected_version: z
|
|
339
|
+
.string()
|
|
340
|
+
.min(1)
|
|
341
|
+
.regex(/^[A-Za-z0-9_.-]+$/u)
|
|
342
|
+
.optional(),
|
|
788
343
|
platform_id: uuidSchema,
|
|
789
344
|
// v1.5 Increment 3 Group C.3 (Phase B, 2026-05-27): только typed sections.
|
|
790
345
|
crm_pipeline_behavior: pipelineCrmBehaviorSchema.optional(),
|
|
@@ -794,8 +349,9 @@ export const platformSetupTools = [
|
|
|
794
349
|
.strict(),
|
|
795
350
|
createRequest: (input) => ({
|
|
796
351
|
method: 'PATCH',
|
|
797
|
-
path: `/
|
|
352
|
+
path: `/channels/${input.platform_id}/pipeline-settings`,
|
|
798
353
|
body: compactObject({
|
|
354
|
+
expectedVersion: input.expected_version,
|
|
799
355
|
crmPipelineBehavior: input.crm_pipeline_behavior
|
|
800
356
|
? mapPipelineCrmBehaviorInput(input.crm_pipeline_behavior)
|
|
801
357
|
: undefined,
|
|
@@ -803,88 +359,43 @@ export const platformSetupTools = [
|
|
|
803
359
|
...setupConfirmation(input),
|
|
804
360
|
}),
|
|
805
361
|
}),
|
|
362
|
+
enhanceResponse: withEditVersionInstructions,
|
|
806
363
|
}),
|
|
807
364
|
defineTool({
|
|
808
365
|
name: 'besales_platform_settings_update',
|
|
809
366
|
sideEffect: 'write',
|
|
810
367
|
requiredFields: ['platform_id'],
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
// v1.5 Increment 3 Group C.2 (Phase B, 2026-05-27).
|
|
815
|
-
// Flat-only fields — backward compat для existing UI clients (deprecated через 2 weeks).
|
|
816
|
-
// Новый код должен использовать generalSettings.* typed section.
|
|
817
|
-
name: z.string().nullable().optional(),
|
|
818
|
-
off_message: z.string().optional(),
|
|
819
|
-
timezone: z.string().optional(),
|
|
820
|
-
// Typed sections (single source of truth для access/variables/crm/widget/instagram).
|
|
821
|
-
access_control: platformAccessControlSchema.optional(),
|
|
822
|
-
variables_config: platformVariablesConfigSchema.optional(),
|
|
823
|
-
crm_behavior: platformCrmBehaviorSchema.optional(),
|
|
824
|
-
widget_marketing: platformWidgetMarketingSchema.optional(),
|
|
825
|
-
instagram_comment_behavior: platformInstagramCommentSchema.optional(),
|
|
826
|
-
// Настройки раздела «Воронка канала»: ворота решения, цель «Пути до стадии», пороги.
|
|
827
|
-
// Бэкенд делегирует запись сервисам раздела — их валидация не обходится.
|
|
828
|
-
funnel_analytics: platformFunnelAnalyticsSchema.optional(),
|
|
829
|
-
// v1.5 Increment 4c — per-channel typed sections (hard 400 для unsupported channel type)
|
|
830
|
-
general_settings: platformGeneralSettingsSchema.optional(),
|
|
831
|
-
salebot_settings: platformSalebotSettingsSchema.optional(),
|
|
832
|
-
smsgorod_settings: platformSmsgorodSettingsSchema.optional(),
|
|
833
|
-
bitrix24_bot_settings: platformBitrix24BotSettingsSchema.optional(),
|
|
834
|
-
getcourse_settings: platformGetcourseSettingsSchema.optional(),
|
|
835
|
-
...platformSetupConfirmationSchema,
|
|
836
|
-
})
|
|
837
|
-
.strict(),
|
|
368
|
+
// Пространство выбирает ключ подключения для составной правки настроек.
|
|
369
|
+
defaultWorkspaceId: true,
|
|
370
|
+
schema: platformSettingsUpdateSchema,
|
|
838
371
|
createRequest: (input) => ({
|
|
839
372
|
method: 'PATCH',
|
|
840
|
-
path: `/
|
|
841
|
-
body:
|
|
842
|
-
|
|
843
|
-
offMessage: input.off_message,
|
|
844
|
-
timezone: input.timezone,
|
|
845
|
-
accessControl: input.access_control
|
|
846
|
-
? mapPlatformAccessControlInput(input.access_control)
|
|
847
|
-
: undefined,
|
|
848
|
-
variablesConfig: input.variables_config
|
|
849
|
-
? mapPlatformVariablesConfigInput(input.variables_config)
|
|
850
|
-
: undefined,
|
|
851
|
-
crmBehavior: input.crm_behavior
|
|
852
|
-
? mapPlatformCrmBehaviorInput(input.crm_behavior)
|
|
853
|
-
: undefined,
|
|
854
|
-
widgetMarketing: input.widget_marketing
|
|
855
|
-
? mapPlatformWidgetMarketingInput(input.widget_marketing)
|
|
856
|
-
: undefined,
|
|
857
|
-
instagramCommentBehavior: input.instagram_comment_behavior
|
|
858
|
-
? mapPlatformInstagramCommentInput(input.instagram_comment_behavior)
|
|
859
|
-
: undefined,
|
|
860
|
-
funnelAnalytics: input.funnel_analytics
|
|
861
|
-
? mapPlatformFunnelAnalyticsInput(input.funnel_analytics)
|
|
862
|
-
: undefined,
|
|
863
|
-
generalSettings: input.general_settings
|
|
864
|
-
? mapPlatformGeneralSettingsInput(input.general_settings)
|
|
865
|
-
: undefined,
|
|
866
|
-
salebotSettings: input.salebot_settings
|
|
867
|
-
? mapPlatformSalebotSettingsInput(input.salebot_settings)
|
|
868
|
-
: undefined,
|
|
869
|
-
smsgorodSettings: input.smsgorod_settings
|
|
870
|
-
? mapPlatformSmsgorodSettingsInput(input.smsgorod_settings)
|
|
871
|
-
: undefined,
|
|
872
|
-
bitrix24BotSettings: input.bitrix24_bot_settings
|
|
873
|
-
? mapPlatformBitrix24BotSettingsInput(input.bitrix24_bot_settings)
|
|
874
|
-
: undefined,
|
|
875
|
-
getcourseSettings: input.getcourse_settings
|
|
876
|
-
? mapPlatformGetcourseSettingsInput(input.getcourse_settings)
|
|
877
|
-
: undefined,
|
|
373
|
+
path: `/channels/${input.platform_id}/settings`,
|
|
374
|
+
body: {
|
|
375
|
+
...platformSettingsSections(input),
|
|
878
376
|
...setupConfirmation(input),
|
|
879
|
-
|
|
377
|
+
...compactObject({ expectedVersion: input.expected_version }),
|
|
378
|
+
},
|
|
880
379
|
}),
|
|
881
380
|
enhanceResponse: (response) => withInstructions(response, [
|
|
882
|
-
|
|
883
|
-
'
|
|
884
|
-
'
|
|
885
|
-
'
|
|
886
|
-
'
|
|
887
|
-
'
|
|
381
|
+
editVersionInstruction(),
|
|
382
|
+
'general_settings обновляет имя, сообщение при выключенном ИИ, зону, включённость канала, включённость ответов агента и phone_parsing_country. От страны разбора зависит, получит ли агент инструмент сохранения телефона; UZ значит, что девятизначный номер трактуется как узбекский, RU — инструмент выдаётся без разбора девяти цифр (российский номер разбирается по своей длине, девятизначный отклоняется). null снимает настройку и инструмент.',
|
|
383
|
+
'У виджета general_settings.page_rules задаёт показ: mode ALL — везде, ALLOW — только на указанных страницах (пустой список — нигде), DENY — кроме указанных. patterns — до 200 полных адресов или масок со звёздочкой до 2000 знаков; маска раздела с /* включает сам раздел. Правило заменяется целиком, null снимает его. Проверка выполняется сервером при подключении; это правило отображения, а не защита доступа.',
|
|
384
|
+
'crm_behavior принимает create_deal_on_first_outbound, finish_auto_enabled, finish_auto_days, send_finish_auto_note_to_crm, finish_auto_note_template, getcourse_create_deal_payment_tracking_enabled и getcourse_status_deal_fallback_enabled. finish_auto_days — целое число от 1 до защитного потолка 36500; null у finish_auto_note_template снимает шаблон и на свежем канале без сохранённых crm_behavior/auto_finish.',
|
|
385
|
+
'Если crm_behavior ещё не сохранён, единственное активное CRM-подключение требуется для send_to_crm, создания сделки по первой исходящей, стратегии и фиксированного ответственного, четырёх флагов отправки заметок, трёх полей маркера сделки, четырёх шаблонов заметок и обоих GetCourse-флагов. Ноль или несколько подключений дают 422 CRM_CONNECTION_UNRESOLVED. При сохранённом crm_behavior подключение этим маршрутом повторно не проверяется.',
|
|
386
|
+
'Опасные изменения create_deal_on_first_outbound, send_finish_auto_note_to_crm и getcourse_create_deal_payment_tracking_enabled требуют explicit_confirmation. Учёт оплат заказов агента GetCourse по умолчанию включён: при отсутствующем сохранённом ключе false требует подтверждения, а true проходит как неизменное действующее значение. Включение автозавершения не требует подтверждения, опасна отправка заметки.',
|
|
387
|
+
'Настройки веб-виджета живут в general_settings, НЕ в widget_marketing: список сайтов (allowed_origins), лимит обращений в минуту (rate_limit — целое число от 1 до 600), передача адреса страницы (show_page_info) и оформление (customization с одиннадцатью разделами). В widget_marketing остаются только две карты — соответствия маркетинговых полей CRM и перенос адреса входа в переменную. Прежняя форма тоже принимается и переводится: widget_marketing.web_widget_allowed_origins / _show_page_info / _rate_limit_per_minute / _customization уходят в general_settings (пустой или незаданный прежний список сайтов — «работать везде», как у прежней версии), web_widget_marketing_field_mappings и web_widget_entry_url_variable_mapping — в две карты раздела, access_control.is_active и is_ai_enabled — в general_settings. Прежнее и новое имя одного поля в одном вызове — отказ, кроме is_active: access_control.is_active и general_settings.is_active принимаются вместе, приоритет у general_settings.is_active.',
|
|
388
|
+
'Список сайтов принимает голый домен (site.ru), домен с портом (site.ru:8443), полный адрес (https://site.ru) и «*» (работать везде). Пустой список означает «не работать нигде» — это выключение виджета, а не сброс настройки. Список ЗАМЕЩАЕТСЯ целиком, разделы оформления сливаются.',
|
|
389
|
+
'smsgorod_settings сохраняет channel (DIGIT/CHAR) и sender на SMS-канале с подключением SMS-город. bitrix24_bot_settings сохраняет bot_name и ignore_crm_stage_gate на Bitrix24 Bot; смена ignore_crm_stage_gate требует explicit_confirmation=true. bot_id/bot_code/open_line_id управляются подключением: допустимо только точное ненулевое эхо, изменение/null даёт 422 BITRIX24_BOT_IDENTITY_MANAGED. Ответ bitrix24BotSettingsApply различает сохранение и применение у провайдера; не обещай применение при отложенном/неизвестном исходе.',
|
|
390
|
+
'crm_behavior.use_cross_platform_history сохраняет канальный выбор истории между каналами одного человека, включая false. Неверный тип канала — 400 BRIDGE_SETTINGS_CHANNEL_TYPE_MISMATCH; нет подключения, неверный sender или отсутствует подтверждение — адресный 422. Отказ любой секции не означает частично сохранённый запрос.',
|
|
391
|
+
'getcourse_settings принимается на канале GetCourse и пишется слиянием: соседние настройки не трогаются. Исключение — field_variable_map: её принимает канал ЛЮБОГО типа (виджет, мессенджер), и там поля заказа школы ложатся в переменные канала по человеку, которого опознали в школе по почте или по ссылке рассылки; прочие поля раздела на канале не GetCourse пропускаются предупреждением. Домен школы, кэш отделов, шаблонные пользователь и заказ здесь не пишутся — ответ назовёт причину и правильное место. wave_field_bindings — в какие поля сделки школы status-волна сама ставит свои метки: тип запуска (OUTGOING), продукт (кодом или названием — product_value_source), сегмент, воронка, каналы (набор через «+», например VK+Telegram). У роли — field_id (номер поля сделки) и field_label; один номер поля — одна роль. Объект ЗАМЕНЯЕТ сохранённые привязки целиком (роль, не названная в запросе, снимается), null снимает все; ручное поле запуска волны в поле роли даёт отказ WAVE_DEAL_FIELD_BINDING_CONFLICT; текущие привязки — в besales_platform_context_get, channel.connection.providerConfig.wave_field_bindings. field_variable_map ЗАМЕНЯЕТ карту «поле сделки → переменная» канала целиком (null очищает): поле называется так, как в школе (регистр не важен), переменная — строковая не-константная переменная ЭТОГО канала, поле и переменная — по разу. Негодная переменная — отказ FIELD_VARIABLE_MAP_VARIABLE_INVALID с перечнем подходящих (allowedVariableNames); текущая карта — в besales_platform_context_get, channel.getcourseFieldVariableMap.',
|
|
392
|
+
'getcourse_settings.guard_active_series / guard_active_application / guard_paid — режимы ПРЕДОХРАНИТЕЛЯ холодных отправок канала (вебинарная серия, действующая заявка, оплата продукта отправки): OFF — выключено, WARN — только записывается, BLOCK — отправка останавливается; null — «не настраивали» (действует BLOCK у всех трёх правил). quiet_days — тихий период канала в сутках (0 — правила нет, null — действует тихий период пространства). Эти поля сохраняются одним PATCH вместе с остальными секциями: ошибка любой секции отменяет всю запись. Ответ — в getcourseOutboundSettings (хранимое и действующее). Ослаблять правило ради одного запуска — не здесь: у пакета «Первого сообщения» для этого есть поле guards.',
|
|
393
|
+
'funnel_analytics — настройки раздела «Воронка канала»: ворота решения (три РАЗНЫЕ стадии «отправлено → одобрено | отклонено», только целиком), цель «Пути до стадии», пороги engaged_inbound_count (2–20) и stuck_threshold_hours (1–720). Стадия — stage_id из справочника либо pipeline_crm_id (подключение из besales_crm_list) + pipeline_id и status_id (числовые или строковые коды из besales_crm_pipeline_status_list); стадия обязана быть живой и в воронке, привязанной к каналу, иначе 422 FUNNEL_ANALYTICS_STAGE_INVALID с полем и причиной. null сбрасывает к «не настраивали», отсутствие поля не трогает, пустой раздел не принимается. Проверяются только присланные поля: уже негодная стадия в нетронутом поле приходит предупреждением FUNNEL_STAGE_UNUSABLE, а не отказом. Хранимое после записи — в ответе, funnelAnalytics. Коды Bitrix24 вида C3:NEW передавай строкой из справочника; числовая форма отгруженного клиента тоже принимается.',
|
|
394
|
+
'Тихий режим бота и создание отсутствующего заказа требуют explicit_confirmation (отказ приходит как EXPLICIT_CONFIRMATION_REQUIRED).',
|
|
395
|
+
'getcourse_settings.open_invoice_silence_enabled и четыре соседних поля (open_invoice_table_id, open_invoice_product_column, open_invoice_topic_column, open_invoice_topic_variable) настраивают молчание бота при подходящем открытом платном счёте за последние 14 суток по московской дате. Для включения все четыре поля должны быть сохранены; передача любого из пяти требует explicit_confirmation=true. Таблица знаний должна принадлежать рабочей области; колонка продукта содержит номера продуктов GetCourse, на которые ссылаются предложения открытого счёта, колонка темы — тему, переменная темы — строковая переменная контакта. Если данные школы, предложение или таблица неизвестны, бот отвечает; задержка кэша после оплаты возможна до 45 секунд. Используй серверные подписи причины на языке канала (ru/en/es/id/uz), не показывай внутренний код.',
|
|
396
|
+
'Деньги GetCourse (revenue_offer_ids, revenue_offers_paid_since) тоже требуют explicit_confirmation. Порядок: сначала дата у ЭТОГО канала (раньше или тем же вызовом), затем набор; снять дату можно только вместе с пустым набором. Предупреждение SECTION_ISSUE:getcourseSettings:revenue_offers_paid_since в ответе значит: у канала хранится набор без даты — задай дату. У канала виджета из денежных полей принимаются только revenue_offer_ids и revenue_offers_paid_since; карта field_variable_map принимается тоже. Денежные поля — метка продажи: совпавшее предложение разрешает автозачёт, а общий арбитр по заказам агента и рассылкам выбирает «Входящие» или «Исходящие»; прочие поля раздела пропускаются предупреждением. Порядок тот же, метка работает только при одной школе GetCourse в рабочей области (иначе WIDGET_SALE_LABEL_NEEDS_SINGLE_SCHOOL), предупреждение о метке без даты — SECTION_ISSUE:getcourseSettings:sale_label_paid_since.',
|
|
397
|
+
'target_department_id работает только при включённом входящем фильтре по сделке: без него перенос диалога в отдел молча не сработает. Фильтр задаётся здесь полями crm_behavior.inbound_deal_filter_enabled / _type / _value / _field_id (включённость и тип требуют explicit_confirmation, включённый фильтр обязан быть полным) либо разделом crm_behavior.inbound_deal_filter инструмента besales_behavior_update.',
|
|
398
|
+
'Response.warnings[] называет пропущенный раздел: widgetMarketing и instagramCommentBehavior — на неподходящем типе канала, generalSettings.widget — когда настройки виджета присланы каналу, который виджетом не является.',
|
|
888
399
|
]),
|
|
889
400
|
}),
|
|
890
401
|
defineTool({
|
|
@@ -900,13 +411,17 @@ export const platformSetupTools = [
|
|
|
900
411
|
// где audit logs пишутся с platformId=null).
|
|
901
412
|
platform_id: uuidSchema.optional(),
|
|
902
413
|
audit_log_id: uuidSchema,
|
|
414
|
+
explicit_confirmation: z.boolean().optional(),
|
|
903
415
|
})
|
|
904
416
|
.strict(),
|
|
905
417
|
createRequest: (input) => {
|
|
906
418
|
if (input.platform_id) {
|
|
907
419
|
return {
|
|
908
420
|
method: 'POST',
|
|
909
|
-
path: `/
|
|
421
|
+
path: `/channels/${input.platform_id}/audit/${input.audit_log_id}/revert`,
|
|
422
|
+
...(input.explicit_confirmation === undefined
|
|
423
|
+
? {}
|
|
424
|
+
: { body: { explicitConfirmation: input.explicit_confirmation } }),
|
|
910
425
|
};
|
|
911
426
|
}
|
|
912
427
|
return {
|
|
@@ -915,19 +430,26 @@ export const platformSetupTools = [
|
|
|
915
430
|
};
|
|
916
431
|
},
|
|
917
432
|
enhanceResponse: (response) => withInstructions(response, [
|
|
433
|
+
'Откат опасных настроек, в том числе откат клона, требует отдельного согласия человека и explicit_confirmation=true; без него сервер возвращает EXPLICIT_CONFIRMATION_REQUIRED. Безопасный откат подтверждения не требует.',
|
|
918
434
|
'Передай `platform_id` для platform-scoped logs (audit через platform-setup-adapter).',
|
|
919
435
|
'Опусти `platform_id` для workspace-scoped logs (variables-adapter и аналоги).',
|
|
436
|
+
'Откат удаления переменной возвращает и собранные значения контактов. Ответ несёт `variableValues: { backedUp, restored }`: если `restored` меньше `backedUp`, разницу составляют люди, стёртые между удалением и откатом — их значения не вернёт ничто. Скажи об этом человеку числом, а не словом «успешно».',
|
|
920
437
|
]),
|
|
921
438
|
}),
|
|
922
439
|
defineTool({
|
|
923
440
|
name: 'besales_feedback_sheet_link',
|
|
924
441
|
sideEffect: 'write',
|
|
442
|
+
resultPolicy: {
|
|
443
|
+
neverTruncate: true,
|
|
444
|
+
narrowingHint: 'Выбери документ с меньшим числом связей; для текущего документа перечитай полный список через besales_feedback_document_access_get.',
|
|
445
|
+
},
|
|
925
446
|
requiredFields: ['agent_id', 'source_url'],
|
|
926
447
|
schema: z.object({
|
|
927
448
|
agent_id: uuidSchema,
|
|
928
449
|
source_url: z.string().url(),
|
|
929
|
-
access_mode: z.enum(['READ_ONLY', 'EDITABLE']).
|
|
450
|
+
access_mode: z.enum(['READ_ONLY', 'EDITABLE']).optional(),
|
|
930
451
|
agent_version_id: uuidSchema.optional(),
|
|
452
|
+
...feedbackDocumentConfirmationSchema,
|
|
931
453
|
}),
|
|
932
454
|
createRequest: (input) => ({
|
|
933
455
|
path: `/agents/${input.agent_id}/feedback-sheets`,
|
|
@@ -935,12 +457,16 @@ export const platformSetupTools = [
|
|
|
935
457
|
sourceUrl: input.source_url,
|
|
936
458
|
accessMode: input.access_mode,
|
|
937
459
|
agentVersionId: input.agent_version_id,
|
|
460
|
+
confirmDocumentAccessChange: input.confirm_document_access_change,
|
|
461
|
+
expectedDocumentSnapshot: input.expected_document_snapshot,
|
|
938
462
|
}),
|
|
939
463
|
}),
|
|
940
464
|
enhanceResponse: (response) => withInstructions(response, [
|
|
941
|
-
'Таблица привязана к промпту.
|
|
465
|
+
'Таблица привязана к промпту. Email для настройки доступа в Google приходит в serviceAccountEmail.',
|
|
942
466
|
'Прочитайте замечания через besales_feedback_sheet_read по feedbackSheet.id.',
|
|
943
|
-
'accessMode
|
|
467
|
+
'accessMode — намерение всего документа, независимое от прав Google. Без access_mode новая связь наследует текущий режим; новый документ начинает с READ_ONLY.',
|
|
468
|
+
'Перед сменой режима прочитайте besales_feedback_document_access_get, покажите все связи и получите согласие человека; передайте confirm_document_access_change=true и expected_document_snapshot.',
|
|
469
|
+
'Повторная привязка возвращает 409 с currentLink. Сохраните прежнюю связь и её версию; не делайте автоматические unlink/link.',
|
|
944
470
|
]),
|
|
945
471
|
}),
|
|
946
472
|
defineTool({
|
|
@@ -1024,7 +550,7 @@ export const platformSetupTools = [
|
|
|
1024
550
|
requiredFields: ['agent_id'],
|
|
1025
551
|
schema: z.object({
|
|
1026
552
|
agent_id: uuidSchema,
|
|
1027
|
-
namespace_record_id:
|
|
553
|
+
namespace_record_id: knowledgeSpaceIdSchema.optional(),
|
|
1028
554
|
}),
|
|
1029
555
|
createRequest: (input) => ({
|
|
1030
556
|
path: `/agents/${input.agent_id}/facts/classify-and-migrate`,
|
|
@@ -1033,8 +559,8 @@ export const platformSetupTools = [
|
|
|
1033
559
|
}),
|
|
1034
560
|
}),
|
|
1035
561
|
enhanceResponse: (response) => withInstructions(response, [
|
|
1036
|
-
'Active facts разобраны: Q&A pairs созданы
|
|
1037
|
-
'Мигрированные chunks перемещены в секцию `## Migrated` в
|
|
562
|
+
'Active facts разобраны: Q&A pairs созданы в knowledge-пространстве, document chunks перенесены отдельными документами.',
|
|
563
|
+
'Мигрированные chunks перемещены в секцию `## Migrated` в факты агента (audit trail).',
|
|
1038
564
|
'Если категория `document` — text→document loader pending, повторно вызовы безопасны (idempotent per chunk).',
|
|
1039
565
|
]),
|
|
1040
566
|
}),
|
|
@@ -1044,15 +570,20 @@ export const platformSetupTools = [
|
|
|
1044
570
|
sideEffect: 'write',
|
|
1045
571
|
requiredFields: ['agent_id', 'factual_context'],
|
|
1046
572
|
schema: z.object({
|
|
573
|
+
expected_version: uuidSchema.optional(),
|
|
1047
574
|
agent_id: uuidSchema,
|
|
1048
575
|
factual_context: z.string(),
|
|
1049
576
|
}),
|
|
1050
577
|
createRequest: (input) => ({
|
|
1051
578
|
method: 'PUT',
|
|
1052
579
|
path: `/agents/${input.agent_id}/facts`,
|
|
1053
|
-
body: {
|
|
580
|
+
body: compactObject({
|
|
581
|
+
factualContext: input.factual_context,
|
|
582
|
+
expectedVersion: input.expected_version,
|
|
583
|
+
}),
|
|
1054
584
|
}),
|
|
1055
585
|
enhanceResponse: (response) => withInstructions(response, [
|
|
586
|
+
editVersionInstruction(),
|
|
1056
587
|
'factualContext записан целиком (PUT-семантика, replace not patch).',
|
|
1057
588
|
'Если в warnings есть `soft_limit_exceeded` (~8000 chars / 2K tokens) — рекомендую запустить `besales_facts_classify_and_migrate`.',
|
|
1058
589
|
'Структура: `## Active facts` блок инъектится в системный промпт; `## Migrated` — лог миграций (не инъектится).',
|
|
@@ -1069,18 +600,33 @@ export const platformSetupTools = [
|
|
|
1069
600
|
// текст здесь незаменим: по нему строят якоря правок, и усечённый даёт промах якоря.
|
|
1070
601
|
resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
|
|
1071
602
|
sideEffect: 'write',
|
|
603
|
+
closedWorld: true,
|
|
1072
604
|
requiredFields: ['agent_id'],
|
|
1073
605
|
schema: z.object({
|
|
1074
606
|
agent_id: uuidSchema,
|
|
607
|
+
include_prompt_text: z.boolean().optional(),
|
|
608
|
+
mode: z.enum(['START', 'CONTINUE', 'RESTART']).optional(),
|
|
609
|
+
draft_id: uuidSchema.optional(),
|
|
610
|
+
expected_content_hash: z
|
|
611
|
+
.string()
|
|
612
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
613
|
+
.optional(),
|
|
1075
614
|
}),
|
|
1076
615
|
createRequest: (input) => ({
|
|
1077
616
|
method: 'POST',
|
|
1078
617
|
path: `/agents/${input.agent_id}/prompt/drafts`,
|
|
618
|
+
body: compactObject({
|
|
619
|
+
mode: input.mode,
|
|
620
|
+
draftId: input.draft_id,
|
|
621
|
+
expectedContentHash: input.expected_content_hash,
|
|
622
|
+
}),
|
|
1079
623
|
}),
|
|
1080
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
1081
|
-
'
|
|
624
|
+
enhanceResponse: (response, input) => withInstructions(input.include_prompt_text === true ? response : withoutDraftPromptText(response), [
|
|
625
|
+
'Текст промпта по умолчанию НЕ возвращается: приходят отпечаток и длина. Нужен сам текст — ' +
|
|
626
|
+
'besales_prompt_patch_get либо include_prompt_text=true. Без текста не построить якоря правок.',
|
|
627
|
+
'При CREATED создан новый черновик; при CONTINUED возвращён выбранный свой черновик. При PROMPT_DRAFT_CHOICE_REQUIRED прочитай besales_prompt_drafts_mine и попроси человека выбрать CONTINUE или RESTART с draft_id и expected_content_hash.',
|
|
1082
628
|
'Дальше: `besales_prompt_patch_apply(draft_id, operations[])` → batch правок → `besales_prompt_patch_commit(draft_id)`.',
|
|
1083
|
-
'
|
|
629
|
+
'conflictingDraftCount — число черновиков других авторов. Их идентификаторы и сроки не выдаются; conflictsWithOtherUsers всегда пустой.',
|
|
1084
630
|
'Server-side hash → клиенту не нужно знать про activePromptContentHash.',
|
|
1085
631
|
'Гигиена: правь формулировки ПО МЕСТУ в существующих секциях; не добавляй override-блоки/дубли-секции в конец (антипаттерн → тех-долг). Сначала прочти весь промпт (besales_prompt_patch_get) и найди, где правило уже есть. См. «Редактирование промпта» в serverInstructions.',
|
|
1086
632
|
]),
|
|
@@ -1092,6 +638,7 @@ export const platformSetupTools = [
|
|
|
1092
638
|
// текст здесь незаменим: по нему строят якоря правок, и усечённый даёт промах якоря.
|
|
1093
639
|
resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
|
|
1094
640
|
sideEffect: 'none',
|
|
641
|
+
closedWorld: true,
|
|
1095
642
|
requiredFields: ['agent_id', 'draft_id'],
|
|
1096
643
|
schema: z.object({
|
|
1097
644
|
agent_id: uuidSchema,
|
|
@@ -1103,10 +650,11 @@ export const platformSetupTools = [
|
|
|
1103
650
|
}),
|
|
1104
651
|
}),
|
|
1105
652
|
// Остаток до лимитов линтера ДО сборки черновика. Порядок здесь обязан совпадать с
|
|
1106
|
-
// mcp-tools.json (registry.spec
|
|
653
|
+
// mcp-tools.json (registry.spec сверяет имена позиционно), поэтому вставка строго после _patch_get.
|
|
1107
654
|
defineTool({
|
|
1108
655
|
name: 'besales_prompt_headroom',
|
|
1109
656
|
sideEffect: 'none',
|
|
657
|
+
closedWorld: true,
|
|
1110
658
|
requiredFields: ['agent_id'],
|
|
1111
659
|
// .strict() — иначе опечатка `draftId` вместо `draft_id` молча отбрасывается zod'ом,
|
|
1112
660
|
// и тулза измеряет закоммиченный промпт вместо черновика.
|
|
@@ -1143,7 +691,10 @@ export const platformSetupTools = [
|
|
|
1143
691
|
createRequest: (input) => ({
|
|
1144
692
|
method: 'POST',
|
|
1145
693
|
path: `/agents/${input.agent_id}/prompt/diff`,
|
|
1146
|
-
body: {
|
|
694
|
+
body: {
|
|
695
|
+
compareAgentId: input.compare_agent_id,
|
|
696
|
+
maxLines: input.max_lines,
|
|
697
|
+
},
|
|
1147
698
|
}),
|
|
1148
699
|
enhanceResponse: (response) => withInstructions(response, [
|
|
1149
700
|
'`identicalBytes: true` — текущие тексты совпадают побайтово, значит один и тот же набор patch-операций найдёт те же якоря. Это НЕ гарантия одинакового исхода commit: lint резолвит канал каждого агента отдельно (одна и та же markdown-правка проходит в веб-виджете и падает в Telegram), а свой черновик каждый агент коммитит независимо.',
|
|
@@ -1159,11 +710,13 @@ export const platformSetupTools = [
|
|
|
1159
710
|
// текст здесь незаменим: по нему строят якоря правок, и усечённый даёт промах якоря.
|
|
1160
711
|
resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
|
|
1161
712
|
sideEffect: 'write',
|
|
713
|
+
closedWorld: true,
|
|
1162
714
|
requiredFields: ['agent_id', 'draft_id', 'operations'],
|
|
1163
715
|
schema: z.object({
|
|
1164
716
|
agent_id: uuidSchema,
|
|
1165
717
|
draft_id: uuidSchema,
|
|
1166
718
|
operations: z.array(promptPatchOperationSchema).min(1),
|
|
719
|
+
include_prompt_text: z.boolean().optional(),
|
|
1167
720
|
}),
|
|
1168
721
|
createRequest: (input) => ({
|
|
1169
722
|
method: 'PATCH',
|
|
@@ -1172,12 +725,12 @@ export const platformSetupTools = [
|
|
|
1172
725
|
operations: input.operations.map(mapPromptPatchOperationInput),
|
|
1173
726
|
},
|
|
1174
727
|
}),
|
|
1175
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
728
|
+
enhanceResponse: (response, input) => withInstructions(input.include_prompt_text === true ? response : withoutDraftPromptText(response), [
|
|
729
|
+
'Текст промпта по умолчанию НЕ возвращается: приходят отпечаток и длина. Изменился ли текст — ' +
|
|
730
|
+
'видно по отпечатку; нужен сам текст для следующих якорей — include_prompt_text=true или ' +
|
|
731
|
+
'besales_prompt_patch_get.',
|
|
1176
732
|
'Operations применены. `appliedCount` — успешно, `skippedCount` — anchor не найден или growth guard сработал (>30% size).',
|
|
1177
733
|
'Если `skippedCount > 0` — проверь target_text / anchor_text на точность. matchVariants[] помогает fuzzy-match.',
|
|
1178
|
-
'Текста черновика в ответе НЕТ — приезжает `diff` (`removedLines`/`addedLines`, `charactersDelta`) и `draft.characters`. Промпт целиком ты уже прочитал на `_start`; перечитать — `besales_prompt_patch_get`.',
|
|
1179
|
-
'Пустые `removedLines`/`addedLines` — НЕ признак «ничего не применилось»: дифф это разность МНОЖЕСТВ строк, и `move_text_after_text` (как и правка одних пробелов) даёт пустые списки. Факт изменения читай по `diff.contentChanged`, объём — по `charactersDelta`.',
|
|
1180
|
-
'`diff.truncated: true` — изменённых строк больше потолка; тогда сверяйся через `besales_prompt_patch_get`.',
|
|
1181
734
|
'TTL draft сброшен на 24h.',
|
|
1182
735
|
'Когда правки готовы — `besales_prompt_patch_commit(draft_id)`.',
|
|
1183
736
|
]),
|
|
@@ -1194,9 +747,10 @@ export const platformSetupTools = [
|
|
|
1194
747
|
method: 'POST',
|
|
1195
748
|
path: `/agents/${input.agent_id}/prompt/drafts/${input.draft_id}/commit`,
|
|
1196
749
|
}),
|
|
1197
|
-
enhanceResponse: (response) => withInstructions(response, [
|
|
1198
|
-
'
|
|
1199
|
-
|
|
750
|
+
enhanceResponse: (response) => withInstructions(withoutDuplicatedPromptText(response), [
|
|
751
|
+
'Текст промпта приходил здесь ДВАЖДЫ — в черновике и в новой версии. Копия из черновика ' +
|
|
752
|
+
'заменена отпечатком; авторитетна версия (newVersion.content) — именно она уехала агенту.',
|
|
753
|
+
'Commit: lint pass → новая PromptVersion в prompt-services → системный промпт агента обновлён.',
|
|
1200
754
|
'Если ошибка 400 с `lintIssues` — поправь через `_apply` (hard_fail issues блокируют commit).',
|
|
1201
755
|
'Если ошибка 409 PROMPT_DRAFT_REBASE_REQUIRED — другой commit прошёл первым. Discard этот draft и сделай новый.',
|
|
1202
756
|
'Server-side hash → клиенту не нужно передавать activePromptContentHash.',
|
|
@@ -1208,6 +762,7 @@ export const platformSetupTools = [
|
|
|
1208
762
|
defineTool({
|
|
1209
763
|
name: 'besales_prompt_patch_discard',
|
|
1210
764
|
sideEffect: 'write',
|
|
765
|
+
closedWorld: true,
|
|
1211
766
|
requiredFields: ['agent_id', 'draft_id'],
|
|
1212
767
|
schema: z.object({
|
|
1213
768
|
agent_id: uuidSchema,
|
|
@@ -1223,6 +778,9 @@ export const platformSetupTools = [
|
|
|
1223
778
|
defineTool({
|
|
1224
779
|
name: 'besales_prompt_batch_start',
|
|
1225
780
|
sideEffect: 'spend',
|
|
781
|
+
// Жёсткий гейт: правка уезжает разом на парк до 200 боевых агентов, у очереди одна
|
|
782
|
+
// попытка и авто-отката нет. Аннотация тут не помогает — она подсказка, которой хост
|
|
783
|
+
// вправе не поверить, а это условие входа, которое обойти нельзя.
|
|
1226
784
|
requiredFields: ['agent_ids', 'operations', 'explicit_confirmation'],
|
|
1227
785
|
schema: z
|
|
1228
786
|
.object({
|
|
@@ -1242,19 +800,21 @@ export const platformSetupTools = [
|
|
|
1242
800
|
operations: input.operations.map(mapPromptPatchOperationInput),
|
|
1243
801
|
allOrNothing: input.all_or_nothing,
|
|
1244
802
|
idempotencyKey: input.idempotency_key,
|
|
1245
|
-
|
|
803
|
+
channelId: input.platform_id,
|
|
1246
804
|
}),
|
|
1247
805
|
}),
|
|
1248
806
|
enhanceResponse: (response) => withInstructions(response, [
|
|
1249
|
-
'Прогон фоновый: опрашивай `besales_prompt_batch_status` по `runId
|
|
807
|
+
'Прогон фоновый: опрашивай `besales_prompt_batch_status` по `runId` до конечного состояния; STOPPED может сохранять не начатых агентов.',
|
|
1250
808
|
'`SKIPPED` — не ошибка: смотри `skipReason`, чаще всего это NO_OPERATIONS_APPLIED (у агента другой промпт, якоря не нашлись).',
|
|
1251
|
-
'
|
|
809
|
+
'После потери ответа читай `besales_prompt_batch_by_key` с исходным idempotency_key. Повтор start с тем же ключом и составом возвращает тот же прогон; другой состав — 409. Новый ключ рискует второй раскаткой.',
|
|
810
|
+
'Для остановки после текущего агента используй `besales_prompt_batch_stop`, для продолжения оставшихся — `besales_prompt_batch_resume`.',
|
|
1252
811
|
'Перед раскаткой на парк проверь запас длины у самого тяжёлого агента через `besales_prompt_headroom`.',
|
|
1253
812
|
]),
|
|
1254
813
|
}),
|
|
1255
814
|
defineTool({
|
|
1256
815
|
name: 'besales_prompt_batch_status',
|
|
1257
816
|
sideEffect: 'none',
|
|
817
|
+
resultPolicy: { neverTruncate: true, maxResultBytes: 400_000 },
|
|
1258
818
|
requiredFields: ['run_id'],
|
|
1259
819
|
schema: z.object({ run_id: uuidSchema }).strict(),
|
|
1260
820
|
createRequest: (input) => ({
|
|
@@ -1272,8 +832,9 @@ export const platformSetupTools = [
|
|
|
1272
832
|
path: `/prompt-batch/runs/${input.run_id}/resume`,
|
|
1273
833
|
}),
|
|
1274
834
|
enhanceResponse: (response) => withInstructions(response, [
|
|
1275
|
-
'
|
|
835
|
+
'Продолжаются оставшиеся и сброшенные барьером агенты вместе с отказавшими, в том числе откатанные подготовкой allOrNothing. Уже записанные не повторяются.',
|
|
1276
836
|
'400 «Run is still in progress» означает, что прогон жив: дождись, а не повторяй resume.',
|
|
837
|
+
'409 — исход прежней операции не установлен: перечитай статус и не запускай новый прогон; 404 — прогон недоступен, 503 — управление или проверка секретов недоступны.',
|
|
1277
838
|
]),
|
|
1278
839
|
}),
|
|
1279
840
|
// S2.6 extra — besales_prompt_lint (после patches, чтобы matched catalog order)
|
|
@@ -1315,7 +876,7 @@ export const platformSetupTools = [
|
|
|
1315
876
|
enhanceResponse: (response) => withInstructions(response, [
|
|
1316
877
|
'Standalone lint: проверка ДО `besales_prompt_finalize` (избегает цикла «finalize → 400 → fix»).',
|
|
1317
878
|
'Severity: `hard_fail` блокирует finalize; `warn` — рекомендация; `info` — заметки.',
|
|
1318
|
-
'Если передан `agent_id` — channel и agentScope резолвятся из
|
|
879
|
+
'Если передан `agent_id` — channel и agentScope резолвятся из агента (markdown-checker и scope-consistency активны).',
|
|
1319
880
|
]),
|
|
1320
881
|
}),
|
|
1321
882
|
];
|