Public Slack Feedback Option (#1270)

This commit is contained in:
Yuhong Sun 2024-03-28 18:21:28 -07:00 committed by GitHub
parent f46e65be92
commit 055cab2944
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 56 additions and 8 deletions

View File

@ -21,6 +21,14 @@ DANSWER_BOT_DISABLE_DOCS_ONLY_ANSWER = os.environ.get(
DANSWER_REACT_EMOJI = os.environ.get("DANSWER_REACT_EMOJI") or "eyes"
# When User needs more help, what should the emoji be
DANSWER_FOLLOWUP_EMOJI = os.environ.get("DANSWER_FOLLOWUP_EMOJI") or "sos"
# What kind of message should be shown when someone gives an AI answer feedback to DanswerBot
# Defaults to Private if not provided or invalid
# Private: Only visible to user clicking the feedback
# Anonymous: Public but anonymous
# Public: Visible with the user name who submitted the feedback
DANSWER_BOT_FEEDBACK_VISIBILITY = (
os.environ.get("DANSWER_BOT_FEEDBACK_VISIBILITY") or "private"
)
# Should DanswerBot send an apology message if it's not able to find an answer
# That way the user isn't confused as to why DanswerBot reacted but then said nothing
# Off by default to be less intrusive (don't want to give a notif that just says we couldnt help)

View File

@ -1,3 +1,5 @@
from enum import Enum
LIKE_BLOCK_ACTION_ID = "feedback-like"
DISLIKE_BLOCK_ACTION_ID = "feedback-dislike"
FEEDBACK_DOC_BUTTON_BLOCK_ACTION_ID = "feedback-doc-button"
@ -6,3 +8,9 @@ FOLLOWUP_BUTTON_ACTION_ID = "followup-button"
FOLLOWUP_BUTTON_RESOLVED_ACTION_ID = "followup-resolved-button"
SLACK_CHANNEL_ID = "channel_id"
VIEW_DOC_FEEDBACK_ID = "view-doc-feedback"
class FeedbackVisibility(str, Enum):
PRIVATE = "private"
ANONYMOUS = "anonymous"
PUBLIC = "public"

View File

@ -15,6 +15,7 @@ from danswer.danswerbot.slack.blocks import build_follow_up_resolved_blocks
from danswer.danswerbot.slack.blocks import get_document_feedback_blocks
from danswer.danswerbot.slack.config import get_slack_bot_config_for_channel
from danswer.danswerbot.slack.constants import DISLIKE_BLOCK_ACTION_ID
from danswer.danswerbot.slack.constants import FeedbackVisibility
from danswer.danswerbot.slack.constants import LIKE_BLOCK_ACTION_ID
from danswer.danswerbot.slack.constants import VIEW_DOC_FEEDBACK_ID
from danswer.danswerbot.slack.utils import build_feedback_id
@ -22,6 +23,7 @@ from danswer.danswerbot.slack.utils import decompose_action_id
from danswer.danswerbot.slack.utils import fetch_groupids_from_names
from danswer.danswerbot.slack.utils import fetch_userids_from_emails
from danswer.danswerbot.slack.utils import get_channel_name_from_id
from danswer.danswerbot.slack.utils import get_feedback_visibility
from danswer.danswerbot.slack.utils import respond_in_thread
from danswer.danswerbot.slack.utils import update_emote_react
from danswer.db.engine import get_sqlalchemy_engine
@ -120,13 +122,33 @@ def handle_slack_feedback(
else:
logger_base.error(f"Feedback type '{feedback_type}' not supported")
# post message to slack confirming that feedback was received
client.chat_postEphemeral(
channel=channel_id_to_post_confirmation,
user=user_id_to_post_confirmation,
thread_ts=thread_ts_to_post_confirmation,
text="Thanks for your feedback!",
)
if get_feedback_visibility() == FeedbackVisibility.PRIVATE or feedback_type not in [
LIKE_BLOCK_ACTION_ID,
DISLIKE_BLOCK_ACTION_ID,
]:
client.chat_postEphemeral(
channel=channel_id_to_post_confirmation,
user=user_id_to_post_confirmation,
thread_ts=thread_ts_to_post_confirmation,
text="Thanks for your feedback!",
)
else:
feedback_response_txt = (
"liked" if feedback_type == LIKE_BLOCK_ACTION_ID else "disliked"
)
if get_feedback_visibility() == FeedbackVisibility.ANONYMOUS:
msg = f"A user has {feedback_response_txt} the AI Answer"
else:
msg = f"<@{user_id_to_post_confirmation}> has {feedback_response_txt} the AI Answer"
respond_in_thread(
client=client,
channel=channel_id_to_post_confirmation,
text=msg,
thread_ts=thread_ts_to_post_confirmation,
unfurl=False,
)
def handle_followup_button(

View File

@ -18,11 +18,13 @@ from sqlalchemy.orm import Session
from danswer.configs.app_configs import DISABLE_TELEMETRY
from danswer.configs.constants import ID_SEPARATOR
from danswer.configs.constants import MessageType
from danswer.configs.danswerbot_configs import DANSWER_BOT_FEEDBACK_VISIBILITY
from danswer.configs.danswerbot_configs import DANSWER_BOT_MAX_QPM
from danswer.configs.danswerbot_configs import DANSWER_BOT_MAX_WAIT_TIME
from danswer.configs.danswerbot_configs import DANSWER_BOT_NUM_RETRIES
from danswer.connectors.slack.utils import make_slack_api_rate_limited
from danswer.connectors.slack.utils import SlackTextCleaner
from danswer.danswerbot.slack.constants import FeedbackVisibility
from danswer.danswerbot.slack.constants import SLACK_CHANNEL_ID
from danswer.danswerbot.slack.tokens import fetch_tokens
from danswer.db.engine import get_sqlalchemy_engine
@ -449,3 +451,10 @@ class SlackRateLimiter:
self.refill()
del self.waiting_questions[0]
def get_feedback_visibility() -> FeedbackVisibility:
try:
return FeedbackVisibility(DANSWER_BOT_FEEDBACK_VISIBILITY.lower())
except ValueError:
return FeedbackVisibility.PRIVATE

View File

@ -219,4 +219,4 @@ def search_postprocessing(
if chunk.unique_id in llm_chunk_selection
]
else:
yield []
yield cast(list[str], [])

View File

@ -151,6 +151,7 @@ services:
- DANSWER_BOT_SLACK_APP_TOKEN=${DANSWER_BOT_SLACK_APP_TOKEN:-}
- DANSWER_BOT_SLACK_BOT_TOKEN=${DANSWER_BOT_SLACK_BOT_TOKEN:-}
- DANSWER_BOT_DISABLE_DOCS_ONLY_ANSWER=${DANSWER_BOT_DISABLE_DOCS_ONLY_ANSWER:-}
- DANSWER_BOT_FEEDBACK_VISIBILITY=${DANSWER_BOT_FEEDBACK_VISIBILITY:-}
- DANSWER_BOT_DISPLAY_ERROR_MSGS=${DANSWER_BOT_DISPLAY_ERROR_MSGS:-}
- DANSWER_BOT_RESPOND_EVERY_CHANNEL=${DANSWER_BOT_RESPOND_EVERY_CHANNEL:-}
- DANSWER_BOT_DISABLE_COT=${DANSWER_BOT_DISABLE_COT:-} # Currently unused