diff --git a/docs/features/plugin/functions/action.mdx b/docs/features/plugin/functions/action.mdx new file mode 100644 index 0000000..969eeed --- /dev/null +++ b/docs/features/plugin/functions/action.mdx @@ -0,0 +1,52 @@ +--- +sidebar_position: 3 +title: "🎬 Action Function" +--- + +Action functions allow you to write custom buttons to the message toolbar for end users to interact +with. This feature enables more interactive messaging, enabling users to grant permission before a +task is performed, generate visualizations of structured data, download an audio snippet of chats, +and many other use cases. + +A scaffold of Action code can be found [in the community section](https://openwebui.com/f/hub/custom_action/). + +An example of a graph visualization Action can be seen in the video below. + +

+ + Graph Visualization Action + +

+ + +### Action +Actions are used to create a button in the Message UI (the small buttons found directly underneath individual chat messages). + +Actions have a single main component called an action function. This component takes an object defining the type of action and the data being processed. + +
+Example + +``` +async def action( + self, + body: dict, + __user__=None, + __event_emitter__=None, + __event_call__=None, + ) -> Optional[dict]: + print(f"action:{__name__}") + + response = await __event_call__( + { + "type": "input", + "data": { + "title": "write a message", + "message": "here write a message to append", + "placeholder": "enter your message", + }, + } + ) + print(response) +``` +
diff --git a/docs/features/plugin/functions/actions.md b/docs/features/plugin/functions/actions.md deleted file mode 100644 index ad0e12a..0000000 --- a/docs/features/plugin/functions/actions.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 6 -title: "🎬 Actions" ---- - -Action functions allow you to write custom buttons to the message toolbar for end users to interact -with. This feature enables more interactive messaging, enabling users to grant permission before a -task is performed, generate visualizations of structured data, download an audio snippet of chats, -and many other use cases. - -A scaffold of Action code can be found [in the community section](https://openwebui.com/f/hub/custom_action/). - -An example of a graph visualization Action can be seen in the video below. - -

- - Graph Visualization Action - -

diff --git a/docs/features/plugin/functions/filter.mdx b/docs/features/plugin/functions/filter.mdx new file mode 100644 index 0000000..4846ca5 --- /dev/null +++ b/docs/features/plugin/functions/filter.mdx @@ -0,0 +1,62 @@ +--- +sidebar_position: 2 +title: "🪄 Filter Function" +--- + + +### Filter +Filters are used to manipulate the user input and/or the LLM output to add, remove, format, or otherwise adjust the content of the body object. + +Filters have a few main components: + +#### Inlet Function +The inlet is user to pre-process a user input before it is send to the LLM for processing. + +#### Outlet Function +The outlet is used to post-process the output from the LLM. It is important to note that when you perform actions such as stripping/replacing content, this will happen after the output is rendered to the UI. + +
+Example + +``` +class Filter: + # Define and Valves + class Valves(BaseModel): + priority: int = Field( + default=0, description="Priority level for the filter operations." + ) + test_valve: int = Field( + default=4, description="A valve controlling a numberical value" + ) + pass + + # Define any UserValves + class UserValves(BaseModel): + test_user_valve: bool = Field( + default=False, description="A user valve controlling a True/False (on/off) switch" + ) + pass + + def __init__(self): + self.valves = self.Valves() + pass + + def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict: + print(f"inlet:{__name__}") + print(f"inlet:body:{body}") + print(f"inlet:user:{__user__}") + + # Pre-processing logic here + + return body + + def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict: + print(f"outlet:{__name__}") + print(f"outlet:body:{body}") + print(f"outlet:user:{__user__}") + + # Post-processing logic here + + return body +``` +
\ No newline at end of file diff --git a/docs/features/plugin/functions/index.mdx b/docs/features/plugin/functions/index.mdx index e65a260..1e1215e 100644 --- a/docs/features/plugin/functions/index.mdx +++ b/docs/features/plugin/functions/index.mdx @@ -3,361 +3,131 @@ sidebar_position: 1 title: "🧰 Functions" --- -## What are Functions? -Functions are modular operations that allow users to enhance the capabilities of the AI by embedding specific logic or actions directly into workflows. Unlike tools, which operate as external utilities, functions run natively within the OpenWebUI environment and handle tasks such as data processing, visualization, and interactive messaging. Functions are lightweight and designed to execute efficiently on the same server as the WebUI, enabling quick responses without the need for external dependencies. +## 🚀 What Are Functions? -## How can I use Functions? -Functions can be used, [once installed](#how-to-install-functions), by assigning them to an LLM or enabling them globally. Some function types will always be enabled globally, such as manifolds. To assign a function to a model, you simply need to navigate to Workspace => Models. Here you can select the model for which you’d like to enable any Functinos. - -Once you click the pencil icon to edit the model settings, scroll down to the Functions section and check any Functions you wish to enable. Once done you must click save. - -You also have the ability to enable Functions globally for ALL models. In order to do this, navigate to Workspace => Functions and click the "..." menu. Once the menu opens, simply enable the "Global" switch and your function will be enabled for every model in your OpenWebUI instance. -## How to install Functions -The Functions import process is quite simple. You will have two options: - -### Download and import manually -Navigate to the community site: https://openwebui.com/functions/ -1) Click on the Function you wish to import -2) Click the blue “Get” button in the top right-hand corner of the page -3) Click “Download as JSON export” -4) You can now upload the Funtion into OpenWebUI by navigating to Workspace => Functions and clicking “Import Functions - -### Import via your OpenWebUI URL -1) Navigate to the community site: https://openwebui.com/functions/ -2) Click on the Function you wish to import -3) Click the blue “Get” button in the top right-hand corner of the page -4) Enter the IP address of your OpenWebUI instance and click “Import to WebUI” which will automatically open your instance and allow you to import the Function. - -Note: You can install your own Function and other Functions not tracked on the community site using the manual import method. Please do not import Functions you do not understand or are not from a trustworthy source. Running unknown code is ALWAYS a risk. - -## What are the support types of functions -### Filter -Filters are used to manipulate the user input and/or the LLM output to add, remove, format, or otherwise adjust the content of the body object. - -Filters have a few main components: - -#### Inlet Function -The inlet is user to pre-process a user input before it is send to the LLM for processing. - -#### Outlet Function -The outlet is used to post-process the output from the LLM. It is important to note that when you perform actions such as stripping/replacing content, this will happen after the output is rendered to the UI. - -
-Example - -``` -class Filter: - # Define and Valves - class Valves(BaseModel): - priority: int = Field( - default=0, description="Priority level for the filter operations." - ) - test_valve: int = Field( - default=4, description="A valve controlling a numberical value" - ) - pass - - # Define any UserValves - class UserValves(BaseModel): - test_user_valve: bool = Field( - default=False, description="A user valve controlling a True/False (on/off) switch" - ) - pass - - def __init__(self): - self.valves = self.Valves() - pass - - def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict: - print(f"inlet:{__name__}") - print(f"inlet:body:{body}") - print(f"inlet:user:{__user__}") - - # Pre-processing logic here - - return body - - def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict: - print(f"outlet:{__name__}") - print(f"outlet:body:{body}") - print(f"outlet:user:{__user__}") - - # Post-processing logic here - - return body -``` -
- -### Action -Actions are used to create a button in the Message UI (the small buttons found directly underneath individual chat messages). - -Actions have a single main component called an action function. This component takes an object defining the type of action and the data being processed. - -
-Example - -``` -async def action( - self, - body: dict, - __user__=None, - __event_emitter__=None, - __event_call__=None, - ) -> Optional[dict]: - print(f"action:{__name__}") - - response = await __event_call__( - { - "type": "input", - "data": { - "title": "write a message", - "message": "here write a message to append", - "placeholder": "enter your message", - }, - } - ) - print(response) -``` -
- -#### Pipes - -#### Pipe -A Pipe is used to create a "Model" with custom logic and processing. A Pipe will always show up as it's own singular model in the OpenWebUI interface and will, much like a filter - -A Pipe has a single main component called a pipe function. This component encapsulates all of the primary logic that the Pipe will perform. - -
-Example - -``` -class Pipe: - class Valves(BaseModel): - RANDOM_CONFIG_OPTION: str = Field(default="") - - def __init__(self): - self.type = "pipe" - self.id = "blah" - self.name = "Testing" - self.valves = self.Valves( - **{"RANDOM_CONFIG_OPTION": os.getenv("RANDOM_CONFIG_OPTION", "")} - ) - pass - - def get_provider_models(self): - return [ - {"id": "model_id_1", "name": "model_1"}, - {"id": "model_id_2", "name": "model_2"}, - {"id": "model_id_3", "name": "model_3"}, - ] - - def pipe(self, body: dict) -> Union[str, Generator, Iterator]: - # Logic goes here - return body -``` -
- -#### Manifold -A Manifold is used to create a collection of Pipes. If a Pipe creates a singular "Model", a Manifold creates a set of "Models." Manifolds are typically used to create integrations with other providers. - -A Manifold has two main components: - -##### Pipes Function -This is used to simply initiate a dictionary to hold all of the Pipes created by the manifold - -##### Pipe Function -As referenced above, this component encapsulates all of the primary logic that the Pipe will perform. - - -
-Example - -``` -class Pipe: - class Valves(BaseModel): - PROVIDER_API_KEY: str = Field(default="") - - def __init__(self): - self.type = "manifold" - self.id = "blah" - self.name = "Testing" - self.valves = self.Valves( - **{"PROVIDER_API_KEY": os.getenv("PROVIDER_API_KEY", "")} - ) - pass - - def get_provider_models(self): - return [ - {"id": "model_id_1", "name": "model_1"}, - {"id": "model_id_2", "name": "model_2"}, - {"id": "model_id_3", "name": "model_3"}, - ] - - def pipes(self) -> List[dict]: - return self.get_provider_models() - - def pipe(self, body: dict) -> Union[str, Generator, Iterator]: - # Logic goes here - return body -``` -
- -Note: To differentiate between a Pipe and a Manifold you will need to specify the type in def init: -``` -def __init__(self): - self.type = "pipe" - self.id = "blah" - self.name = "Testing" - pass -``` - -or - -``` -def __init__(self): - self.type = "manifold" - self.id = "blah" - self.name = "Testing/" - pass -``` - -## Shared Function Components - -### Valves and UserValves - (optional, but HIGHLY encouraged) - -Valves and UserValves are used to allow users to provide dyanmic details such as an API key or a configuration option. These will create a fillable field or a bool switch in the GUI menu for the given function. - -Valves are configurable by admins alone and UserValves are configurable by any users. - -
-Example - -``` -# Define and Valves - class Valves(BaseModel): - priority: int = Field( - default=0, description="Priority level for the filter operations." - ) - test_valve: int = Field( - default=4, description="A valve controlling a numberical value" - ) - pass - - # Define any UserValves - class UserValves(BaseModel): - test_user_valve: bool = Field( - default=False, description="A user valve controlling a True/False (on/off) switch" - ) - pass - - def __init__(self): - self.valves = self.Valves() - pass -``` -
- -### Event Emitters -Event Emitters are used to add additional information to the chat interface. Similarly to Filter Outlets, Event Emitters are capable of appending content to the chat. Unlike Filter Outlets, they are not capable of stripping information. Additionally, emitters can be activated at any stage during the function. - -There are two different types of Event Emitters: - -#### Status -This is used to add statuses to a message while it is performing steps. These can be done at any stage during the Function. These statuses appear right above the message content. These are very useful for Functions that delay the LLM response or process large amounts of information. This allows you to inform users what is being processed in real-time. - -``` -await __event_emitter__( - { - "type": "status", # We set the type here - "data": {"description": "Message that shows up in the chat", "done": False}, - # Note done is False here indicating we are still emitting statuses - } - ) -``` - -
-Example - -``` -async def test_function( - self, prompt: str, __user__: dict, __event_emitter__=None - ) -> str: - """ - This is a demo - - :param test: this is a test parameter - """ - - await __event_emitter__( - { - "type": "status", # We set the type here - "data": {"description": "Message that shows up in the chat", "done": False}, - # Note done is False here indicating we are still emitting statuses - } - ) - - # Do some other logic here - await __event_emitter__( - { - "type": "status", - "data": {"description": "Completed a task message", "done": True}, - # Note done is True here indicating we are done emitting statuses - } - ) - - except Exception as e: - await __event_emitter__( - { - "type": "status", - "data": {"description": f"An error occured: {e}", "done": True}, - } - ) - - return f"Tell the user: {e}" -``` -
- -#### Message -This type is used to append a message to the LLM at any stage in the Function. This means that you can append messages, embed images, and even render web pages before, or after, or during the LLM response. - -``` -await __event_emitter__( - { - "type": "message", # We set the type here - "data": {"content": "This message will be appended to the chat."}, - # Note that with message types we do NOT have to set a done condition - } - ) -``` - -
-Example - -``` -async def test_function( - self, prompt: str, __user__: dict, __event_emitter__=None - ) -> str: - """ - This is a demo - - :param test: this is a test parameter - """ - - await __event_emitter__( - { - "type": "message", # We set the type here - "data": {"content": "This message will be appended to the chat."}, - # Note that with message types we do NOT have to set a done condition - } - ) - - except Exception as e: - await __event_emitter__( - { - "type": "status", - "data": {"description": f"An error occured: {e}", "done": True}, - } - ) - - return f"Tell the user: {e}" -``` -
+Functions are like **plugins** for OpenWebUI. They help you **extend its capabilities**—whether it’s adding support for new AI models like Anthropic or Vertex AI, tweaking how messages are processed, or introducing custom buttons to the interface for better usability. + +Unlike external tools that may require complex integrations, **Functions are built-in and run within the OpenWebUI environment.** That means they are fast, modular, and don’t rely on external dependencies. + +Think of Functions as **modular building blocks** that let you enhance how the WebUI works, tailored exactly to what you need. They’re lightweight, highly customizable, and written in **pure Python**, so you have the freedom to create anything—from new AI-powered workflows to integrations with anything you use, like Google Search or Home Assistant. + +--- + +## 🏗️ Types of Functions + +There are **three types of Functions** in OpenWebUI, each with a specific purpose. Let’s break them down and explain exactly what they do: + +--- + +### 1. [**Pipe Function** – Create Custom "Models" ](./pipe.mdx) + +A **Pipe Function** is how you create **custom models** or integrations, which then appear in the interface as if they were standalone models. + +**What does it do?** +- Pipes let you define complex workflows. For instance, you could create a Pipe that sends data to **Model A** and **Model B**, processes their outputs, and combines the results into one finalized answer. +- Pipes don’t even have to use AI! They can be setups for **search APIs**, **weather data**, or even systems like **Home Assistant**. Basically, anything you’d like to interact with can become part of OpenWebUI. + +**Use case example:** +Imagine you want to query Google Search directly from OpenWebUI. You can create a Pipe Function that: +1. Takes your input. +2. Sends the query to Google Search’s API. +3. Processes the response and returns it to you inside the WebUI like a normal "model" response. + +When enabled, **Pipe Functions show up as their own selectable model**. Use Pipes whenever you need custom functionality that works like a model in the interface. + +For a detailed guide, see [**Pipe Functions**](./pipe.mdx). + +--- + +### 2. [**Filter Function** – Modify Inputs and Outputs](./filter.mdx) + +A **Filter Function** is like a tool for tweaking data before it gets sent to the AI **or** after it comes back. + +**What does it do?** +Filters act as "hooks" in the workflow and have two main parts: +- **Inlet**: Adjust the input that is sent to the model. For example, adding additional instructions, keywords, or formatting tweaks. +- **Outlet**: Modify the output that you receive from the model. For instance, cleaning up the response, adjusting tone, or formatting data into a specific style. + +**Use case example:** +Suppose you’re working on a project that needs precise formatting. You can use a Filter to ensure: +1. Your input is always transformed into the required format. +2. The output from the model is cleaned up before being displayed. + +Filters are **linked to specific models** or can be enabled for all models **globally**, depending on your needs. + +Check out the full guide for more examples and instructions: [**Filter Functions**](./filter.mdx). + +--- + +### 3. [**Action Function** – Add Custom Buttons](./action.mdx) + +An **Action Function** is used to add **custom buttons** to the chat interface. + +**What does it do?** +Actions allow you to define **interactive shortcuts** that trigger specific functionality directly from the chat. These buttons appear underneath individual chat messages, giving you convenient, one-click access to the actions you define. + +**Use case example:** +Let’s say you often need to summarize long messages or generate specific outputs like translations. You can create an Action Function to: +1. Add a “Summarize” button under every incoming message. +2. When clicked, it triggers your custom function to process that message and return the summary. + +Buttons provide a **clean and user-friendly way** to interact with extended functionality you define. + +Learn how to set them up in the [**Action Functions Guide**](./action.mdx). + +--- + +## 🛠️ How to Use Functions + +Here's how to put Functions to work in OpenWebUI: + +### 1. **Install Functions** +You can install Functions via the OpenWebUI interface or by importing them manually. + +⚠️ **Be cautious.** Only install Functions from trusted sources. Running unknown code poses security risks. + +--- + +### 2. **Enable Functions** +Functions must be explicitly enabled after installation: +- When you enable a **Pipe Function**, it becomes available as its own **model** in the interface. +- For **Filter** and **Action Functions**, enabling them isn’t enough—you also need to assign them to specific models or enable them globally for all models. + +--- + +### 3. **Assign Filters or Actions to Models** +- Navigate to `Workspace => Models` and assign your Filter or Action to the relevant model there. +- Alternatively, enable Functions for **all models globally** by going to `Workspace => Functions`, selecting the "..." menu, and toggling the **Global** switch. + +--- + +### Quick Summary +- **Pipes** appear as standalone models you can interact with. +- **Filters** modify inputs/outputs for smoother AI interactions. +- **Actions** add clickable buttons to individual chat messages. + +Once you’ve followed the setup process, Functions will seamlessly enhance your workflows. + +--- + +## ✅ Why Use Functions? + +Functions are designed for anyone who wants to **unlock new possibilities** with OpenWebUI: + +- **Extend**: Add new models or integrate with non-AI tools like APIs, databases, or smart devices. +- **Optimize**: Tweak inputs and outputs to fit your use case perfectly. +- **Simplify**: Add buttons or shortcuts to make the interface intuitive and efficient. + +Whether you’re customizing workflows for specific projects, integrating external data, or just making OpenWebUI easier to use, Functions are the key to taking control of your instance. + +--- + +### 📝 Final Notes: +1. Always install Functions from **trusted sources only**. +2. Make sure you understand the difference between Pipe, Filter, and Action Functions to use them effectively. +3. Explore the official guides: + - [Pipe Functions Guide](./pipe.mdx) + - [Filter Functions Guide](./filter.mdx) + - [Action Functions Guide](./action.mdx) + +By leveraging Functions, you’ll bring entirely new capabilities to your OpenWebUI setup. Start experimenting today! 🚀 \ No newline at end of file diff --git a/docs/features/plugin/functions/pipe.mdx b/docs/features/plugin/functions/pipe.mdx new file mode 100644 index 0000000..68318a3 --- /dev/null +++ b/docs/features/plugin/functions/pipe.mdx @@ -0,0 +1,109 @@ +--- +sidebar_position: 1 +title: "🚰 Pipe Function" +--- + + +import Common from './tab-shared/Common.md'; + + +#### Pipe +A Pipe is used to create a "Model" with custom logic and processing. A Pipe will always show up as it's own singular model in the OpenWebUI interface and will, much like a filter + +A Pipe has a single main component called a pipe function. This component encapsulates all of the primary logic that the Pipe will perform. + +
+Example + +``` +class Pipe: + class Valves(BaseModel): + RANDOM_CONFIG_OPTION: str = Field(default="") + + def __init__(self): + self.type = "pipe" + self.id = "blah" + self.name = "Testing" + self.valves = self.Valves( + **{"RANDOM_CONFIG_OPTION": os.getenv("RANDOM_CONFIG_OPTION", "")} + ) + pass + + def get_provider_models(self): + return [ + {"id": "model_id_1", "name": "model_1"}, + {"id": "model_id_2", "name": "model_2"}, + {"id": "model_id_3", "name": "model_3"}, + ] + + def pipe(self, body: dict) -> Union[str, Generator, Iterator]: + # Logic goes here + return body +``` +
+ +#### Manifold +A Manifold is used to create a collection of Pipes. If a Pipe creates a singular "Model", a Manifold creates a set of "Models." Manifolds are typically used to create integrations with other providers. + +A Manifold has two main components: + +##### Pipes Function +This is used to simply initiate a dictionary to hold all of the Pipes created by the manifold + +##### Pipe Function +As referenced above, this component encapsulates all of the primary logic that the Pipe will perform. + + +
+Example + +``` +class Pipe: + class Valves(BaseModel): + PROVIDER_API_KEY: str = Field(default="") + + def __init__(self): + self.type = "manifold" + self.id = "blah" + self.name = "Testing" + self.valves = self.Valves( + **{"PROVIDER_API_KEY": os.getenv("PROVIDER_API_KEY", "")} + ) + pass + + def get_provider_models(self): + return [ + {"id": "model_id_1", "name": "model_1"}, + {"id": "model_id_2", "name": "model_2"}, + {"id": "model_id_3", "name": "model_3"}, + ] + + def pipes(self) -> List[dict]: + return self.get_provider_models() + + def pipe(self, body: dict) -> Union[str, Generator, Iterator]: + # Logic goes here + return body +``` +
+ +Note: To differentiate between a Pipe and a Manifold you will need to specify the type in def init: +``` +def __init__(self): + self.type = "pipe" + self.id = "blah" + self.name = "Testing" + pass +``` + +or + +``` +def __init__(self): + self.type = "manifold" + self.id = "blah" + self.name = "Testing/" + pass +``` + + \ No newline at end of file diff --git a/docs/features/plugin/functions/tab-shared/Common.md b/docs/features/plugin/functions/tab-shared/Common.md new file mode 100644 index 0000000..d7c5e4d --- /dev/null +++ b/docs/features/plugin/functions/tab-shared/Common.md @@ -0,0 +1,140 @@ +## Shared Function Components + +### Valves and UserValves - (optional, but HIGHLY encouraged) + +Valves and UserValves are used to allow users to provide dyanmic details such as an API key or a configuration option. These will create a fillable field or a bool switch in the GUI menu for the given function. + +Valves are configurable by admins alone and UserValves are configurable by any users. + +
+Example + +``` +# Define and Valves + class Valves(BaseModel): + priority: int = Field( + default=0, description="Priority level for the filter operations." + ) + test_valve: int = Field( + default=4, description="A valve controlling a numberical value" + ) + pass + + # Define any UserValves + class UserValves(BaseModel): + test_user_valve: bool = Field( + default=False, description="A user valve controlling a True/False (on/off) switch" + ) + pass + + def __init__(self): + self.valves = self.Valves() + pass +``` +
+ +### Event Emitters +Event Emitters are used to add additional information to the chat interface. Similarly to Filter Outlets, Event Emitters are capable of appending content to the chat. Unlike Filter Outlets, they are not capable of stripping information. Additionally, emitters can be activated at any stage during the function. + +There are two different types of Event Emitters: + +#### Status +This is used to add statuses to a message while it is performing steps. These can be done at any stage during the Function. These statuses appear right above the message content. These are very useful for Functions that delay the LLM response or process large amounts of information. This allows you to inform users what is being processed in real-time. + +``` +await __event_emitter__( + { + "type": "status", # We set the type here + "data": {"description": "Message that shows up in the chat", "done": False}, + # Note done is False here indicating we are still emitting statuses + } + ) +``` + +
+Example + +``` +async def test_function( + self, prompt: str, __user__: dict, __event_emitter__=None + ) -> str: + """ + This is a demo + + :param test: this is a test parameter + """ + + await __event_emitter__( + { + "type": "status", # We set the type here + "data": {"description": "Message that shows up in the chat", "done": False}, + # Note done is False here indicating we are still emitting statuses + } + ) + + # Do some other logic here + await __event_emitter__( + { + "type": "status", + "data": {"description": "Completed a task message", "done": True}, + # Note done is True here indicating we are done emitting statuses + } + ) + + except Exception as e: + await __event_emitter__( + { + "type": "status", + "data": {"description": f"An error occured: {e}", "done": True}, + } + ) + + return f"Tell the user: {e}" +``` +
+ +#### Message +This type is used to append a message to the LLM at any stage in the Function. This means that you can append messages, embed images, and even render web pages before, or after, or during the LLM response. + +``` +await __event_emitter__( + { + "type": "message", # We set the type here + "data": {"content": "This message will be appended to the chat."}, + # Note that with message types we do NOT have to set a done condition + } + ) +``` + +
+Example + +``` +async def test_function( + self, prompt: str, __user__: dict, __event_emitter__=None + ) -> str: + """ + This is a demo + + :param test: this is a test parameter + """ + + await __event_emitter__( + { + "type": "message", # We set the type here + "data": {"content": "This message will be appended to the chat."}, + # Note that with message types we do NOT have to set a done condition + } + ) + + except Exception as e: + await __event_emitter__( + { + "type": "status", + "data": {"description": f"An error occured: {e}", "done": True}, + } + ) + + return f"Tell the user: {e}" +``` +
diff --git a/docs/features/plugin/tools/index.mdx b/docs/features/plugin/tools/index.mdx index c12373b..1bf6af3 100644 --- a/docs/features/plugin/tools/index.mdx +++ b/docs/features/plugin/tools/index.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 0 +sidebar_position: 2 title: "⚙️ Tools" ---