diff --git a/claude-agent-sdk/listeners/events/app_home_opened.py b/claude-agent-sdk/listeners/events/app_home_opened.py index 1198092..9ecd95f 100644 --- a/claude-agent-sdk/listeners/events/app_home_opened.py +++ b/claude-agent-sdk/listeners/events/app_home_opened.py @@ -24,7 +24,11 @@ async def handle_app_home_opened( redirect_uri = os.environ.get("SLACK_REDIRECT_URI", "") install_url = urljoin(redirect_uri, "/slack/install") - view = build_app_home_view(install_url=install_url, is_connected=is_connected) + view = build_app_home_view( + install_url=install_url, + is_connected=is_connected, + bot_user_id=context.bot_user_id, + ) await client.views_publish(user_id=user_id, view=view) except Exception as e: logger.exception(f"Failed to publish App Home: {e}") diff --git a/claude-agent-sdk/listeners/views/app_home_builder.py b/claude-agent-sdk/listeners/views/app_home_builder.py index 448eb66..6eb6229 100644 --- a/claude-agent-sdk/listeners/views/app_home_builder.py +++ b/claude-agent-sdk/listeners/views/app_home_builder.py @@ -28,7 +28,9 @@ def build_app_home_view( - install_url: str | None = None, is_connected: bool = False + install_url: str | None = None, + is_connected: bool = False, + bot_user_id: str | None = None, ) -> dict: """Build the App Home Block Kit view with category buttons. @@ -37,13 +39,15 @@ def build_app_home_view( connected and will see a link to install. is_connected: When ``True``, the user is connected and the MCP status section shows as connected. + bot_user_id: The bot's user ID for dynamic mentions. """ + mention = f" with <@{bot_user_id}>" if bot_user_id else "" blocks = [ { "type": "header", "text": { "type": "plain_text", - "text": "Hey there :wave: I'm Casey, your IT helpdesk agent.", + "text": "Hey there :wave: I'm your IT helpdesk agent.", }, }, { @@ -79,7 +83,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "You can also mention me in any channel with `@Casey` or send me a DM.", + "text": f"You can also mention me in any channel{mention} or send me a DM.", } ], }, @@ -102,7 +106,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "Casey has access to search messages, read channels, and more.", + "text": "This agent has access to search messages, read channels, and more.", } ], } @@ -123,7 +127,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "The Slack MCP Server enables Casey to search messages, read channels, and more.", + "text": "The Slack MCP Server enables this agent to search messages, read channels, and more.", } ], } @@ -144,7 +148,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "The Slack MCP Server enables Casey to search messages, read channels, and more.", + "text": "The Slack MCP Server enables this agent to search messages, read channels, and more.", } ], } diff --git a/claude-agent-sdk/tests/test_view_builders.py b/claude-agent-sdk/tests/test_view_builders.py index 89df6b4..0774e30 100644 --- a/claude-agent-sdk/tests/test_view_builders.py +++ b/claude-agent-sdk/tests/test_view_builders.py @@ -65,3 +65,21 @@ def test_build_app_home_view_connected(): ] mcp_section = next(t for t in section_texts if "Slack MCP Server" in t) assert "connected" in mcp_section + + +def test_build_app_home_view_with_bot_user_id(): + """bot_user_id provided — context block includes dynamic mention.""" + view = build_app_home_view(bot_user_id="U0BOT") + + context_blocks = [b for b in view["blocks"] if b["type"] == "context"] + mention_text = context_blocks[0]["elements"][0]["text"] + assert "<@U0BOT>" in mention_text + + +def test_build_app_home_view_without_bot_user_id(): + """bot_user_id not provided — context block omits mention.""" + view = build_app_home_view() + + context_blocks = [b for b in view["blocks"] if b["type"] == "context"] + mention_text = context_blocks[0]["elements"][0]["text"] + assert "<@" not in mention_text diff --git a/openai-agents-sdk/listeners/events/app_home_opened.py b/openai-agents-sdk/listeners/events/app_home_opened.py index 47dc3d8..759c243 100644 --- a/openai-agents-sdk/listeners/events/app_home_opened.py +++ b/openai-agents-sdk/listeners/events/app_home_opened.py @@ -22,7 +22,11 @@ def handle_app_home_opened(client: WebClient, context: BoltContext, logger: Logg redirect_uri = os.environ.get("SLACK_REDIRECT_URI", "") install_url = urljoin(redirect_uri, "/slack/install") - view = build_app_home_view(install_url=install_url, is_connected=is_connected) + view = build_app_home_view( + install_url=install_url, + is_connected=is_connected, + bot_user_id=context.bot_user_id, + ) client.views_publish(user_id=user_id, view=view) except Exception as e: logger.exception(f"Failed to publish App Home: {e}") diff --git a/openai-agents-sdk/listeners/views/app_home_builder.py b/openai-agents-sdk/listeners/views/app_home_builder.py index 0198b1f..a42a9a6 100644 --- a/openai-agents-sdk/listeners/views/app_home_builder.py +++ b/openai-agents-sdk/listeners/views/app_home_builder.py @@ -28,7 +28,9 @@ def build_app_home_view( - install_url: str | None = None, is_connected: bool = False + install_url: str | None = None, + is_connected: bool = False, + bot_user_id: str | None = None, ) -> dict: """Build the App Home Block Kit view with category buttons. @@ -37,13 +39,15 @@ def build_app_home_view( connected and will see a link to install. is_connected: When ``True``, the user is connected and the MCP status section shows as connected. + bot_user_id: The bot's user ID for dynamic mentions. """ + mention = f" with <@{bot_user_id}>" if bot_user_id else "" blocks = [ { "type": "header", "text": { "type": "plain_text", - "text": "Hey there :wave: I'm Casey, your IT helpdesk agent.", + "text": "Hey there :wave: I'm your IT helpdesk agent.", }, }, { @@ -79,7 +83,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "You can also mention me in any channel with `@Casey` or send me a DM.", + "text": f"You can also mention me in any channel{mention} or send me a DM.", } ], }, @@ -102,7 +106,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "Casey has access to search messages, read channels, and more.", + "text": "This agent has access to search messages, read channels, and more.", } ], } @@ -123,7 +127,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "The Slack MCP Server enables Casey to search messages, read channels, and more.", + "text": "The Slack MCP Server enables this agent to search messages, read channels, and more.", } ], } @@ -144,7 +148,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "The Slack MCP Server enables Casey to search messages, read channels, and more.", + "text": "The Slack MCP Server enables this agent to search messages, read channels, and more.", } ], } diff --git a/openai-agents-sdk/tests/test_view_builders.py b/openai-agents-sdk/tests/test_view_builders.py index 89df6b4..0774e30 100644 --- a/openai-agents-sdk/tests/test_view_builders.py +++ b/openai-agents-sdk/tests/test_view_builders.py @@ -65,3 +65,21 @@ def test_build_app_home_view_connected(): ] mcp_section = next(t for t in section_texts if "Slack MCP Server" in t) assert "connected" in mcp_section + + +def test_build_app_home_view_with_bot_user_id(): + """bot_user_id provided — context block includes dynamic mention.""" + view = build_app_home_view(bot_user_id="U0BOT") + + context_blocks = [b for b in view["blocks"] if b["type"] == "context"] + mention_text = context_blocks[0]["elements"][0]["text"] + assert "<@U0BOT>" in mention_text + + +def test_build_app_home_view_without_bot_user_id(): + """bot_user_id not provided — context block omits mention.""" + view = build_app_home_view() + + context_blocks = [b for b in view["blocks"] if b["type"] == "context"] + mention_text = context_blocks[0]["elements"][0]["text"] + assert "<@" not in mention_text diff --git a/pydantic-ai/listeners/events/app_home_opened.py b/pydantic-ai/listeners/events/app_home_opened.py index 47dc3d8..759c243 100644 --- a/pydantic-ai/listeners/events/app_home_opened.py +++ b/pydantic-ai/listeners/events/app_home_opened.py @@ -22,7 +22,11 @@ def handle_app_home_opened(client: WebClient, context: BoltContext, logger: Logg redirect_uri = os.environ.get("SLACK_REDIRECT_URI", "") install_url = urljoin(redirect_uri, "/slack/install") - view = build_app_home_view(install_url=install_url, is_connected=is_connected) + view = build_app_home_view( + install_url=install_url, + is_connected=is_connected, + bot_user_id=context.bot_user_id, + ) client.views_publish(user_id=user_id, view=view) except Exception as e: logger.exception(f"Failed to publish App Home: {e}") diff --git a/pydantic-ai/listeners/views/app_home_builder.py b/pydantic-ai/listeners/views/app_home_builder.py index 92ef2c3..8861e4f 100644 --- a/pydantic-ai/listeners/views/app_home_builder.py +++ b/pydantic-ai/listeners/views/app_home_builder.py @@ -28,7 +28,9 @@ def build_app_home_view( - install_url: str | None = None, is_connected: bool = False + install_url: str | None = None, + is_connected: bool = False, + bot_user_id: str | None = None, ) -> dict: """Build the App Home Block Kit view with category buttons. @@ -37,13 +39,15 @@ def build_app_home_view( connected and will see a link to install. is_connected: When ``True``, the user is connected and the MCP status section shows as connected. + bot_user_id: The bot's user ID for dynamic mentions. """ + mention = f" with <@{bot_user_id}>" if bot_user_id else "" blocks = [ { "type": "header", "text": { "type": "plain_text", - "text": "Hey there :wave: I'm Casey, your IT helpdesk agent.", + "text": "Hey there :wave: I'm your IT helpdesk agent.", }, }, { @@ -79,7 +83,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "You can also mention me in any channel with `@Casey` or send me a DM.", + "text": f"You can also mention me in any channel{mention} or send me a DM.", } ], }, @@ -102,7 +106,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "Casey has access to search messages, read channels, and more.", + "text": "This agent has access to search messages, read channels, and more.", } ], } @@ -123,7 +127,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "The Slack MCP Server enables Casey to search messages, read channels, and more.", + "text": "The Slack MCP Server enables this agent to search messages, read channels, and more.", } ], } @@ -144,7 +148,7 @@ def build_app_home_view( "elements": [ { "type": "mrkdwn", - "text": "The Slack MCP Server enables Casey to search messages, read channels, and more.", + "text": "The Slack MCP Server enables this agent to search messages, read channels, and more.", } ], } diff --git a/pydantic-ai/tests/test_view_builders.py b/pydantic-ai/tests/test_view_builders.py index 89df6b4..0774e30 100644 --- a/pydantic-ai/tests/test_view_builders.py +++ b/pydantic-ai/tests/test_view_builders.py @@ -65,3 +65,21 @@ def test_build_app_home_view_connected(): ] mcp_section = next(t for t in section_texts if "Slack MCP Server" in t) assert "connected" in mcp_section + + +def test_build_app_home_view_with_bot_user_id(): + """bot_user_id provided — context block includes dynamic mention.""" + view = build_app_home_view(bot_user_id="U0BOT") + + context_blocks = [b for b in view["blocks"] if b["type"] == "context"] + mention_text = context_blocks[0]["elements"][0]["text"] + assert "<@U0BOT>" in mention_text + + +def test_build_app_home_view_without_bot_user_id(): + """bot_user_id not provided — context block omits mention.""" + view = build_app_home_view() + + context_blocks = [b for b in view["blocks"] if b["type"] == "context"] + mention_text = context_blocks[0]["elements"][0]["text"] + assert "<@" not in mention_text