{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import panel as pn\n", "from panel_material_ui import ChatInterface\n", "\n", "pn.extension()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `ChatInterface` is a high-level layout, providing a user-friendly front-end interface for inputting different kinds of messages: text, images, PDFs, etc.\n", "\n", "This layout provides front-end methods to:\n", "\n", "- Input (append) messages to the chat log.\n", "- Re-run (resend) the most recent `user` input [`ChatMessage`](ChatMessage.ipynb).\n", "- Remove messages until the previous `user` input [`ChatMessage`](ChatMessage.ipynb).\n", "- Clear the chat log, erasing all [`ChatMessage`](ChatMessage.ipynb) objects.\n", "\n", "**Since `ChatInterface` inherits from [`ChatFeed`](ChatFeed.ipynb), it features all the capabilities of [`ChatFeed`](ChatFeed.ipynb); please see [ChatFeed.ipynb](ChatFeed.ipynb) for its backend capabilities.**\n", "\n", "Check out the [panel-chat-examples](https://holoviz-topics.github.io/panel-chat-examples/) docs to see applicable examples related to [LangChain](https://python.langchain.com/docs/get_started/introduction), [OpenAI](https://openai.com/blog/chatgpt), [Mistral](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjZtP35yvSBAxU00wIHHerUDZAQFnoECBEQAQ&url=https%3A%2F%2Fdocs.mistral.ai%2F&usg=AOvVaw2qpx09O_zOzSksgjBKiJY_&opi=89978449), [Llama](https://ai.meta.com/llama/), etc. If you have an example to demo, we'd love to add it to the panel-chat-examples gallery!\n", "\n", "\"Chat\n", "\n", "#### Parameters:\n", "\n", "##### Core\n", "\n", "* **`widgets`** (`Widget | List[Widget]`): Widgets to use for the input. If not provided, defaults to `[TextInput]`.\n", "* **`user`** (`str`): Name of the ChatInterface user.\n", "* **`avatar`** (`str | bytes | BytesIO | pn.pane.Image`): The avatar to use for the user. Can be a single character text, an emoji, or anything supported by `pn.pane.Image`. If not set, uses the first character of the name.\n", "* **`reset_on_send`** (`bool`): Whether to reset the widget's value after sending a message; has no effect for `TextInput`.\n", "* **`auto_send_types`** (`tuple`): The widget types to automatically send when the user presses enter or clicks away from the widget. If not provided, defaults to `[TextInput]`.\n", "* **`button_properties`** (`Dict[Dict[str, Any]]`): Allows addition of functionality or customization of buttons by supplying a mapping from the button name to a dictionary containing the `icon`, `callback`, `post_callback`, and/or `js_on_click` keys. \n", " * If the button names correspond to default buttons\n", "(send, rerun, undo, clear), the default icon can be\n", "updated and if a `callback` key value pair is provided,\n", "the specified callback functionality runs before the existing one.\n", " * For button names that don't match existing ones,\n", "new buttons are created and must include a\n", "`callback`, `post_callback`, and/or `js_on_click` key.\n", " * The provided callbacks should have a signature that accepts\n", "two positional arguments: instance (the ChatInterface instance)\n", "and event (the button click event).\n", " * The `js_on_click` key should be a str or dict. If str,\n", "provide the JavaScript code; else if dict, it must have a\n", "`code` key, containing the JavaScript code\n", "to execute when the button is clicked, and optionally an `args` key,\n", "containing dictionary of arguments to pass to the JavaScript\n", "code.\n", "\n", "##### Styling\n", "\n", "* **`show_send`** (`bool`): Whether to show the send button. Default is True.\n", "* **`show_stop`** (`bool`): Whether to show the stop button, temporarily replacing the send button during callback; has no effect if `callback` is not async.\n", "* **`show_rerun`** (`bool`): Whether to show the rerun button. Default is True.\n", "* **`show_undo`** (`bool`): Whether to show the undo button. Default is True.\n", "* **`show_clear`** (`bool`): Whether to show the clear button. Default is True.\n", "* **`show_button_name`** (`bool`): Whether to show the button name. Default is True.\n", "\n", "#### Properties:\n", "\n", "* **`active_widget`** (`Widget`): The currently active widget.\n", "* **`active`** (`int`): The currently active input widget tab index; -1 if there is only one widget available which is not in a tab.\n", "\n", "___" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Basics" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ChatInterface()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Although `ChatInterface` can be initialized without any arguments, it becomes much more useful, and interesting, with a `callback`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def even_or_odd(contents):\n", " if len(contents) % 2 == 0:\n", " return \"Even number of characters.\"\n", " return \"Odd number of characters.\"\n", "\n", "ChatInterface(callback=even_or_odd)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may also provide a more relevant, default `user` name and `avatar`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ChatInterface(\n", " callback=even_or_odd,\n", " user=\"Asker\",\n", " avatar=\"?\",\n", " callback_user=\"Counter\",\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Buttons\n", "\n", "Unlike the buttons in the `panel.chat.ChatInterface` the `panel_material_ui.chat.ChatInterface` folds the buttons into the so called speed-dial. You can still control which options are available using the `show_` options.\n", "\n", "If you're not using an LLM to respond, the `Rerun` button may not be practical so it can be hidden by setting `show_rerun=False`.\n", "\n", "The same can be done for other buttons including `show_undo`, and `show_clear`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_num(contents):\n", " if isinstance(contents, str):\n", " num = len(contents)\n", " else:\n", " num = contents\n", " return f\"Got {num}.\"\n", "\n", "ChatInterface(callback=get_num, show_rerun=False, show_undo=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "New buttons with custom functionality can be added to the input row through `button_properties`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def show_notice(instance, event):\n", " instance.send(\"This is how you add buttons!\", respond=False, user=\"System\")\n", "\n", "ChatInterface(\n", " button_properties={\"help\": {\"callback\": show_notice, \"icon\": \"help\"}}\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Default buttons can also be updated with custom behaviors, before using `callback` and after using `post_callback`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def run_before(instance, event):\n", " instance.send(\n", " \"This will be cleared so it won't show after clear!\",\n", " respond=False,\n", " user=\"System\",\n", " )\n", "\n", "\n", "def run_after(instance, event):\n", " instance.send(\"This will show after clear!\", respond=False, user=\"System\")\n", "\n", "\n", "ChatInterface(\n", " button_properties={\n", " \"clear\": {\"callback\": run_before, \"post_callback\": run_after, \"icon\": \"help\"}\n", " }\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Check out the [panel-chat-examples](https://holoviz-topics.github.io/panel-chat-examples/) docs for more examples related to [LangChain](https://python.langchain.com/docs/get_started/introduction), [OpenAI](https://openai.com/blog/chatgpt), [Mistral](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjZtP35yvSBAxU00wIHHerUDZAQFnoECBEQAQ&url=https%3A%2F%2Fdocs.mistral.ai%2F&usg=AOvVaw2qpx09O_zOzSksgjBKiJY_&opi=89978449), [Llama](https://ai.meta.com/llama/), etc.\n", "\n", "\n", "Also, since `ChatInterface` inherits from [`ChatFeed`](ChatFeed.ipynb), be sure to also read [ChatFeed.ipynb](ChatFeed.ipynb) to understand `ChatInterface`'s full potential!" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.2" } }, "nbformat": 4, "nbformat_minor": 4 }