@@ -86,6 +86,56 @@ async def handle_action(ack, agent: AsyncBoltAgent):
8686 assert response .status == 200
8787 await assert_target_called ()
8888
89+ @pytest .mark .asyncio
90+ async def test_agent_thread_ts_from_event_in_thread (self ):
91+ """Agent gets thread_ts from event when in a thread."""
92+ app = AsyncApp (client = self .web_client )
93+
94+ state = {"thread_ts" : None }
95+
96+ async def assert_target_called ():
97+ count = 0
98+ while state ["thread_ts" ] is None and count < 20 :
99+ await asyncio .sleep (0.1 )
100+ count += 1
101+ assert state ["thread_ts" ] is not None
102+
103+ @app .event ("app_mention" )
104+ async def handle_mention (agent : AsyncBoltAgent ):
105+ state ["thread_ts" ] = agent ._thread_ts
106+
107+ request = AsyncBoltRequest (body = app_mention_in_thread_body , mode = "socket_mode" )
108+ response = await app .async_dispatch (request )
109+ assert response .status == 200
110+ await assert_target_called ()
111+ # Should use event.thread_ts (the thread root), not event.ts
112+ assert state ["thread_ts" ] == "1111111111.111111"
113+
114+ @pytest .mark .asyncio
115+ async def test_agent_thread_ts_falls_back_to_ts (self ):
116+ """Agent falls back to event.ts when not in a thread."""
117+ app = AsyncApp (client = self .web_client )
118+
119+ state = {"thread_ts" : None }
120+
121+ async def assert_target_called ():
122+ count = 0
123+ while state ["thread_ts" ] is None and count < 20 :
124+ await asyncio .sleep (0.1 )
125+ count += 1
126+ assert state ["thread_ts" ] is not None
127+
128+ @app .event ("app_mention" )
129+ async def handle_mention (agent : AsyncBoltAgent ):
130+ state ["thread_ts" ] = agent ._thread_ts
131+
132+ request = AsyncBoltRequest (body = app_mention_event_body , mode = "socket_mode" )
133+ response = await app .async_dispatch (request )
134+ assert response .status == 200
135+ await assert_target_called ()
136+ # Should fall back to event.ts since no thread_ts
137+ assert state ["thread_ts" ] == "1234567890.123456"
138+
89139 @pytest .mark .asyncio
90140 async def test_agent_kwarg_emits_experimental_warning (self ):
91141 app = AsyncApp (client = self .web_client )
@@ -147,6 +197,18 @@ def build_payload(event: dict) -> dict:
147197 }
148198)
149199
200+ app_mention_in_thread_body = build_payload (
201+ {
202+ "type" : "app_mention" ,
203+ "user" : "W222" ,
204+ "text" : "<@W111> hello in thread" ,
205+ "ts" : "2222222222.222222" ,
206+ "thread_ts" : "1111111111.111111" , # Thread root timestamp
207+ "channel" : "C111" ,
208+ "event_ts" : "2222222222.222222" ,
209+ }
210+ )
211+
150212action_event_body = {
151213 "type" : "block_actions" ,
152214 "user" : {"id" : "W222" , "username" : "test_user" , "name" : "test_user" , "team_id" : "T111" },
0 commit comments