📝 docs(custom-component.mdx): add documentation for custom components
🎨 style(custom.css): update styling for code blocks and sidebar in documentation
This commit is contained in:
parent
9a1c20d750
commit
6b7ab2aded
2 changed files with 338 additions and 11 deletions
317
docs/docs/guidelines/custom-component.mdx
Normal file
317
docs/docs/guidelines/custom-component.mdx
Normal file
|
|
@ -0,0 +1,317 @@
|
||||||
|
---
|
||||||
|
description: Custom Components
|
||||||
|
hide_table_of_contents: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Custom Components
|
||||||
|
|
||||||
|
A Custom Component has almost infinite possibilities. It can be a simple function that takes a string and returns a string,
|
||||||
|
or it can be a complex function that takes other components, calls APIs, and returns a custom object only you know how to use (which might not be ideal).
|
||||||
|
|
||||||
|
Let's take a look at the basic rules, then we'll talk about the ones that are not so basic.
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
This is a simple example of a Custom Component. We will go over the rules in detail later.
|
||||||
|
|
||||||
|
<CH.Code linuNumbers={false}>
|
||||||
|
|
||||||
|
```python
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Best Component"
|
||||||
|
description = "This is the best component ever"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
cool_tool_names = ["Cool Tool",
|
||||||
|
"Cooler Tool",
|
||||||
|
"Coolest Tool"]
|
||||||
|
return {
|
||||||
|
"description": {"multiline": True},
|
||||||
|
"name": {"is_list": True,
|
||||||
|
"options": cool_tool_names}}
|
||||||
|
|
||||||
|
def build(self, name: str, description: str, chain: Chain) -> Tool:
|
||||||
|
return Tool(name=name,
|
||||||
|
description=description,
|
||||||
|
func=chain.run)
|
||||||
|
```
|
||||||
|
|
||||||
|
</CH.Code>
|
||||||
|
|
||||||
|
## Rules:
|
||||||
|
|
||||||
|
<CH.Scrollycoding rows={20} className={""}>
|
||||||
|
|
||||||
|
## Rule 1
|
||||||
|
|
||||||
|
The class must inherit from _`CustomComponent`_.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# focus
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
# focus
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Custom Component"
|
||||||
|
description = "This is a custom component"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rule 2:
|
||||||
|
|
||||||
|
The class must have a _`build`_ method
|
||||||
|
|
||||||
|
```python
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Custom Component"
|
||||||
|
description = "This is a custom component"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
# focus[5:13]
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rule 3
|
||||||
|
|
||||||
|
The type annotations of the _`build`_ method will be used to create the fields of the component
|
||||||
|
|
||||||
|
The types supported are:
|
||||||
|
|
||||||
|
- _`str`_, _`int`_, _`float`_, _`bool`_, _`list`_, _`dict`_
|
||||||
|
- [_`langchain.chains.base.Chain`_](focus://3)
|
||||||
|
- [_`langchain.PromptTemplate`_](focus://4)
|
||||||
|
- [_`langchain.llms.base.BaseLLM`_](focus://5)
|
||||||
|
- [_`langchain.Tool`_](focus://6)
|
||||||
|
- _`langchain.document_loaders.base.BaseLoader`_
|
||||||
|
- _`langchain.schema.Document`_
|
||||||
|
- _`langchain.text_splitters.TextSplitter`_
|
||||||
|
- _`langchain.vectorstores.base.VectorStore`_
|
||||||
|
- _`langchain.embeddings.base.Embeddings`_
|
||||||
|
- _`langchain.schema.BaseRetriever`_
|
||||||
|
|
||||||
|
```python
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Custom Component"
|
||||||
|
description = "This is a custom component"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
# focus[14:75]
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```python
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Custom Component"
|
||||||
|
description = "This is a custom component"
|
||||||
|
|
||||||
|
# focus
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rule 4:
|
||||||
|
|
||||||
|
The class can have a [_`build_config`_](focus://11:19) method
|
||||||
|
|
||||||
|
- The _`build_config`_ method will be used to create the config fields of the component (if any)
|
||||||
|
- It should always return a _`dict`_
|
||||||
|
|
||||||
|
The _`dict`_ should have the following format:
|
||||||
|
|
||||||
|
- The top level keys are the names of the fields
|
||||||
|
- The values are _`dict`_ with the following keys:
|
||||||
|
|
||||||
|
- _`field_type: str`_: The type of the field (can be str, int, float, bool, file or any of the types supported by the _`build`_ method)
|
||||||
|
- _`is_list: bool`_: If the field is a list
|
||||||
|
- _`options: List[str]`_: If the field is a list, the options that will be displayed
|
||||||
|
- _`multiline: bool`_: If the field is a string, if it should be multiline
|
||||||
|
- _`input_types: List[str]`_: To be used when you want a _`str`_ field to have connectable handles.
|
||||||
|
- _`dispaly_name: str`_: To change the name of the field
|
||||||
|
- _`advanced: bool`_: To hide the field in the default view
|
||||||
|
- _`password: bool`_: To mask the input
|
||||||
|
- _`required: bool`_: To make the field required
|
||||||
|
- _`info: str`_: To add a tooltip to the field
|
||||||
|
- _`file_types: List[str]`_: This is a requirement if the _`field_type`_ is 'file'
|
||||||
|
(must be used in conjunction with _`suffixes`_)
|
||||||
|
|
||||||
|
Example: _`["json", "yaml", "yml"]`_
|
||||||
|
|
||||||
|
- _`suffixes: List[str]`_: This is a requirement if the _`field_type`_ is 'file' (must be used in conjunction with _`file_types`_, and it must be a list of strings like 'json')
|
||||||
|
|
||||||
|
Example: _`[".json", ".yaml", ".yml"]`_
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Change the name
|
||||||
|
|
||||||
|
We can change the name of the component by adding a _`display_name`_ attribute.
|
||||||
|
|
||||||
|
```python focus=9
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Best Component"
|
||||||
|
description = "This is a custom component"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Change the description
|
||||||
|
|
||||||
|
We can change the description of the component by adding a _`description`_ attribute.
|
||||||
|
|
||||||
|
```python focus=10
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Best Component"
|
||||||
|
description = "This is the best component ever"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Add a config
|
||||||
|
|
||||||
|
The _`build_config`_ method will be used to create the config fields of the component (if any).
|
||||||
|
|
||||||
|
- _`multiline`_ is a special option that will give the option to open a text editor.
|
||||||
|
|
||||||
|
- _`is_list`_ is a special option that will give the option to add multiple values. When paired with _`options`_ it will transform it into a select field.
|
||||||
|
|
||||||
|
```python focus=12:19
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Best Component"
|
||||||
|
description = "This is the best component ever"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
cool_tool_names = ["Cool Tool",
|
||||||
|
"Cooler Tool",
|
||||||
|
"Coolest Tool"]
|
||||||
|
return {
|
||||||
|
"description": {"multiline": True},
|
||||||
|
"name": {"is_list": True,
|
||||||
|
"options": cool_tool_names}}
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```python focus=21:25
|
||||||
|
from langflow import CustomComponent
|
||||||
|
from langchain.chains import LLMChain
|
||||||
|
from langchain.chains.base import Chain
|
||||||
|
from langchain import PromptTemplate
|
||||||
|
from langchain.llms.base import BaseLLM
|
||||||
|
from langchain import Tool
|
||||||
|
|
||||||
|
class BestComponent(CustomComponent):
|
||||||
|
display_name = "Best Component"
|
||||||
|
description = "This is the best component ever"
|
||||||
|
|
||||||
|
def build_config(self) -> dict:
|
||||||
|
cool_tool_names = ["Cool Tool",
|
||||||
|
"Cooler Tool",
|
||||||
|
"Coolest Tool"]
|
||||||
|
return {
|
||||||
|
"description": {"multiline": True},
|
||||||
|
"name": {"is_list": True,
|
||||||
|
"options": cool_tool_names}}
|
||||||
|
|
||||||
|
def build(self, name: str, description: str, chain: Chain) -> Tool:
|
||||||
|
return Tool(name=name,
|
||||||
|
description=description,
|
||||||
|
func=chain.run)
|
||||||
|
```
|
||||||
|
|
||||||
|
# Add the build method
|
||||||
|
|
||||||
|
- name is a string
|
||||||
|
- description is a string
|
||||||
|
- chain is a Chain
|
||||||
|
- The return type is Tool
|
||||||
|
|
||||||
|
</CH.Scrollycoding>
|
||||||
|
|
@ -3,17 +3,19 @@
|
||||||
* bundles Infima by default. Infima is a CSS framework designed to
|
* bundles Infima by default. Infima is a CSS framework designed to
|
||||||
* work well for content-centric websites.
|
* work well for content-centric websites.
|
||||||
*/
|
*/
|
||||||
:root {
|
:root {
|
||||||
--ifm-background-color: var(--token-primary-bg-c);
|
--ifm-background-color: var(--token-primary-bg-c);
|
||||||
--ifm-navbar-link-hover-color: initial;
|
--ifm-navbar-link-hover-color: initial;
|
||||||
--ifm-navbar-padding-vertical: 0;
|
--ifm-navbar-padding-vertical: 0;
|
||||||
--ifm-navbar-item-padding-vertical: 0;
|
--ifm-navbar-item-padding-vertical: 0;
|
||||||
--ifm-font-family-base: -apple-system, BlinkMacSystemFont, Inter, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI emoji';
|
--ifm-font-family-base: -apple-system, BlinkMacSystemFont, Inter, Helvetica,
|
||||||
--ifm-font-family-monospace: 'SFMono-Regular', 'Roboto Mono', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
Arial, sans-serif, "Apple Color Emoji", "Segoe UI emoji";
|
||||||
|
--ifm-font-family-monospace: "SFMono-Regular", "Roboto Mono", Consolas,
|
||||||
|
"Liberation Mono", Menlo, Courier, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-doc-sidebar-item-category.menu__list-item:not(:first-child) {
|
.theme-doc-sidebar-item-category.menu__list-item:not(:first-child) {
|
||||||
margin-top: 1.5rem!important;
|
margin-top: 1.5rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.docusaurus-highlight-code-line {
|
.docusaurus-highlight-code-line {
|
||||||
|
|
@ -31,7 +33,7 @@
|
||||||
transform: skewY(6deg);
|
transform: skewY(6deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
[class^='announcementBar'] {
|
[class^="announcementBar"] {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +114,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-github-link:before {
|
.header-github-link:before {
|
||||||
content: '';
|
content: "";
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -126,7 +128,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-twitter-link::before {
|
.header-twitter-link::before {
|
||||||
content: '';
|
content: "";
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -140,7 +142,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-discord-link::before {
|
.header-discord-link::before {
|
||||||
content: '';
|
content: "";
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -148,7 +150,6 @@ body {
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Images */
|
/* Images */
|
||||||
.image-rendering-crisp {
|
.image-rendering-crisp {
|
||||||
image-rendering: crisp-edges;
|
image-rendering: crisp-edges;
|
||||||
|
|
@ -164,7 +165,7 @@ body {
|
||||||
.img-center {
|
.img-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%,
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resized-image {
|
.resized-image {
|
||||||
|
|
@ -188,4 +189,13 @@ body {
|
||||||
.mendable-search {
|
.mendable-search {
|
||||||
width: 140px;
|
width: 140px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ch-scrollycoding-content {
|
||||||
|
max-width: 40% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ch-scrollycoding-sticker {
|
||||||
|
max-width: 60% !important;
|
||||||
|
min-width: 60% !important;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue