From 045a41d9294cf5d81931cbbeefafb518a9c4578b Mon Sep 17 00:00:00 2001 From: pablonyx Date: Mon, 17 Feb 2025 20:08:33 -0800 Subject: [PATCH] Add default slack bot disabling (#3935) * add slack bot disabling * update * k * minor --- backend/onyx/db/models.py | 2 ++ backend/onyx/db/slack_channel_config.py | 1 + .../onyxbot/slack/handlers/handle_message.py | 7 ++++++ backend/onyx/onyxbot/slack/listener.py | 1 + backend/onyx/server/manage/models.py | 1 + backend/onyx/server/manage/slack_bot.py | 3 +++ .../SlackChannelConfigCreationForm.tsx | 4 ++++ .../channels/SlackChannelConfigFormFields.tsx | 24 ++++++++++++++++--- web/src/app/admin/bots/[bot-id]/lib.ts | 2 ++ web/src/lib/types.ts | 1 + 10 files changed, 43 insertions(+), 3 deletions(-) diff --git a/backend/onyx/db/models.py b/backend/onyx/db/models.py index 5e18e016c..b321ae926 100644 --- a/backend/onyx/db/models.py +++ b/backend/onyx/db/models.py @@ -1742,6 +1742,7 @@ class ChannelConfig(TypedDict): # If empty list, follow up with no tags follow_up_tags: NotRequired[list[str]] show_continue_in_web_ui: NotRequired[bool] # defaults to False + disabled: NotRequired[bool] # defaults to False class SlackChannelConfig(Base): @@ -1765,6 +1766,7 @@ class SlackChannelConfig(Base): is_default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) persona: Mapped[Persona | None] = relationship("Persona") + slack_bot: Mapped["SlackBot"] = relationship( "SlackBot", back_populates="slack_channel_configs", diff --git a/backend/onyx/db/slack_channel_config.py b/backend/onyx/db/slack_channel_config.py index 06dd6a8ae..7930d8e66 100644 --- a/backend/onyx/db/slack_channel_config.py +++ b/backend/onyx/db/slack_channel_config.py @@ -151,6 +151,7 @@ def update_slack_channel_config( channel_config: ChannelConfig, standard_answer_category_ids: list[int], enable_auto_filters: bool, + disabled: bool, ) -> SlackChannelConfig: slack_channel_config = db_session.scalar( select(SlackChannelConfig).where( diff --git a/backend/onyx/onyxbot/slack/handlers/handle_message.py b/backend/onyx/onyxbot/slack/handlers/handle_message.py index fb0447028..013501d26 100644 --- a/backend/onyx/onyxbot/slack/handlers/handle_message.py +++ b/backend/onyx/onyxbot/slack/handlers/handle_message.py @@ -180,6 +180,13 @@ def handle_message( ) return False + if slack_channel_config.channel_config.get("disabled") and not bypass_filters: + logger.info( + "Skipping message since the channel is configured such that " + "OnyxBot is disabled" + ) + return False + # List of user id to send message to, if None, send to everyone in channel send_to: list[str] | None = None missing_users: list[str] | None = None diff --git a/backend/onyx/onyxbot/slack/listener.py b/backend/onyx/onyxbot/slack/listener.py index b21fd23c6..ecc03f838 100644 --- a/backend/onyx/onyxbot/slack/listener.py +++ b/backend/onyx/onyxbot/slack/listener.py @@ -806,6 +806,7 @@ def process_message( and slack_channel_config.channel_config.get("follow_up_tags") is not None ) + feedback_reminder_id = schedule_feedback_reminder( details=details, client=client.web_client, include_followup=follow_up ) diff --git a/backend/onyx/server/manage/models.py b/backend/onyx/server/manage/models.py index 7c74b9765..5256119ab 100644 --- a/backend/onyx/server/manage/models.py +++ b/backend/onyx/server/manage/models.py @@ -187,6 +187,7 @@ class SlackChannelConfigCreationRequest(BaseModel): response_type: SlackBotResponseType # XXX this is going away soon standard_answer_categories: list[int] = Field(default_factory=list) + disabled: bool = False @field_validator("answer_filters", mode="before") @classmethod diff --git a/backend/onyx/server/manage/slack_bot.py b/backend/onyx/server/manage/slack_bot.py index 8c602ba69..1cc2b2e78 100644 --- a/backend/onyx/server/manage/slack_bot.py +++ b/backend/onyx/server/manage/slack_bot.py @@ -93,6 +93,8 @@ def _form_channel_config( "respond_to_bots" ] = slack_channel_config_creation_request.respond_to_bots + channel_config["disabled"] = slack_channel_config_creation_request.disabled + return channel_config @@ -194,6 +196,7 @@ def patch_slack_channel_config( channel_config=channel_config, standard_answer_category_ids=slack_channel_config_creation_request.standard_answer_categories, enable_auto_filters=slack_channel_config_creation_request.enable_auto_filters, + disabled=slack_channel_config_creation_request.disabled, ) return SlackChannelConfig.from_model(slack_channel_config_model) diff --git a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigCreationForm.tsx b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigCreationForm.tsx index 4415d9e4c..f4bfff0d5 100644 --- a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigCreationForm.tsx +++ b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigCreationForm.tsx @@ -124,6 +124,8 @@ export const SlackChannelConfigCreationForm = ({ : existingSlackChannelConfig?.persona ? "document_sets" : "all_public", + disabled: + existingSlackChannelConfig?.channel_config?.disabled ?? false, }} validationSchema={Yup.object().shape({ slack_bot_id: Yup.number().required(), @@ -170,6 +172,7 @@ export const SlackChannelConfigCreationForm = ({ "non_search_assistant", ]) .required(), + disabled: Yup.boolean().optional().default(false), })} onSubmit={async (values, formikHelpers) => { formikHelpers.setSubmitting(true); @@ -195,6 +198,7 @@ export const SlackChannelConfigCreationForm = ({ (category: any) => category.id ), response_type: values.response_type as SlackBotResponseType, + disabled: values.disabled ?? false, }; if (!cleanedValues.still_need_help_enabled) { diff --git a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx index 4f154a081..3372756e9 100644 --- a/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx +++ b/web/src/app/admin/bots/[bot-id]/channels/SlackChannelConfigFormFields.tsx @@ -197,9 +197,27 @@ export function SlackChannelConfigFormFields({ <>
{isDefault && ( - - Default Configuration - + <> + + Default Configuration + +

+ This default configuration will apply across all Slack channels + the bot is added to in the Slack workspace, as well as direct + messages (DMs), unless disabled. +

+
+ +

+ Warning: Disabling the default configuration means the bot + won't respond in Slack channels or DMs unless explicitly + configured for them. +

+
+ )} {!isDefault && ( <> diff --git a/web/src/app/admin/bots/[bot-id]/lib.ts b/web/src/app/admin/bots/[bot-id]/lib.ts index 198444164..5c72c9f20 100644 --- a/web/src/app/admin/bots/[bot-id]/lib.ts +++ b/web/src/app/admin/bots/[bot-id]/lib.ts @@ -21,6 +21,7 @@ interface SlackChannelConfigCreationRequest { usePersona: boolean; response_type: SlackBotResponseType; standard_answer_categories: number[]; + disabled: boolean; } const buildFiltersFromCreationRequest = ( @@ -54,6 +55,7 @@ const buildRequestBodyFromCreationRequest = ( : { document_sets: creationRequest.document_sets }), response_type: creationRequest.response_type, standard_answer_categories: creationRequest.standard_answer_categories, + disabled: creationRequest.disabled, }); }; diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index 022ea3b70..ad0ed00e0 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -252,6 +252,7 @@ export interface ChannelConfig { respond_member_group_list?: string[]; answer_filters?: AnswerFilterOption[]; follow_up_tags?: string[]; + disabled?: boolean; } export type SlackBotResponseType = "quotes" | "citations";