Merge branch 'dev' of https://github.com/logspace-ai/langflow into backend_refactor
This commit is contained in:
commit
58fd8a1a44
11 changed files with 123 additions and 105 deletions
40
CONTRIBUTING.md
Normal file
40
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Contributing to LangFlow
|
||||||
|
|
||||||
|
Hello there! I appreciate your interest in contributing to LangFlow.
|
||||||
|
As an open-source project in a rapidly developing field, we are extremely open
|
||||||
|
to contributions, whether it be in the form of a new feature, improved infra, or better documentation.
|
||||||
|
|
||||||
|
To contribute to this project, please follow a ["fork and pull request"](https://docs.github.com/en/get-started/quickstart/contributing-to-projects) workflow.
|
||||||
|
Please do not try to push directly to this repo unless you are a maintainer.
|
||||||
|
|
||||||
|
## 🗺️Contributing Guidelines
|
||||||
|
|
||||||
|
### 🚩GitHub Issues
|
||||||
|
|
||||||
|
Our [issues](https://github.com/logspace-ai/langflow/issues) page is kept up to date
|
||||||
|
with bugs, improvements, and feature requests. There is a taxonomy of labels to help
|
||||||
|
with sorting and discovery of issues of interest.
|
||||||
|
|
||||||
|
If you're looking for help with your code, consider posting a question on the
|
||||||
|
[GitHub Discussions board](https://github.com/logspace-ai/langflow/discussions) or
|
||||||
|
[Stack Overflow](http://stackoverflow.com/questions/). Please
|
||||||
|
understand that we won't be able to provide individual support via email. We
|
||||||
|
also believe that help is much more valuable if it's **shared publicly**,
|
||||||
|
so that more people can benefit from it.
|
||||||
|
|
||||||
|
- **Describing your issue:** Try to provide as many details as possible. What
|
||||||
|
exactly goes wrong? _How_ is it failing? Is there an error?
|
||||||
|
"XY doesn't work" usually isn't that helpful for tracking down problems. Always
|
||||||
|
remember to include the code you ran and if possible, extract only the relevant
|
||||||
|
parts and don't just dump your entire script. This will make it easier for us to
|
||||||
|
reproduce the error.
|
||||||
|
|
||||||
|
- **Sharing long blocks of code or logs:** If you need to include long code,
|
||||||
|
logs or tracebacks, you can wrap them in `<details>` and `</details>`. This
|
||||||
|
[collapses the content](https://developer.mozilla.org/en/docs/Web/HTML/Element/details)
|
||||||
|
so it only becomes visible on click, making the issue easier to read and follow.
|
||||||
|
|
||||||
|
### Issue labels
|
||||||
|
|
||||||
|
[See this page](https://github.com/logspace-ai/langflow/labels) for an overview of
|
||||||
|
the system we use to tag our issues and pull requests.
|
||||||
|
|
@ -52,14 +52,7 @@ COPY ./langflow ./langflow
|
||||||
# Copy files from frontend
|
# Copy files from frontend
|
||||||
COPY --from=frontend_build /app/build /app/langflow/frontend/build/
|
COPY --from=frontend_build /app/build /app/langflow/frontend/build/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# RUN pip install langflow-0.0.17-py3-none-any.whl
|
|
||||||
RUN pip install .
|
RUN pip install .
|
||||||
# RUN poetry add dist/langflow-0.0.17-py3-none-any.whl
|
|
||||||
# RUN rm *.whl
|
|
||||||
|
|
||||||
# RUN poetry build
|
|
||||||
|
|
||||||
EXPOSE 5003
|
EXPOSE 5003
|
||||||
|
|
||||||
|
|
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 Logspace
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
55
README.md
Normal file
55
README.md
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
<!-- Title -->
|
||||||
|
|
||||||
|
# ⛓️ LangFlow
|
||||||
|
|
||||||
|
~ A no-code flow builder for langchain ~
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<img alt="GitHub Contributors" src="https://img.shields.io/github/contributors/logspace-ai/langflow" />
|
||||||
|
<img alt="GitHub Last Commit" src="https://img.shields.io/github/last-commit/logspace-ai/langflow" />
|
||||||
|
<!-- <img alt="GitHub Language Count" src="https://img.shields.io/github/languages/count/logspace-ai/langflow" /> -->
|
||||||
|
<img alt="" src="https://img.shields.io/github/repo-size/logspace-ai/langflow" />
|
||||||
|
<!-- <img alt="GitHub Issues" src="https://img.shields.io/github/issues/logspace-ai/langflow" /> -->
|
||||||
|
<!-- <img alt="GitHub Closed Issues" src="https://img.shields.io/github/issues-closed/logspace-ai/langflow" /> -->
|
||||||
|
<!-- <img alt="GitHub Pull Requests" src="https://img.shields.io/github/issues-pr/logspace-ai/langflow" /> -->
|
||||||
|
<!-- <img alt="GitHub Closed Pull Requests" src="https://img.shields.io/github/issues-pr-closed/logspace-ai/langflow" /> -->
|
||||||
|
<!-- <img alt="GitHub Commit Activity (Year)" src="https://img.shields.io/github/commit-activity/y/logspace-ai/langflow" /> -->
|
||||||
|
<img alt="Github License" src="https://img.shields.io/github/license/logspace-ai/langflow" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
LangFlow is a no-code flow builder for LangChain, designed to provide a drag-and-drop UI, combining the capabilities of LangChain with reactFlow and a chat interface.
|
||||||
|
|
||||||
|
## 📦 Installation
|
||||||
|
|
||||||
|
You can install LangFlow from pip:
|
||||||
|
|
||||||
|
`pip install langflow`
|
||||||
|
|
||||||
|
Next, set the `OPENAI_API_KEY` environment variable using one of the following methods:
|
||||||
|
|
||||||
|
- Use the following command in your terminal: `export OPENAI_API_KEY=your-api-key`.
|
||||||
|
- In a Python script or Jupyter notebook, use the following code: `import os; os.environ["OPENAI_API_KEY"] = "your-api-key"`.
|
||||||
|
|
||||||
|
## 🎨 Creating Flows
|
||||||
|
|
||||||
|
Creating flows with LangFlow is easy, thanks to its intuitive drag-and-drop interface. Simply drag components from the sidebar onto the canvas, and connect them together to create your custom NLP pipeline. LangFlow provides a range of pre-built components to choose from, including LLMs, prompt serializers, agents, and chains.
|
||||||
|
|
||||||
|
## 💻 Examples
|
||||||
|
|
||||||
|
LangFlow comes with a number of example flows to help you get started. These examples cover a range of use cases, from chatbots and question-answering systems to data augmentation and model comparison. You can use these examples as a starting point for your own custom flows, or modify them to suit your needs.
|
||||||
|
|
||||||
|
## 🧰 Components
|
||||||
|
|
||||||
|
LangFlow provides support for LangChain main components, including prompts, LLMs, document loaders, utils, chains, indexes, agents, and memory. For each module, we provide examples to get started, how-to guides, reference docs, and conceptual guides.
|
||||||
|
|
||||||
|
For more information on each component, please refer to the [Modules section of the LangChain documentation](https://langchain-docs.example.com/modules).
|
||||||
|
|
||||||
|
## 🔧 Contributing
|
||||||
|
|
||||||
|
We welcome contributions to LangFlow! If you'd like to contribute, please follow our contributing guidelines. You can also get in touch with us via GitHub issues or our community forum.
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
LangFlow is released under the MIT License. See the LICENSE file for details.
|
||||||
|
|
@ -8,5 +8,4 @@ docker build -t logspace/backend_build -f build.Dockerfile .
|
||||||
cd ../../
|
cd ../../
|
||||||
VERSION=$(toml get --toml-path pyproject.toml tool.poetry.version)
|
VERSION=$(toml get --toml-path pyproject.toml tool.poetry.version)
|
||||||
docker build --build-arg VERSION=$VERSION -t ibiscp/langflow:$VERSION .
|
docker build --build-arg VERSION=$VERSION -t ibiscp/langflow:$VERSION .
|
||||||
# docker push ibiscp/langflow:$VERSION
|
docker push ibiscp/langflow:$VERSION
|
||||||
# poetry add --editable ../../../langchain
|
|
||||||
|
|
|
||||||
BIN
img/llm_simple_flow.png
Normal file
BIN
img/llm_simple_flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
|
|
@ -42,27 +42,6 @@ def get_all():
|
||||||
for prompt in list_endpoints.list_prompts()
|
for prompt in list_endpoints.list_prompts()
|
||||||
},
|
},
|
||||||
"llms": {llm: signature.get_llm(llm) for llm in list_endpoints.list_llms()},
|
"llms": {llm: signature.get_llm(llm) for llm in list_endpoints.list_llms()},
|
||||||
# "utilities": {
|
|
||||||
# "template": {
|
|
||||||
# # utility: templates.utility(utility) for utility in list.list_utilities()
|
|
||||||
# }
|
|
||||||
# },
|
|
||||||
# "memories": {
|
|
||||||
# memory: signature.get_memory(memory)
|
|
||||||
# for memory in list_endpoints.list_memories()
|
|
||||||
# },
|
|
||||||
# "document_loaders": {
|
|
||||||
# "template": {
|
|
||||||
# # memory: templates.document_loader(memory)
|
|
||||||
# # for memory in list.list_document_loaders()
|
|
||||||
# }
|
|
||||||
# },
|
|
||||||
# "vectorstores": {"template": {}},
|
|
||||||
# "docstores": {"template": {}},
|
|
||||||
# "tools": {
|
|
||||||
# tool: {"template": signature.tool(tool), **values}
|
|
||||||
# for tool, values in tools.items()
|
|
||||||
# },
|
|
||||||
"tools": {
|
"tools": {
|
||||||
tool: signature.get_tool(tool) for tool in list_endpoints.list_tools()
|
tool: signature.get_tool(tool) for tool in list_endpoints.list_tools()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,6 @@ def read_items():
|
||||||
"agents",
|
"agents",
|
||||||
"prompts",
|
"prompts",
|
||||||
"llms",
|
"llms",
|
||||||
# "utilities",
|
|
||||||
# "memories",
|
|
||||||
# "document_loaders",
|
|
||||||
# "vectorstores",
|
|
||||||
# "docstores",
|
|
||||||
"tools",
|
"tools",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -83,30 +78,6 @@ def list_memories():
|
||||||
return [memory.__name__ for memory in memories.type_to_cls_dict.values()]
|
return [memory.__name__ for memory in memories.type_to_cls_dict.values()]
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/utilities")
|
|
||||||
# def list_utilities():
|
|
||||||
# """List all utility types"""
|
|
||||||
# return list(utilities.__all__)
|
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/document_loaders")
|
|
||||||
# def list_document_loaders():
|
|
||||||
# """List all document loader types"""
|
|
||||||
# return list(document_loaders.__all__)
|
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/vectorstores")
|
|
||||||
# def list_vectorstores():
|
|
||||||
# """List all vector store types"""
|
|
||||||
# return list(vectorstores.__all__)
|
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/docstores")
|
|
||||||
# def list_docstores():
|
|
||||||
# """List all document store types"""
|
|
||||||
# return list(docstore.__all__)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/tools")
|
@router.get("/tools")
|
||||||
def list_tools():
|
def list_tools():
|
||||||
"""List all load tools"""
|
"""List all load tools"""
|
||||||
|
|
@ -119,8 +90,3 @@ def list_tools():
|
||||||
tools.append(tool_params["name"])
|
tools.append(tool_params["name"])
|
||||||
|
|
||||||
return tools
|
return tools
|
||||||
|
|
||||||
# return [
|
|
||||||
# util.get_tool_params(util.get_tools_dict(tool))["name"]
|
|
||||||
# for tool in get_all_tool_names()
|
|
||||||
# ]
|
|
||||||
|
|
|
||||||
|
|
@ -62,18 +62,6 @@ def get_llm(name: str):
|
||||||
raise HTTPException(status_code=404, detail="LLM not found") from exc
|
raise HTTPException(status_code=404, detail="LLM not found") from exc
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/utility")
|
|
||||||
# def utility(name: str):
|
|
||||||
# # Raise error if name is not in utilities
|
|
||||||
# if name not in utilities.__all__:
|
|
||||||
# raise Exception(f"Prompt {name} not found.")
|
|
||||||
# _class = getattr(utilities, name)
|
|
||||||
# return {
|
|
||||||
# name: {name: value for (name, value) in value.__repr_args__() if name != "name"}
|
|
||||||
# for name, value in _class.__fields__.items()
|
|
||||||
# }
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/memory")
|
@router.get("/memory")
|
||||||
def get_memory(name: str):
|
def get_memory(name: str):
|
||||||
"""Get the signature of a memory."""
|
"""Get the signature of a memory."""
|
||||||
|
|
@ -83,18 +71,6 @@ def get_memory(name: str):
|
||||||
raise HTTPException(status_code=404, detail="Memory not found") from exc
|
raise HTTPException(status_code=404, detail="Memory not found") from exc
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/document_loader")
|
|
||||||
# def document_loader(name: str):
|
|
||||||
# # Raise error if name is not in document_loader
|
|
||||||
# if name not in document_loaders.__all__:
|
|
||||||
# raise Exception(f"Prompt {name} not found.")
|
|
||||||
# _class = getattr(document_loaders, name)
|
|
||||||
# return {
|
|
||||||
# name: {name: value for (name, value) in value.__repr_args__() if name != "name"}
|
|
||||||
# for name, value in _class.__fields__.items()
|
|
||||||
# }
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/tool")
|
@router.get("/tool")
|
||||||
def get_tool(name: str):
|
def get_tool(name: str):
|
||||||
"""Get the signature of a tool."""
|
"""Get the signature of a tool."""
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ from langchain.agents.mrkl import prompt
|
||||||
|
|
||||||
|
|
||||||
def get_custom_prompts():
|
def get_custom_prompts():
|
||||||
|
"""Get custom prompts."""
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"ZeroShotPrompt": {
|
"ZeroShotPrompt": {
|
||||||
"template": {
|
"template": {
|
||||||
|
|
|
||||||
|
|
@ -52,21 +52,15 @@ def build_json(root, nodes, edges):
|
||||||
for key, value in final_dict.items():
|
for key, value in final_dict.items():
|
||||||
if key == "_type":
|
if key == "_type":
|
||||||
continue
|
continue
|
||||||
# elif key == "prompt":
|
|
||||||
# pass
|
|
||||||
|
|
||||||
module_type = value["type"]
|
module_type = value["type"]
|
||||||
# if module_type == "Tool":
|
|
||||||
# pass
|
|
||||||
# if module_type in ["str", "bool", "int", "float", "Any"] or value["value"]:
|
|
||||||
# value = value["value"]
|
|
||||||
if "value" in value and value["value"] is not None:
|
if "value" in value and value["value"] is not None:
|
||||||
value = value["value"]
|
value = value["value"]
|
||||||
elif "dict" in module_type:
|
elif "dict" in module_type:
|
||||||
value = {}
|
value = {}
|
||||||
else:
|
else:
|
||||||
# if value['list']:
|
|
||||||
# print(key)
|
|
||||||
children = []
|
children = []
|
||||||
for c in local_nodes:
|
for c in local_nodes:
|
||||||
module_types = [c["data"]["type"]]
|
module_types = [c["data"]["type"]]
|
||||||
|
|
@ -74,19 +68,12 @@ def build_json(root, nodes, edges):
|
||||||
module_types += c["data"]["node"]["base_classes"]
|
module_types += c["data"]["node"]["base_classes"]
|
||||||
if module_type in module_types:
|
if module_type in module_types:
|
||||||
children.append(c)
|
children.append(c)
|
||||||
# children = [
|
|
||||||
# c
|
|
||||||
# for c in local_nodes
|
|
||||||
# if module_type
|
|
||||||
# in [c["data"]["type"]] + c["data"]["node"]["base_classes"]
|
|
||||||
# ]
|
|
||||||
# else:
|
|
||||||
# children = next((c for c in local_nodes if type in [c['data']['type']] + c['data']['node']['base_classes']), None)
|
|
||||||
if value["required"] and not children:
|
if value["required"] and not children:
|
||||||
raise ValueError(f"No child with type {module_type} found")
|
raise ValueError(f"No child with type {module_type} found")
|
||||||
values = [
|
values = [
|
||||||
build_json(child, nodes, edges) for child in children
|
build_json(child, nodes, edges) for child in children
|
||||||
] # if children else None
|
]
|
||||||
value = list(values) if value["list"] else next(iter(values), None)
|
value = list(values) if value["list"] else next(iter(values), None)
|
||||||
final_dict[key] = value
|
final_dict[key] = value
|
||||||
return final_dict
|
return final_dict
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue