fix(assistant): improve middleware dispatch and inject kwargs in middleware#1456
fix(assistant): improve middleware dispatch and inject kwargs in middleware#1456WilliamBergamin wants to merge 5 commits intomainfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1456 +/- ##
==========================================
+ Coverage 90.67% 91.15% +0.48%
==========================================
Files 226 229 +3
Lines 7205 7262 +57
==========================================
+ Hits 6533 6620 +87
+ Misses 672 642 -30 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
good catch on process() skipping listener-level middleware! keeping the AttachingAssistantKwargs seperate from generic context makes the assistant code much cleaner 🫧 .
my only recommendation would be to add a changelog 🦋 for users who rely on getting thread_ts in non assistant listeners 🤔
for example - @mention -ing the app in a channel thread. if you start a thread on a regular message, then @mention the bot in that thread the handle_mention listener's say() posts to the channel (not the thread), because thread_ts is no longer injected into say for non-assistant listeners
| """ | ||
| if "say" not in self: | ||
| self["say"] = Say(client=self.client, channel=self.channel_id, thread_ts=self.thread_ts) | ||
| self["say"] = Say(client=self.client, channel=self.channel_id) |
There was a problem hiding this comment.
🌟 praise: In agreement with @srtaalej this is a good change - the thread_ts attempted before was not set at this point in execution. Now we want to avoid changing this behavior while still improving the available context values. Solid!
| from slack_bolt.response.response import BoltResponse | ||
|
|
||
|
|
||
| class AttachingAssistantKwargs(Middleware): |
There was a problem hiding this comment.
great to see this consolidated into one file ⭐
I understand your concern around the @mention -ing the app in a channel thread, but from my testing this behavior was not present, looking at the implementation of extract_thread_ts, But I agree its worth calling out in the changelog that some undocumented behaviors around |
|
@srtaalej these are good concerns 💯 in a follow up PR I will address these concerns |
zimeg
left a comment
There was a problem hiding this comment.
@WilliamBergamin Awesome separation of middleware! Testing went well for me and these patterns are looking good to me 🚢
I left a question about the scope of middleware but this might be a misunderstanding I have in how events are processed.
📣 We might want to callout that context.thread_ts is available more often now in CHANGELOG entries too but I don't know if this is documented elsewhere so no blocker!
| """ | ||
| if "say" not in self: | ||
| self["say"] = Say(client=self.client, channel=self.channel_id, thread_ts=self.thread_ts) | ||
| self["say"] = Say(client=self.client, channel=self.channel_id) |
There was a problem hiding this comment.
🌟 praise: In agreement with @srtaalej this is a good change - the thread_ts attempted before was not set at this point in execution. Now we want to avoid changing this behavior while still improving the available context values. Solid!
| # This means the listener is not for this incoming request. | ||
| continue | ||
| if middleware_resp is not None: | ||
| resp = middleware_resp |
There was a problem hiding this comment.
👁️🗨️ question: Was middleware not handled for the assistant listener? I'm curious if app.py#L907 is a sufficient addition or if this is also needed? I haven't given detailed look to this, but I understood the order:
- Global middleware
- Listener middleware
And it's not clear to me if the global middleware is sufficient or if this is gives us confidence that listeners for the assistant class has these arguments in all cases?
| if payload.get("event") is not None: | ||
| return extract_thread_ts(payload["event"]) |
| def start_thread(say: Say, set_suggested_prompts: SetSuggestedPrompts, context: BoltContext): | ||
| assert context.channel_id == "D111" | ||
| assert context.thread_ts == "1726133698.626339" | ||
| assert say.thread_ts == context.thread_ts |
There was a problem hiding this comment.
🧪 praise: Thanks for adding asserts!
Summary
say,set_status,set_title,set_suggested_prompts,get_thread_context,save_thread_context) fromApp._init_context/AsyncApp._init_contextintodedicated listener middleware (
AttachingAssistantKwargs/AsyncAttachingAssistantKwargs)extract_thread_tsto work for all event types (not just assistant events), populatingcontext.thread_tsfor any threaded eventthread_tsfrom the defaultSayconstructor inBoltContext.say— assistant threading is now handled entirely by the Assistant middlewareTesting
Category
slack_bolt.Appand/or its core componentsslack_bolt.async_app.AsyncAppand/or its core componentsslack_bolt.adapter/docsRequirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.
./scripts/install_all_and_run_tests.shafter making the changes.