finished first draft

This commit is contained in:
hagen-danswer 2024-06-19 22:11:33 -07:00
parent 9e30ec1f1f
commit 694e9e8679
8 changed files with 59 additions and 2 deletions

View File

@ -37,6 +37,7 @@ from danswer.danswerbot.slack.constants import SLACK_CHANNEL_ID
from danswer.danswerbot.slack.models import SlackMessageInfo
from danswer.danswerbot.slack.utils import ChannelIdAdapter
from danswer.danswerbot.slack.utils import fetch_userids_from_emails
from danswer.danswerbot.slack.utils import fetch_userids_from_groups
from danswer.danswerbot.slack.utils import respond_in_thread
from danswer.danswerbot.slack.utils import slack_usage_report
from danswer.danswerbot.slack.utils import SlackRateLimiter
@ -262,6 +263,7 @@ def handle_message(
respond_tag_only = channel_conf.get("respond_tag_only") or False
respond_team_member_list = channel_conf.get("respond_team_member_list") or None
respond_slack_group_list = channel_conf.get("respond_slack_group_list") or None
if respond_tag_only and not bypass_filters:
logger.info(
@ -271,7 +273,11 @@ def handle_message(
return False
if respond_team_member_list:
send_to, _ = fetch_userids_from_emails(respond_team_member_list, client)
user_ids, _ = fetch_userids_from_emails(respond_team_member_list, client)
send_to = (send_to + user_ids) if send_to else user_ids
if respond_slack_group_list:
user_ids, _ = fetch_userids_from_groups(respond_slack_group_list, client)
send_to = (send_to + user_ids) if send_to else user_ids
# If configured to respond to team members only, then cannot be used with a /DanswerBot command
# which would just respond to the sender

View File

@ -308,6 +308,31 @@ def fetch_userids_from_emails(
return user_ids, failed_to_find
def fetch_userids_from_groups(
group_names: list[str], client: WebClient
) -> tuple[list[str], list[str]]:
user_ids: list[str] = []
failed_to_find: list[str] = []
for group_name in group_names:
try:
# First, find the group ID from the group name
response = client.usergroups_list()
groups = {group["name"]: group["id"] for group in response["usergroups"]}
group_id = groups.get(group_name)
if group_id:
# Fetch user IDs for the group
response = client.usergroups_users_list(usergroup=group_id)
user_ids.extend(response["users"])
else:
failed_to_find.append(group_name)
except Exception as e:
logger.error(f"Error fetching user IDs for group {group_name}: {str(e)}")
failed_to_find.append(group_name)
return user_ids, failed_to_find
def fetch_groupids_from_names(
names: list[str], client: WebClient
) -> tuple[list[str], list[str]]:

View File

@ -1059,6 +1059,7 @@ class ChannelConfig(TypedDict):
respond_tag_only: NotRequired[bool] # defaults to False
respond_to_bots: NotRequired[bool] # defaults to False
respond_team_member_list: NotRequired[list[str]]
respond_slack_group_list: NotRequired[list[str]]
answer_filters: NotRequired[list[AllowedAnswerFilters]]
# If None then no follow up
# If empty list, follow up with no tags

View File

@ -104,6 +104,7 @@ class SlackBotConfigCreationRequest(BaseModel):
respond_to_bots: bool = False
# If no team members, assume respond in the channel to everyone
respond_team_member_list: list[str] = []
respond_slack_group_list: list[str] = []
answer_filters: list[AllowedAnswerFilters] = []
# list of user emails
follow_up_tags: list[str] | None = None

View File

@ -37,6 +37,9 @@ def _form_channel_config(
respond_team_member_list = (
slack_bot_config_creation_request.respond_team_member_list
)
respond_slack_group_list = (
slack_bot_config_creation_request.respond_slack_group_list
)
answer_filters = slack_bot_config_creation_request.answer_filters
follow_up_tags = slack_bot_config_creation_request.follow_up_tags
@ -58,7 +61,7 @@ def _form_channel_config(
detail=str(e),
)
if respond_tag_only and respond_team_member_list:
if respond_tag_only and (respond_team_member_list or respond_slack_group_list):
raise ValueError(
"Cannot set DanswerBot to only respond to tags only and "
"also respond to a predetermined set of users."
@ -71,6 +74,8 @@ def _form_channel_config(
channel_config["respond_tag_only"] = respond_tag_only
if respond_team_member_list:
channel_config["respond_team_member_list"] = respond_team_member_list
if respond_slack_group_list:
channel_config["respond_slack_group_list"] = respond_slack_group_list
if answer_filters:
channel_config["answer_filters"] = answer_filters
if follow_up_tags is not None:

View File

@ -74,6 +74,9 @@ export const SlackBotCreationForm = ({
respond_team_member_list:
existingSlackBotConfig?.channel_config
?.respond_team_member_list || ([] as string[]),
respond_slack_group_list:
existingSlackBotConfig?.channel_config
?.respond_slack_group_list || ([] as string[]),
still_need_help_enabled:
existingSlackBotConfig?.channel_config?.follow_up_tags !==
undefined,
@ -102,6 +105,7 @@ export const SlackBotCreationForm = ({
respond_tag_only: Yup.boolean().required(),
respond_to_bots: Yup.boolean().required(),
respond_team_member_list: Yup.array().of(Yup.string()).required(),
respond_slack_group_list: Yup.array().of(Yup.string()).required(),
still_need_help_enabled: Yup.boolean().required(),
follow_up_tags: Yup.array().of(Yup.string()),
document_sets: Yup.array().of(Yup.number()),
@ -119,6 +123,9 @@ export const SlackBotCreationForm = ({
respond_team_member_list: values.respond_team_member_list.filter(
(teamMemberEmail) => teamMemberEmail !== ""
),
respond_slack_group_list: values.respond_slack_group_list.filter(
(slackGroupName) => slackGroupName !== ""
),
usePersona: usingPersonas,
};
if (!cleanedValues.still_need_help_enabled) {
@ -237,6 +244,15 @@ export const SlackBotCreationForm = ({
out the occasional incorrect answer.`}
values={values}
/>
<TextArrayField
name="respond_slack_group_list"
label="Slack Group Names"
subtext={`If specified, DanswerBot responses will only be
visible to slack groups in this list. This is
useful if you want DanswerBot to operate in an
"assistant" mode.`}
values={values}
/>
<Divider />
<SectionHeader>Post Response Behavior</SectionHeader>

View File

@ -14,6 +14,7 @@ interface SlackBotConfigCreationRequest {
respond_tag_only: boolean;
respond_to_bots: boolean;
respond_team_member_list: string[];
respond_slack_group_list: string[];
follow_up_tags?: string[];
usePersona: boolean;
response_type: SlackBotResponseType;
@ -40,6 +41,7 @@ const buildRequestBodyFromCreationRequest = (
respond_tag_only: creationRequest.respond_tag_only,
respond_to_bots: creationRequest.respond_to_bots,
respond_team_member_list: creationRequest.respond_team_member_list,
respond_slack_group_list: creationRequest.respond_slack_group_list,
answer_filters: buildFiltersFromCreationRequest(creationRequest),
follow_up_tags: creationRequest.follow_up_tags?.filter((tag) => tag !== ""),
...(creationRequest.usePersona

View File

@ -475,6 +475,7 @@ export interface ChannelConfig {
respond_tag_only?: boolean;
respond_to_bots?: boolean;
respond_team_member_list?: string[];
respond_slack_group_list?: string[];
answer_filters?: AnswerFilterOption[];
follow_up_tags?: string[];
}