From efb7ba2a1994cb638bc9815d094b38205a3ed051 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 13 Jan 2026 15:23:42 -0800 Subject: [PATCH] feat: add task_display_mode option to the start of chat streams --- slack_sdk/web/async_chat_stream.py | 4 ++++ slack_sdk/web/async_client.py | 6 ++++++ slack_sdk/web/chat_stream.py | 4 ++++ slack_sdk/web/client.py | 6 ++++++ slack_sdk/web/legacy_client.py | 2 ++ tests/slack_sdk/web/test_chat_stream.py | 2 ++ 6 files changed, 24 insertions(+) diff --git a/slack_sdk/web/async_chat_stream.py b/slack_sdk/web/async_chat_stream.py index 55090218..7af774bb 100644 --- a/slack_sdk/web/async_chat_stream.py +++ b/slack_sdk/web/async_chat_stream.py @@ -39,6 +39,7 @@ def __init__( buffer_size: int, recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, + task_display_mode: Optional[str] = None, **kwargs, ): """Initialize a new ChatStream instance. @@ -54,6 +55,8 @@ def __init__( recipient_team_id: The encoded ID of the team the user receiving the streaming text belongs to. Required when streaming to channels. recipient_user_id: The encoded ID of the user to receive the streaming text. Required when streaming to channels. + task_display_mode: Specifies how tasks are displayed in the message. A "timeline" displays individual tasks + interleaved with text and "plan" displays all tasks together. buffer_size: The length of markdown_text to buffer in-memory before calling a method. Increasing this value decreases the number of method calls made for the same amount of text, which is useful to avoid rate limits. **kwargs: Additional arguments passed to the underlying API calls. @@ -66,6 +69,7 @@ def __init__( "thread_ts": thread_ts, "recipient_team_id": recipient_team_id, "recipient_user_id": recipient_user_id, + "task_display_mode": task_display_mode, **kwargs, } self._buffer = "" diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index 5aaa2c61..7464b754 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -2889,6 +2889,7 @@ async def chat_startStream( recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, chunks: Optional[Sequence[Union[Dict, Chunk]]] = None, + task_display_mode: Optional[str] = None, # timeline, plan **kwargs, ) -> AsyncSlackResponse: """Starts a new streaming conversation. @@ -2902,6 +2903,7 @@ async def chat_startStream( "recipient_team_id": recipient_team_id, "recipient_user_id": recipient_user_id, "chunks": chunks, + "task_display_mode": task_display_mode, } ) _parse_web_class_objects(kwargs) @@ -2944,6 +2946,7 @@ async def chat_stream( thread_ts: str, recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, + task_display_mode: Optional[str] = None, **kwargs, ) -> AsyncChatStream: """Stream markdown text into a conversation. @@ -2970,6 +2973,8 @@ async def chat_stream( recipient_team_id: The encoded ID of the team the user receiving the streaming text belongs to. Required when streaming to channels. recipient_user_id: The encoded ID of the user to receive the streaming text. Required when streaming to channels. + task_display_mode: Specifies how tasks are displayed in the message. A "timeline" displays individual tasks + interleaved with text and "plan" displays all tasks together. **kwargs: Additional arguments passed to the underlying API calls. Returns: @@ -2995,6 +3000,7 @@ async def chat_stream( thread_ts=thread_ts, recipient_team_id=recipient_team_id, recipient_user_id=recipient_user_id, + task_display_mode=task_display_mode, buffer_size=buffer_size, **kwargs, ) diff --git a/slack_sdk/web/chat_stream.py b/slack_sdk/web/chat_stream.py index acdac728..580f7cac 100644 --- a/slack_sdk/web/chat_stream.py +++ b/slack_sdk/web/chat_stream.py @@ -29,6 +29,7 @@ def __init__( buffer_size: int, recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, + task_display_mode: Optional[str] = None, **kwargs, ): """Initialize a new ChatStream instance. @@ -44,6 +45,8 @@ def __init__( recipient_team_id: The encoded ID of the team the user receiving the streaming text belongs to. Required when streaming to channels. recipient_user_id: The encoded ID of the user to receive the streaming text. Required when streaming to channels. + task_display_mode: Specifies how tasks are displayed in the message. A "timeline" displays individual tasks + interleaved with text and "plan" displays all tasks together. buffer_size: The length of markdown_text to buffer in-memory before calling a method. Increasing this value decreases the number of method calls made for the same amount of text, which is useful to avoid rate limits. **kwargs: Additional arguments passed to the underlying API calls. @@ -56,6 +59,7 @@ def __init__( "thread_ts": thread_ts, "recipient_team_id": recipient_team_id, "recipient_user_id": recipient_user_id, + "task_display_mode": task_display_mode, **kwargs, } self._buffer = "" diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py index 392a261a..638b4ab6 100644 --- a/slack_sdk/web/client.py +++ b/slack_sdk/web/client.py @@ -2879,6 +2879,7 @@ def chat_startStream( recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, chunks: Optional[Sequence[Union[Dict, Chunk]]] = None, + task_display_mode: Optional[str] = None, # timeline, plan **kwargs, ) -> SlackResponse: """Starts a new streaming conversation. @@ -2892,6 +2893,7 @@ def chat_startStream( "recipient_team_id": recipient_team_id, "recipient_user_id": recipient_user_id, "chunks": chunks, + "task_display_mode": task_display_mode, } ) _parse_web_class_objects(kwargs) @@ -2934,6 +2936,7 @@ def chat_stream( thread_ts: str, recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, + task_display_mode: Optional[str] = None, **kwargs, ) -> ChatStream: """Stream markdown text into a conversation. @@ -2960,6 +2963,8 @@ def chat_stream( recipient_team_id: The encoded ID of the team the user receiving the streaming text belongs to. Required when streaming to channels. recipient_user_id: The encoded ID of the user to receive the streaming text. Required when streaming to channels. + task_display_mode: Specifies how tasks are displayed in the message. A "timeline" displays individual tasks + interleaved with text and "plan" displays all tasks together. **kwargs: Additional arguments passed to the underlying API calls. Returns: @@ -2985,6 +2990,7 @@ def chat_stream( thread_ts=thread_ts, recipient_team_id=recipient_team_id, recipient_user_id=recipient_user_id, + task_display_mode=task_display_mode, buffer_size=buffer_size, **kwargs, ) diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index 7bb0609c..061be7c8 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -2890,6 +2890,7 @@ def chat_startStream( recipient_team_id: Optional[str] = None, recipient_user_id: Optional[str] = None, chunks: Optional[Sequence[Union[Dict, Chunk]]] = None, + task_display_mode: Optional[str] = None, # timeline, plan **kwargs, ) -> Union[Future, SlackResponse]: """Starts a new streaming conversation. @@ -2903,6 +2904,7 @@ def chat_startStream( "recipient_team_id": recipient_team_id, "recipient_user_id": recipient_user_id, "chunks": chunks, + "task_display_mode": task_display_mode, } ) _parse_web_class_objects(kwargs) diff --git a/tests/slack_sdk/web/test_chat_stream.py b/tests/slack_sdk/web/test_chat_stream.py index a6d84676..0a11b9d5 100644 --- a/tests/slack_sdk/web/test_chat_stream.py +++ b/tests/slack_sdk/web/test_chat_stream.py @@ -185,6 +185,7 @@ def test_streams_a_chunk_message(self): recipient_team_id="T0123456789", recipient_user_id="U0123456789", thread_ts="123.000", + task_display_mode="timeline", ) streamer.append(markdown_text="**this is ") streamer.append(markdown_text="buffered**") @@ -223,6 +224,7 @@ def test_streams_a_chunk_message(self): ) self.assertEqual(start_request.get("recipient_team_id"), "T0123456789") self.assertEqual(start_request.get("recipient_user_id"), "U0123456789") + self.assertEqual(start_request.get("task_display_mode"), "timeline") append_request = self.thread.server.chat_stream_requests.get("/chat.appendStream", {}) self.assertEqual(append_request.get("channel"), "C0123456789")