-
-
Notifications
You must be signed in to change notification settings - Fork 20
Add mention detection to update_message #302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add mention detection to update_message #302
Conversation
|
Looks great @Abigayle-Mercer! Just left a minor comment about the argument name. |
This patch extends the mention detection functionality from add_message (added in PR jupyterlab#235) to update_message. This enables automatic @mention detection when messages are updated, which is particularly useful for streaming scenarios where message content is built incrementally. Changes: - Refactored mention detection logic into reusable _extract_mentions() helper method - Updated add_message to use the new helper method - Added mention detection to update_message that scans the complete message body - Added three test cases covering mention updates, append with mentions, and deduplication - Fixed regex pattern to use raw string to avoid SyntaxWarning The implementation ensures no duplicate mentions are added when the same message is updated multiple times, making it safe for streaming use cases.
brichet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Abigayle-Mercer for working on this.
I have some comments below.
| updated_msg = chat.get_message(msg_id) | ||
| assert updated_msg | ||
| # Should only have one mention despite appearing twice | ||
| assert set(updated_msg.mentions) == set([USER2.username]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK the set function returns unique elements, which would no prove that USER2 is not mentioned several times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thank you!
| return uid | ||
|
|
||
| def update_message(self, message: Message, append: bool = False): | ||
| def update_message(self, message: Message, append: bool = False, find_mentions: bool = False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC the expectation is to find the mentions for the last update of a streaming message.
Maybe in future we'd like to trigger other actions on the last update. I wonder if we should rename this parameter last_update or something similar to be more generic.
I also wonder if the default value should be True, to trigger the find_mentions by default when this is not a streaming message.
| def update_message(self, message: Message, append: bool = False, find_mentions: bool = False): | |
| def update_message(self, message: Message, append: bool = False, last_update: bool = True): |
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that it has been discussed and updated in another comment, with the opposite argument 😄
I still think that the default could be True, though, but don't have a strong opinion on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😆 I think you make a great point though, @brichet.
Maybe this should be more generic... like trigger_actions—where actions are a set of callbacks that get triggered when the message is updated. Right now, we can just hardcode a single action, finding mentions. This would allows us to expand that API to include other actions without changing this method signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think that the default could be
True
I wrestled with this a bit too. I think it should be False. The simple argument, is that keeps backwards compatibility. Right now, streaming doesn't ever parse the mentions, so this won't introduce unexpected behavior.
But the deeper reason is that if the developer is not explicit when using this API, it has the potential to trigger a bunch of actions repeatedly, unintendedly. While it's a bit more verbose in the downstream code, I think it's best to force folks to be explicit when triggering actions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Zsailer Are you suggesting something like this for now?
def update_message(self, message: Message, append: bool = False, trigger_actions: set[str] | None = None):
# Then inside:
if trigger_actions and 'mentions' in trigger_actions:
message.mentions = self._find_mentions(message.body)
And then down the road make trigger_actions be flexible callbacks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Abigayle-Mercer your suggestion sounds good to me, for full flexibility in the long run.
Perhaps trigger_actions could be a list rather than a set, converting it to a set at the beginning of the function in order to remove duplicate entries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the approach you took in the latest updates!
I don't think the set action is needed. I can imagine cases where people might actually pass a trigger that they want to happen twice... Let's leave it as a list like @brichet suggested.
… set() for better comparison
edc43a8 to
f6440ea
Compare
|
This looks great @Abigayle-Mercer! I like how you split out the Minor nitpick about the function name. Otherwise this LGTM! I can merge once you update. Thank you! |
This patch extends the mention detection functionality from add_message (added in PR #235) to
update_message, enabling automatic @mention detection when messages are updated. This is particularly useful forstreaming scenarios where message content is built incrementally, allowing personas to mention each other while streaming.
Changes:
find_mentions()function in utils.pyadd_messageto accepttrigger_actionsparameter (defaults to[find_mentions_callback]) to maintain expected behaviortrigger_actionsparameter toupdate_messagefor flexible callback executiontrigger_actionsparameterStreaming Support:
The new
trigger_actionsparameter provides flexible control over when mention extraction and notifications occur:update_message(chunk, append=True, trigger_actions=None)- defers mention extractionupdate_message(message, trigger_actions=[find_mentions_callback])- triggers mention extraction and persona notificationsThis callback-based approach ensures personas are only notified once when the complete message is ready, rather than on every incremental update. The
find_mentionsimplementation ensures no duplicatementions are added when messages are updated multiple times, making it safe for streaming use cases.
Extensibility:
The
trigger_actionsparameter accepts a list of callbacks, allowing consumers to register custom actions beyond mention detection. Each callback receives (message, chat) arguments and can inspect or modifymessage state before the update is committed.
Integration:
This PR enables a forthcoming jupyter-ai-contrib/jupyter-ai-persona-manager#11 to
stream_message()in BasePersona (jupyter-ai-persona-manager) that will leverage thetrigger_actionsparameter to properly handle @mentions in streaming responses. The companion PR will add a final
update_message(..., trigger_actions=[find_mentions_callback])call after streaming completes, ensuringmentioned personas are notified only when the full message is available.