From 069bf005b21150dea5171e518b4562c850f68e44 Mon Sep 17 00:00:00 2001 From: Andrew Huang Date: Mon, 13 May 2024 17:09:41 -0700 Subject: [PATCH] Propagate message params --- examples/reference/chat/ChatFeed.ipynb | 17 ++++++++++++++--- panel/chat/feed.py | 15 +++++++++++++-- panel/tests/chat/test_feed.py | 9 ++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/examples/reference/chat/ChatFeed.ipynb b/examples/reference/chat/ChatFeed.ipynb index cf3fc7e2b3..9a64d1329e 100644 --- a/examples/reference/chat/ChatFeed.ipynb +++ b/examples/reference/chat/ChatFeed.ipynb @@ -116,7 +116,12 @@ "metadata": {}, "outputs": [], "source": [ - "message = chat_feed.send(\"Hello world!\", user=\"Bot\", avatar=\"B\")" + "message = chat_feed.send(\n", + " \"Hello world!\",\n", + " user=\"Bot\",\n", + " avatar=\"B\",\n", + " footer_objects=[pn.widgets.Button(name=\"Footer Object\")],\n", + ")" ] }, { @@ -148,7 +153,7 @@ "metadata": {}, "outputs": [], "source": [ - "message = chat_feed.send({\"object\": \"Welcome!\", \"user\": \"Bot\", \"avatar\": \"B\"})" + "message = chat_feed.send({\"object\": \"Welcome!\", \"user\": \"Bot\", \"avatar\": \"B\", \"footer_objects\": [pn.widgets.Button(name=\"Footer Object\")]})" ] }, { @@ -850,7 +855,13 @@ "outputs": [], "source": [ "# streams (appends) to the previous message\n", - "message = chat_feed.stream(\" World!\", user=\"Aspiring User\", avatar=\"🤓\", message=message)" + "message = chat_feed.stream(\n", + " \" World!\",\n", + " user=\"Aspiring User\",\n", + " avatar=\"🤓\",\n", + " message=message,\n", + " footer_objects=[pn.widgets.Button(name=\"Footer Object\")],\n", + ")" ] }, { diff --git a/panel/chat/feed.py b/panel/chat/feed.py index a6c400c9b3..9479c624e6 100644 --- a/panel/chat/feed.py +++ b/panel/chat/feed.py @@ -346,6 +346,7 @@ def _build_message( value: dict, user: str | None = None, avatar: str | bytes | BytesIO | None = None, + **input_message_params ) -> ChatMessage | None: """ Builds a ChatMessage from the value. @@ -366,6 +367,7 @@ def _build_message( message_params["avatar"] = avatar if self.width: message_params["width"] = int(self.width - 80) + message_params.update(input_message_params) message = ChatMessage(**message_params) return message @@ -568,6 +570,7 @@ def send( user: str | None = None, avatar: str | bytes | BytesIO | None = None, respond: bool = True, + **message_params ) -> ChatMessage | None: """ Sends a value and creates a new message in the chat log. @@ -584,6 +587,8 @@ def send( The avatar to use; overrides the message message's avatar if provided. respond : bool Whether to execute the callback. + message_params : dict + Additional parameters to pass to the ChatMessage. Returns ------- @@ -599,7 +604,7 @@ def send( else: if not isinstance(value, dict): value = {"object": value} - message = self._build_message(value, user=user, avatar=avatar) + message = self._build_message(value, user=user, avatar=avatar, **message_params) self.append(message) self.param.trigger("_post_hook_trigger") if respond: @@ -613,6 +618,7 @@ def stream( avatar: str | bytes | BytesIO | None = None, message: ChatMessage | None = None, replace: bool = False, + **message_params ) -> ChatMessage | None: """ Streams a token and updates the provided message, if provided. @@ -635,6 +641,8 @@ def stream( The message to update. replace : bool Whether to replace the existing text when streaming a string or dict. + message_params : dict + Additional parameters to pass to the ChatMessage. Returns ------- @@ -657,6 +665,9 @@ def stream( message.avatar = avatar else: message.update(value, user=user, avatar=avatar) + + if message_params: + message.param.update(**message_params) return message if isinstance(value, ChatMessage): @@ -664,7 +675,7 @@ def stream( else: if not isinstance(value, dict): value = {"object": value} - message = self._build_message(value, user=user, avatar=avatar) + message = self._build_message(value, user=user, avatar=avatar, **message_params) self._replace_placeholder(message) self.param.trigger("_post_hook_trigger") diff --git a/panel/tests/chat/test_feed.py b/panel/tests/chat/test_feed.py index 3a17249592..9fa128253b 100644 --- a/panel/tests/chat/test_feed.py +++ b/panel/tests/chat/test_feed.py @@ -69,10 +69,11 @@ def test_card_params(self, chat_feed): assert not chat_feed._card.hide_header def test_send(self, chat_feed): - message = chat_feed.send("Message") + message = chat_feed.send("Message", footer_objects=[HTML("Footer")]) wait_until(lambda: len(chat_feed.objects) == 1) assert chat_feed.objects[0] is message assert chat_feed.objects[0].object == "Message" + assert chat_feed.objects[0].footer_objects[0].object == "Footer" def test_link_chat_log_objects(self, chat_feed): chat_feed.send("Message") @@ -164,21 +165,23 @@ def test_respond_without_callback(self, chat_feed): chat_feed.respond() # Should not raise any errors def test_stream(self, chat_feed): - message = chat_feed.stream("Streaming message", user="Person", avatar="P") + message = chat_feed.stream("Streaming message", user="Person", avatar="P", footer_objects=[HTML("Footer")]) assert len(chat_feed.objects) == 1 assert chat_feed.objects[0] is message assert chat_feed.objects[0].object == "Streaming message" assert chat_feed.objects[0].user == "Person" assert chat_feed.objects[0].avatar == "P" + assert chat_feed.objects[0].footer_objects[0].object == "Footer" updated_entry = chat_feed.stream( - " Appended message", user="New Person", message=message, avatar="N" + " Appended message", user="New Person", message=message, avatar="N", footer_objects=[HTML("New Footer")] ) wait_until(lambda: len(chat_feed.objects) == 1) assert chat_feed.objects[0] is updated_entry assert chat_feed.objects[0].object == "Streaming message Appended message" assert chat_feed.objects[0].user == "New Person" assert chat_feed.objects[0].avatar == "N" + assert chat_feed.objects[0].footer_objects[0].object == "New Footer" new_entry = chat_feed.stream("New message") wait_until(lambda: len(chat_feed.objects) == 2)