Skip to content

Commit 256388c

Browse files
WilliamBergaminClaude
andauthored
feat: widen set_suggested_prompts initialization scope to any DM (#1549)
Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
1 parent 8fbd503 commit 256388c

12 files changed

Lines changed: 634 additions & 132 deletions

File tree

slack_bolt/context/assistant/assistant_utilities.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import warnings
21
from typing import Optional
32

43
from slack_sdk.web import WebClient
@@ -11,8 +10,6 @@
1110
from .internals import has_channel_id_and_thread_ts
1211
from ..get_thread_context.get_thread_context import GetThreadContext
1312
from ..save_thread_context import SaveThreadContext
14-
from ..set_status import SetStatus
15-
from ..set_suggested_prompts import SetSuggestedPrompts
1613
from ..set_title import SetTitle
1714

1815

@@ -47,28 +44,10 @@ def __init__(
4744
# When moving this code to Bolt internals, no need to raise an exception for this pattern
4845
raise ValueError(f"Cannot instantiate Assistant for this event pattern ({self.payload})")
4946

50-
def is_valid(self) -> bool:
51-
return self.channel_id is not None and self.thread_ts is not None
52-
53-
@property
54-
def set_status(self) -> SetStatus:
55-
warnings.warn(
56-
"AssistantUtilities.set_status is deprecated. "
57-
"Use the set_status argument directly in your listener function "
58-
"or access it via context.set_status instead.",
59-
DeprecationWarning,
60-
stacklevel=2,
61-
)
62-
return SetStatus(self.client, self.channel_id, self.thread_ts)
63-
6447
@property
6548
def set_title(self) -> SetTitle:
6649
return SetTitle(self.client, self.channel_id, self.thread_ts)
6750

68-
@property
69-
def set_suggested_prompts(self) -> SetSuggestedPrompts:
70-
return SetSuggestedPrompts(self.client, self.channel_id, self.thread_ts)
71-
7251
@property
7352
def say(self) -> Say:
7453
def build_metadata() -> Optional[dict]:

slack_bolt/context/assistant/async_assistant_utilities.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import warnings
21
from typing import Optional
32

43
from slack_sdk.web.async_client import AsyncWebClient
@@ -14,8 +13,6 @@
1413
from .internals import has_channel_id_and_thread_ts
1514
from ..get_thread_context.async_get_thread_context import AsyncGetThreadContext
1615
from ..save_thread_context.async_save_thread_context import AsyncSaveThreadContext
17-
from ..set_status.async_set_status import AsyncSetStatus
18-
from ..set_suggested_prompts.async_set_suggested_prompts import AsyncSetSuggestedPrompts
1916
from ..set_title.async_set_title import AsyncSetTitle
2017

2118

@@ -50,28 +47,10 @@ def __init__(
5047
# When moving this code to Bolt internals, no need to raise an exception for this pattern
5148
raise ValueError(f"Cannot instantiate Assistant for this event pattern ({self.payload})")
5249

53-
def is_valid(self) -> bool:
54-
return self.channel_id is not None and self.thread_ts is not None
55-
56-
@property
57-
def set_status(self) -> AsyncSetStatus:
58-
warnings.warn(
59-
"AsyncAssistantUtilities.set_status is deprecated. "
60-
"Use the set_status argument directly in your listener function "
61-
"or access it via context.set_status instead.",
62-
DeprecationWarning,
63-
stacklevel=2,
64-
)
65-
return AsyncSetStatus(self.client, self.channel_id, self.thread_ts)
66-
6750
@property
6851
def set_title(self) -> AsyncSetTitle:
6952
return AsyncSetTitle(self.client, self.channel_id, self.thread_ts)
7053

71-
@property
72-
def set_suggested_prompts(self) -> AsyncSetSuggestedPrompts:
73-
return AsyncSetSuggestedPrompts(self.client, self.channel_id, self.thread_ts)
74-
7554
@property
7655
def say(self) -> AsyncSay:
7756
return AsyncSay(

slack_bolt/context/set_suggested_prompts/async_set_suggested_prompts.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
class AsyncSetSuggestedPrompts:
88
client: AsyncWebClient
99
channel_id: str
10-
thread_ts: str
10+
thread_ts: Optional[str]
1111

1212
def __init__(
1313
self,
1414
client: AsyncWebClient,
1515
channel_id: str,
16-
thread_ts: str,
16+
thread_ts: Optional[str] = None,
1717
):
1818
self.client = client
1919
self.channel_id = channel_id
@@ -23,6 +23,7 @@ async def __call__(
2323
self,
2424
prompts: Sequence[Union[str, Dict[str, str]]],
2525
title: Optional[str] = None,
26+
thread_ts: Optional[str] = None,
2627
) -> AsyncSlackResponse:
2728
prompts_arg: List[Dict[str, str]] = []
2829
for prompt in prompts:
@@ -33,7 +34,7 @@ async def __call__(
3334

3435
return await self.client.assistant_threads_setSuggestedPrompts(
3536
channel_id=self.channel_id,
36-
thread_ts=self.thread_ts,
37+
thread_ts=thread_ts if thread_ts is not None else self.thread_ts,
3738
prompts=prompts_arg,
3839
title=title,
3940
)

slack_bolt/context/set_suggested_prompts/set_suggested_prompts.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
class SetSuggestedPrompts:
88
client: WebClient
99
channel_id: str
10-
thread_ts: str
10+
thread_ts: Optional[str]
1111

1212
def __init__(
1313
self,
1414
client: WebClient,
1515
channel_id: str,
16-
thread_ts: str,
16+
thread_ts: Optional[str] = None,
1717
):
1818
self.client = client
1919
self.channel_id = channel_id
@@ -23,6 +23,7 @@ def __call__(
2323
self,
2424
prompts: Sequence[Union[str, Dict[str, str]]],
2525
title: Optional[str] = None,
26+
thread_ts: Optional[str] = None,
2627
) -> SlackResponse:
2728
prompts_arg: List[Dict[str, str]] = []
2829
for prompt in prompts:
@@ -33,7 +34,7 @@ def __call__(
3334

3435
return self.client.assistant_threads_setSuggestedPrompts(
3536
channel_id=self.channel_id,
36-
thread_ts=self.thread_ts,
37+
thread_ts=thread_ts if thread_ts is not None else self.thread_ts,
3738
prompts=prompts_arg,
3839
title=title,
3940
)

slack_bolt/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.py

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@
44
from slack_bolt.context.assistant.thread_context_store.async_store import AsyncAssistantThreadContextStore
55
from slack_bolt.context.say_stream.async_say_stream import AsyncSayStream
66
from slack_bolt.context.set_status.async_set_status import AsyncSetStatus
7+
from slack_bolt.context.set_suggested_prompts.async_set_suggested_prompts import AsyncSetSuggestedPrompts
78
from slack_bolt.middleware.async_middleware import AsyncMiddleware
89
from slack_bolt.request.async_request import AsyncBoltRequest
9-
from slack_bolt.request.payload_utils import is_assistant_event, to_event
10+
from slack_bolt.request.payload_utils import (
11+
is_app_home_opened_event,
12+
is_assistant_event,
13+
is_assistant_thread_context_changed_event,
14+
is_assistant_thread_started_event,
15+
is_im_message_event,
16+
to_event,
17+
)
1018
from slack_bolt.response import BoltResponse
1119

1220

@@ -25,32 +33,48 @@ async def async_process(
2533
next: Callable[[], Awaitable[BoltResponse]],
2634
) -> Optional[BoltResponse]:
2735
event = to_event(req.body)
28-
if event is not None:
29-
if is_assistant_event(req.body):
30-
assistant = AsyncAssistantUtilities(
31-
payload=event,
32-
context=req.context,
33-
thread_context_store=self.thread_context_store,
34-
)
35-
req.context["say"] = assistant.say
36-
req.context["set_title"] = assistant.set_title
37-
req.context["set_suggested_prompts"] = assistant.set_suggested_prompts
38-
req.context["get_thread_context"] = assistant.get_thread_context
39-
req.context["save_thread_context"] = assistant.save_thread_context
40-
41-
# TODO: in the future we might want to introduce a "proper" extract_ts utility
42-
thread_ts = req.context.thread_ts or event.get("ts")
43-
if req.context.channel_id and thread_ts:
44-
req.context["set_status"] = AsyncSetStatus(
45-
client=req.context.client,
46-
channel_id=req.context.channel_id,
47-
thread_ts=thread_ts,
48-
)
49-
req.context["say_stream"] = AsyncSayStream(
50-
client=req.context.client,
51-
channel=req.context.channel_id,
52-
recipient_team_id=req.context.team_id or req.context.enterprise_id,
53-
recipient_user_id=req.context.user_id,
54-
thread_ts=thread_ts,
55-
)
36+
if event is None:
37+
return await next()
38+
if req.context.channel_id is None:
39+
return await next()
40+
41+
if is_assistant_event(req.body):
42+
# TODO: eventually we might remove this assistant specific logic
43+
assistant = AsyncAssistantUtilities(
44+
payload=event,
45+
context=req.context,
46+
thread_context_store=self.thread_context_store,
47+
)
48+
req.context["say"] = assistant.say
49+
req.context["set_title"] = assistant.set_title
50+
req.context["get_thread_context"] = assistant.get_thread_context
51+
req.context["save_thread_context"] = assistant.save_thread_context
52+
53+
if (
54+
is_im_message_event(req.body)
55+
or is_assistant_thread_started_event(req.body)
56+
or is_assistant_thread_context_changed_event(req.body)
57+
or is_app_home_opened_event(req.body, tab="messages")
58+
):
59+
req.context["set_suggested_prompts"] = AsyncSetSuggestedPrompts(
60+
client=req.context.client,
61+
channel_id=req.context.channel_id,
62+
thread_ts=req.context.thread_ts,
63+
)
64+
65+
# TODO: in the future we might want to introduce a "proper" extract_ts utility
66+
thread_ts_or_ts = req.context.thread_ts or event.get("ts")
67+
if thread_ts_or_ts:
68+
req.context["set_status"] = AsyncSetStatus(
69+
client=req.context.client,
70+
channel_id=req.context.channel_id,
71+
thread_ts=thread_ts_or_ts,
72+
)
73+
req.context["say_stream"] = AsyncSayStream(
74+
client=req.context.client,
75+
channel=req.context.channel_id,
76+
recipient_team_id=req.context.team_id or req.context.enterprise_id,
77+
recipient_user_id=req.context.user_id,
78+
thread_ts=thread_ts_or_ts,
79+
)
5680
return await next()
Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
from typing import Optional, Callable
22

3-
from slack_bolt.context.assistant.assistant_utilities import AssistantUtilities
43
from slack_bolt.context.assistant.thread_context_store.store import AssistantThreadContextStore
54
from slack_bolt.context.say_stream.say_stream import SayStream
65
from slack_bolt.context.set_status.set_status import SetStatus
6+
from slack_bolt.context.set_suggested_prompts.set_suggested_prompts import SetSuggestedPrompts
77
from slack_bolt.middleware import Middleware
8-
from slack_bolt.request.payload_utils import is_assistant_event, to_event
8+
from slack_bolt.context.assistant.assistant_utilities import AssistantUtilities
9+
from slack_bolt.request.payload_utils import (
10+
is_app_home_opened_event,
11+
is_assistant_event,
12+
is_assistant_thread_context_changed_event,
13+
is_assistant_thread_started_event,
14+
is_im_message_event,
15+
to_event,
16+
)
917
from slack_bolt.request.request import BoltRequest
1018
from slack_bolt.response.response import BoltResponse
1119

@@ -19,32 +27,48 @@ def __init__(self, thread_context_store: Optional[AssistantThreadContextStore] =
1927

2028
def process(self, *, req: BoltRequest, resp: BoltResponse, next: Callable[[], BoltResponse]) -> Optional[BoltResponse]:
2129
event = to_event(req.body)
22-
if event is not None:
23-
if is_assistant_event(req.body):
24-
assistant = AssistantUtilities(
25-
payload=event,
26-
context=req.context,
27-
thread_context_store=self.thread_context_store,
28-
)
29-
req.context["say"] = assistant.say
30-
req.context["set_title"] = assistant.set_title
31-
req.context["set_suggested_prompts"] = assistant.set_suggested_prompts
32-
req.context["get_thread_context"] = assistant.get_thread_context
33-
req.context["save_thread_context"] = assistant.save_thread_context
34-
35-
# TODO: in the future we might want to introduce a "proper" extract_ts utility
36-
thread_ts = req.context.thread_ts or event.get("ts")
37-
if req.context.channel_id and thread_ts:
38-
req.context["set_status"] = SetStatus(
39-
client=req.context.client,
40-
channel_id=req.context.channel_id,
41-
thread_ts=thread_ts,
42-
)
43-
req.context["say_stream"] = SayStream(
44-
client=req.context.client,
45-
channel=req.context.channel_id,
46-
recipient_team_id=req.context.team_id or req.context.enterprise_id,
47-
recipient_user_id=req.context.user_id,
48-
thread_ts=thread_ts,
49-
)
30+
if event is None:
31+
return next()
32+
if req.context.channel_id is None:
33+
return next()
34+
35+
if is_assistant_event(req.body):
36+
# TODO: eventually we might remove this assistant specific logic
37+
assistant = AssistantUtilities(
38+
payload=event,
39+
context=req.context,
40+
thread_context_store=self.thread_context_store,
41+
)
42+
req.context["say"] = assistant.say
43+
req.context["set_title"] = assistant.set_title
44+
req.context["get_thread_context"] = assistant.get_thread_context
45+
req.context["save_thread_context"] = assistant.save_thread_context
46+
47+
if (
48+
is_im_message_event(req.body)
49+
or is_assistant_thread_started_event(req.body)
50+
or is_assistant_thread_context_changed_event(req.body)
51+
or is_app_home_opened_event(req.body, tab="messages")
52+
):
53+
req.context["set_suggested_prompts"] = SetSuggestedPrompts(
54+
client=req.context.client,
55+
channel_id=req.context.channel_id,
56+
thread_ts=req.context.thread_ts,
57+
)
58+
59+
# TODO: in the future we might want to introduce a "proper" extract_ts utility
60+
thread_ts_or_ts = req.context.thread_ts or event.get("ts")
61+
if thread_ts_or_ts:
62+
req.context["set_status"] = SetStatus(
63+
client=req.context.client,
64+
channel_id=req.context.channel_id,
65+
thread_ts=thread_ts_or_ts,
66+
)
67+
req.context["say_stream"] = SayStream(
68+
client=req.context.client,
69+
channel=req.context.channel_id,
70+
recipient_team_id=req.context.team_id or req.context.enterprise_id,
71+
recipient_user_id=req.context.user_id,
72+
thread_ts=thread_ts_or_ts,
73+
)
5074
return next()

0 commit comments

Comments
 (0)