From 922108054e13f6b5f8ad11738a9c2e4bcd58cab8 Mon Sep 17 00:00:00 2001 From: Ale Mercado Date: Fri, 10 Oct 2025 11:10:35 -0400 Subject: [PATCH 1/8] ref: breakup assistant.py into separate files --- listeners/assistant/__init__.py | 11 ++++- .../assistant/assistant_thread_started.py | 41 +++++++++++++++++ .../assistant/{assistant.py => message.py} | 44 +------------------ manifest.json | 2 - 4 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 listeners/assistant/assistant_thread_started.py rename listeners/assistant/{assistant.py => message.py} (62%) diff --git a/listeners/assistant/__init__.py b/listeners/assistant/__init__.py index f0235ac..b44a8f9 100644 --- a/listeners/assistant/__init__.py +++ b/listeners/assistant/__init__.py @@ -1,7 +1,14 @@ -from slack_bolt import App +from slack_bolt import App, Assistant -from .assistant import assistant +from .assistant_thread_started import start_assistant_thread +from .message import respond_in_assistant_thread +# Refer to https://tools.slack.dev/bolt-python/concepts/assistant/ for more details on the Assistant class def register(app: App): + assistant = Assistant() + + assistant.thread_started(start_assistant_thread) + assistant.user_message(respond_in_assistant_thread) + app.assistant(assistant) diff --git a/listeners/assistant/assistant_thread_started.py b/listeners/assistant/assistant_thread_started.py new file mode 100644 index 0000000..339c957 --- /dev/null +++ b/listeners/assistant/assistant_thread_started.py @@ -0,0 +1,41 @@ +from logging import Logger +from typing import Dict, List + +from slack_bolt import Say, SetSuggestedPrompts + + +def start_assistant_thread( + say: Say, + set_suggested_prompts: SetSuggestedPrompts, + logger: Logger, +): + """ + Handle the assistant thread start event by greeting the user and setting suggested prompts. + + Args: + say: Function to send messages to the thread from the app + set_suggested_prompts: Function to configure suggested prompt options + logger: Logger instance for error tracking + """ + try: + say("How can I help you?") + + prompts: List[Dict[str, str]] = [ + { + "title": "What does Slack stand for?", + "message": "Slack, a business communication service, was named after an acronym. Can you guess what it stands for?", + }, + { + "title": "Write a draft announcement", + "message": "Can you write a draft announcement about a new feature my team just released? It must include how impactful it is.", + }, + { + "title": "Suggest names for my Slack app", + "message": "Can you suggest a few names for my Slack app? The app helps my teammates better organize information and plan priorities and action items.", + }, + ] + + set_suggested_prompts(prompts=prompts) + except Exception as e: + logger.exception(f"Failed to handle an assistant_thread_started event: {e}", e) + say(f":warning: Something went wrong! ({e})") diff --git a/listeners/assistant/assistant.py b/listeners/assistant/message.py similarity index 62% rename from listeners/assistant/assistant.py rename to listeners/assistant/message.py index e0df965..857ae53 100644 --- a/listeners/assistant/assistant.py +++ b/listeners/assistant/message.py @@ -1,57 +1,15 @@ from logging import Logger from typing import Dict, List -from slack_bolt import Assistant, BoltContext, Say, SetStatus, SetSuggestedPrompts +from slack_bolt import BoltContext, Say, SetStatus from slack_sdk import WebClient from ai.llm_caller import call_llm from ..views.feedback_block import create_feedback_block -# Refer to https://tools.slack.dev/bolt-python/concepts/assistant/ for more details -assistant = Assistant() - - -@assistant.thread_started -def start_assistant_thread( - say: Say, - set_suggested_prompts: SetSuggestedPrompts, - logger: Logger, -): - """ - Handle the assistant thread start event by greeting the user and setting suggested prompts. - - Args: - say: Function to send messages to the thread from the app - set_suggested_prompts: Function to configure suggested prompt options - logger: Logger instance for error tracking - """ - try: - say("How can I help you?") - - prompts: List[Dict[str, str]] = [ - { - "title": "What does Slack stand for?", - "message": "Slack, a business communication service, was named after an acronym. Can you guess what it stands for?", - }, - { - "title": "Write a draft announcement", - "message": "Can you write a draft announcement about a new feature my team just released? It must include how impactful it is.", - }, - { - "title": "Suggest names for my Slack app", - "message": "Can you suggest a few names for my Slack app? The app helps my teammates better organize information and plan priorities and action items.", - }, - ] - - set_suggested_prompts(prompts=prompts) - except Exception as e: - logger.exception(f"Failed to handle an assistant_thread_started event: {e}", e) - say(f":warning: Something went wrong! ({e})") - # This listener is invoked when the human user sends a reply in the assistant thread -@assistant.user_message def respond_in_assistant_thread( client: WebClient, context: BoltContext, diff --git a/manifest.json b/manifest.json index 15aa21f..2123a0d 100644 --- a/manifest.json +++ b/manifest.json @@ -23,7 +23,6 @@ "app_mentions:read", "assistant:write", "im:history", - "channels:read", "chat:write" ] } @@ -31,7 +30,6 @@ "settings": { "event_subscriptions": { "bot_events": [ - "assistant_thread_context_changed", "assistant_thread_started", "message.im", "app_mention" From 1ed34619bbf1e82340dd8c23cc576f936d9d870b Mon Sep 17 00:00:00 2001 From: Ale Mercado Date: Fri, 10 Oct 2025 11:17:26 -0400 Subject: [PATCH 2/8] docs: update README to reflect file structure changes --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8cc86cd..3e38e5c 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,14 @@ Every incoming request is routed to a "listener". This directory groups each lis Configures the new Slack Assistant features, providing a dedicated side panel UI for users to interact with the AI chatbot. This module includes: -`assistant.py`, which contains two listeners: +`assistant_thread_started.py`, which contains: * The `@assistant.thread_started` listener receives an event when users start new app thread. + +`message.py`, which contains: * The `@assistant.user_message` listener processes user messages in app threads or from the app **Chat** and **History** tab. -`ai/llm_caller.py`, which handles OpenAI API integration and message formatting. It includes the `call_llm()` function that sends conversation threads to OpenAI's models. +### `ai/` +`llm_caller.py`, which handles OpenAI API integration and message formatting. It includes the `call_llm()` function that sends conversation threads to OpenAI's models. ## App Distribution / OAuth From 75bbdd978c4935902210aa002a6cda60f890aa2c Mon Sep 17 00:00:00 2001 From: Maria Alejandra <104795114+srtaalej@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:07:05 -0700 Subject: [PATCH 3/8] Update listeners/assistant/__init__.py Co-authored-by: Eden Zimbelman --- listeners/assistant/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/listeners/assistant/__init__.py b/listeners/assistant/__init__.py index b44a8f9..ad243da 100644 --- a/listeners/assistant/__init__.py +++ b/listeners/assistant/__init__.py @@ -8,7 +8,7 @@ def register(app: App): assistant = Assistant() - assistant.thread_started(start_assistant_thread) - assistant.user_message(respond_in_assistant_thread) + assistant.thread_started(assistant_thread_started) + assistant.user_message(message) app.assistant(assistant) From 0b1814573b0bd7d779a4eaaaaf36ec21df608bf6 Mon Sep 17 00:00:00 2001 From: Maria Alejandra <104795114+srtaalej@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:07:19 -0700 Subject: [PATCH 4/8] Update listeners/assistant/__init__.py Co-authored-by: Eden Zimbelman --- listeners/assistant/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/listeners/assistant/__init__.py b/listeners/assistant/__init__.py index ad243da..d4091bd 100644 --- a/listeners/assistant/__init__.py +++ b/listeners/assistant/__init__.py @@ -4,7 +4,7 @@ from .message import respond_in_assistant_thread -# Refer to https://tools.slack.dev/bolt-python/concepts/assistant/ for more details on the Assistant class +# Refer to https://docs.slack.dev/tools/bolt-python/concepts/ai-apps#assistant for more details on the Assistant class def register(app: App): assistant = Assistant() From 16872837cdb4f127a293aa8f05a9bbee7084808c Mon Sep 17 00:00:00 2001 From: Maria Alejandra <104795114+srtaalej@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:07:31 -0700 Subject: [PATCH 5/8] Update README.md Co-authored-by: Eden Zimbelman --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3e38e5c..6977cb5 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,8 @@ Every incoming request is routed to a "listener". This directory groups each lis Configures the new Slack Assistant features, providing a dedicated side panel UI for users to interact with the AI chatbot. This module includes: -`assistant_thread_started.py`, which contains: -* The `@assistant.thread_started` listener receives an event when users start new app thread. - -`message.py`, which contains: -* The `@assistant.user_message` listener processes user messages in app threads or from the app **Chat** and **History** tab. +- The `assistant_thread_started.py` file, which responds to new app threads with a list of suggested prompts. +- The `message.py` file, which responds to user messages sent to app threads or from the **Chat** and **History** tab with an LLM generated response. ### `ai/` `llm_caller.py`, which handles OpenAI API integration and message formatting. It includes the `call_llm()` function that sends conversation threads to OpenAI's models. From bd0da37c269ccae07ef217e687f1dccf5d33e0db Mon Sep 17 00:00:00 2001 From: Maria Alejandra <104795114+srtaalej@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:07:41 -0700 Subject: [PATCH 6/8] Update README.md Co-authored-by: Eden Zimbelman --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6977cb5..fa6f6cb 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Configures the new Slack Assistant features, providing a dedicated side panel UI - The `message.py` file, which responds to user messages sent to app threads or from the **Chat** and **History** tab with an LLM generated response. ### `ai/` -`llm_caller.py`, which handles OpenAI API integration and message formatting. It includes the `call_llm()` function that sends conversation threads to OpenAI's models. +The `llm_caller.py` file, which handles OpenAI API integration and message formatting. It includes the `call_llm()` function that sends conversation threads to OpenAI's models. ## App Distribution / OAuth From afa1d4d87886cbe7ad5c1b612f92748239d18781 Mon Sep 17 00:00:00 2001 From: Maria Alejandra <104795114+srtaalej@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:08:28 -0700 Subject: [PATCH 7/8] Update listeners/assistant/message.py Co-authored-by: Eden Zimbelman --- listeners/assistant/message.py | 1 - 1 file changed, 1 deletion(-) diff --git a/listeners/assistant/message.py b/listeners/assistant/message.py index 857ae53..907592e 100644 --- a/listeners/assistant/message.py +++ b/listeners/assistant/message.py @@ -9,7 +9,6 @@ from ..views.feedback_block import create_feedback_block -# This listener is invoked when the human user sends a reply in the assistant thread def respond_in_assistant_thread( client: WebClient, context: BoltContext, From 73b13e59295019ce002de427eb055e7ca9e35ffd Mon Sep 17 00:00:00 2001 From: Ale Mercado Date: Mon, 13 Oct 2025 14:28:15 -0700 Subject: [PATCH 8/8] chore: match js sample app name conventions --- listeners/assistant/__init__.py | 4 ++-- listeners/assistant/assistant_thread_started.py | 2 +- listeners/assistant/message.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/listeners/assistant/__init__.py b/listeners/assistant/__init__.py index d4091bd..5763994 100644 --- a/listeners/assistant/__init__.py +++ b/listeners/assistant/__init__.py @@ -1,7 +1,7 @@ from slack_bolt import App, Assistant -from .assistant_thread_started import start_assistant_thread -from .message import respond_in_assistant_thread +from .assistant_thread_started import assistant_thread_started +from .message import message # Refer to https://docs.slack.dev/tools/bolt-python/concepts/ai-apps#assistant for more details on the Assistant class diff --git a/listeners/assistant/assistant_thread_started.py b/listeners/assistant/assistant_thread_started.py index 339c957..9d2990f 100644 --- a/listeners/assistant/assistant_thread_started.py +++ b/listeners/assistant/assistant_thread_started.py @@ -4,7 +4,7 @@ from slack_bolt import Say, SetSuggestedPrompts -def start_assistant_thread( +def assistant_thread_started( say: Say, set_suggested_prompts: SetSuggestedPrompts, logger: Logger, diff --git a/listeners/assistant/message.py b/listeners/assistant/message.py index 907592e..b61de90 100644 --- a/listeners/assistant/message.py +++ b/listeners/assistant/message.py @@ -9,7 +9,7 @@ from ..views.feedback_block import create_feedback_block -def respond_in_assistant_thread( +def message( client: WebClient, context: BoltContext, logger: Logger,