diff --git a/claude-agent-sdk/listeners/events/__init__.py b/claude-agent-sdk/listeners/events/__init__.py index f9a1dfb..01f9e9e 100644 --- a/claude-agent-sdk/listeners/events/__init__.py +++ b/claude-agent-sdk/listeners/events/__init__.py @@ -2,12 +2,10 @@ from .app_home_opened import handle_app_home_opened from .app_mentioned import handle_app_mentioned -from .assistant_thread_started import handle_assistant_thread_started from .message import handle_message def register(app: AsyncApp): app.event("app_home_opened")(handle_app_home_opened) app.event("app_mention")(handle_app_mentioned) - app.event("assistant_thread_started")(handle_assistant_thread_started) app.event("message")(handle_message) diff --git a/claude-agent-sdk/listeners/events/app_home_opened.py b/claude-agent-sdk/listeners/events/app_home_opened.py index 9ecd95f..315d07f 100644 --- a/claude-agent-sdk/listeners/events/app_home_opened.py +++ b/claude-agent-sdk/listeners/events/app_home_opened.py @@ -7,12 +7,33 @@ from listeners.views.app_home_builder import build_app_home_view +SUGGESTED_PROMPTS = [ + {"title": "Reset Password", "message": "I need to reset my password"}, + {"title": "Request Access", "message": "I need access to a system or tool"}, + {"title": "Network Issues", "message": "I'm having network connectivity issues"}, +] + async def handle_app_home_opened( - client: AsyncWebClient, context: AsyncBoltContext, logger: Logger + client: AsyncWebClient, event: dict, context: AsyncBoltContext, logger: Logger ): - """Publish the App Home view when a user opens the app's Home tab.""" + """Handle app_home_opened events. + + Under agent_view, this event fires for both the Home tab and the Messages + tab (the agent DM). Branch on ``event["tab"]``: + * ``"messages"`` -- pin suggested prompts to the top of the DM. + * ``"home"`` -- publish the App Home Block Kit view. + """ try: + if event.get("tab") == "messages": + await client.assistant_threads_setSuggestedPrompts( + channel_id=event["channel"], + title="How can I help you today?", + prompts=SUGGESTED_PROMPTS, + ) + # TODO(agent-dm-messages-tab): handle app_context_changed once Bolt supports it + return + user_id = context.user_id install_url = None is_connected = False @@ -31,4 +52,4 @@ async def handle_app_home_opened( ) await client.views_publish(user_id=user_id, view=view) except Exception as e: - logger.exception(f"Failed to publish App Home: {e}") + logger.exception(f"Failed to handle app_home_opened: {e}") diff --git a/claude-agent-sdk/listeners/events/assistant_thread_started.py b/claude-agent-sdk/listeners/events/assistant_thread_started.py deleted file mode 100644 index 6071cdf..0000000 --- a/claude-agent-sdk/listeners/events/assistant_thread_started.py +++ /dev/null @@ -1,24 +0,0 @@ -from logging import Logger - -from slack_bolt.context.set_suggested_prompts.async_set_suggested_prompts import ( - AsyncSetSuggestedPrompts, -) - -SUGGESTED_PROMPTS = [ - {"title": "Reset Password", "message": "I need to reset my password"}, - {"title": "Request Access", "message": "I need access to a system or tool"}, - {"title": "Network Issues", "message": "I'm having network connectivity issues"}, -] - - -async def handle_assistant_thread_started( - set_suggested_prompts: AsyncSetSuggestedPrompts, logger: Logger -): - """Handle assistant thread started events by setting suggested prompts.""" - try: - await set_suggested_prompts( - prompts=SUGGESTED_PROMPTS, - title="How can I help you today?", - ) - except Exception as e: - logger.exception(f"Failed to handle assistant thread started: {e}") diff --git a/claude-agent-sdk/manifest.json b/claude-agent-sdk/manifest.json index cf6e061..d404a77 100644 --- a/claude-agent-sdk/manifest.json +++ b/claude-agent-sdk/manifest.json @@ -3,8 +3,8 @@ "name": "Casey - Claude Agent SDK" }, "features": { - "assistant_view": { - "assistant_description": "Hi, I am an agent built using Bolt for Python. I am here to help you out!", + "agent_view": { + "agent_description": "Hi, I am an agent built using Bolt for Python. I am here to help you out!", "suggested_prompts": [] }, "app_home": { @@ -63,7 +63,6 @@ "bot_events": [ "app_home_opened", "app_mention", - "assistant_thread_started", "message.channels", "message.groups", "message.im" diff --git a/claude-agent-sdk/tests/test_app_home_opened.py b/claude-agent-sdk/tests/test_app_home_opened.py index 1c52f03..9950fa9 100644 --- a/claude-agent-sdk/tests/test_app_home_opened.py +++ b/claude-agent-sdk/tests/test_app_home_opened.py @@ -14,13 +14,16 @@ class TestAppHomeOpened: def setup_method(self): self.fake_client = Mock(AsyncWebClient) self.fake_client.views_publish = AsyncMock() + self.fake_client.assistant_threads_setSuggestedPrompts = AsyncMock() self.fake_context = Mock(AsyncBoltContext) self.fake_context.user_id = "U123" + self.fake_context.bot_user_id = "U0BOT" @pytest.mark.asyncio - async def test_publishes_home_view(self): + async def test_publishes_home_view_when_tab_is_home(self): await handle_app_home_opened( client=self.fake_client, + event={"tab": "home", "channel": "D123"}, context=self.fake_context, logger=test_logger, ) @@ -29,6 +32,23 @@ async def test_publishes_home_view(self): kwargs = self.fake_client.views_publish.call_args.kwargs assert kwargs["user_id"] == "U123" assert kwargs["view"]["type"] == "home" + self.fake_client.assistant_threads_setSuggestedPrompts.assert_not_called() + + @pytest.mark.asyncio + async def test_sets_suggested_prompts_when_tab_is_messages(self): + await handle_app_home_opened( + client=self.fake_client, + event={"tab": "messages", "channel": "D123"}, + context=self.fake_context, + logger=test_logger, + ) + + self.fake_client.assistant_threads_setSuggestedPrompts.assert_called_once() + kwargs = self.fake_client.assistant_threads_setSuggestedPrompts.call_args.kwargs + assert kwargs["channel_id"] == "D123" + assert isinstance(kwargs["prompts"], list) + assert len(kwargs["prompts"]) > 0 + self.fake_client.views_publish.assert_not_called() @pytest.mark.asyncio async def test_views_publish_exception(self, caplog): @@ -36,6 +56,7 @@ async def test_views_publish_exception(self, caplog): await handle_app_home_opened( client=self.fake_client, + event={"tab": "home", "channel": "D123"}, context=self.fake_context, logger=test_logger, ) diff --git a/openai-agents-sdk/listeners/events/__init__.py b/openai-agents-sdk/listeners/events/__init__.py index 206ad37..bf83b72 100644 --- a/openai-agents-sdk/listeners/events/__init__.py +++ b/openai-agents-sdk/listeners/events/__init__.py @@ -2,12 +2,10 @@ from .app_home_opened import handle_app_home_opened from .app_mentioned import handle_app_mentioned -from .assistant_thread_started import handle_assistant_thread_started from .message import handle_message def register(app: App): app.event("app_home_opened")(handle_app_home_opened) app.event("app_mention")(handle_app_mentioned) - app.event("assistant_thread_started")(handle_assistant_thread_started) app.event("message")(handle_message) diff --git a/openai-agents-sdk/listeners/events/app_home_opened.py b/openai-agents-sdk/listeners/events/app_home_opened.py index 759c243..378bd46 100644 --- a/openai-agents-sdk/listeners/events/app_home_opened.py +++ b/openai-agents-sdk/listeners/events/app_home_opened.py @@ -7,10 +7,33 @@ from listeners.views.app_home_builder import build_app_home_view +SUGGESTED_PROMPTS = [ + {"title": "Reset Password", "message": "I need to reset my password"}, + {"title": "Request Access", "message": "I need access to a system or tool"}, + {"title": "Network Issues", "message": "I'm having network connectivity issues"}, +] -def handle_app_home_opened(client: WebClient, context: BoltContext, logger: Logger): - """Publish the App Home view when a user opens the app's Home tab.""" + +def handle_app_home_opened( + client: WebClient, event: dict, context: BoltContext, logger: Logger +): + """Handle app_home_opened events. + + Under agent_view, this event fires for both the Home tab and the Messages + tab (the agent DM). Branch on ``event["tab"]``: + * ``"messages"`` -- pin suggested prompts to the top of the DM. + * ``"home"`` -- publish the App Home Block Kit view. + """ try: + if event.get("tab") == "messages": + client.assistant_threads_setSuggestedPrompts( + channel_id=event["channel"], + title="How can I help you today?", + prompts=SUGGESTED_PROMPTS, + ) + # TODO(agent-dm-messages-tab): handle app_context_changed once Bolt supports it + return + user_id = context.user_id install_url = None is_connected = False @@ -29,4 +52,4 @@ def handle_app_home_opened(client: WebClient, context: BoltContext, logger: Logg ) client.views_publish(user_id=user_id, view=view) except Exception as e: - logger.exception(f"Failed to publish App Home: {e}") + logger.exception(f"Failed to handle app_home_opened: {e}") diff --git a/openai-agents-sdk/listeners/events/assistant_thread_started.py b/openai-agents-sdk/listeners/events/assistant_thread_started.py deleted file mode 100644 index 76224cb..0000000 --- a/openai-agents-sdk/listeners/events/assistant_thread_started.py +++ /dev/null @@ -1,22 +0,0 @@ -from logging import Logger - -from slack_bolt.context.set_suggested_prompts import SetSuggestedPrompts - -SUGGESTED_PROMPTS = [ - {"title": "Reset Password", "message": "I need to reset my password"}, - {"title": "Request Access", "message": "I need access to a system or tool"}, - {"title": "Network Issues", "message": "I'm having network connectivity issues"}, -] - - -def handle_assistant_thread_started( - set_suggested_prompts: SetSuggestedPrompts, logger: Logger -): - """Handle assistant thread started events by setting suggested prompts.""" - try: - set_suggested_prompts( - prompts=SUGGESTED_PROMPTS, - title="How can I help you today?", - ) - except Exception as e: - logger.exception(f"Failed to handle assistant thread started: {e}") diff --git a/openai-agents-sdk/manifest.json b/openai-agents-sdk/manifest.json index c5de245..3633b2d 100644 --- a/openai-agents-sdk/manifest.json +++ b/openai-agents-sdk/manifest.json @@ -3,8 +3,8 @@ "name": "Casey - OpenAI SDK" }, "features": { - "assistant_view": { - "assistant_description": "Hi, I am an agent built using Bolt for Python. I am here to help you out!", + "agent_view": { + "agent_description": "Hi, I am an agent built using Bolt for Python. I am here to help you out!", "suggested_prompts": [] }, "app_home": { @@ -63,7 +63,6 @@ "bot_events": [ "app_home_opened", "app_mention", - "assistant_thread_started", "message.channels", "message.groups", "message.im" diff --git a/openai-agents-sdk/tests/test_app_home_opened.py b/openai-agents-sdk/tests/test_app_home_opened.py index f9df038..e3044b5 100644 --- a/openai-agents-sdk/tests/test_app_home_opened.py +++ b/openai-agents-sdk/tests/test_app_home_opened.py @@ -14,10 +14,12 @@ def setup_method(self): self.fake_client = Mock(WebClient) self.fake_context = Mock(BoltContext) self.fake_context.user_id = "U123" + self.fake_context.bot_user_id = "U0BOT" - def test_publishes_home_view(self): + def test_publishes_home_view_when_tab_is_home(self): handle_app_home_opened( client=self.fake_client, + event={"tab": "home", "channel": "D123"}, context=self.fake_context, logger=test_logger, ) @@ -26,12 +28,29 @@ def test_publishes_home_view(self): kwargs = self.fake_client.views_publish.call_args.kwargs assert kwargs["user_id"] == "U123" assert kwargs["view"]["type"] == "home" + self.fake_client.assistant_threads_setSuggestedPrompts.assert_not_called() + + def test_sets_suggested_prompts_when_tab_is_messages(self): + handle_app_home_opened( + client=self.fake_client, + event={"tab": "messages", "channel": "D123"}, + context=self.fake_context, + logger=test_logger, + ) + + self.fake_client.assistant_threads_setSuggestedPrompts.assert_called_once() + kwargs = self.fake_client.assistant_threads_setSuggestedPrompts.call_args.kwargs + assert kwargs["channel_id"] == "D123" + assert isinstance(kwargs["prompts"], list) + assert len(kwargs["prompts"]) > 0 + self.fake_client.views_publish.assert_not_called() def test_views_publish_exception(self, caplog): self.fake_client.views_publish.side_effect = Exception("test exception") handle_app_home_opened( client=self.fake_client, + event={"tab": "home", "channel": "D123"}, context=self.fake_context, logger=test_logger, ) diff --git a/pydantic-ai/listeners/events/__init__.py b/pydantic-ai/listeners/events/__init__.py index 206ad37..bf83b72 100644 --- a/pydantic-ai/listeners/events/__init__.py +++ b/pydantic-ai/listeners/events/__init__.py @@ -2,12 +2,10 @@ from .app_home_opened import handle_app_home_opened from .app_mentioned import handle_app_mentioned -from .assistant_thread_started import handle_assistant_thread_started from .message import handle_message def register(app: App): app.event("app_home_opened")(handle_app_home_opened) app.event("app_mention")(handle_app_mentioned) - app.event("assistant_thread_started")(handle_assistant_thread_started) app.event("message")(handle_message) diff --git a/pydantic-ai/listeners/events/app_home_opened.py b/pydantic-ai/listeners/events/app_home_opened.py index 759c243..378bd46 100644 --- a/pydantic-ai/listeners/events/app_home_opened.py +++ b/pydantic-ai/listeners/events/app_home_opened.py @@ -7,10 +7,33 @@ from listeners.views.app_home_builder import build_app_home_view +SUGGESTED_PROMPTS = [ + {"title": "Reset Password", "message": "I need to reset my password"}, + {"title": "Request Access", "message": "I need access to a system or tool"}, + {"title": "Network Issues", "message": "I'm having network connectivity issues"}, +] -def handle_app_home_opened(client: WebClient, context: BoltContext, logger: Logger): - """Publish the App Home view when a user opens the app's Home tab.""" + +def handle_app_home_opened( + client: WebClient, event: dict, context: BoltContext, logger: Logger +): + """Handle app_home_opened events. + + Under agent_view, this event fires for both the Home tab and the Messages + tab (the agent DM). Branch on ``event["tab"]``: + * ``"messages"`` -- pin suggested prompts to the top of the DM. + * ``"home"`` -- publish the App Home Block Kit view. + """ try: + if event.get("tab") == "messages": + client.assistant_threads_setSuggestedPrompts( + channel_id=event["channel"], + title="How can I help you today?", + prompts=SUGGESTED_PROMPTS, + ) + # TODO(agent-dm-messages-tab): handle app_context_changed once Bolt supports it + return + user_id = context.user_id install_url = None is_connected = False @@ -29,4 +52,4 @@ def handle_app_home_opened(client: WebClient, context: BoltContext, logger: Logg ) client.views_publish(user_id=user_id, view=view) except Exception as e: - logger.exception(f"Failed to publish App Home: {e}") + logger.exception(f"Failed to handle app_home_opened: {e}") diff --git a/pydantic-ai/listeners/events/assistant_thread_started.py b/pydantic-ai/listeners/events/assistant_thread_started.py deleted file mode 100644 index 76224cb..0000000 --- a/pydantic-ai/listeners/events/assistant_thread_started.py +++ /dev/null @@ -1,22 +0,0 @@ -from logging import Logger - -from slack_bolt.context.set_suggested_prompts import SetSuggestedPrompts - -SUGGESTED_PROMPTS = [ - {"title": "Reset Password", "message": "I need to reset my password"}, - {"title": "Request Access", "message": "I need access to a system or tool"}, - {"title": "Network Issues", "message": "I'm having network connectivity issues"}, -] - - -def handle_assistant_thread_started( - set_suggested_prompts: SetSuggestedPrompts, logger: Logger -): - """Handle assistant thread started events by setting suggested prompts.""" - try: - set_suggested_prompts( - prompts=SUGGESTED_PROMPTS, - title="How can I help you today?", - ) - except Exception as e: - logger.exception(f"Failed to handle assistant thread started: {e}") diff --git a/pydantic-ai/manifest.json b/pydantic-ai/manifest.json index 4ae618f..d0853cc 100644 --- a/pydantic-ai/manifest.json +++ b/pydantic-ai/manifest.json @@ -3,8 +3,8 @@ "name": "Casey - Pydantic AI" }, "features": { - "assistant_view": { - "assistant_description": "Hi, I am an agent built using Bolt for Python. I am here to help you out!", + "agent_view": { + "agent_description": "Hi, I am an agent built using Bolt for Python. I am here to help you out!", "suggested_prompts": [] }, "app_home": { @@ -63,7 +63,6 @@ "bot_events": [ "app_home_opened", "app_mention", - "assistant_thread_started", "message.channels", "message.groups", "message.im" diff --git a/pydantic-ai/tests/test_app_home_opened.py b/pydantic-ai/tests/test_app_home_opened.py index f9df038..e3044b5 100644 --- a/pydantic-ai/tests/test_app_home_opened.py +++ b/pydantic-ai/tests/test_app_home_opened.py @@ -14,10 +14,12 @@ def setup_method(self): self.fake_client = Mock(WebClient) self.fake_context = Mock(BoltContext) self.fake_context.user_id = "U123" + self.fake_context.bot_user_id = "U0BOT" - def test_publishes_home_view(self): + def test_publishes_home_view_when_tab_is_home(self): handle_app_home_opened( client=self.fake_client, + event={"tab": "home", "channel": "D123"}, context=self.fake_context, logger=test_logger, ) @@ -26,12 +28,29 @@ def test_publishes_home_view(self): kwargs = self.fake_client.views_publish.call_args.kwargs assert kwargs["user_id"] == "U123" assert kwargs["view"]["type"] == "home" + self.fake_client.assistant_threads_setSuggestedPrompts.assert_not_called() + + def test_sets_suggested_prompts_when_tab_is_messages(self): + handle_app_home_opened( + client=self.fake_client, + event={"tab": "messages", "channel": "D123"}, + context=self.fake_context, + logger=test_logger, + ) + + self.fake_client.assistant_threads_setSuggestedPrompts.assert_called_once() + kwargs = self.fake_client.assistant_threads_setSuggestedPrompts.call_args.kwargs + assert kwargs["channel_id"] == "D123" + assert isinstance(kwargs["prompts"], list) + assert len(kwargs["prompts"]) > 0 + self.fake_client.views_publish.assert_not_called() def test_views_publish_exception(self, caplog): self.fake_client.views_publish.side_effect = Exception("test exception") handle_app_home_opened( client=self.fake_client, + event={"tab": "home", "channel": "D123"}, context=self.fake_context, logger=test_logger, )