From 0513b035afdecefae34c880141ab28ae6f924828 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 16:29:18 -0300 Subject: [PATCH 01/54] Update flow names in NewFlowModal and documentation --- docs/docs/guides/rag-with-astradb.mdx | 16 +- docs/docs/index.mdx | 9 +- .../starter_projects/AstraDB-RAG-Flows.json | 3403 +++++++++++++++++ .../components/undrawCards/index.tsx | 2 +- .../src/modals/NewFlowModal/index.tsx | 12 +- 5 files changed, 3417 insertions(+), 25 deletions(-) create mode 100644 src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json diff --git a/docs/docs/guides/rag-with-astradb.mdx b/docs/docs/guides/rag-with-astradb.mdx index 310f9ea70..4d9fec45e 100644 --- a/docs/docs/guides/rag-with-astradb.mdx +++ b/docs/docs/guides/rag-with-astradb.mdx @@ -1,7 +1,6 @@ import ThemedImage from "@theme/ThemedImage"; import useBaseUrl from "@docusaurus/useBaseUrl"; import ZoomableImage from "/src/theme/ZoomableImage.js"; -import DownloadableJsonFile from "/src/theme/DownloadableJsonFile.js"; import Admonition from "@theme/Admonition"; # 🌟 RAG with AstraDB @@ -22,10 +21,7 @@ TLDR; - Visit the [Astra](https://astra.datastax.com) website and create a free account - Duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) - Create a new database, get a **Token** and the **API Endpoint** -- +- Click on the **New Project** button and look for Vector Store RAG. This will create a new project with the necessary components - Import the project into Langflow by dropping it on the Canvas or My Collection page - Update the **Token** and **API Endpoint** in the **AstraDB** components - Update the OpenAI API key in the **OpenAI** components @@ -79,13 +75,9 @@ Now we are all set to start building our RAG application using AstraDB and Langf If you haven't already, now is the time to launch Langflow. To make things easier, you can duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) which sets up a Langflow instance just for you. -You'll still need to get the Project file and import it so, let's get to that. +## Open the Vector Store RAG Project -## Import AstraDB RAG Flows - -To get started, you will need to . - -Once you have downloaded the project file, you can import it into Langflow by dropping it on the Canvas or My Collection page. +To get started, click on the **New Project** button and look for the **Vector Store RAG** project. This will open a starter project with the necessary components to run a RAG application using AstraDB. -Now, on to the **RAG Flow**. This flow is responsible for generating responses to your queries. +Now, on to the **RAG Flow**. This flow is responsible for generating responses to your queries. It will define all of the steps from getting the User's input to generating a response and displaying it in the Interaction Panel. The RAG flow is a bit more complex. It consists of: diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index c2c15ec32..c5c818d6f 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -17,7 +17,6 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; style={{ width: "100%" }} /> - ## 🚀 First steps ## Installation @@ -37,9 +36,9 @@ pip install langflow -U Or you can install a pre-release version using: ```bash -pipx install langflow --python python3.10 --fetch-missing-python --pip-args="--pre" +pipx install langflow --python python3.10 --fetch-missing-python --pip-args="--pre --force-reinstall" # or -pip install langflow --pre -U +pip install langflow --pre --force-reinstall ``` ### ⛓️ Running Langflow @@ -67,14 +66,12 @@ Remember to use a Chromium-based browser for the best experience. You'll be pres style={{ width: "100%" }} /> - From here, just name your Space, define the visibility (Public or Private), and click on `Duplicate Space` to start the installation process. When that is done, you'll be redirected to the Space's main page to start using Langflow right away! Once you get Langflow running, click on New Project in the top right corner of the screen. Langflow provides a range of example flows to help you get started. To quickly try one of them, open a starter example, set up your API keys and click ⚡ Run, on the bottom right corner of the canvas. This will open up Langflow's Interaction Panel with the chat console, text inputs, and outputs. - ### 🖥️ Command Line Interface (CLI) Langflow provides a command-line interface (CLI) for easy management and configuration. @@ -91,4 +88,4 @@ Find more information about the available options by running: ```bash langflow --help -``` \ No newline at end of file +``` diff --git a/src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json new file mode 100644 index 000000000..f80a20d15 --- /dev/null +++ b/src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json @@ -0,0 +1,3403 @@ +{ + "id": "51e2b78a-199b-4054-9f32-e288eef6924c", + "data": { + "nodes": [ + { + "id": "ChatInput-yxMKE", + "type": "genericNode", + "position": { + "x": 1195.5276981160775, + "y": 209.421875 + }, + "data": { + "type": "ChatInput", + "node": { + "template": { + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Interaction Panel.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Message\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "input_value": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Message", + "advanced": false, + "input_types": [], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "value": "what is a line" + }, + "return_record": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "return_record", + "display_name": "Return Record", + "advanced": true, + "dynamic": false, + "info": "Return the message as a record containing the sender, sender_name, and session_id.", + "load_from_db": false, + "title_case": false + }, + "sender": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "User", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Machine", + "User" + ], + "name": "sender", + "display_name": "Sender Type", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "sender_name": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "User", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "sender_name", + "display_name": "Sender Name", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "session_id": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "session_id", + "display_name": "Session ID", + "advanced": true, + "dynamic": false, + "info": "If provided, the message will be stored in the memory.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Get chat inputs from the Interaction Panel.", + "icon": "ChatInput", + "base_classes": [ + "Text", + "str", + "object", + "Record" + ], + "display_name": "Chat Input", + "documentation": "", + "custom_fields": { + "sender": null, + "sender_name": null, + "input_value": null, + "session_id": null, + "return_record": null + }, + "output_types": [ + "Text", + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "ChatInput-yxMKE" + }, + "selected": false, + "width": 384, + "height": 383 + }, + { + "id": "TextOutput-BDknO", + "type": "genericNode", + "position": { + "x": 2322.600672827879, + "y": 604.9467307442569 + }, + "data": { + "type": "TextOutput", + "node": { + "template": { + "input_value": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Value", + "advanced": false, + "input_types": [ + "Record", + "Text" + ], + "dynamic": false, + "info": "Text or Record to be passed as output.", + "load_from_db": false, + "title_case": false + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextOutput(TextComponent):\n display_name = \"Text Output\"\n description = \"Display a text output in the Interaction Panel.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Value\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as output.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(self, input_value: Optional[Text] = \"\", record_template: str = \"\") -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "record_template": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "{text}", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "record_template", + "display_name": "Record Template", + "advanced": true, + "dynamic": false, + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Display a text output in the Interaction Panel.", + "icon": "type", + "base_classes": [ + "object", + "Text", + "str" + ], + "display_name": "Extracted Chunks", + "documentation": "", + "custom_fields": { + "input_value": null, + "record_template": null + }, + "output_types": [ + "Text" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "TextOutput-BDknO" + }, + "selected": false, + "width": 384, + "height": 289, + "positionAbsolute": { + "x": 2322.600672827879, + "y": 604.9467307442569 + }, + "dragging": false + }, + { + "id": "OpenAIEmbeddings-ZlOk1", + "type": "genericNode", + "position": { + "x": 1183.667250865064, + "y": 687.3171828430261 + }, + "data": { + "type": "OpenAIEmbeddings", + "node": { + "template": { + "allowed_special": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": [], + "fileTypes": [], + "file_path": "", + "password": false, + "name": "allowed_special", + "display_name": "Allowed Special", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "chunk_size": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 1000, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "chunk_size", + "display_name": "Chunk Size", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "client": { + "type": "Any", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "client", + "display_name": "Client", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-3-small\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-3-small\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "default_headers": { + "type": "dict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "default_headers", + "display_name": "Default Headers", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "default_query": { + "type": "NestedDict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": {}, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "default_query", + "display_name": "Default Query", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "deployment": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "text-embedding-3-small", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "deployment", + "display_name": "Deployment", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "disallowed_special": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": [ + "all" + ], + "fileTypes": [], + "file_path": "", + "password": false, + "name": "disallowed_special", + "display_name": "Disallowed Special", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "embedding_ctx_length": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 8191, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "embedding_ctx_length", + "display_name": "Embedding Context Length", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "max_retries": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 6, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "max_retries", + "display_name": "Max Retries", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "model": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "text-embedding-3-small", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "text-embedding-3-small", + "text-embedding-3-large", + "text-embedding-ada-002" + ], + "name": "model", + "display_name": "Model", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "model_kwargs": { + "type": "NestedDict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": {}, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "model_kwargs", + "display_name": "Model Kwargs", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "openai_api_base": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_base", + "display_name": "OpenAI API Base", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_key": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_key", + "display_name": "OpenAI API Key", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "openai_api_type": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_type", + "display_name": "OpenAI API Type", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_version": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_api_version", + "display_name": "OpenAI API Version", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_organization": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_organization", + "display_name": "OpenAI Organization", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_proxy": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_proxy", + "display_name": "OpenAI Proxy", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "request_timeout": { + "type": "float", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "request_timeout", + "display_name": "Request Timeout", + "advanced": true, + "dynamic": false, + "info": "", + "rangeSpec": { + "step_type": "float", + "min": -1, + "max": 1, + "step": 0.1 + }, + "load_from_db": false, + "title_case": false + }, + "show_progress_bar": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "show_progress_bar", + "display_name": "Show Progress Bar", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "skip_empty": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "skip_empty", + "display_name": "Skip Empty", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "tiktoken_enable": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "tiktoken_enable", + "display_name": "TikToken Enable", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "tiktoken_model_name": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "tiktoken_model_name", + "display_name": "TikToken Model Name", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Generate embeddings using OpenAI models.", + "base_classes": [ + "Embeddings" + ], + "display_name": "OpenAI Embeddings", + "documentation": "", + "custom_fields": { + "openai_api_key": null, + "default_headers": null, + "default_query": null, + "allowed_special": null, + "disallowed_special": null, + "chunk_size": null, + "client": null, + "deployment": null, + "embedding_ctx_length": null, + "max_retries": null, + "model": null, + "model_kwargs": null, + "openai_api_base": null, + "openai_api_type": null, + "openai_api_version": null, + "openai_organization": null, + "openai_proxy": null, + "request_timeout": null, + "show_progress_bar": null, + "skip_empty": null, + "tiktoken_enable": null, + "tiktoken_model_name": null + }, + "output_types": [ + "Embeddings" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "OpenAIEmbeddings-ZlOk1" + }, + "selected": false, + "width": 384, + "height": 383, + "dragging": false + }, + { + "id": "OpenAIModel-EjXlN", + "type": "genericNode", + "position": { + "x": 3410.117202077183, + "y": 431.2038048137648 + }, + "data": { + "type": "OpenAIModel", + "node": { + "template": { + "input_value": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Input", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\"},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": [\n \"gpt-4-turbo-preview\",\n \"gpt-3.5-turbo\",\n \"gpt-4-0125-preview\",\n \"gpt-4-1106-preview\",\n \"gpt-4-vision-preview\",\n \"gpt-3.5-turbo-0125\",\n \"gpt-3.5-turbo-1106\",\n ],\n \"value\": \"gpt-4-turbo-preview\",\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float,\n model_name: str,\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n output = ChatOpenAI(\n max_tokens=max_tokens,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=openai_api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "max_tokens": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 256, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "max_tokens", + "display_name": "Max Tokens", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "model_kwargs": { + "type": "NestedDict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": {}, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "model_kwargs", + "display_name": "Model Kwargs", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "model_name": { + "type": "str", + "required": true, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "gpt-3.5-turbo", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-4-0125-preview", + "gpt-4-1106-preview", + "gpt-4-vision-preview", + "gpt-3.5-turbo-0125", + "gpt-3.5-turbo-1106" + ], + "name": "model_name", + "display_name": "Model Name", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_base": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_api_base", + "display_name": "OpenAI API Base", + "advanced": true, + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_key": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_key", + "display_name": "OpenAI API Key", + "advanced": false, + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "stream": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "stream", + "display_name": "Stream", + "advanced": true, + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "load_from_db": false, + "title_case": false + }, + "system_message": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "system_message", + "display_name": "System Message", + "advanced": true, + "dynamic": false, + "info": "System message to pass to the model.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "temperature": { + "type": "float", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 0.1, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "temperature", + "display_name": "Temperature", + "advanced": false, + "dynamic": false, + "info": "", + "rangeSpec": { + "step_type": "float", + "min": -1, + "max": 1, + "step": 0.1 + }, + "load_from_db": false, + "title_case": false + }, + "_type": "CustomComponent" + }, + "description": "Generates text using OpenAI LLMs.", + "icon": "OpenAI", + "base_classes": [ + "object", + "Text", + "str" + ], + "display_name": "OpenAI", + "documentation": "", + "custom_fields": { + "input_value": null, + "openai_api_key": null, + "temperature": null, + "model_name": null, + "max_tokens": null, + "model_kwargs": null, + "openai_api_base": null, + "stream": null, + "system_message": null + }, + "output_types": [ + "Text" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [ + "max_tokens", + "model_kwargs", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "input_value", + "system_message", + "stream" + ], + "beta": false + }, + "id": "OpenAIModel-EjXlN" + }, + "selected": true, + "width": 384, + "height": 563, + "positionAbsolute": { + "x": 3410.117202077183, + "y": 431.2038048137648 + }, + "dragging": false + }, + { + "id": "Prompt-xeI6K", + "type": "genericNode", + "position": { + "x": 2969.0261961391298, + "y": 442.1613649809069 + }, + "data": { + "type": "Prompt", + "node": { + "template": { + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.field_typing import Prompt, TemplateField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "template": { + "type": "prompt", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: ", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "template", + "display_name": "Template", + "advanced": false, + "input_types": [ + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "_type": "CustomComponent", + "context": { + "field_type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "context", + "display_name": "context", + "advanced": false, + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "type": "str" + }, + "question": { + "field_type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "question", + "display_name": "question", + "advanced": false, + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "type": "str" + } + }, + "description": "Create a prompt template with dynamic variables.", + "icon": "prompts", + "is_input": null, + "is_output": null, + "is_composition": null, + "base_classes": [ + "object", + "Text", + "str" + ], + "name": "", + "display_name": "Prompt", + "documentation": "", + "custom_fields": { + "template": [ + "context", + "question" + ] + }, + "output_types": [ + "Text" + ], + "full_path": null, + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false, + "error": null + }, + "id": "Prompt-xeI6K", + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt" + }, + "selected": false, + "width": 384, + "height": 477, + "positionAbsolute": { + "x": 2969.0261961391298, + "y": 442.1613649809069 + }, + "dragging": false + }, + { + "id": "ChatOutput-Q39I8", + "type": "genericNode", + "position": { + "x": 3887.2073667611485, + "y": 588.4801225794856 + }, + "data": { + "type": "ChatOutput", + "node": { + "template": { + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Interaction Panel.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n record_template: Optional[str] = \"{text}\",\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n record_template=record_template,\n )\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "input_value": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Message", + "advanced": false, + "input_types": [ + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "record_template": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "{text}", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "record_template", + "display_name": "Record Template", + "advanced": true, + "dynamic": false, + "info": "In case of Message being a Record, this template will be used to convert it to text.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "return_record": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "return_record", + "display_name": "Return Record", + "advanced": true, + "dynamic": false, + "info": "Return the message as a record containing the sender, sender_name, and session_id.", + "load_from_db": false, + "title_case": false + }, + "sender": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "Machine", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Machine", + "User" + ], + "name": "sender", + "display_name": "Sender Type", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "sender_name": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "AI", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "sender_name", + "display_name": "Sender Name", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "session_id": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "session_id", + "display_name": "Session ID", + "advanced": true, + "dynamic": false, + "info": "If provided, the message will be stored in the memory.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Display a chat message in the Interaction Panel.", + "icon": "ChatOutput", + "base_classes": [ + "object", + "Text", + "Record", + "str" + ], + "display_name": "Chat Output", + "documentation": "", + "custom_fields": { + "sender": null, + "sender_name": null, + "input_value": null, + "session_id": null, + "return_record": null, + "record_template": null + }, + "output_types": [ + "Text", + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "ChatOutput-Q39I8" + }, + "selected": false, + "width": 384, + "height": 383, + "positionAbsolute": { + "x": 3887.2073667611485, + "y": 588.4801225794856 + }, + "dragging": false + }, + { + "id": "File-t0a6a", + "type": "genericNode", + "position": { + "x": 2257.233450682836, + "y": 1747.5389618367233 + }, + "data": { + "type": "File", + "node": { + "template": { + "path": { + "type": "file", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [ + ".txt", + ".md", + ".mdx", + ".csv", + ".json", + ".yaml", + ".yml", + ".xml", + ".html", + ".htm", + ".pdf", + ".docx" + ], + "file_path": "51e2b78a-199b-4054-9f32-e288eef6924c/Langflow conversation.pdf", + "password": false, + "name": "path", + "display_name": "Path", + "advanced": false, + "dynamic": false, + "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx", + "load_from_db": false, + "title_case": false, + "value": "" + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from pathlib import Path\nfrom typing import Any, Dict\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\n\n\nclass FileComponent(CustomComponent):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n def build_config(self) -> Dict[str, Any]:\n return {\n \"path\": {\n \"display_name\": \"Path\",\n \"field_type\": \"file\",\n \"file_types\": TEXT_FILE_TYPES,\n \"info\": f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n },\n \"silent_errors\": {\n \"display_name\": \"Silent Errors\",\n \"advanced\": True,\n \"info\": \"If true, errors will not raise an exception.\",\n },\n }\n\n def load_file(self, path: str, silent_errors: bool = False) -> Record:\n resolved_path = self.resolve_path(path)\n path_obj = Path(resolved_path)\n extension = path_obj.suffix[1:].lower()\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n record = parse_text_file_to_record(resolved_path, silent_errors)\n self.status = record if record else \"No data\"\n return record or Record()\n\n def build(\n self,\n path: str,\n silent_errors: bool = False,\n ) -> Record:\n record = self.load_file(path, silent_errors)\n self.status = record\n return record\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "silent_errors": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "silent_errors", + "display_name": "Silent Errors", + "advanced": true, + "dynamic": false, + "info": "If true, errors will not raise an exception.", + "load_from_db": false, + "title_case": false + }, + "_type": "CustomComponent" + }, + "description": "A generic file loader.", + "icon": "file-text", + "base_classes": [ + "Record" + ], + "display_name": "File", + "documentation": "", + "custom_fields": { + "path": null, + "silent_errors": null + }, + "output_types": [ + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "File-t0a6a" + }, + "selected": false, + "width": 384, + "height": 281, + "positionAbsolute": { + "x": 2257.233450682836, + "y": 1747.5389618367233 + }, + "dragging": false + }, + { + "id": "RecursiveCharacterTextSplitter-tR9QM", + "type": "genericNode", + "position": { + "x": 2791.013514133929, + "y": 1462.9588953494142 + }, + "data": { + "type": "RecursiveCharacterTextSplitter", + "node": { + "template": { + "inputs": { + "type": "Document", + "required": true, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "inputs", + "display_name": "Input", + "advanced": false, + "input_types": [ + "Document", + "Record" + ], + "dynamic": false, + "info": "The texts to split.", + "load_from_db": false, + "title_case": false + }, + "chunk_overlap": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 200, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "chunk_overlap", + "display_name": "Chunk Overlap", + "advanced": false, + "dynamic": false, + "info": "The amount of overlap between chunks.", + "load_from_db": false, + "title_case": false + }, + "chunk_size": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 1000, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "chunk_size", + "display_name": "Chunk Size", + "advanced": false, + "dynamic": false, + "info": "The maximum length of each chunk.", + "load_from_db": false, + "title_case": false + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional\n\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain_core.documents import Document\n\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\nfrom langflow.utils.util import build_loader_repr_from_records, unescape_string\n\n\nclass RecursiveCharacterTextSplitterComponent(CustomComponent):\n display_name: str = \"Recursive Character Text Splitter\"\n description: str = \"Split text into chunks of a specified length.\"\n documentation: str = \"https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter\"\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Input\",\n \"info\": \"The texts to split.\",\n \"input_types\": [\"Document\", \"Record\"],\n },\n \"separators\": {\n \"display_name\": \"Separators\",\n \"info\": 'The characters to split on.\\nIf left empty defaults to [\"\\\\n\\\\n\", \"\\\\n\", \" \", \"\"].',\n \"is_list\": True,\n },\n \"chunk_size\": {\n \"display_name\": \"Chunk Size\",\n \"info\": \"The maximum length of each chunk.\",\n \"field_type\": \"int\",\n \"value\": 1000,\n },\n \"chunk_overlap\": {\n \"display_name\": \"Chunk Overlap\",\n \"info\": \"The amount of overlap between chunks.\",\n \"field_type\": \"int\",\n \"value\": 200,\n },\n \"code\": {\"show\": False},\n }\n\n def build(\n self,\n inputs: list[Document],\n separators: Optional[list[str]] = None,\n chunk_size: Optional[int] = 1000,\n chunk_overlap: Optional[int] = 200,\n ) -> list[Record]:\n \"\"\"\n Split text into chunks of a specified length.\n\n Args:\n separators (list[str]): The characters to split on.\n chunk_size (int): The maximum length of each chunk.\n chunk_overlap (int): The amount of overlap between chunks.\n length_function (function): The function to use to calculate the length of the text.\n\n Returns:\n list[str]: The chunks of text.\n \"\"\"\n\n if separators == \"\":\n separators = None\n elif separators:\n # check if the separators list has escaped characters\n # if there are escaped characters, unescape them\n separators = [unescape_string(x) for x in separators]\n\n # Make sure chunk_size and chunk_overlap are ints\n if isinstance(chunk_size, str):\n chunk_size = int(chunk_size)\n if isinstance(chunk_overlap, str):\n chunk_overlap = int(chunk_overlap)\n splitter = RecursiveCharacterTextSplitter(\n separators=separators,\n chunk_size=chunk_size,\n chunk_overlap=chunk_overlap,\n )\n documents = []\n for _input in inputs:\n if isinstance(_input, Record):\n documents.append(_input.to_lc_document())\n else:\n documents.append(_input)\n docs = splitter.split_documents(documents)\n records = self.to_records(docs)\n self.repr_value = build_loader_repr_from_records(records)\n return records\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "separators": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "separators", + "display_name": "Separators", + "advanced": false, + "dynamic": false, + "info": "The characters to split on.\nIf left empty defaults to [\"\\n\\n\", \"\\n\", \" \", \"\"].", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": [ + "" + ] + }, + "_type": "CustomComponent" + }, + "description": "Split text into chunks of a specified length.", + "base_classes": [ + "Record" + ], + "display_name": "Recursive Character Text Splitter", + "documentation": "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter", + "custom_fields": { + "inputs": null, + "separators": null, + "chunk_size": null, + "chunk_overlap": null + }, + "output_types": [ + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "RecursiveCharacterTextSplitter-tR9QM" + }, + "selected": false, + "width": 384, + "height": 501, + "positionAbsolute": { + "x": 2791.013514133929, + "y": 1462.9588953494142 + }, + "dragging": false + }, + { + "id": "AstraDBSearch-41nRz", + "type": "genericNode", + "position": { + "x": 1723.976434815103, + "y": 277.03317407245913 + }, + "data": { + "type": "AstraDBSearch", + "node": { + "template": { + "embedding": { + "type": "Embeddings", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "embedding", + "display_name": "Embedding", + "advanced": false, + "dynamic": false, + "info": "Embedding to use", + "load_from_db": false, + "title_case": false + }, + "input_value": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Input Value", + "advanced": false, + "dynamic": false, + "info": "Input value to search", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "api_endpoint": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "api_endpoint", + "display_name": "API Endpoint", + "advanced": false, + "dynamic": false, + "info": "API endpoint URL for the AstraDB service.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "batch_size": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "batch_size", + "display_name": "Batch Size", + "advanced": true, + "dynamic": false, + "info": "Optional number of records to process in a single batch.", + "load_from_db": false, + "title_case": false + }, + "bulk_delete_concurrency": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "bulk_delete_concurrency", + "display_name": "Bulk Delete Concurrency", + "advanced": true, + "dynamic": false, + "info": "Optional concurrency level for bulk delete operations.", + "load_from_db": false, + "title_case": false + }, + "bulk_insert_batch_concurrency": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "bulk_insert_batch_concurrency", + "display_name": "Bulk Insert Batch Concurrency", + "advanced": true, + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations.", + "load_from_db": false, + "title_case": false + }, + "bulk_insert_overwrite_concurrency": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "bulk_insert_overwrite_concurrency", + "display_name": "Bulk Insert Overwrite Concurrency", + "advanced": true, + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations that overwrite existing records.", + "load_from_db": false, + "title_case": false + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"AstraDB Search\"\n description = \"Searches an existing AstraDB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within AstraDB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing AstraDB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the AstraDB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within AstraDB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'.\"\n )\n else:\n raise e\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "collection_indexing_policy": { + "type": "dict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "collection_indexing_policy", + "display_name": "Collection Indexing Policy", + "advanced": true, + "dynamic": false, + "info": "Optional dictionary defining the indexing policy for the collection.", + "load_from_db": false, + "title_case": false + }, + "collection_name": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "collection_name", + "display_name": "Collection Name", + "advanced": false, + "dynamic": false, + "info": "The name of the collection within AstraDB where the vectors will be stored.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "langflow" + }, + "metadata_indexing_exclude": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "metadata_indexing_exclude", + "display_name": "Metadata Indexing Exclude", + "advanced": true, + "dynamic": false, + "info": "Optional list of metadata fields to exclude from the indexing.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "metadata_indexing_include": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "metadata_indexing_include", + "display_name": "Metadata Indexing Include", + "advanced": true, + "dynamic": false, + "info": "Optional list of metadata fields to include in the indexing.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "metric": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "metric", + "display_name": "Metric", + "advanced": true, + "dynamic": false, + "info": "Optional distance metric for vector comparisons in the vector store.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "namespace": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "namespace", + "display_name": "Namespace", + "advanced": true, + "dynamic": false, + "info": "Optional namespace within AstraDB to use for the collection.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "number_of_results": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 4, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "number_of_results", + "display_name": "Number of Results", + "advanced": true, + "dynamic": false, + "info": "Number of results to return.", + "load_from_db": false, + "title_case": false + }, + "pre_delete_collection": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "pre_delete_collection", + "display_name": "Pre Delete Collection", + "advanced": true, + "dynamic": false, + "info": "Boolean flag to determine whether to delete the collection before creating a new one.", + "load_from_db": false, + "title_case": false + }, + "search_type": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "Similarity", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Similarity", + "MMR" + ], + "name": "search_type", + "display_name": "Search Type", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "setup_mode": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "Sync", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Sync", + "Async", + "Off" + ], + "name": "setup_mode", + "display_name": "Setup Mode", + "advanced": true, + "dynamic": false, + "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "token": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "token", + "display_name": "Token", + "advanced": false, + "dynamic": false, + "info": "Authentication token for accessing AstraDB.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "_type": "CustomComponent" + }, + "description": "Searches an existing AstraDB Vector Store.", + "icon": "AstraDB", + "base_classes": [ + "Record" + ], + "display_name": "AstraDB Search", + "documentation": "", + "custom_fields": { + "embedding": null, + "collection_name": null, + "input_value": null, + "token": null, + "api_endpoint": null, + "search_type": null, + "number_of_results": null, + "namespace": null, + "metric": null, + "batch_size": null, + "bulk_insert_batch_concurrency": null, + "bulk_insert_overwrite_concurrency": null, + "bulk_delete_concurrency": null, + "setup_mode": null, + "pre_delete_collection": null, + "metadata_indexing_include": null, + "metadata_indexing_exclude": null, + "collection_indexing_policy": null + }, + "output_types": [ + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [ + "token", + "api_endpoint", + "collection_name", + "input_value", + "embedding" + ], + "beta": false + }, + "id": "AstraDBSearch-41nRz" + }, + "selected": false, + "width": 384, + "height": 713, + "dragging": false, + "positionAbsolute": { + "x": 1723.976434815103, + "y": 277.03317407245913 + } + }, + { + "id": "AstraDB-eUCSS", + "type": "genericNode", + "position": { + "x": 3372.04958055989, + "y": 1611.0742035495277 + }, + "data": { + "type": "AstraDB", + "node": { + "template": { + "embedding": { + "type": "Embeddings", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "embedding", + "display_name": "Embedding", + "advanced": false, + "dynamic": false, + "info": "Embedding to use", + "load_from_db": false, + "title_case": false + }, + "inputs": { + "type": "Record", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "inputs", + "display_name": "Inputs", + "advanced": false, + "dynamic": false, + "info": "Optional list of records to be processed and stored in the vector store.", + "load_from_db": false, + "title_case": false + }, + "api_endpoint": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "api_endpoint", + "display_name": "API Endpoint", + "advanced": false, + "dynamic": false, + "info": "API endpoint URL for the AstraDB service.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "batch_size": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "batch_size", + "display_name": "Batch Size", + "advanced": true, + "dynamic": false, + "info": "Optional number of records to process in a single batch.", + "load_from_db": false, + "title_case": false + }, + "bulk_delete_concurrency": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "bulk_delete_concurrency", + "display_name": "Bulk Delete Concurrency", + "advanced": true, + "dynamic": false, + "info": "Optional concurrency level for bulk delete operations.", + "load_from_db": false, + "title_case": false + }, + "bulk_insert_batch_concurrency": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "bulk_insert_batch_concurrency", + "display_name": "Bulk Insert Batch Concurrency", + "advanced": true, + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations.", + "load_from_db": false, + "title_case": false + }, + "bulk_insert_overwrite_concurrency": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "bulk_insert_overwrite_concurrency", + "display_name": "Bulk Insert Overwrite Concurrency", + "advanced": true, + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations that overwrite existing records.", + "load_from_db": false, + "title_case": false + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"AstraDB\"\n description = \"Builds or loads an AstraDB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within AstraDB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing AstraDB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the AstraDB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within AstraDB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "collection_indexing_policy": { + "type": "dict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "collection_indexing_policy", + "display_name": "Collection Indexing Policy", + "advanced": true, + "dynamic": false, + "info": "Optional dictionary defining the indexing policy for the collection.", + "load_from_db": false, + "title_case": false + }, + "collection_name": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "collection_name", + "display_name": "Collection Name", + "advanced": false, + "dynamic": false, + "info": "The name of the collection within AstraDB where the vectors will be stored.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "langflow" + }, + "metadata_indexing_exclude": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "metadata_indexing_exclude", + "display_name": "Metadata Indexing Exclude", + "advanced": true, + "dynamic": false, + "info": "Optional list of metadata fields to exclude from the indexing.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "metadata_indexing_include": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "metadata_indexing_include", + "display_name": "Metadata Indexing Include", + "advanced": true, + "dynamic": false, + "info": "Optional list of metadata fields to include in the indexing.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "metric": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "metric", + "display_name": "Metric", + "advanced": true, + "dynamic": false, + "info": "Optional distance metric for vector comparisons in the vector store.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "namespace": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "namespace", + "display_name": "Namespace", + "advanced": true, + "dynamic": false, + "info": "Optional namespace within AstraDB to use for the collection.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "pre_delete_collection": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "pre_delete_collection", + "display_name": "Pre Delete Collection", + "advanced": true, + "dynamic": false, + "info": "Boolean flag to determine whether to delete the collection before creating a new one.", + "load_from_db": false, + "title_case": false + }, + "setup_mode": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "Async", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Sync", + "Async", + "Off" + ], + "name": "setup_mode", + "display_name": "Setup Mode", + "advanced": true, + "dynamic": false, + "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "token": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "token", + "display_name": "Token", + "advanced": false, + "dynamic": false, + "info": "Authentication token for accessing AstraDB.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "_type": "CustomComponent" + }, + "description": "Builds or loads an AstraDB Vector Store.", + "icon": "AstraDB", + "base_classes": [ + "VectorStore" + ], + "display_name": "AstraDB", + "documentation": "", + "custom_fields": { + "embedding": null, + "token": null, + "api_endpoint": null, + "collection_name": null, + "inputs": null, + "namespace": null, + "metric": null, + "batch_size": null, + "bulk_insert_batch_concurrency": null, + "bulk_insert_overwrite_concurrency": null, + "bulk_delete_concurrency": null, + "setup_mode": null, + "pre_delete_collection": null, + "metadata_indexing_include": null, + "metadata_indexing_exclude": null, + "collection_indexing_policy": null + }, + "output_types": [ + "VectorStore" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [ + "token", + "api_endpoint", + "collection_name", + "inputs", + "embedding" + ], + "beta": false + }, + "id": "AstraDB-eUCSS" + }, + "selected": false, + "width": 384, + "height": 573, + "positionAbsolute": { + "x": 3372.04958055989, + "y": 1611.0742035495277 + }, + "dragging": false + }, + { + "id": "OpenAIEmbeddings-9TPjc", + "type": "genericNode", + "position": { + "x": 2814.0402191223047, + "y": 1955.9268168273086 + }, + "data": { + "type": "OpenAIEmbeddings", + "node": { + "template": { + "allowed_special": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": [], + "fileTypes": [], + "file_path": "", + "password": false, + "name": "allowed_special", + "display_name": "Allowed Special", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "chunk_size": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 1000, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "chunk_size", + "display_name": "Chunk Size", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "client": { + "type": "Any", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "client", + "display_name": "Client", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-3-small\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-3-small\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "default_headers": { + "type": "dict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "default_headers", + "display_name": "Default Headers", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "default_query": { + "type": "NestedDict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": {}, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "default_query", + "display_name": "Default Query", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "deployment": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "text-embedding-3-small", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "deployment", + "display_name": "Deployment", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "disallowed_special": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": [ + "all" + ], + "fileTypes": [], + "file_path": "", + "password": false, + "name": "disallowed_special", + "display_name": "Disallowed Special", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "embedding_ctx_length": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 8191, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "embedding_ctx_length", + "display_name": "Embedding Context Length", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "max_retries": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 6, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "max_retries", + "display_name": "Max Retries", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "model": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "text-embedding-3-small", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "text-embedding-3-small", + "text-embedding-3-large", + "text-embedding-ada-002" + ], + "name": "model", + "display_name": "Model", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "model_kwargs": { + "type": "NestedDict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": {}, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "model_kwargs", + "display_name": "Model Kwargs", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "openai_api_base": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_base", + "display_name": "OpenAI API Base", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_key": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_key", + "display_name": "OpenAI API Key", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "openai_api_type": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_type", + "display_name": "OpenAI API Type", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_version": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_api_version", + "display_name": "OpenAI API Version", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_organization": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_organization", + "display_name": "OpenAI Organization", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_proxy": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_proxy", + "display_name": "OpenAI Proxy", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "request_timeout": { + "type": "float", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "request_timeout", + "display_name": "Request Timeout", + "advanced": true, + "dynamic": false, + "info": "", + "rangeSpec": { + "step_type": "float", + "min": -1, + "max": 1, + "step": 0.1 + }, + "load_from_db": false, + "title_case": false + }, + "show_progress_bar": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "show_progress_bar", + "display_name": "Show Progress Bar", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "skip_empty": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "skip_empty", + "display_name": "Skip Empty", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "tiktoken_enable": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "tiktoken_enable", + "display_name": "TikToken Enable", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "tiktoken_model_name": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "tiktoken_model_name", + "display_name": "TikToken Model Name", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Generate embeddings using OpenAI models.", + "base_classes": [ + "Embeddings" + ], + "display_name": "OpenAI Embeddings", + "documentation": "", + "custom_fields": { + "openai_api_key": null, + "default_headers": null, + "default_query": null, + "allowed_special": null, + "disallowed_special": null, + "chunk_size": null, + "client": null, + "deployment": null, + "embedding_ctx_length": null, + "max_retries": null, + "model": null, + "model_kwargs": null, + "openai_api_base": null, + "openai_api_type": null, + "openai_api_version": null, + "openai_organization": null, + "openai_proxy": null, + "request_timeout": null, + "show_progress_bar": null, + "skip_empty": null, + "tiktoken_enable": null, + "tiktoken_model_name": null + }, + "output_types": [ + "Embeddings" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "OpenAIEmbeddings-9TPjc" + }, + "selected": false, + "width": 384, + "height": 383, + "positionAbsolute": { + "x": 2814.0402191223047, + "y": 1955.9268168273086 + }, + "dragging": false + } + ], + "edges": [ + { + "source": "TextOutput-BDknO", + "target": "Prompt-xeI6K", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextOutputœ,œidœ:œTextOutput-BDknOœ}", + "targetHandle": "{œfieldNameœ:œcontextœ,œidœ:œPrompt-xeI6Kœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-TextOutput-BDknO{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextOutputœ,œidœ:œTextOutput-BDknOœ}-Prompt-xeI6K{œfieldNameœ:œcontextœ,œidœ:œPrompt-xeI6Kœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "context", + "id": "Prompt-xeI6K", + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "Text", + "str" + ], + "dataType": "TextOutput", + "id": "TextOutput-BDknO" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "selected": false + }, + { + "source": "ChatInput-yxMKE", + "target": "Prompt-xeI6K", + "sourceHandle": "{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ,œRecordœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-yxMKEœ}", + "targetHandle": "{œfieldNameœ:œquestionœ,œidœ:œPrompt-xeI6Kœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-yxMKE{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ,œRecordœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-yxMKEœ}-Prompt-xeI6K{œfieldNameœ:œquestionœ,œidœ:œPrompt-xeI6Kœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "question", + "id": "Prompt-xeI6K", + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "Text", + "str", + "object", + "Record" + ], + "dataType": "ChatInput", + "id": "ChatInput-yxMKE" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "selected": false + }, + { + "source": "Prompt-xeI6K", + "target": "OpenAIModel-EjXlN", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-xeI6Kœ}", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-EjXlNœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-xeI6K{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-xeI6Kœ}-OpenAIModel-EjXlN{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-EjXlNœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-EjXlN", + "inputTypes": [ + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "Text", + "str" + ], + "dataType": "Prompt", + "id": "Prompt-xeI6K" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "selected": false + }, + { + "source": "OpenAIModel-EjXlN", + "target": "ChatOutput-Q39I8", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-EjXlNœ}", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-Q39I8œ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-OpenAIModel-EjXlN{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-EjXlNœ}-ChatOutput-Q39I8{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-Q39I8œ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-Q39I8", + "inputTypes": [ + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "Text", + "str" + ], + "dataType": "OpenAIModel", + "id": "OpenAIModel-EjXlN" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "selected": false + }, + { + "source": "File-t0a6a", + "target": "RecursiveCharacterTextSplitter-tR9QM", + "sourceHandle": "{œbaseClassesœ:[œRecordœ],œdataTypeœ:œFileœ,œidœ:œFile-t0a6aœ}", + "targetHandle": "{œfieldNameœ:œinputsœ,œidœ:œRecursiveCharacterTextSplitter-tR9QMœ,œinputTypesœ:[œDocumentœ,œRecordœ],œtypeœ:œDocumentœ}", + "id": "reactflow__edge-File-t0a6a{œbaseClassesœ:[œRecordœ],œdataTypeœ:œFileœ,œidœ:œFile-t0a6aœ}-RecursiveCharacterTextSplitter-tR9QM{œfieldNameœ:œinputsœ,œidœ:œRecursiveCharacterTextSplitter-tR9QMœ,œinputTypesœ:[œDocumentœ,œRecordœ],œtypeœ:œDocumentœ}", + "data": { + "targetHandle": { + "fieldName": "inputs", + "id": "RecursiveCharacterTextSplitter-tR9QM", + "inputTypes": [ + "Document", + "Record" + ], + "type": "Document" + }, + "sourceHandle": { + "baseClasses": [ + "Record" + ], + "dataType": "File", + "id": "File-t0a6a" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "selected": false + }, + { + "source": "OpenAIEmbeddings-ZlOk1", + "sourceHandle": "{œbaseClassesœ:[œEmbeddingsœ],œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-ZlOk1œ}", + "target": "AstraDBSearch-41nRz", + "targetHandle": "{œfieldNameœ:œembeddingœ,œidœ:œAstraDBSearch-41nRzœ,œinputTypesœ:null,œtypeœ:œEmbeddingsœ}", + "data": { + "targetHandle": { + "fieldName": "embedding", + "id": "AstraDBSearch-41nRz", + "inputTypes": null, + "type": "Embeddings" + }, + "sourceHandle": { + "baseClasses": [ + "Embeddings" + ], + "dataType": "OpenAIEmbeddings", + "id": "OpenAIEmbeddings-ZlOk1" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-OpenAIEmbeddings-ZlOk1{œbaseClassesœ:[œEmbeddingsœ],œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-ZlOk1œ}-AstraDBSearch-41nRz{œfieldNameœ:œembeddingœ,œidœ:œAstraDBSearch-41nRzœ,œinputTypesœ:null,œtypeœ:œEmbeddingsœ}" + }, + { + "source": "ChatInput-yxMKE", + "sourceHandle": "{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ,œRecordœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-yxMKEœ}", + "target": "AstraDBSearch-41nRz", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAstraDBSearch-41nRzœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "AstraDBSearch-41nRz", + "inputTypes": [ + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "Text", + "str", + "object", + "Record" + ], + "dataType": "ChatInput", + "id": "ChatInput-yxMKE" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-ChatInput-yxMKE{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ,œRecordœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-yxMKEœ}-AstraDBSearch-41nRz{œfieldNameœ:œinput_valueœ,œidœ:œAstraDBSearch-41nRzœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" + }, + { + "source": "RecursiveCharacterTextSplitter-tR9QM", + "sourceHandle": "{œbaseClassesœ:[œRecordœ],œdataTypeœ:œRecursiveCharacterTextSplitterœ,œidœ:œRecursiveCharacterTextSplitter-tR9QMœ}", + "target": "AstraDB-eUCSS", + "targetHandle": "{œfieldNameœ:œinputsœ,œidœ:œAstraDB-eUCSSœ,œinputTypesœ:null,œtypeœ:œRecordœ}", + "data": { + "targetHandle": { + "fieldName": "inputs", + "id": "AstraDB-eUCSS", + "inputTypes": null, + "type": "Record" + }, + "sourceHandle": { + "baseClasses": [ + "Record" + ], + "dataType": "RecursiveCharacterTextSplitter", + "id": "RecursiveCharacterTextSplitter-tR9QM" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-RecursiveCharacterTextSplitter-tR9QM{œbaseClassesœ:[œRecordœ],œdataTypeœ:œRecursiveCharacterTextSplitterœ,œidœ:œRecursiveCharacterTextSplitter-tR9QMœ}-AstraDB-eUCSS{œfieldNameœ:œinputsœ,œidœ:œAstraDB-eUCSSœ,œinputTypesœ:null,œtypeœ:œRecordœ}", + "selected": false + }, + { + "source": "OpenAIEmbeddings-9TPjc", + "sourceHandle": "{œbaseClassesœ:[œEmbeddingsœ],œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-9TPjcœ}", + "target": "AstraDB-eUCSS", + "targetHandle": "{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-eUCSSœ,œinputTypesœ:null,œtypeœ:œEmbeddingsœ}", + "data": { + "targetHandle": { + "fieldName": "embedding", + "id": "AstraDB-eUCSS", + "inputTypes": null, + "type": "Embeddings" + }, + "sourceHandle": { + "baseClasses": [ + "Embeddings" + ], + "dataType": "OpenAIEmbeddings", + "id": "OpenAIEmbeddings-9TPjc" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-OpenAIEmbeddings-9TPjc{œbaseClassesœ:[œEmbeddingsœ],œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-9TPjcœ}-AstraDB-eUCSS{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-eUCSSœ,œinputTypesœ:null,œtypeœ:œEmbeddingsœ}", + "selected": false + }, + { + "source": "AstraDBSearch-41nRz", + "sourceHandle": "{œbaseClassesœ:[œRecordœ],œdataTypeœ:œAstraDBSearchœ,œidœ:œAstraDBSearch-41nRzœ}", + "target": "TextOutput-BDknO", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-BDknOœ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "TextOutput-BDknO", + "inputTypes": [ + "Record", + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "Record" + ], + "dataType": "AstraDBSearch", + "id": "AstraDBSearch-41nRz" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-AstraDBSearch-41nRz{œbaseClassesœ:[œRecordœ],œdataTypeœ:œAstraDBSearchœ,œidœ:œAstraDBSearch-41nRzœ}-TextOutput-BDknO{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-BDknOœ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}" + } + ], + "viewport": { + "x": -259.6782520315529, + "y": 90.3428735006047, + "zoom": 0.2687057134854984 + } + }, + "description": "Visit https://pre-release.langflow.org/guides/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an AstraDB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the AstraDB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", + "name": "Vector Store RAG", + "last_tested_version": "1.0.0a0", + "is_component": false +} \ No newline at end of file diff --git a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx index 010a1815d..8ba328cfe 100644 --- a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx +++ b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx @@ -83,7 +83,7 @@ export default function UndrawCardComponent({ }} /> ); - case "Prompt Chaining": + case "Vector Store RAG": return ( e.name == "Document QA")!} /> )} - {examples.find((e) => e.name == "Prompt Chaining") && ( - e.name == "Prompt Chaining")!} - /> - )} {examples.find((e) => e.name == "Blog Writer") && ( e.name == "Blog Writer")!} /> )} + {examples.find((e) => e.name == "Vector Store RAG") && ( + e.name == "Vector Store RAG")!} + /> + )} From b545712c4cf50e0fe8e2bd45b3a215f303ccd753 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 16:33:59 -0300 Subject: [PATCH 02/54] Add starter projects to sidebars.js --- docs/docs/migration/api.mdx | 0 docs/docs/starter-projects/basic-prompting.mdx | 0 docs/docs/starter-projects/blog-writer.mdx | 0 docs/docs/starter-projects/document-qa.mdx | 0 docs/docs/starter-projects/memory-chatbot.mdx | 0 .../rag-with-astradb.mdx | 4 ++-- docs/sidebars.js | 15 +++++++++++++-- 7 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 docs/docs/migration/api.mdx create mode 100644 docs/docs/starter-projects/basic-prompting.mdx create mode 100644 docs/docs/starter-projects/blog-writer.mdx create mode 100644 docs/docs/starter-projects/document-qa.mdx create mode 100644 docs/docs/starter-projects/memory-chatbot.mdx rename docs/docs/{guides => starter-projects}/rag-with-astradb.mdx (96%) diff --git a/docs/docs/migration/api.mdx b/docs/docs/migration/api.mdx new file mode 100644 index 000000000..e69de29bb diff --git a/docs/docs/starter-projects/basic-prompting.mdx b/docs/docs/starter-projects/basic-prompting.mdx new file mode 100644 index 000000000..e69de29bb diff --git a/docs/docs/starter-projects/blog-writer.mdx b/docs/docs/starter-projects/blog-writer.mdx new file mode 100644 index 000000000..e69de29bb diff --git a/docs/docs/starter-projects/document-qa.mdx b/docs/docs/starter-projects/document-qa.mdx new file mode 100644 index 000000000..e69de29bb diff --git a/docs/docs/starter-projects/memory-chatbot.mdx b/docs/docs/starter-projects/memory-chatbot.mdx new file mode 100644 index 000000000..e69de29bb diff --git a/docs/docs/guides/rag-with-astradb.mdx b/docs/docs/starter-projects/rag-with-astradb.mdx similarity index 96% rename from docs/docs/guides/rag-with-astradb.mdx rename to docs/docs/starter-projects/rag-with-astradb.mdx index 4d9fec45e..baae6288c 100644 --- a/docs/docs/guides/rag-with-astradb.mdx +++ b/docs/docs/starter-projects/rag-with-astradb.mdx @@ -187,8 +187,8 @@ Once we interact with it we get a response and the Extracted Chunks section is u style={{ width: "80%" }} /> -And that's it! You have successfully built a RAG application using AstraDB and Langflow. +And that's it! You have successfully ran a RAG application using AstraDB and Langflow. # Conclusion -In this guide, we have learned how to build a RAG application using AstraDB and Langflow. We have seen how to create an AstraDB database, import the AstraDB RAG Flows project into Langflow, and run the ingestion and RAG flows. +In this guide, we have learned how to run a RAG application using AstraDB and Langflow. We have seen how to create an AstraDB database, import the AstraDB RAG Flows project into Langflow, and run the ingestion and RAG flows. diff --git a/docs/sidebars.js b/docs/sidebars.js index 6f8cd3411..029ccf94e 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -20,12 +20,23 @@ module.exports = { "whats-new/migrating-to-one-point-zero", ], }, + { + type: "category", + label: " Starter Projects", + collapsed: false, + items: [ + "starter-projects/rag-with-astradb", + "starter-projects/basic-prompting", + "starter-projects/memory-chatbot", + "starter-projects/document-qa", + "starter-projects/blog-writer", + ], + }, { type: "category", label: " Step-by-Step Guides", collapsed: false, items: [ - "guides/rag-with-astradb", "guides/async-tasks", "guides/loading_document", "guides/chatprompttemplate_guide", @@ -83,7 +94,7 @@ module.exports = { "components/models", "components/helpers", "components/vector-stores", - "components/embeddings", + "components/embeddings", ], }, { From 2f0ce80d193beefd0ee7fe7ecfd2fe3f0c9adca8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 16:47:31 -0300 Subject: [PATCH 03/54] Fix error handling in DirectoryReader class --- .../custom/directory_reader/directory_reader.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py index 9ffb9825d..83075eeb3 100644 --- a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py +++ b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py @@ -3,9 +3,11 @@ import os import zlib from pathlib import Path -from langflow.interface.custom.custom_component import CustomComponent from loguru import logger +from langflow.interface.custom.custom_component import CustomComponent +from langflow.interface.custom.custom_component import CustomComponent + class CustomComponentPathValueError(ValueError): pass @@ -198,7 +200,12 @@ class DirectoryReader: Process a file by validating its content and returning the result and content/error message. """ - file_content = self.read_file_content(file_path) + try: + file_content = self.read_file_content(file_path) + except Exception as exc: + logger.exception(exc) + logger.error(f"Error while reading file {file_path}: {str(exc)}") + return False, f"Could not read {file_path}" if file_content is None: return False, f"Could not read {file_path}" From 81757f006fe25b725fa1c523feb4ab51487efb44 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 16:47:37 -0300 Subject: [PATCH 04/54] Handle exception when loading components in setup.py --- src/backend/base/langflow/initial_setup/setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/base/langflow/initial_setup/setup.py b/src/backend/base/langflow/initial_setup/setup.py index cf958d0c2..33e839689 100644 --- a/src/backend/base/langflow/initial_setup/setup.py +++ b/src/backend/base/langflow/initial_setup/setup.py @@ -197,7 +197,11 @@ def delete_start_projects(session): def create_or_update_starter_projects(): components_paths = get_settings_service().settings.COMPONENTS_PATH - all_types_dict = get_all_components(components_paths, as_dict=True) + try: + all_types_dict = get_all_components(components_paths, as_dict=True) + except Exception as e: + logger.exception(f"Error loading components: {e}") + raise e with session_scope() as session: starter_projects = load_starter_projects() delete_start_projects(session) From 96ae4da44f2e8b846d2d77dc3ae6c5c338ad7a50 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 16:49:56 -0300 Subject: [PATCH 05/54] Update version numbers in pyproject.toml files --- poetry.lock | 488 +++++++++++++++++--------------- pyproject.toml | 2 +- src/backend/base/poetry.lock | 339 +++++++++++----------- src/backend/base/pyproject.toml | 2 +- 4 files changed, 429 insertions(+), 402 deletions(-) diff --git a/poetry.lock b/poetry.lock index f27242d09..cb8e68605 100644 --- a/poetry.lock +++ b/poetry.lock @@ -455,17 +455,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.75" +version = "1.34.77" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.75-py3-none-any.whl", hash = "sha256:ba5d2104bba4370766036d64ad9021eb6289d154265852a2a821ec6a5e816faa"}, - {file = "boto3-1.34.75.tar.gz", hash = "sha256:eaec72fda124084105a31bcd67eafa1355b34df6da70cadae0c0f262d8a4294f"}, + {file = "boto3-1.34.77-py3-none-any.whl", hash = "sha256:7abd327980258ec2ae980d2ff7fc32ede7448146b14d34c56bf0be074e2a149b"}, + {file = "boto3-1.34.77.tar.gz", hash = "sha256:8ebed4fa5a3b84dd4037f28226985af00e00fb860d739fc8b1ed6381caa4b330"}, ] [package.dependencies] -botocore = ">=1.34.75,<1.35.0" +botocore = ">=1.34.77,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -474,13 +474,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.75" +version = "1.34.77" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.75-py3-none-any.whl", hash = "sha256:1d7f683d99eba65076dfb9af3b42fa967c64f11111d9699b65757420902aa002"}, - {file = "botocore-1.34.75.tar.gz", hash = "sha256:06113ee2587e6160211a6bd797e135efa6aa21b5bde97bf455c02f7dff40203c"}, + {file = "botocore-1.34.77-py3-none-any.whl", hash = "sha256:6d6a402032ca0b89525212356a865397f8f2839683dd53d41b8cee1aa84b2b4b"}, + {file = "botocore-1.34.77.tar.gz", hash = "sha256:6dab60261cdbfb7d0059488ea39408d5522fad419c004ba5db3484e6df854ea8"}, ] [package.dependencies] @@ -1129,13 +1129,13 @@ testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] [[package]] name = "cohere" -version = "5.1.7" +version = "5.2.1" description = "" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "cohere-5.1.7-py3-none-any.whl", hash = "sha256:66e149425ba10d9d6ed2980ad869afae2ed79b1f4c375f215ff4953f389cf5f9"}, - {file = "cohere-5.1.7.tar.gz", hash = "sha256:5b5ba38e614313d96f4eb362046a3470305e57119e39538afa3220a27614ba15"}, + {file = "cohere-5.2.1-py3-none-any.whl", hash = "sha256:c694f9d2cdafd87443f54ea5238b51a0fb807f119673e00b814c2a2993368e38"}, + {file = "cohere-5.2.1.tar.gz", hash = "sha256:7cd5522bb162c05c67b2db0b7aba2a103622e17ece9e885f5ef2de66bb67a324"}, ] [package.dependencies] @@ -1143,6 +1143,7 @@ fastavro = ">=1.9.4,<2.0.0" httpx = ">=0.21.2" pydantic = ">=1.9.2" requests = ">=2.31.0,<3.0.0" +tokenizers = ">=0.15.2,<0.16.0" types-requests = ">=2.31.0.20240311,<3.0.0.0" typing_extensions = ">=4.0.0" @@ -2560,13 +2561,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-api-python-client" -version = "2.124.0" +version = "2.125.0" description = "Google API Client Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-python-client-2.124.0.tar.gz", hash = "sha256:f6d3258420f7c76b0f5266b5e402e6f804e30351b018a10083f4a46c3ec33773"}, - {file = "google_api_python_client-2.124.0-py2.py3-none-any.whl", hash = "sha256:07dc674449ed353704b1169fdee792f74438d024261dad71b6ce7bb9c683d51f"}, + {file = "google-api-python-client-2.125.0.tar.gz", hash = "sha256:51a0385cff65ec135106e8be60ee7112557396dde5f44113ae23912baddda143"}, + {file = "google_api_python_client-2.125.0-py2.py3-none-any.whl", hash = "sha256:0a62b60fbd61b61a455f15d925264b3301099b67cafd2d33cf8bf151f1fca4f4"}, ] [package.dependencies] @@ -3772,13 +3773,13 @@ numpy = ">=1,<2" [[package]] name = "langchain-cohere" -version = "0.1.0rc1" +version = "0.1.0" description = "An integration package connecting Cohere and LangChain" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_cohere-0.1.0rc1-py3-none-any.whl", hash = "sha256:698ee4e889169c1115bc2b0992c152aafd574030e6ea18238dd6b5d034733c64"}, - {file = "langchain_cohere-0.1.0rc1.tar.gz", hash = "sha256:cc91b33cc5c6cb8d04c12034366c52b94798313d4503b776de9345e7261e8d15"}, + {file = "langchain_cohere-0.1.0-py3-none-any.whl", hash = "sha256:f60e9eb41f7d4ead9659bddb3fae7aa18ddc3fdf2b2867be4bd8a565229f488d"}, + {file = "langchain_cohere-0.1.0.tar.gz", hash = "sha256:960551293ea58d170fad37d44657d3ae4587f6b2e8f3f58922c53c59b9e9d85c"}, ] [package.dependencies] @@ -3813,13 +3814,13 @@ extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15. [[package]] name = "langchain-core" -version = "0.1.38" +version = "0.1.40" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_core-0.1.38-py3-none-any.whl", hash = "sha256:d881b2754254cb4bdb0d5bb56e5c138d032b6e75e5cb21f151b01224b322e02b"}, - {file = "langchain_core-0.1.38.tar.gz", hash = "sha256:ee8da6d061c06cce7dc22fec224b6ecbc3a8de106d6dd9f409c7fe448ea41861"}, + {file = "langchain_core-0.1.40-py3-none-any.whl", hash = "sha256:618dbb7ab44d8b263b91e384db1ff07d0db256ae5bdafa0123a115b6a75a13f1"}, + {file = "langchain_core-0.1.40.tar.gz", hash = "sha256:34c06fc0e6d3534b738c63f85403446b4be71161665b7e091f9bb19c914ec100"}, ] [package.dependencies] @@ -3828,7 +3829,6 @@ langsmith = ">=0.1.0,<0.2.0" packaging = ">=23.2,<24.0" pydantic = ">=1,<3" PyYAML = ">=5.3" -requests = ">=2,<3" tenacity = ">=8.1.0,<9.0.0" [package.extras] @@ -3920,7 +3920,7 @@ six = "*" [[package]] name = "langflow-base" -version = "0.0.16" +version = "0.0.17" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.12" @@ -3973,13 +3973,13 @@ url = "src/backend/base" [[package]] name = "langfuse" -version = "2.21.1" +version = "2.21.2" description = "A client library for accessing langfuse" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langfuse-2.21.1-py3-none-any.whl", hash = "sha256:5ef286823a4c9903e2120ad2bf0169a929d41789702535abc713e66a0d270f05"}, - {file = "langfuse-2.21.1.tar.gz", hash = "sha256:36494ea016784ac339a1a5375b88c33484e81668433956ead442d7a93c217078"}, + {file = "langfuse-2.21.2-py3-none-any.whl", hash = "sha256:bd65858e6326776f65c9b2e414e64fdea0f14402f5c784952af93346dfd489bb"}, + {file = "langfuse-2.21.2.tar.gz", hash = "sha256:eb7911aa640f020f097cb56eaa7d67f01d39f9e2bdd6226e0c5d642a87f3663c"}, ] [package.dependencies] @@ -3992,18 +3992,18 @@ wrapt = ">=1.14,<2.0" [package.extras] langchain = ["langchain (>=0.0.309)"] -llama-index = ["llama-index (>=0.10.12,<0.11.0)"] +llama-index = ["llama-index (>=0.10.12,<2.0.0)"] openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.38" +version = "0.1.39" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.38-py3-none-any.whl", hash = "sha256:f36479f82cf537cf40d129ac2e485e72a3981360c7b6cf2549dad77d98eafd8f"}, - {file = "langsmith-0.1.38.tar.gz", hash = "sha256:2c1f98ac0a8c02e43b625650a6e13c65b09523551bfc21a59d20963f46f7d265"}, + {file = "langsmith-0.1.39-py3-none-any.whl", hash = "sha256:85c19177162585728001cb7ae91ab48ca4abe39b7bc1ff783212ac426ded222b"}, + {file = "langsmith-0.1.39.tar.gz", hash = "sha256:2aec9d2f9cc664042d2121b13da569b0902aff842c86b17b440245d57da84ec5"}, ] [package.dependencies] @@ -4030,12 +4030,12 @@ regex = ["regex"] [[package]] name = "llama-cpp-python" -version = "0.2.58" +version = "0.2.59" description = "Python bindings for the llama.cpp library" optional = true python-versions = ">=3.8" files = [ - {file = "llama_cpp_python-0.2.58.tar.gz", hash = "sha256:50d4d16835326b15f5c4ed20dbf2f24508bf29b34531d50612ce215a596dde3f"}, + {file = "llama_cpp_python-0.2.59.tar.gz", hash = "sha256:4b19283226ab91c74c6d811d88724a6f32d9dd7d07caf9d8b897dd3372d5d4d2"}, ] [package.dependencies] @@ -4077,18 +4077,19 @@ llama-index-readers-llama-parse = ">=0.1.2,<0.2.0" [[package]] name = "llama-index-agent-openai" -version = "0.2.1" +version = "0.2.2" description = "llama-index agent openai integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_agent_openai-0.2.1-py3-none-any.whl", hash = "sha256:0127414bd0afcdd2eb5f7f97dc9693653ca435160fd09af83ac67fb3b07bf991"}, - {file = "llama_index_agent_openai-0.2.1.tar.gz", hash = "sha256:c9d0a2c43d2f752b80f7d3dd7e56e112c49dddbd06974973153cfdb9374b62b4"}, + {file = "llama_index_agent_openai-0.2.2-py3-none-any.whl", hash = "sha256:fa8cbc2c7be5a465848f8d5b432db01c55f07dfa06357edb7fb77fb17d534d1e"}, + {file = "llama_index_agent_openai-0.2.2.tar.gz", hash = "sha256:12063dd932c74015796f973986cc52d783f51fda38e4ead72a56d0fd195925ee"}, ] [package.dependencies] llama-index-core = ">=0.10.1,<0.11.0" llama-index-llms-openai = ">=0.1.5,<0.2.0" +openai = ">=1.14.0" [[package]] name = "llama-index-cli" @@ -4328,13 +4329,13 @@ llama-index-core = ">=0.10.7" [[package]] name = "llamaindex-py-client" -version = "0.1.15" +version = "0.1.16" description = "" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "llamaindex_py_client-0.1.15-py3-none-any.whl", hash = "sha256:d189f23a8f7f78d0e170f62b531dd6ac030eadcb7dd7d38c1b543c4c98c51e5c"}, - {file = "llamaindex_py_client-0.1.15.tar.gz", hash = "sha256:c7ce26855ba976153bb40157c3c194223c6b75179935b988dd4bd6a3fe83aacb"}, + {file = "llamaindex_py_client-0.1.16-py3-none-any.whl", hash = "sha256:b34e0a14984468f46ff5eebfe4b2b88598a24ff9459338a5621eee78e58bf0db"}, + {file = "llamaindex_py_client-0.1.16.tar.gz", hash = "sha256:e99bbc0855e6caaa75eba219cdb3cf6c943ae94fa15ccbb68a3a08d452fd6380"}, ] [package.dependencies] @@ -4388,124 +4389,165 @@ dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptio [[package]] name = "lxml" -version = "5.2.0" +version = "5.2.1" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c54f8d6160080831a76780d850302fdeb0e8d0806f661777b0714dfb55d9a08a"}, - {file = "lxml-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e95ae029396382a0d2e8174e4077f96befcd4a2184678db363ddc074eb4d3b2"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5810fa80e64a0c689262a71af999c5735f48c0da0affcbc9041d1ef5ef3920be"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae69524fd6a68b288574013f8fadac23cacf089c75cd3fc5b216277a445eb736"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fadda215e32fe375d65e560b7f7e2a37c7f9c4ecee5315bb1225ca6ac9bf5838"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:f1f164e4cc6bc646b1fc86664c3543bf4a941d45235797279b120dc740ee7af5"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:3603a8a41097daf7672cae22cc4a860ab9ea5597f1c5371cb21beca3398b8d6a"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3b4bb89a785f4fd60e05f3c3a526c07d0d68e3536f17f169ca13bf5b5dd75a5"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1effc10bf782f0696e76ecfeba0720ea02c0c31d5bffb7b29ba10debd57d1c3d"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b03531f6cd6ce4b511dcece060ca20aa5412f8db449274b44f4003f282e6272f"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fac15090bb966719df06f0c4f8139783746d1e60e71016d8a65db2031ca41b8"}, - {file = "lxml-5.2.0-cp310-cp310-win32.whl", hash = "sha256:92bb37c96215c4b2eb26f3c791c0bf02c64dd251effa532b43ca5049000c4478"}, - {file = "lxml-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:b0181c22fdb89cc19e70240a850e5480817c3e815b1eceb171b3d7a3aa3e596a"}, - {file = "lxml-5.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ada8ce9e6e1d126ef60d215baaa0c81381ba5841c25f1d00a71cdafdc038bd27"}, - {file = "lxml-5.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cefb133c859f06dab2ae63885d9f405000c4031ec516e0ed4f9d779f690d8e3"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ede2a7a86a977b0c741654efaeca0af7860a9b1ae39f9268f0936246a977ee0"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d46df6f0b1a0cda39d12c5c4615a7d92f40342deb8001c7b434d7c8c78352e58"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2259243ee734cc736e237719037efb86603c891fd363cc7973a2d0ac8a0e3f"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c53164f29ed3c3868787144e8ea8a399ffd7d8215f59500a20173593c19e96eb"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:371aab9a397dcc76625ad3b02fa9b21be63406d69237b773156e7d1fc2ce0cae"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e08784288a179b59115b5e57abf6d387528b39abb61105fe17510a199a277a40"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c232726f7b6df5143415a06323faaa998ef8abbe1c0ed00d718755231d76f08"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e4366e58c0508da4dee4c7c70cee657e38553d73abdffa53abbd7d743711ee11"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c84dce8fb2e900d4fb094e76fdad34a5fd06de53e41bddc1502c146eb11abd74"}, - {file = "lxml-5.2.0-cp311-cp311-win32.whl", hash = "sha256:0947d1114e337dc2aae2fa14bbc9ed5d9ca1a0acd6d2f948df9926aef65305e9"}, - {file = "lxml-5.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1eace37a9f4a1bef0bb5c849434933fd6213008ec583c8e31ee5b8e99c7c8500"}, - {file = "lxml-5.2.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f2cb157e279d28c66b1c27e0948687dc31dc47d1ab10ce0cd292a8334b7de3d5"}, - {file = "lxml-5.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:53c0e56f41ef68c1ce4e96f27ecdc2df389730391a2fd45439eb3facb02d36c8"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703d60e59ab45c17485c2c14b11880e4f7f0eab07134afa9007573fa5a779a5a"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaf5e308a5e50bc0548c4fdca0117a31ec9596f8cfc96592db170bcecc71a957"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af64df85fecd3cf3b2e792f0b5b4d92740905adfa8ce3b24977a55415f1a0c40"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:df7dfbdef11702fd22c2eaf042d7098d17edbc62d73f2199386ad06cbe466f6d"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7250030a7835bfd5ba6ca7d1ad483ec90f9cbc29978c5e75c1cc3e031d3c4160"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:be5faa2d5c8c8294d770cfd09d119fb27b5589acc59635b0cf90f145dbe81dca"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:347ec08250d5950f5b016caa3e2e13fb2cb9714fe6041d52e3716fb33c208663"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:dc7b630c4fb428b8a40ddd0bfc4bc19de11bb3c9b031154f77360e48fe8b4451"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ae550cbd7f229cdf2841d9b01406bcca379a5fb327b9efb53ba620a10452e835"}, - {file = "lxml-5.2.0-cp312-cp312-win32.whl", hash = "sha256:7c61ce3cdd6e6c9f4003ac118be7eb3036d0ce2afdf23929e533e54482780f74"}, - {file = "lxml-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:f90c36ca95a44d2636bbf55a51ca30583b59b71b6547b88d954e029598043551"}, - {file = "lxml-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1cce2eaad7e38b985b0f91f18468dda0d6b91862d32bec945b0e46e2ffe7222e"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60a3983d32f722a8422c01e4dc4badc7a307ca55c59e2485d0e14244a52c482f"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60847dfbdfddf08a56c4eefe48234e8c1ab756c7eda4a2a7c1042666a5516564"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bbe335f0d1a86391671d975a1b5e9b08bb72fba6b567c43bdc2e55ca6e6c086"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_28_aarch64.whl", hash = "sha256:3ac7c8a60b8ad51fe7bca99a634dd625d66492c502fd548dc6dc769ce7d94b6a"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:73e69762cf740ac3ae81137ef9d6f15f93095f50854e233d50b29e7b8a91dbc6"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:281ee1ffeb0ab06204dfcd22a90e9003f0bb2dab04101ad983d0b1773bc10588"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ba3a86b0d5a5c93104cb899dff291e3ae13729c389725a876d00ef9696de5425"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:356f8873b1e27b81793e30144229adf70f6d3e36e5cb7b6d289da690f4398953"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:2a34e74ffe92c413f197ff4967fb1611d938ee0691b762d062ef0f73814f3aa4"}, - {file = "lxml-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:6f0d2b97a5a06c00c963d4542793f3e486b1ed3a957f8c19f6006ed39d104bb0"}, - {file = "lxml-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:35e39c6fd089ad6674eb52d93aa874d6027b3ae44d2381cca6e9e4c2e102c9c8"}, - {file = "lxml-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5f6e4e5a62114ae76690c4a04c5108d067442d0a41fd092e8abd25af1288c450"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93eede9bcc842f891b2267c7f0984d811940d1bc18472898a1187fe560907a99"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad364026c2cebacd7e01d1138bd53639822fefa8f7da90fc38cd0e6319a2699"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f06e4460e76468d99cc36d5b9bc6fc5f43e6662af44960e13e3f4e040aacb35"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:ca3236f31d565555139d5b00b790ed2a98ac6f0c4470c4032f8b5e5a5dba3c1a"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:a9b67b850ab1d304cb706cf71814b0e0c3875287083d7ec55ee69504a9c48180"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5261c858c390ae9a19aba96796948b6a2d56649cbd572968970dc8da2b2b2a42"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e8359fb610c8c444ac473cfd82dae465f405ff807cabb98a9b9712bbd0028751"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:f9e27841cddfaebc4e3ffbe5dbdff42891051acf5befc9f5323944b2c61cef16"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:641a8da145aca67671205f3e89bfec9815138cf2fe06653c909eab42e486d373"}, - {file = "lxml-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:931a3a13e0f574abce8f3152b207938a54304ccf7a6fd7dff1fdb2f6691d08af"}, - {file = "lxml-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:246c93e2503c710cf02c7e9869dc0258223cbefe5e8f9ecded0ac0aa07fd2bf8"}, - {file = "lxml-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:11acfcdf5a38cf89c48662123a5d02ae0a7d99142c7ee14ad90de5c96a9b6f06"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:200f70b5d95fc79eb9ed7f8c4888eef4e274b9bf380b829d3d52e9ed962e9231"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba4d02aed47c25be6775a40d55c5774327fdedba79871b7c2485e80e45750cb2"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e283b24c14361fe9e04026a1d06c924450415491b83089951d469509900d9f32"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:03e3962d6ad13a862dacd5b3a3ea60b4d092a550f36465234b8639311fd60989"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6e45fd5213e5587a610b7e7c8c5319a77591ab21ead42df46bb342e21bc1418d"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:27877732946843f4b6bfc56eb40d865653eef34ad2edeed16b015d5c29c248df"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4d16b44ad0dd8c948129639e34c8d301ad87ebc852568ace6fe9a5ad9ce67ee1"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b8f842df9ba26135c5414e93214e04fe0af259bb4f96a32f756f89467f7f3b45"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c74e77df9e36c8c91157853e6cd400f6f9ca7a803ba89981bfe3f3fc7e5651ef"}, - {file = "lxml-5.2.0-cp38-cp38-win32.whl", hash = "sha256:1459a998c10a99711ac532abe5cc24ba354e4396dafef741c7797f8830712d56"}, - {file = "lxml-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a00f5931b7cccea775123c3c0a2513aee58afdad8728550cc970bff32280bdd2"}, - {file = "lxml-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ddda5ba8831f258ac7e6364be03cb27aa62f50c67fd94bc1c3b6247959cc0369"}, - {file = "lxml-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56835b9e9a7767202fae06310c6b67478963e535fe185bed3bf9af5b18d2b67e"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25fef8794f0dc89f01bdd02df6a7fec4bcb2fbbe661d571e898167a83480185e"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32d44af078485c4da9a7ec460162392d49d996caf89516fa0b75ad0838047122"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f354d62345acdf22aa3e171bd9723790324a66fafe61bfe3873b86724cf6daaa"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6a7e0935f05e1cf1a3aa1d49a87505773b04f128660eac2a24a5594ea6b1baa7"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:75a4117b43694c72a0d89f6c18a28dc57407bde4650927d4ef5fd384bdf6dcc7"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:57402d6cdd8a897ce21cf8d1ff36683583c17a16322a321184766c89a1980600"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:56591e477bea531e5e1854f5dfb59309d5708669bc921562a35fd9ca5182bdcd"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7efbce96719aa275d49ad5357886845561328bf07e1d5ab998f4e3066c5ccf15"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a3c39def0965e8fb5c8d50973e0c7b4ce429a2fa730f3f9068a7f4f9ce78410b"}, - {file = "lxml-5.2.0-cp39-cp39-win32.whl", hash = "sha256:5188f22c00381cb44283ecb28c8d85c2db4a3035774dd851876c8647cb809c27"}, - {file = "lxml-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:ed1fe80e1fcdd1205a443bddb1ad3c3135bb1cd3f36cc996a1f4aed35960fbe8"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d2b339fb790fc923ae2e9345c8633e3d0064d37ea7920c027f20c8ae6f65a91f"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06036d60fccb21e22dd167f6d0e422b9cbdf3588a7e999a33799f9cbf01e41a5"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1611fb9de0a269c05575c024e6d8cdf2186e3fa52b364e3b03dcad82514d57"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:05fc3720250d221792b6e0d150afc92d20cb10c9cdaa8c8f93c2a00fbdd16015"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:11e41ffd3cd27b0ca1c76073b27bd860f96431d9b70f383990f1827ca19f2f52"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0382e6a3eefa3f6699b14fa77c2eb32af2ada261b75120eaf4fc028a20394975"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be5c8e776ecbcf8c1bce71a7d90e3a3680c9ceae516cac0be08b47e9fac0ca43"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da12b4efc93d53068888cb3b58e355b31839f2428b8f13654bd25d68b201c240"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f46f8033da364bacc74aca5e319509a20bb711c8a133680ca5f35020f9eaf025"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:50a26f68d090594477df8572babac64575cd5c07373f7a8319c527c8e56c0f99"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:57cbadf028727705086047994d2e50124650e63ce5a035b0aa79ab50f001989f"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8aa11638902ac23f944f16ce45c9f04c9d5d57bb2da66822abb721f4efe5fdbb"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b7150e630b879390e02121e71ceb1807f682b88342e2ea2082e2c8716cf8bd93"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4add722393c99da4d51c8d9f3e1ddf435b30677f2d9ba9aeaa656f23c1b7b580"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd0f25a431cd16f70ec1c47c10b413e7ddfe1ccaaddd1a7abd181e507c012374"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:883e382695f346c2ea3ad96bdbdf4ca531788fbeedb4352be3a8fcd169fc387d"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:80cc2b55bb6e35d3cb40936b658837eb131e9f16357241cd9ba106ae1e9c5ecb"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:59ec2948385336e9901008fdf765780fe30f03e7fdba8090aafdbe5d1b7ea0cd"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ddbea6e58cce1a640d9d65947f1e259423fc201c9cf9761782f355f53b7f3097"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52d6cdea438eb7282c41c5ac00bd6d47d14bebb6e8a8d2a1c168ed9e0cacfbab"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c556bbf88a8b667c849d326dd4dd9c6290ede5a33383ffc12b0ed17777f909d"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:947fa8bf15d1c62c6db36c6ede9389cac54f59af27010251747f05bddc227745"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e6cb8f7a332eaa2d876b649a748a445a38522e12f2168e5e838d1505a91cdbb7"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:16e65223f34fd3d65259b174f0f75a4bb3d9893698e5e7d01e54cd8c5eb98d85"}, - {file = "lxml-5.2.0.tar.gz", hash = "sha256:21dc490cdb33047bc7f7ad76384f3366fa8f5146b86cc04c4af45de901393b90"}, + {file = "lxml-5.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1"}, + {file = "lxml-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1"}, + {file = "lxml-5.2.1-cp310-cp310-win32.whl", hash = "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5"}, + {file = "lxml-5.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f"}, + {file = "lxml-5.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867"}, + {file = "lxml-5.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534"}, + {file = "lxml-5.2.1-cp311-cp311-win32.whl", hash = "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be"}, + {file = "lxml-5.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102"}, + {file = "lxml-5.2.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851"}, + {file = "lxml-5.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4"}, + {file = "lxml-5.2.1-cp312-cp312-win32.whl", hash = "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134"}, + {file = "lxml-5.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a"}, + {file = "lxml-5.2.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c"}, + {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0"}, + {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1"}, + {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461"}, + {file = "lxml-5.2.1-cp36-cp36m-win32.whl", hash = "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0"}, + {file = "lxml-5.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289"}, + {file = "lxml-5.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029"}, + {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af"}, + {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0"}, + {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8"}, + {file = "lxml-5.2.1-cp37-cp37m-win32.whl", hash = "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd"}, + {file = "lxml-5.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c"}, + {file = "lxml-5.2.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3e183c6e3298a2ed5af9d7a356ea823bccaab4ec2349dc9ed83999fd289d14d5"}, + {file = "lxml-5.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637"}, + {file = "lxml-5.2.1-cp38-cp38-win32.whl", hash = "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da"}, + {file = "lxml-5.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806"}, + {file = "lxml-5.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd"}, + {file = "lxml-5.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188"}, + {file = "lxml-5.2.1-cp39-cp39-win32.whl", hash = "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708"}, + {file = "lxml-5.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704"}, + {file = "lxml-5.2.1.tar.gz", hash = "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306"}, ] [package.extras] @@ -5478,13 +5520,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.16.0" +version = "1.16.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.16.0-py3-none-any.whl", hash = "sha256:c715c9872515369621ab16d31af917540b69af7d5df2d01b4c81f809cc17e91d"}, - {file = "openai-1.16.0.tar.gz", hash = "sha256:2d1f2b106f0efc35ac9590dd7e4d1fcc10c616bfdd7eae17829c07f9ea212517"}, + {file = "openai-1.16.1-py3-none-any.whl", hash = "sha256:77ef3db6110071f7154859e234250fb945a36554207a30a4491092eadb73fcb5"}, + {file = "openai-1.16.1.tar.gz", hash = "sha256:58922c785d167458b46e3c76e7b1bc2306f313ee9b71791e84cbf590abe160f2"}, ] [package.dependencies] @@ -6956,60 +6998,54 @@ zstd = ["zstandard"] [[package]] name = "pymupdf" -version = "1.24.0" +version = "1.24.1" description = "A high performance Python library for data extraction, analysis, conversion & manipulation of PDF (and other) documents." optional = false python-versions = ">=3.8" files = [ - {file = "PyMuPDF-1.24.0-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:37160eb301e017ec67bb63b1c6f52eae2c90bd1159f6a6b2ec469c3e69d55f74"}, - {file = "PyMuPDF-1.24.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:af2d8ba47851f2a5a2f7592453792a03cbcd705e40512e9aeb199edd7bcce886"}, - {file = "PyMuPDF-1.24.0-cp310-none-manylinux2014_aarch64.whl", hash = "sha256:f318efcfda3ca625b2b2318019d8195b2e239cf1e66eaf5a94cd1e6bd11999d2"}, - {file = "PyMuPDF-1.24.0-cp310-none-manylinux2014_x86_64.whl", hash = "sha256:986b234751e734da1b4f983fd270fa595258781abc25e26d409d96439136c41c"}, - {file = "PyMuPDF-1.24.0-cp310-none-win32.whl", hash = "sha256:490d10c85defec873bf33a54eea1e8cc637927c7efeaff3570b812d7c65256f7"}, - {file = "PyMuPDF-1.24.0-cp310-none-win_amd64.whl", hash = "sha256:2d46cd6535f25ffeb6261d389b932fa6359193a12de3633e200504898d48c27d"}, - {file = "PyMuPDF-1.24.0-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:9354c2654512390d261bad37a90168de0cb954be4e9b3d55073a67e8ca07f7f8"}, - {file = "PyMuPDF-1.24.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:bfc953361277cafa38e5bb93edd2b7c6c0c4284f137cea5847efe730759fe0d2"}, - {file = "PyMuPDF-1.24.0-cp311-none-manylinux2014_aarch64.whl", hash = "sha256:13625c9da4021e649da11acb60e0a8aa300fb6c4bdb450754f975d7f92043999"}, - {file = "PyMuPDF-1.24.0-cp311-none-manylinux2014_x86_64.whl", hash = "sha256:8db27eca7f6aa2c5aa84278cc9961a0183e8aca6d7210a5648658816ea9601bf"}, - {file = "PyMuPDF-1.24.0-cp311-none-win32.whl", hash = "sha256:fc4b7a212b9f3216bb32c1146340efe5282c1519f7250e52ccd9dedcfd04df5d"}, - {file = "PyMuPDF-1.24.0-cp311-none-win_amd64.whl", hash = "sha256:4e92d2895eb55b5475572bda167bb6d3c5b7757ba0b6beee0456ca0d3db852b2"}, - {file = "PyMuPDF-1.24.0-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:963759f1a2722d25d08e79e00db696e4f5342675bed3b2f2129f03a8d4c41b77"}, - {file = "PyMuPDF-1.24.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:96bcecd0a33b2de6954c4a3c677719cd1d1f36c1fe7dc4e229e06177aef8bdb7"}, - {file = "PyMuPDF-1.24.0-cp312-none-manylinux2014_aarch64.whl", hash = "sha256:b9fb4df0d584b1df3789f521e3950a930884fe0fdd28d4c4ef1c571f3fb9b56e"}, - {file = "PyMuPDF-1.24.0-cp312-none-manylinux2014_x86_64.whl", hash = "sha256:65fc88a23804b83b9390016d377d9350dece167e349140de93769618858ccf8d"}, - {file = "PyMuPDF-1.24.0-cp312-none-win32.whl", hash = "sha256:4395b420477620be4fc90567deb20f17eda5e9757e2ca95f7bc3854d2a6713cc"}, - {file = "PyMuPDF-1.24.0-cp312-none-win_amd64.whl", hash = "sha256:ee1188a8d9bf9dbf21aab8229c99472dd47af315a71753452210f40cff744a7b"}, - {file = "PyMuPDF-1.24.0-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:82ff0a4ed3a27de95726db1f10744c2865212eed2a28e3fd19a081b9c247028d"}, - {file = "PyMuPDF-1.24.0-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:9e9945d1af3ec6deff4c5d61edc63b9c68d49c2212df1104614e2ab173b1d158"}, - {file = "PyMuPDF-1.24.0-cp38-none-manylinux2014_aarch64.whl", hash = "sha256:f120a23a0690be2e6d3ec195c308582930c75fbf3fb6cb6785252a01454fb0ef"}, - {file = "PyMuPDF-1.24.0-cp38-none-manylinux2014_x86_64.whl", hash = "sha256:08bb534a046d7492ab7cf726ef9aa01a14791e53922ffc2a341fa617709434f2"}, - {file = "PyMuPDF-1.24.0-cp38-none-win32.whl", hash = "sha256:f428210b2fc7e0094dbcd62acc15554cb3ee9778a3429bf2d04850cfbab227fb"}, - {file = "PyMuPDF-1.24.0-cp38-none-win_amd64.whl", hash = "sha256:6731cc7ef76d972220bd1bb50d5b67720de2038312be23806045bcc5f9675951"}, - {file = "PyMuPDF-1.24.0-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:de1aa7825f3333dfbff26e88f9cd37491a625b783b8b4780a14e5f70ab6d9853"}, - {file = "PyMuPDF-1.24.0-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:160a3310f33fda1c0cfaed82d4e22a2aca960ebf5c6919982032727973e42830"}, - {file = "PyMuPDF-1.24.0-cp39-none-manylinux2014_aarch64.whl", hash = "sha256:ce6f1f0b3ca8023bdbbc90fd2428b05db5c7c4b581d785072200082924f6c82f"}, - {file = "PyMuPDF-1.24.0-cp39-none-manylinux2014_x86_64.whl", hash = "sha256:750908f95771fa0fcdbc690f6aae7e0031ff002c5ea343f12930e42da73e5c8b"}, - {file = "PyMuPDF-1.24.0-cp39-none-win32.whl", hash = "sha256:d193319e3850f4025dc1e3c8a6a0b03683668353aacf660d434668be51e3e464"}, - {file = "PyMuPDF-1.24.0-cp39-none-win_amd64.whl", hash = "sha256:e72b7ab4b2dfffe38ceed1e577ffaaa2e34117d87fc716b0238a6f2a12670fe4"}, - {file = "PyMuPDF-1.24.0.tar.gz", hash = "sha256:b6811b09af1ddb93229066f7acf183f6aeeeec4bf9c2290ff81fbeebbc5a4f79"}, + {file = "PyMuPDF-1.24.1-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:6427aee313e24447f57edbfc7a28aa6bbca007fe0ad77603f54a371c6c510eeb"}, + {file = "PyMuPDF-1.24.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:12078c0bee337de969dbd6d89ef446312794d74db365cb9ac14902b863b35414"}, + {file = "PyMuPDF-1.24.1-cp310-none-manylinux2014_x86_64.whl", hash = "sha256:caf6ceb1dbebe9f70bf7dd683cc91b896604a7c62873e5b50089f9e85e85c517"}, + {file = "PyMuPDF-1.24.1-cp310-none-win32.whl", hash = "sha256:468a8bb2b95828e0f6739fbfe509700cc0dac600f756d8cb6316316e1eba9689"}, + {file = "PyMuPDF-1.24.1-cp310-none-win_amd64.whl", hash = "sha256:e47504391908e2d721c743aed36196310a5e15355a85459c1c4ddcf8f2002fbe"}, + {file = "PyMuPDF-1.24.1-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:c54ff927257b432ffd39dc6a0a46bd1120e85d192100efca021f27d4b881cfd6"}, + {file = "PyMuPDF-1.24.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:6d412da9f9a73f66973eea4284776f292135906700a06c39122e862a1e3ccf58"}, + {file = "PyMuPDF-1.24.1-cp311-none-manylinux2014_x86_64.whl", hash = "sha256:9a3b21c8fc274ff42855ca2da65961e2319b05b75ef9e2caf25c04f9083ec79c"}, + {file = "PyMuPDF-1.24.1-cp311-none-win32.whl", hash = "sha256:8a81106a8bc229823736487d2492fd3af724a94521a1cd9b67849dd04b9c31ed"}, + {file = "PyMuPDF-1.24.1-cp311-none-win_amd64.whl", hash = "sha256:de5b6c4db4a2a9f28937e79135f732827c424f7444c12767cc1081c8006f0430"}, + {file = "PyMuPDF-1.24.1-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:02a6586979df2ad958b524ba42955beaa67fd21661616a0ed04ac07db009474c"}, + {file = "PyMuPDF-1.24.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:8eb292d16671166acdaa280e98cac4368298f32556f2de2ee690782a635df8ee"}, + {file = "PyMuPDF-1.24.1-cp312-none-manylinux2014_x86_64.whl", hash = "sha256:6832f1d9332810760b587ad375eb84d64ec8d8f29395995b463cb5f30533a413"}, + {file = "PyMuPDF-1.24.1-cp312-none-win32.whl", hash = "sha256:f775bb56391629e81b5f870fc3dec0a0fb44cb34a92b4696b9207b31234711df"}, + {file = "PyMuPDF-1.24.1-cp312-none-win_amd64.whl", hash = "sha256:8489df092473d590fb14903433bd99a07dc3d2924f5a5c8ead615795f2d65a65"}, + {file = "PyMuPDF-1.24.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:ee9cfac470aeb6b5b7deb4f6472b7796c3132856849c635c8e56c7a371e40238"}, + {file = "PyMuPDF-1.24.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:825c62367b01e61b4bce0cc96d45b0ec336475422cfa36de6f441b4d3389a26e"}, + {file = "PyMuPDF-1.24.1-cp38-none-manylinux2014_x86_64.whl", hash = "sha256:d2b4f8956d0ca7564604491db8b29cd7872a2b4d65f1d7e16a1bccfecf84bb56"}, + {file = "PyMuPDF-1.24.1-cp38-none-win32.whl", hash = "sha256:7df966954ff0edbcd5d743c5f6fb68b3203e67534747e8753691b8ffedeaa518"}, + {file = "PyMuPDF-1.24.1-cp38-none-win_amd64.whl", hash = "sha256:6952d47f0f05cf9338470dda078e4533ddb876368b199ebfa2f9e6076311898b"}, + {file = "PyMuPDF-1.24.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:e3f7a101a14d742c93b660b7586ab4c1491caea9062a5de9c308578a7a4f8b69"}, + {file = "PyMuPDF-1.24.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:dbc5d67dfd07123293993eb93bee35d329fce0bc8134b9cd5514ef75c68ffee8"}, + {file = "PyMuPDF-1.24.1-cp39-none-manylinux2014_x86_64.whl", hash = "sha256:38728bb6aab9e3879aa8ac4d337be8fe838d33973f43e3b7805b86265c24f349"}, + {file = "PyMuPDF-1.24.1-cp39-none-win32.whl", hash = "sha256:b8a5247d0cec87765481c38d2b8602f0264bf7ca6b5dc3013caf64ce46ad4d5e"}, + {file = "PyMuPDF-1.24.1-cp39-none-win_amd64.whl", hash = "sha256:d1078ea265635e962693d7298bd39be64af7d1dd2c6dc663a8562e75f547f948"}, + {file = "PyMuPDF-1.24.1.tar.gz", hash = "sha256:38e6101dab2ff86c4e2444fcec8a04377ae1d6db1bef0f7a1ddab3ac6abe4d41"}, ] [package.dependencies] -PyMuPDFb = "1.24.0" +PyMuPDFb = "1.24.1" [[package]] name = "pymupdfb" -version = "1.24.0" +version = "1.24.1" description = "MuPDF shared libraries for PyMuPDF." optional = false python-versions = ">=3.8" files = [ - {file = "PyMuPDFb-1.24.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:5af4e14171efd5e85b82ce2ae94caaebae9f4314103fc9af62be99537e21562e"}, - {file = "PyMuPDFb-1.24.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:113e424b534a73a00dfaf2407beab3e9c35bfe406f77cfa66a43cf5f87bafef6"}, - {file = "PyMuPDFb-1.24.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:347fff11c61e82538bdf6293cb4cfb41aa7b6ae14a4785efaaa81da949126424"}, - {file = "PyMuPDFb-1.24.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:871e100637fd64c76356656ca4122f4d355906aa25173997959ccaf39413c8d4"}, - {file = "PyMuPDFb-1.24.0-py3-none-win32.whl", hash = "sha256:051e043ada55ecf03cae28b9990ec53b975a69995a0f177caedc9b3bf85d2d22"}, - {file = "PyMuPDFb-1.24.0-py3-none-win_amd64.whl", hash = "sha256:3e368ce2a8935881965343a7b87565b532a1787a3dc8f5580980dfb8b91d0c39"}, + {file = "PyMuPDFb-1.24.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:37179e363bf69ce9be637937c5469957b96968341dabe3ce8f4b690a82e9ad92"}, + {file = "PyMuPDFb-1.24.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:17444ea7d6897c27759880ad76af537d19779f901de82ae9548598a70f614558"}, + {file = "PyMuPDFb-1.24.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0fbcc0d2a9ce79fa38eb4e8bb5c959b582f7a49938874e9f61d1a6f5eeb1e4b8"}, + {file = "PyMuPDFb-1.24.1-py3-none-win32.whl", hash = "sha256:ae67736058882cdd9459810a4aae9ac2b2e89ac2e916cb5fefb0f651c9739e9e"}, + {file = "PyMuPDFb-1.24.1-py3-none-win_amd64.whl", hash = "sha256:01c8b7f0ce9166310eb28c7aebcb8d5fe12a4bc082f9b00d580095eebeaf0af5"}, ] [[package]] @@ -8209,45 +8245,45 @@ tests = ["black (>=23.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.3)", "numpydoc ( [[package]] name = "scipy" -version = "1.12.0" +version = "1.13.0" description = "Fundamental algorithms for scientific computing in Python" optional = true python-versions = ">=3.9" files = [ - {file = "scipy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78e4402e140879387187f7f25d91cc592b3501a2e51dfb320f48dfb73565f10b"}, - {file = "scipy-1.12.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5f00ebaf8de24d14b8449981a2842d404152774c1a1d880c901bf454cb8e2a1"}, - {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e53958531a7c695ff66c2e7bb7b79560ffdc562e2051644c5576c39ff8efb563"}, - {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e32847e08da8d895ce09d108a494d9eb78974cf6de23063f93306a3e419960c"}, - {file = "scipy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c1020cad92772bf44b8e4cdabc1df5d87376cb219742549ef69fc9fd86282dd"}, - {file = "scipy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:75ea2a144096b5e39402e2ff53a36fecfd3b960d786b7efd3c180e29c39e53f2"}, - {file = "scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:408c68423f9de16cb9e602528be4ce0d6312b05001f3de61fe9ec8b1263cad08"}, - {file = "scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5adfad5dbf0163397beb4aca679187d24aec085343755fcdbdeb32b3679f254c"}, - {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3003652496f6e7c387b1cf63f4bb720951cfa18907e998ea551e6de51a04467"}, - {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8066bce124ee5531d12a74b617d9ac0ea59245246410e19bca549656d9a40a"}, - {file = "scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8bee4993817e204d761dba10dbab0774ba5a8612e57e81319ea04d84945375ba"}, - {file = "scipy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a24024d45ce9a675c1fb8494e8e5244efea1c7a09c60beb1eeb80373d0fecc70"}, - {file = "scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7e76cc48638228212c747ada851ef355c2bb5e7f939e10952bc504c11f4e372"}, - {file = "scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f7ce148dffcd64ade37b2df9315541f9adad6efcaa86866ee7dd5db0c8f041c3"}, - {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c39f92041f490422924dfdb782527a4abddf4707616e07b021de33467f917bc"}, - {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7ebda398f86e56178c2fa94cad15bf457a218a54a35c2a7b4490b9f9cb2676c"}, - {file = "scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:95e5c750d55cf518c398a8240571b0e0782c2d5a703250872f36eaf737751338"}, - {file = "scipy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e646d8571804a304e1da01040d21577685ce8e2db08ac58e543eaca063453e1c"}, - {file = "scipy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:913d6e7956c3a671de3b05ccb66b11bc293f56bfdef040583a7221d9e22a2e35"}, - {file = "scipy-1.12.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba1b0c7256ad75401c73e4b3cf09d1f176e9bd4248f0d3112170fb2ec4db067"}, - {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:730badef9b827b368f351eacae2e82da414e13cf8bd5051b4bdfd720271a5371"}, - {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6546dc2c11a9df6926afcbdd8a3edec28566e4e785b915e849348c6dd9f3f490"}, - {file = "scipy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:196ebad3a4882081f62a5bf4aeb7326aa34b110e533aab23e4374fcccb0890dc"}, - {file = "scipy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:b360f1b6b2f742781299514e99ff560d1fe9bd1bff2712894b52abe528d1fd1e"}, - {file = "scipy-1.12.0.tar.gz", hash = "sha256:4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3"}, + {file = "scipy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba419578ab343a4e0a77c0ef82f088238a93eef141b2b8017e46149776dfad4d"}, + {file = "scipy-1.13.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:22789b56a999265431c417d462e5b7f2b487e831ca7bef5edeb56efe4c93f86e"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f1432ba070e90d42d7fd836462c50bf98bd08bed0aa616c359eed8a04e3922"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8434f6f3fa49f631fae84afee424e2483289dfc30a47755b4b4e6b07b2633a4"}, + {file = "scipy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:dcbb9ea49b0167de4167c40eeee6e167caeef11effb0670b554d10b1e693a8b9"}, + {file = "scipy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d2f7bb14c178f8b13ebae93f67e42b0a6b0fc50eba1cd8021c9b6e08e8fb1cd"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fbcf8abaf5aa2dc8d6400566c1a727aed338b5fe880cde64907596a89d576fa"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5e4a756355522eb60fcd61f8372ac2549073c8788f6114449b37e9e8104f15a5"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5acd8e1dbd8dbe38d0004b1497019b2dbbc3d70691e65d69615f8a7292865d7"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ff7dad5d24a8045d836671e082a490848e8639cabb3dbdacb29f943a678683d"}, + {file = "scipy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4dca18c3ffee287ddd3bc8f1dabaf45f5305c5afc9f8ab9cbfab855e70b2df5c"}, + {file = "scipy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:a2f471de4d01200718b2b8927f7d76b5d9bde18047ea0fa8bd15c5ba3f26a1d6"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0de696f589681c2802f9090fff730c218f7c51ff49bf252b6a97ec4a5d19e8b"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:b2a3ff461ec4756b7e8e42e1c681077349a038f0686132d623fa404c0bee2551"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf9fe63e7a4bf01d3645b13ff2aa6dea023d38993f42aaac81a18b1bda7a82a"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e7626dfd91cdea5714f343ce1176b6c4745155d234f1033584154f60ef1ff42"}, + {file = "scipy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:109d391d720fcebf2fbe008621952b08e52907cf4c8c7efc7376822151820820"}, + {file = "scipy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:8930ae3ea371d6b91c203b1032b9600d69c568e537b7988a3073dfe4d4774f21"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5407708195cb38d70fd2d6bb04b1b9dd5c92297d86e9f9daae1576bd9e06f602"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ac38c4c92951ac0f729c4c48c9e13eb3675d9986cc0c83943784d7390d540c78"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c74543c4fbeb67af6ce457f6a6a28e5d3739a87f62412e4a16e46f164f0ae5"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28e286bf9ac422d6beb559bc61312c348ca9b0f0dae0d7c5afde7f722d6ea13d"}, + {file = "scipy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33fde20efc380bd23a78a4d26d59fc8704e9b5fd9b08841693eb46716ba13d86"}, + {file = "scipy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:45c08bec71d3546d606989ba6e7daa6f0992918171e2a6f7fbedfa7361c2de1e"}, + {file = "scipy-1.13.0.tar.gz", hash = "sha256:58569af537ea29d3f78e5abd18398459f195546bb3be23d16677fb26616cc11e"}, ] [package.dependencies] -numpy = ">=1.22.4,<1.29.0" +numpy = ">=1.22.4,<2.3" [package.extras] -dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "sentence-transformers" @@ -9176,13 +9212,13 @@ types-pyOpenSSL = "*" [[package]] name = "types-requests" -version = "2.31.0.20240402" +version = "2.31.0.20240403" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.31.0.20240402.tar.gz", hash = "sha256:e5c09a202f8ae79cd6ffbbba2203b6c3775a83126283bb2a6abbc129abc02a12"}, - {file = "types_requests-2.31.0.20240402-py3-none-any.whl", hash = "sha256:bd7eb7102168d4b5b489f15cdd9842b63ab7fe56aa82a0589fa595b94195acf4"}, + {file = "types-requests-2.31.0.20240403.tar.gz", hash = "sha256:e1e0cd0b655334f39d9f872b68a1310f0e343647688bf2cee932ec4c2b04de59"}, + {file = "types_requests-2.31.0.20240403-py3-none-any.whl", hash = "sha256:06abf6a68f5c4f2a62f6bb006672dfb26ed50ccbfddb281e1ee6f09a65707d5d"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 346767203..6ca2076d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a0" +version = "1.0.0a1" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 2d5c03cba..caf2af880 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -2487,13 +2487,13 @@ extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15. [[package]] name = "langchain-core" -version = "0.1.38" +version = "0.1.40" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_core-0.1.38-py3-none-any.whl", hash = "sha256:d881b2754254cb4bdb0d5bb56e5c138d032b6e75e5cb21f151b01224b322e02b"}, - {file = "langchain_core-0.1.38.tar.gz", hash = "sha256:ee8da6d061c06cce7dc22fec224b6ecbc3a8de106d6dd9f409c7fe448ea41861"}, + {file = "langchain_core-0.1.40-py3-none-any.whl", hash = "sha256:618dbb7ab44d8b263b91e384db1ff07d0db256ae5bdafa0123a115b6a75a13f1"}, + {file = "langchain_core-0.1.40.tar.gz", hash = "sha256:34c06fc0e6d3534b738c63f85403446b4be71161665b7e091f9bb19c914ec100"}, ] [package.dependencies] @@ -2502,7 +2502,6 @@ langsmith = ">=0.1.0,<0.2.0" packaging = ">=23.2,<24.0" pydantic = ">=1,<3" PyYAML = ">=5.3" -requests = ">=2,<3" tenacity = ">=8.1.0,<9.0.0" [package.extras] @@ -2545,13 +2544,13 @@ extended-testing = ["lxml (>=5.1.0,<6.0.0)"] [[package]] name = "langsmith" -version = "0.1.38" +version = "0.1.39" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.38-py3-none-any.whl", hash = "sha256:f36479f82cf537cf40d129ac2e485e72a3981360c7b6cf2549dad77d98eafd8f"}, - {file = "langsmith-0.1.38.tar.gz", hash = "sha256:2c1f98ac0a8c02e43b625650a6e13c65b09523551bfc21a59d20963f46f7d265"}, + {file = "langsmith-0.1.39-py3-none-any.whl", hash = "sha256:85c19177162585728001cb7ae91ab48ca4abe39b7bc1ff783212ac426ded222b"}, + {file = "langsmith-0.1.39.tar.gz", hash = "sha256:2aec9d2f9cc664042d2121b13da569b0902aff842c86b17b440245d57da84ec5"}, ] [package.dependencies] @@ -2606,124 +2605,165 @@ dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptio [[package]] name = "lxml" -version = "5.2.0" +version = "5.2.1" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c54f8d6160080831a76780d850302fdeb0e8d0806f661777b0714dfb55d9a08a"}, - {file = "lxml-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e95ae029396382a0d2e8174e4077f96befcd4a2184678db363ddc074eb4d3b2"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5810fa80e64a0c689262a71af999c5735f48c0da0affcbc9041d1ef5ef3920be"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae69524fd6a68b288574013f8fadac23cacf089c75cd3fc5b216277a445eb736"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fadda215e32fe375d65e560b7f7e2a37c7f9c4ecee5315bb1225ca6ac9bf5838"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:f1f164e4cc6bc646b1fc86664c3543bf4a941d45235797279b120dc740ee7af5"}, - {file = "lxml-5.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:3603a8a41097daf7672cae22cc4a860ab9ea5597f1c5371cb21beca3398b8d6a"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3b4bb89a785f4fd60e05f3c3a526c07d0d68e3536f17f169ca13bf5b5dd75a5"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1effc10bf782f0696e76ecfeba0720ea02c0c31d5bffb7b29ba10debd57d1c3d"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b03531f6cd6ce4b511dcece060ca20aa5412f8db449274b44f4003f282e6272f"}, - {file = "lxml-5.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fac15090bb966719df06f0c4f8139783746d1e60e71016d8a65db2031ca41b8"}, - {file = "lxml-5.2.0-cp310-cp310-win32.whl", hash = "sha256:92bb37c96215c4b2eb26f3c791c0bf02c64dd251effa532b43ca5049000c4478"}, - {file = "lxml-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:b0181c22fdb89cc19e70240a850e5480817c3e815b1eceb171b3d7a3aa3e596a"}, - {file = "lxml-5.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ada8ce9e6e1d126ef60d215baaa0c81381ba5841c25f1d00a71cdafdc038bd27"}, - {file = "lxml-5.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cefb133c859f06dab2ae63885d9f405000c4031ec516e0ed4f9d779f690d8e3"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ede2a7a86a977b0c741654efaeca0af7860a9b1ae39f9268f0936246a977ee0"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d46df6f0b1a0cda39d12c5c4615a7d92f40342deb8001c7b434d7c8c78352e58"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2259243ee734cc736e237719037efb86603c891fd363cc7973a2d0ac8a0e3f"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c53164f29ed3c3868787144e8ea8a399ffd7d8215f59500a20173593c19e96eb"}, - {file = "lxml-5.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:371aab9a397dcc76625ad3b02fa9b21be63406d69237b773156e7d1fc2ce0cae"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e08784288a179b59115b5e57abf6d387528b39abb61105fe17510a199a277a40"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c232726f7b6df5143415a06323faaa998ef8abbe1c0ed00d718755231d76f08"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e4366e58c0508da4dee4c7c70cee657e38553d73abdffa53abbd7d743711ee11"}, - {file = "lxml-5.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c84dce8fb2e900d4fb094e76fdad34a5fd06de53e41bddc1502c146eb11abd74"}, - {file = "lxml-5.2.0-cp311-cp311-win32.whl", hash = "sha256:0947d1114e337dc2aae2fa14bbc9ed5d9ca1a0acd6d2f948df9926aef65305e9"}, - {file = "lxml-5.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1eace37a9f4a1bef0bb5c849434933fd6213008ec583c8e31ee5b8e99c7c8500"}, - {file = "lxml-5.2.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f2cb157e279d28c66b1c27e0948687dc31dc47d1ab10ce0cd292a8334b7de3d5"}, - {file = "lxml-5.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:53c0e56f41ef68c1ce4e96f27ecdc2df389730391a2fd45439eb3facb02d36c8"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703d60e59ab45c17485c2c14b11880e4f7f0eab07134afa9007573fa5a779a5a"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaf5e308a5e50bc0548c4fdca0117a31ec9596f8cfc96592db170bcecc71a957"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af64df85fecd3cf3b2e792f0b5b4d92740905adfa8ce3b24977a55415f1a0c40"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:df7dfbdef11702fd22c2eaf042d7098d17edbc62d73f2199386ad06cbe466f6d"}, - {file = "lxml-5.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7250030a7835bfd5ba6ca7d1ad483ec90f9cbc29978c5e75c1cc3e031d3c4160"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:be5faa2d5c8c8294d770cfd09d119fb27b5589acc59635b0cf90f145dbe81dca"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:347ec08250d5950f5b016caa3e2e13fb2cb9714fe6041d52e3716fb33c208663"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:dc7b630c4fb428b8a40ddd0bfc4bc19de11bb3c9b031154f77360e48fe8b4451"}, - {file = "lxml-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ae550cbd7f229cdf2841d9b01406bcca379a5fb327b9efb53ba620a10452e835"}, - {file = "lxml-5.2.0-cp312-cp312-win32.whl", hash = "sha256:7c61ce3cdd6e6c9f4003ac118be7eb3036d0ce2afdf23929e533e54482780f74"}, - {file = "lxml-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:f90c36ca95a44d2636bbf55a51ca30583b59b71b6547b88d954e029598043551"}, - {file = "lxml-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1cce2eaad7e38b985b0f91f18468dda0d6b91862d32bec945b0e46e2ffe7222e"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60a3983d32f722a8422c01e4dc4badc7a307ca55c59e2485d0e14244a52c482f"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60847dfbdfddf08a56c4eefe48234e8c1ab756c7eda4a2a7c1042666a5516564"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bbe335f0d1a86391671d975a1b5e9b08bb72fba6b567c43bdc2e55ca6e6c086"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_28_aarch64.whl", hash = "sha256:3ac7c8a60b8ad51fe7bca99a634dd625d66492c502fd548dc6dc769ce7d94b6a"}, - {file = "lxml-5.2.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:73e69762cf740ac3ae81137ef9d6f15f93095f50854e233d50b29e7b8a91dbc6"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:281ee1ffeb0ab06204dfcd22a90e9003f0bb2dab04101ad983d0b1773bc10588"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ba3a86b0d5a5c93104cb899dff291e3ae13729c389725a876d00ef9696de5425"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:356f8873b1e27b81793e30144229adf70f6d3e36e5cb7b6d289da690f4398953"}, - {file = "lxml-5.2.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:2a34e74ffe92c413f197ff4967fb1611d938ee0691b762d062ef0f73814f3aa4"}, - {file = "lxml-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:6f0d2b97a5a06c00c963d4542793f3e486b1ed3a957f8c19f6006ed39d104bb0"}, - {file = "lxml-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:35e39c6fd089ad6674eb52d93aa874d6027b3ae44d2381cca6e9e4c2e102c9c8"}, - {file = "lxml-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5f6e4e5a62114ae76690c4a04c5108d067442d0a41fd092e8abd25af1288c450"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93eede9bcc842f891b2267c7f0984d811940d1bc18472898a1187fe560907a99"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad364026c2cebacd7e01d1138bd53639822fefa8f7da90fc38cd0e6319a2699"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f06e4460e76468d99cc36d5b9bc6fc5f43e6662af44960e13e3f4e040aacb35"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:ca3236f31d565555139d5b00b790ed2a98ac6f0c4470c4032f8b5e5a5dba3c1a"}, - {file = "lxml-5.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:a9b67b850ab1d304cb706cf71814b0e0c3875287083d7ec55ee69504a9c48180"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5261c858c390ae9a19aba96796948b6a2d56649cbd572968970dc8da2b2b2a42"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e8359fb610c8c444ac473cfd82dae465f405ff807cabb98a9b9712bbd0028751"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:f9e27841cddfaebc4e3ffbe5dbdff42891051acf5befc9f5323944b2c61cef16"}, - {file = "lxml-5.2.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:641a8da145aca67671205f3e89bfec9815138cf2fe06653c909eab42e486d373"}, - {file = "lxml-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:931a3a13e0f574abce8f3152b207938a54304ccf7a6fd7dff1fdb2f6691d08af"}, - {file = "lxml-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:246c93e2503c710cf02c7e9869dc0258223cbefe5e8f9ecded0ac0aa07fd2bf8"}, - {file = "lxml-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:11acfcdf5a38cf89c48662123a5d02ae0a7d99142c7ee14ad90de5c96a9b6f06"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:200f70b5d95fc79eb9ed7f8c4888eef4e274b9bf380b829d3d52e9ed962e9231"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba4d02aed47c25be6775a40d55c5774327fdedba79871b7c2485e80e45750cb2"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e283b24c14361fe9e04026a1d06c924450415491b83089951d469509900d9f32"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:03e3962d6ad13a862dacd5b3a3ea60b4d092a550f36465234b8639311fd60989"}, - {file = "lxml-5.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6e45fd5213e5587a610b7e7c8c5319a77591ab21ead42df46bb342e21bc1418d"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:27877732946843f4b6bfc56eb40d865653eef34ad2edeed16b015d5c29c248df"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4d16b44ad0dd8c948129639e34c8d301ad87ebc852568ace6fe9a5ad9ce67ee1"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b8f842df9ba26135c5414e93214e04fe0af259bb4f96a32f756f89467f7f3b45"}, - {file = "lxml-5.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c74e77df9e36c8c91157853e6cd400f6f9ca7a803ba89981bfe3f3fc7e5651ef"}, - {file = "lxml-5.2.0-cp38-cp38-win32.whl", hash = "sha256:1459a998c10a99711ac532abe5cc24ba354e4396dafef741c7797f8830712d56"}, - {file = "lxml-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a00f5931b7cccea775123c3c0a2513aee58afdad8728550cc970bff32280bdd2"}, - {file = "lxml-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ddda5ba8831f258ac7e6364be03cb27aa62f50c67fd94bc1c3b6247959cc0369"}, - {file = "lxml-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56835b9e9a7767202fae06310c6b67478963e535fe185bed3bf9af5b18d2b67e"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25fef8794f0dc89f01bdd02df6a7fec4bcb2fbbe661d571e898167a83480185e"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32d44af078485c4da9a7ec460162392d49d996caf89516fa0b75ad0838047122"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f354d62345acdf22aa3e171bd9723790324a66fafe61bfe3873b86724cf6daaa"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6a7e0935f05e1cf1a3aa1d49a87505773b04f128660eac2a24a5594ea6b1baa7"}, - {file = "lxml-5.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:75a4117b43694c72a0d89f6c18a28dc57407bde4650927d4ef5fd384bdf6dcc7"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:57402d6cdd8a897ce21cf8d1ff36683583c17a16322a321184766c89a1980600"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:56591e477bea531e5e1854f5dfb59309d5708669bc921562a35fd9ca5182bdcd"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7efbce96719aa275d49ad5357886845561328bf07e1d5ab998f4e3066c5ccf15"}, - {file = "lxml-5.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a3c39def0965e8fb5c8d50973e0c7b4ce429a2fa730f3f9068a7f4f9ce78410b"}, - {file = "lxml-5.2.0-cp39-cp39-win32.whl", hash = "sha256:5188f22c00381cb44283ecb28c8d85c2db4a3035774dd851876c8647cb809c27"}, - {file = "lxml-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:ed1fe80e1fcdd1205a443bddb1ad3c3135bb1cd3f36cc996a1f4aed35960fbe8"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d2b339fb790fc923ae2e9345c8633e3d0064d37ea7920c027f20c8ae6f65a91f"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06036d60fccb21e22dd167f6d0e422b9cbdf3588a7e999a33799f9cbf01e41a5"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1611fb9de0a269c05575c024e6d8cdf2186e3fa52b364e3b03dcad82514d57"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:05fc3720250d221792b6e0d150afc92d20cb10c9cdaa8c8f93c2a00fbdd16015"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:11e41ffd3cd27b0ca1c76073b27bd860f96431d9b70f383990f1827ca19f2f52"}, - {file = "lxml-5.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0382e6a3eefa3f6699b14fa77c2eb32af2ada261b75120eaf4fc028a20394975"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be5c8e776ecbcf8c1bce71a7d90e3a3680c9ceae516cac0be08b47e9fac0ca43"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da12b4efc93d53068888cb3b58e355b31839f2428b8f13654bd25d68b201c240"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f46f8033da364bacc74aca5e319509a20bb711c8a133680ca5f35020f9eaf025"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:50a26f68d090594477df8572babac64575cd5c07373f7a8319c527c8e56c0f99"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:57cbadf028727705086047994d2e50124650e63ce5a035b0aa79ab50f001989f"}, - {file = "lxml-5.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8aa11638902ac23f944f16ce45c9f04c9d5d57bb2da66822abb721f4efe5fdbb"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b7150e630b879390e02121e71ceb1807f682b88342e2ea2082e2c8716cf8bd93"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4add722393c99da4d51c8d9f3e1ddf435b30677f2d9ba9aeaa656f23c1b7b580"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd0f25a431cd16f70ec1c47c10b413e7ddfe1ccaaddd1a7abd181e507c012374"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:883e382695f346c2ea3ad96bdbdf4ca531788fbeedb4352be3a8fcd169fc387d"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:80cc2b55bb6e35d3cb40936b658837eb131e9f16357241cd9ba106ae1e9c5ecb"}, - {file = "lxml-5.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:59ec2948385336e9901008fdf765780fe30f03e7fdba8090aafdbe5d1b7ea0cd"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ddbea6e58cce1a640d9d65947f1e259423fc201c9cf9761782f355f53b7f3097"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52d6cdea438eb7282c41c5ac00bd6d47d14bebb6e8a8d2a1c168ed9e0cacfbab"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c556bbf88a8b667c849d326dd4dd9c6290ede5a33383ffc12b0ed17777f909d"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:947fa8bf15d1c62c6db36c6ede9389cac54f59af27010251747f05bddc227745"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e6cb8f7a332eaa2d876b649a748a445a38522e12f2168e5e838d1505a91cdbb7"}, - {file = "lxml-5.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:16e65223f34fd3d65259b174f0f75a4bb3d9893698e5e7d01e54cd8c5eb98d85"}, - {file = "lxml-5.2.0.tar.gz", hash = "sha256:21dc490cdb33047bc7f7ad76384f3366fa8f5146b86cc04c4af45de901393b90"}, + {file = "lxml-5.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1"}, + {file = "lxml-5.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a"}, + {file = "lxml-5.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01"}, + {file = "lxml-5.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1"}, + {file = "lxml-5.2.1-cp310-cp310-win32.whl", hash = "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5"}, + {file = "lxml-5.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f"}, + {file = "lxml-5.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867"}, + {file = "lxml-5.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a"}, + {file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f"}, + {file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534"}, + {file = "lxml-5.2.1-cp311-cp311-win32.whl", hash = "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be"}, + {file = "lxml-5.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102"}, + {file = "lxml-5.2.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851"}, + {file = "lxml-5.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0"}, + {file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169"}, + {file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4"}, + {file = "lxml-5.2.1-cp312-cp312-win32.whl", hash = "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134"}, + {file = "lxml-5.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a"}, + {file = "lxml-5.2.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c"}, + {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0"}, + {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1"}, + {file = "lxml-5.2.1-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62"}, + {file = "lxml-5.2.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461"}, + {file = "lxml-5.2.1-cp36-cp36m-win32.whl", hash = "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0"}, + {file = "lxml-5.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289"}, + {file = "lxml-5.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029"}, + {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af"}, + {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0"}, + {file = "lxml-5.2.1-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75"}, + {file = "lxml-5.2.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8"}, + {file = "lxml-5.2.1-cp37-cp37m-win32.whl", hash = "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd"}, + {file = "lxml-5.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c"}, + {file = "lxml-5.2.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3e183c6e3298a2ed5af9d7a356ea823bccaab4ec2349dc9ed83999fd289d14d5"}, + {file = "lxml-5.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533"}, + {file = "lxml-5.2.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c"}, + {file = "lxml-5.2.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637"}, + {file = "lxml-5.2.1-cp38-cp38-win32.whl", hash = "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da"}, + {file = "lxml-5.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806"}, + {file = "lxml-5.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd"}, + {file = "lxml-5.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b"}, + {file = "lxml-5.2.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c"}, + {file = "lxml-5.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188"}, + {file = "lxml-5.2.1-cp39-cp39-win32.whl", hash = "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708"}, + {file = "lxml-5.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e"}, + {file = "lxml-5.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96"}, + {file = "lxml-5.2.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85"}, + {file = "lxml-5.2.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246"}, + {file = "lxml-5.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704"}, + {file = "lxml-5.2.1.tar.gz", hash = "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306"}, ] [package.extras] @@ -3830,41 +3870,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa typing = ["typing-extensions"] xmp = ["defusedxml"] -[[package]] -name = "pip" -version = "24.0" -description = "The PyPA recommended tool for installing Python packages." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pip-24.0-py3-none-any.whl", hash = "sha256:ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc"}, - {file = "pip-24.0.tar.gz", hash = "sha256:ea9bd1a847e8c5774a5777bb398c19e80bcd4e2aa16a4b301b718fe6f593aba2"}, -] - -[[package]] -name = "pip-tools" -version = "7.4.1" -description = "pip-tools keeps your pinned dependencies fresh." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pip-tools-7.4.1.tar.gz", hash = "sha256:864826f5073864450e24dbeeb85ce3920cdfb09848a3d69ebf537b521f14bcc9"}, - {file = "pip_tools-7.4.1-py3-none-any.whl", hash = "sha256:4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9"}, -] - -[package.dependencies] -build = ">=1.0.0" -click = ">=8" -pip = ">=22.2" -pyproject_hooks = "*" -setuptools = "*" -tomli = {version = "*", markers = "python_version < \"3.11\""} -wheel = "*" - -[package.extras] -coverage = ["covdefaults", "pytest-cov"] -testing = ["flit_core (>=2,<4)", "poetry_core (>=1.0.0)", "pytest (>=7.2.0)", "pytest-rerunfailures", "pytest-xdist", "tomli-w"] - [[package]] name = "platformdirs" version = "4.2.0" @@ -5404,13 +5409,13 @@ types-pyOpenSSL = "*" [[package]] name = "types-requests" -version = "2.31.0.20240402" +version = "2.31.0.20240403" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.31.0.20240402.tar.gz", hash = "sha256:e5c09a202f8ae79cd6ffbbba2203b6c3775a83126283bb2a6abbc129abc02a12"}, - {file = "types_requests-2.31.0.20240402-py3-none-any.whl", hash = "sha256:bd7eb7102168d4b5b489f15cdd9842b63ab7fe56aa82a0589fa595b94195acf4"}, + {file = "types-requests-2.31.0.20240403.tar.gz", hash = "sha256:e1e0cd0b655334f39d9f872b68a1310f0e343647688bf2cee932ec4c2b04de59"}, + {file = "types_requests-2.31.0.20240403-py3-none-any.whl", hash = "sha256:06abf6a68f5c4f2a62f6bb006672dfb26ed50ccbfddb281e1ee6f09a65707d5d"}, ] [package.dependencies] @@ -5752,20 +5757,6 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] -[[package]] -name = "wheel" -version = "0.43.0" -description = "A built-package format for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "wheel-0.43.0-py3-none-any.whl", hash = "sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81"}, - {file = "wheel-0.43.0.tar.gz", hash = "sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85"}, -] - -[package.extras] -test = ["pytest (>=6.0.0)", "setuptools (>=65)"] - [[package]] name = "win32-setctime" version = "1.1.0" @@ -6070,4 +6061,4 @@ local = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "455e5f44f2e5dcbc3e0359658d7c4ef9f93e40c99841c9de99311a0ecad483c2" +content-hash = "5473eb333e6fd18ecc70e845f0a34a2d0d267f5a5055e31624453dd9a5485f0e" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 63b0a116c..544c7f3a7 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.16" +version = "0.0.17" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ From 3ef0049bef3c287b3b03e2463d89a651afab024e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 16:50:01 -0300 Subject: [PATCH 06/54] Update build_langflow_base and build_langflow_backup in Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e1407c733..71c7f026f 100644 --- a/Makefile +++ b/Makefile @@ -178,12 +178,12 @@ build_langflow_base: rm -rf src/backend/base/langflow/frontend build_langflow_backup: - poetry lock && poetry build-rewrite-path-deps --version-pinning-strategy=semver + poetry lock && poetry build-rewrite-path-deps --version-pinning-strategy=semver --sdist build_langflow: cd ./scripts && python update_dependencies.py poetry lock - poetry build-rewrite-path-deps --version-pinning-strategy=semver + poetry build-rewrite-path-deps --version-pinning-strategy=semver --sdist mv pyproject.toml.bak pyproject.toml mv poetry.lock.bak poetry.lock From 53afd012ee41268b9fc72929e5a5c833ff0ffda5 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Wed, 3 Apr 2024 22:06:10 +0200 Subject: [PATCH 07/54] Added docs --- docs/docusaurus.config.js | 4 ++++ docs/package-lock.json | 1 + docs/package.json | 1 + 3 files changed, 6 insertions(+) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index a9a8a06e0..979953918 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -43,6 +43,10 @@ module.exports = { path: "docs", // sidebarPath: 'sidebars.js', }, + gtag: { + trackingID: 'G-XHC7G628ZP', + anonymizeIP: true, + }, theme: { customCss: [ require.resolve("@code-hike/mdx/styles.css"), diff --git a/docs/package-lock.json b/docs/package-lock.json index 7e5d0e8b9..c91a4ec06 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -11,6 +11,7 @@ "@babel/preset-react": "^7.22.3", "@code-hike/mdx": "^0.9.0", "@docusaurus/core": "^3.2.0", + "@docusaurus/plugin-google-gtag": "^3.2.0", "@docusaurus/plugin-ideal-image": "^3.2.0", "@docusaurus/preset-classic": "^3.2.0", "@docusaurus/theme-classic": "^3.2.0", diff --git a/docs/package.json b/docs/package.json index ce14c7568..87f3d3d71 100644 --- a/docs/package.json +++ b/docs/package.json @@ -17,6 +17,7 @@ "@babel/preset-react": "^7.22.3", "@code-hike/mdx": "^0.9.0", "@docusaurus/core": "^3.2.0", + "@docusaurus/plugin-google-gtag": "^3.2.0", "@docusaurus/plugin-ideal-image": "^3.2.0", "@docusaurus/preset-classic": "^3.2.0", "@docusaurus/theme-classic": "^3.2.0", From 7d3eabd33428fa5b9cbc5657e79865e228119b11 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 17:15:02 -0300 Subject: [PATCH 08/54] Update dependencies and build process --- Makefile | 8 ++++---- poetry.lock | 34 +++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 71c7f026f..dc779fa03 100644 --- a/Makefile +++ b/Makefile @@ -178,12 +178,12 @@ build_langflow_base: rm -rf src/backend/base/langflow/frontend build_langflow_backup: - poetry lock && poetry build-rewrite-path-deps --version-pinning-strategy=semver --sdist + poetry lock && poetry build-rewrite-path-deps --version-pinning-strategy=semver build_langflow: cd ./scripts && python update_dependencies.py - poetry lock - poetry build-rewrite-path-deps --version-pinning-strategy=semver --sdist + -poetry lock + -poetry build-rewrite-path-deps --version-pinning-strategy=semver mv pyproject.toml.bak pyproject.toml mv poetry.lock.bak poetry.lock @@ -218,7 +218,7 @@ publish_langflow: publish: make publish_base - make publish_langflow + make publish_langflowpoetr help: @echo '----' diff --git a/poetry.lock b/poetry.lock index cb8e68605..dc6cb7649 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4028,6 +4028,32 @@ interegular = ["interegular (>=0.3.1,<0.4.0)"] nearley = ["js2py"] regex = ["regex"] +[[package]] +name = "litellm" +version = "1.34.22" +description = "Library to easily interface with LLM API providers" +optional = false +python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" +files = [ + {file = "litellm-1.34.22-py3-none-any.whl", hash = "sha256:0e573d56d762f4060c53493da4a08c48034b5bb5ba22e34517065739adfd9154"}, + {file = "litellm-1.34.22.tar.gz", hash = "sha256:ca50ede3ca8d3f9dc2765ca13cf2ff5c4e4b9afb4db222f9d7cb9ee838b6180f"}, +] + +[package.dependencies] +aiohttp = "*" +click = "*" +importlib-metadata = ">=6.8.0" +jinja2 = ">=3.1.2,<4.0.0" +openai = ">=1.0.0" +python-dotenv = ">=0.2.0" +requests = ">=2.31.0,<3.0.0" +tiktoken = ">=0.4.0" +tokenizers = "*" + +[package.extras] +extra-proxy = ["azure-identity (>=1.15.0,<2.0.0)", "azure-keyvault-secrets (>=4.8.0,<5.0.0)", "google-cloud-kms (>=2.21.3,<3.0.0)", "prisma (==0.11.0)", "resend (>=0.8.0,<0.9.0)"] +proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", "cryptography (>=42.0.5,<43.0.0)", "fastapi (>=0.109.1,<0.110.0)", "fastapi-sso (>=0.10.0,<0.11.0)", "gunicorn (>=21.2.0,<22.0.0)", "orjson (>=3.9.7,<4.0.0)", "python-multipart (>=0.0.9,<0.0.10)", "pyyaml (>=6.0.1,<7.0.0)", "rq", "uvicorn (>=0.22.0,<0.23.0)"] + [[package]] name = "llama-cpp-python" version = "0.2.59" @@ -7005,26 +7031,31 @@ python-versions = ">=3.8" files = [ {file = "PyMuPDF-1.24.1-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:6427aee313e24447f57edbfc7a28aa6bbca007fe0ad77603f54a371c6c510eeb"}, {file = "PyMuPDF-1.24.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:12078c0bee337de969dbd6d89ef446312794d74db365cb9ac14902b863b35414"}, + {file = "PyMuPDF-1.24.1-cp310-none-manylinux2014_aarch64.whl", hash = "sha256:73f86eefd7f3878f112fa10791aa2e63934cf59a4c024dd54cd6fe94443c352c"}, {file = "PyMuPDF-1.24.1-cp310-none-manylinux2014_x86_64.whl", hash = "sha256:caf6ceb1dbebe9f70bf7dd683cc91b896604a7c62873e5b50089f9e85e85c517"}, {file = "PyMuPDF-1.24.1-cp310-none-win32.whl", hash = "sha256:468a8bb2b95828e0f6739fbfe509700cc0dac600f756d8cb6316316e1eba9689"}, {file = "PyMuPDF-1.24.1-cp310-none-win_amd64.whl", hash = "sha256:e47504391908e2d721c743aed36196310a5e15355a85459c1c4ddcf8f2002fbe"}, {file = "PyMuPDF-1.24.1-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:c54ff927257b432ffd39dc6a0a46bd1120e85d192100efca021f27d4b881cfd6"}, {file = "PyMuPDF-1.24.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:6d412da9f9a73f66973eea4284776f292135906700a06c39122e862a1e3ccf58"}, + {file = "PyMuPDF-1.24.1-cp311-none-manylinux2014_aarch64.whl", hash = "sha256:95a54611abb7322f5b10b44cbf19b605ed172df2c4c7995ad78854bc8423dd9c"}, {file = "PyMuPDF-1.24.1-cp311-none-manylinux2014_x86_64.whl", hash = "sha256:9a3b21c8fc274ff42855ca2da65961e2319b05b75ef9e2caf25c04f9083ec79c"}, {file = "PyMuPDF-1.24.1-cp311-none-win32.whl", hash = "sha256:8a81106a8bc229823736487d2492fd3af724a94521a1cd9b67849dd04b9c31ed"}, {file = "PyMuPDF-1.24.1-cp311-none-win_amd64.whl", hash = "sha256:de5b6c4db4a2a9f28937e79135f732827c424f7444c12767cc1081c8006f0430"}, {file = "PyMuPDF-1.24.1-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:02a6586979df2ad958b524ba42955beaa67fd21661616a0ed04ac07db009474c"}, {file = "PyMuPDF-1.24.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:8eb292d16671166acdaa280e98cac4368298f32556f2de2ee690782a635df8ee"}, + {file = "PyMuPDF-1.24.1-cp312-none-manylinux2014_aarch64.whl", hash = "sha256:f7b7f2011fa522a57fb3d6a7a58bcdcf01ee59bdad536ef9eb5c3fdf1e04e6c3"}, {file = "PyMuPDF-1.24.1-cp312-none-manylinux2014_x86_64.whl", hash = "sha256:6832f1d9332810760b587ad375eb84d64ec8d8f29395995b463cb5f30533a413"}, {file = "PyMuPDF-1.24.1-cp312-none-win32.whl", hash = "sha256:f775bb56391629e81b5f870fc3dec0a0fb44cb34a92b4696b9207b31234711df"}, {file = "PyMuPDF-1.24.1-cp312-none-win_amd64.whl", hash = "sha256:8489df092473d590fb14903433bd99a07dc3d2924f5a5c8ead615795f2d65a65"}, {file = "PyMuPDF-1.24.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:ee9cfac470aeb6b5b7deb4f6472b7796c3132856849c635c8e56c7a371e40238"}, {file = "PyMuPDF-1.24.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:825c62367b01e61b4bce0cc96d45b0ec336475422cfa36de6f441b4d3389a26e"}, + {file = "PyMuPDF-1.24.1-cp38-none-manylinux2014_aarch64.whl", hash = "sha256:73d07e127936948a29a7dbd4c831e9eb45a60b495d72e604d454fd040fd08c5f"}, {file = "PyMuPDF-1.24.1-cp38-none-manylinux2014_x86_64.whl", hash = "sha256:d2b4f8956d0ca7564604491db8b29cd7872a2b4d65f1d7e16a1bccfecf84bb56"}, {file = "PyMuPDF-1.24.1-cp38-none-win32.whl", hash = "sha256:7df966954ff0edbcd5d743c5f6fb68b3203e67534747e8753691b8ffedeaa518"}, {file = "PyMuPDF-1.24.1-cp38-none-win_amd64.whl", hash = "sha256:6952d47f0f05cf9338470dda078e4533ddb876368b199ebfa2f9e6076311898b"}, {file = "PyMuPDF-1.24.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:e3f7a101a14d742c93b660b7586ab4c1491caea9062a5de9c308578a7a4f8b69"}, {file = "PyMuPDF-1.24.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:dbc5d67dfd07123293993eb93bee35d329fce0bc8134b9cd5514ef75c68ffee8"}, + {file = "PyMuPDF-1.24.1-cp39-none-manylinux2014_aarch64.whl", hash = "sha256:0edda1024ada67603e5888f31656048d3fd53167c8b0d56f435b986eb507df8f"}, {file = "PyMuPDF-1.24.1-cp39-none-manylinux2014_x86_64.whl", hash = "sha256:38728bb6aab9e3879aa8ac4d337be8fe838d33973f43e3b7805b86265c24f349"}, {file = "PyMuPDF-1.24.1-cp39-none-win32.whl", hash = "sha256:b8a5247d0cec87765481c38d2b8602f0264bf7ca6b5dc3013caf64ce46ad4d5e"}, {file = "PyMuPDF-1.24.1-cp39-none-win_amd64.whl", hash = "sha256:d1078ea265635e962693d7298bd39be64af7d1dd2c6dc663a8562e75f547f948"}, @@ -7043,6 +7074,7 @@ python-versions = ">=3.8" files = [ {file = "PyMuPDFb-1.24.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:37179e363bf69ce9be637937c5469957b96968341dabe3ce8f4b690a82e9ad92"}, {file = "PyMuPDFb-1.24.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:17444ea7d6897c27759880ad76af537d19779f901de82ae9548598a70f614558"}, + {file = "PyMuPDFb-1.24.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:490f7fff4dbe362bc895cefdfc5030d712311d024d357a1388d64816eb215d34"}, {file = "PyMuPDFb-1.24.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0fbcc0d2a9ce79fa38eb4e8bb5c959b582f7a49938874e9f61d1a6f5eeb1e4b8"}, {file = "PyMuPDFb-1.24.1-py3-none-win32.whl", hash = "sha256:ae67736058882cdd9459810a4aae9ac2b2e89ac2e916cb5fefb0f651c9739e9e"}, {file = "PyMuPDFb-1.24.1-py3-none-win_amd64.whl", hash = "sha256:01c8b7f0ce9166310eb28c7aebcb8d5fe12a4bc082f9b00d580095eebeaf0af5"}, @@ -10285,4 +10317,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "3eb1181a83884c7ba52a7d1c98dcff13a307452eaf8f4a148fc0778f97499dfd" +content-hash = "ed8605b2934fceb591d03d5be7461ed05a8f427512b693ce1baefeaa4fa21500" diff --git a/pyproject.toml b/pyproject.toml index 6ca2076d9..c30130e7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,6 +80,7 @@ dspy-ai = "^2.4.0" crewai = "^0.22.5" html2text = "^2024.2.26" assemblyai = "^0.23.1" +litellm = "^1.34.22" [tool.poetry.group.dev.dependencies] types-redis = "^4.6.0.5" From c357b1b4623b5f78a748bbbe117e2516ba5cbdb5 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 17:15:14 -0300 Subject: [PATCH 09/54] Add Admonition component for API Key documentation --- docs/docs/guidelines/api.mdx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/docs/guidelines/api.mdx b/docs/docs/guidelines/api.mdx index 8bba633fb..6ba2c3a72 100644 --- a/docs/docs/guidelines/api.mdx +++ b/docs/docs/guidelines/api.mdx @@ -1,5 +1,6 @@ import useBaseUrl from "@docusaurus/useBaseUrl"; import ZoomableImage from "/src/theme/ZoomableImage.js"; +import Admonition from "/src/theme/Admonition.js"; # API Keys @@ -7,12 +8,17 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; Langflow offers an API Key functionality that allows users to access their individual components and flows without going through traditional login authentication. The API Key is a user-specific token that can be included in the request's header or query parameter to authenticate API calls. The following documentation outlines how to generate, use, and manage these API Keys in Langflow. + + This feature requires the `LANGFLOW_AUTO_LOGIN` environment variable to be set + to `False`. The default user and password are set using _`LANGFLOW_SUPERUSER`_ + and _`LANGFLOW_SUPERUSER_PASSWORD`_ environment variables. Default values are + _`langflow`_ and _`langflow`_ respectively. + + ## Generating an API Key ### Through Langflow UI -{/* add image img/api-key.png */} - \ + http://localhost:3000/api/v1/run/ \ -H 'Content-Type: application/json'\ -H 'x-api-key: '\ -d '{"inputs": {"text":""}, "tweaks": {}}' From 524156db795f876334eef76e2ff5dddae59eaf67 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 17:15:48 -0300 Subject: [PATCH 10/54] Update API endpoint in async-api.mdx --- docs/docs/guidelines/async-api.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/guidelines/async-api.mdx b/docs/docs/guidelines/async-api.mdx index c5473812e..4b40f2c1d 100644 --- a/docs/docs/guidelines/async-api.mdx +++ b/docs/docs/guidelines/async-api.mdx @@ -14,17 +14,17 @@ This feature supports running tasks in a Celery worker queue and AnyIO task grou ## The _`sync`_ Flag -The _`sync`_ flag can be included in the payload of your POST request to the _`/api/v1/process/`_ endpoint. +The _`sync`_ flag can be included in the payload of your POST request to the _`/api/v1/run/`_ endpoint. When set to _`false`_, the API will initiate an asynchronous task instead of processing the flow synchronously. ### API Request with _`sync`_ flag ```bash curl -X POST \ - http://localhost:3000/api/v1/process/ \ + http://localhost:3000/api/v1/run/ \ -H 'Content-Type: application/json' \ -H 'x-api-key: ' \ - -d '{"inputs": {"text": ""}, "tweaks": {}, "sync": false}' + -d '{"input_value": "Message", "tweaks": {}, "sync": false}' ``` Response: From 1a9dd80cb02c5077901d36869b0304f97e96010c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 17:17:51 -0300 Subject: [PATCH 11/54] Remove async-api guidelines --- docs/docs/guidelines/async-api.mdx | 73 ------------------------------ docs/sidebars.js | 1 - 2 files changed, 74 deletions(-) delete mode 100644 docs/docs/guidelines/async-api.mdx diff --git a/docs/docs/guidelines/async-api.mdx b/docs/docs/guidelines/async-api.mdx deleted file mode 100644 index 4b40f2c1d..000000000 --- a/docs/docs/guidelines/async-api.mdx +++ /dev/null @@ -1,73 +0,0 @@ -import Admonition from "@theme/Admonition"; - -# Asynchronous Processing - -## Introduction - -Starting from version 0.5, Langflow introduces a new feature to its API: the _`sync`_ flag. This flag allows users to opt for asynchronous processing of their flows, freeing up resources and enabling better control over long-running tasks. -This feature supports running tasks in a Celery worker queue and AnyIO task groups for now. - - - This is an experimental feature. The default behavior of the API is still - synchronous processing. The API may change in the future. - - -## The _`sync`_ Flag - -The _`sync`_ flag can be included in the payload of your POST request to the _`/api/v1/run/`_ endpoint. -When set to _`false`_, the API will initiate an asynchronous task instead of processing the flow synchronously. - -### API Request with _`sync`_ flag - -```bash -curl -X POST \ - http://localhost:3000/api/v1/run/ \ - -H 'Content-Type: application/json' \ - -H 'x-api-key: ' \ - -d '{"input_value": "Message", "tweaks": {}, "sync": false}' -``` - -Response: - -```json -{ - "result": { - "output": "..." - }, - "task": { - "id": "...", - "href": "api/v1/task/" - }, - "session_id": "...", - "backend": "..." // celery or anyio -} -``` - -## Checking Task Status - -You can check the status of an asynchronous task by making a GET request to the `/task/{task_id}` endpoint. - -```bash -curl -X GET \ - http://localhost:3000/api/v1/task/ \ - -H 'x-api-key: ' -``` - -### Response - -The endpoint will return the current status of the task and, if completed, the result of the task. Possible statuses include: - -- _`PENDING`_: The task is waiting for execution. -- _`SUCCESS`_: The task has completed successfully. -- _`FAILURE`_: The task has failed. - -Example response for a completed task: - -```json -{ - "status": "SUCCESS", - "result": { - "output": "..." - } -} -``` diff --git a/docs/sidebars.js b/docs/sidebars.js index 029ccf94e..07af44af3 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -73,7 +73,6 @@ module.exports = { items: [ "guidelines/login", "guidelines/api", - "guidelines/async-api", "guidelines/components", "guidelines/features", "guidelines/collection", From f9db119931ed2c39f5882e50ab244146ed17be6f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 17:21:34 -0300 Subject: [PATCH 12/54] Fix UnicodeDecodeError in DirectoryReader --- .../custom/directory_reader/directory_reader.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py index 83075eeb3..34ca2491b 100644 --- a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py +++ b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py @@ -6,7 +6,6 @@ from pathlib import Path from loguru import logger from langflow.interface.custom.custom_component import CustomComponent -from langflow.interface.custom.custom_component import CustomComponent class CustomComponentPathValueError(ValueError): @@ -109,7 +108,14 @@ class DirectoryReader: if not os.path.isfile(file_path): return None with open(file_path, "r") as file: - return file.read() + # UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 3069: character maps to + try: + return file.read() + except UnicodeDecodeError: + # This is happening in Windows, so we need to open the file in binary mode + # The file is always just a python file, so we can safely read it as utf-8 + with open(file_path, "rb") as file: + return file.read().decode("utf-8") def get_files(self): """ From fba7ee1fd83f1eb9090737dae1c56136ec7ea466 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:02:41 -0300 Subject: [PATCH 13/54] Update dependency version and fix encoding issues --- scripts/update_dependencies.py | 11 ++++++++++- src/backend/base/langflow/initial_setup/setup.py | 4 ++-- .../custom/directory_reader/directory_reader.py | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/update_dependencies.py b/scripts/update_dependencies.py index a46a95f8a..c70cf8f8f 100644 --- a/scripts/update_dependencies.py +++ b/scripts/update_dependencies.py @@ -11,6 +11,15 @@ def read_version_from_pyproject(file_path): return None +def get_version_from_pypi(package_name): + import requests + + response = requests.get(f"https://pypi.org/pypi/{package_name}/json") + if response.ok: + return response.json()["info"]["version"] + return None + + def update_pyproject_dependency(pyproject_path, version): pattern = re.compile(r'langflow-base = \{ path = "\./src/backend/base", develop = true \}') replacement = f'langflow-base = "^{version}"' @@ -35,7 +44,7 @@ if __name__ == "__main__": # Reading version and updating pyproject.toml langflow_base_path = Path(__file__).resolve().parent / "../src/backend/base/pyproject.toml" - version = read_version_from_pyproject(langflow_base_path) + version = get_version_from_pypi("langflow-base") if version: update_pyproject_dependency(pyproject_path, version) else: diff --git a/src/backend/base/langflow/initial_setup/setup.py b/src/backend/base/langflow/initial_setup/setup.py index 33e839689..f2181f85e 100644 --- a/src/backend/base/langflow/initial_setup/setup.py +++ b/src/backend/base/langflow/initial_setup/setup.py @@ -88,7 +88,7 @@ def load_starter_projects(): starter_projects = [] folder = Path(__file__).parent / "starter_projects" for file in folder.glob("*.json"): - project = orjson.loads(file.read_text()) + project = orjson.loads(file.read_text(encoding="utf-8")) starter_projects.append((file, project)) logger.info(f"Loaded starter project {file}") return starter_projects @@ -124,7 +124,7 @@ def get_project_data(project): def update_project_file(project_path, project, updated_project_data): project["data"] = updated_project_data - with open(project_path, "w") as f: + with open(project_path, "w", encoding="utf-8") as f: f.write(orjson.dumps(project, option=orjson.OPT_INDENT_2).decode()) logger.info(f"Updated starter project {project['name']} file") diff --git a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py index 34ca2491b..b4ebefaf1 100644 --- a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py +++ b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py @@ -107,7 +107,7 @@ class DirectoryReader: """ if not os.path.isfile(file_path): return None - with open(file_path, "r") as file: + with open(file_path, "r", encoding="utf-8") as file: # UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 3069: character maps to try: return file.read() From 093535009555fad32946b640cd072cb60d17320c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:03:11 -0300 Subject: [PATCH 14/54] Add conditional build and publish for base and main projects --- Makefile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dc779fa03..78bd7e568 100644 --- a/Makefile +++ b/Makefile @@ -168,8 +168,13 @@ build_frontend: build: @echo 'Building the project' @make setup_env +ifdef base make build_langflow_base +endif + +ifdef main make build_langflow +endif build_langflow_base: make install_frontendci @@ -208,6 +213,7 @@ lock: @echo 'Locking dependencies' cd src/backend/base && poetry lock poetry lock + publish_base: make build_langflow_base cd src/backend/base && poetry publish @@ -217,8 +223,14 @@ publish_langflow: poetry publish publish: + @echo 'Publishing the project' +ifdef base make publish_base - make publish_langflowpoetr +endif + +ifdef main + make publish_langflow +endif help: @echo '----' From e98005731b641173afb2e801573036ccf3fdfcee Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:07:42 -0300 Subject: [PATCH 15/54] Update version to 1.0.0a2 in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c30130e7a..39978b03d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a1" +version = "1.0.0a2" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ From 6d5cd815351183002ff370e510f6db0278ee0165 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:07:52 -0300 Subject: [PATCH 16/54] Remove duplicate imports and unnecessary code in custom-component.mdx --- docs/docs/guidelines/custom-component.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/docs/guidelines/custom-component.mdx b/docs/docs/guidelines/custom-component.mdx index 77a1c5aaa..daf47987f 100644 --- a/docs/docs/guidelines/custom-component.mdx +++ b/docs/docs/guidelines/custom-component.mdx @@ -406,8 +406,4 @@ Langflow will attempt to load all of the components found in the specified direc Once your custom components have been loaded successfully, they will appear in Langflow's sidebar. From there, you can add them to your Langflow canvas for use. However, please note that components with errors will not be available for addition to the canvas. Always ensure your code is error-free before attempting to load components. -Remember, creating custom components allows you to extend the functionality of Langflow to better suit your unique needs. Happy coding!import ZoomableImage from "/src/theme/ZoomableImage.js"; -import Admonition from "@theme/Admonition"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; -import Admonition from "@theme/Admonition"; - +Remember, creating custom components allows you to extend the functionality of Langflow to better suit your unique needs. Happy coding! From 0267bef2fe26abbf9fbfda52da329ccf68786daa Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:43:27 -0300 Subject: [PATCH 17/54] Fix poetry lock command in Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 78bd7e568..67b48917e 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,7 @@ build_langflow_backup: build_langflow: cd ./scripts && python update_dependencies.py - -poetry lock + poetry lock -poetry build-rewrite-path-deps --version-pinning-strategy=semver mv pyproject.toml.bak pyproject.toml mv poetry.lock.bak poetry.lock @@ -225,11 +225,11 @@ publish_langflow: publish: @echo 'Publishing the project' ifdef base - make publish_base + -make publish_base endif ifdef main - make publish_langflow + -make publish_langflow endif help: From 38b14526b68a42270e768912670e5356bd9bbf47 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:46:11 -0300 Subject: [PATCH 18/54] Update package versions in pyproject.toml --- pyproject.toml | 2 +- src/backend/base/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 39978b03d..5a2dc622a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a2" +version = "1.0.0a4" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 544c7f3a7..471477d82 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.17" +version = "0.0.18" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ From c88a134815cc7641beab990c5ff45425aeb15b5e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 18:58:56 -0300 Subject: [PATCH 19/54] Remove unused components and update imports --- docs/docs/components/wrappers.mdx | 20 ------- docs/docs/examples/how-upload-examples.mdx | 28 --------- .../docs/examples/midjourney-prompt-chain.mdx | 46 --------------- docs/docs/examples/multiple-vectorstores.mdx | 58 ------------------- docs/docs/guidelines/api.mdx | 2 +- docs/sidebars.js | 5 -- 6 files changed, 1 insertion(+), 158 deletions(-) delete mode 100644 docs/docs/components/wrappers.mdx delete mode 100644 docs/docs/examples/how-upload-examples.mdx delete mode 100644 docs/docs/examples/midjourney-prompt-chain.mdx delete mode 100644 docs/docs/examples/multiple-vectorstores.mdx diff --git a/docs/docs/components/wrappers.mdx b/docs/docs/components/wrappers.mdx deleted file mode 100644 index 4b1251b60..000000000 --- a/docs/docs/components/wrappers.mdx +++ /dev/null @@ -1,20 +0,0 @@ -import Admonition from '@theme/Admonition'; - -# Wrappers - - -

- We appreciate your understanding as we polish our documentation – it may contain some rough edges. Share your feedback or report issues to help us improve! 🛠️📝 -

-
- - -### TextRequestsWrapper - -This component is designed to work with the Python Requests module, which is a popular tool for making web requests. Used to fetch data from a particular website. - -**Params** - -- **header:** specifies the headers to be included in the HTTP request. Defaults to `{'Authorization': 'Bearer '}`. - - Headers are key-value pairs that provide additional information about the request or the client making the request. They can be used to send authentication credentials, specify the content type of the request, set cookies, and more. They allow the client and the server to communicate additional information beyond the basic request. \ No newline at end of file diff --git a/docs/docs/examples/how-upload-examples.mdx b/docs/docs/examples/how-upload-examples.mdx deleted file mode 100644 index 4f54558eb..000000000 --- a/docs/docs/examples/how-upload-examples.mdx +++ /dev/null @@ -1,28 +0,0 @@ -import ThemedImage from "@theme/ThemedImage"; -import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; - -# 📚 How to Upload Examples? - -We welcome all examples that can help our community learn and explore Langflow's capabilities. -Langflow Examples is a repository on [GitHub](https://github.com/logspace-ai/langflow_examples) that contains examples of flows that people can use for inspiration and learning. - -{" "} - - -To upload examples, please follow these steps: - -1. **Create a Flow:** First, create a flow using Langflow. You can use any of the available templates or create a new flow from scratch. - -2. **Export the Flow:** Once you have created a flow, export it as a JSON file. Make sure to give your file a descriptive name and include a brief description of what it does. - -3. **Submit a Pull Request:** Finally, submit a pull request (PR) to the examples repo. Make sure to include your JSON file in the PR. - -If your example uses any third-party libraries or packages, please include them in your PR and make sure that your example follows the [**⛓️ Langflow Code Of Conduct**](https://github.com/logspace-ai/langflow/blob/dev/CODE_OF_CONDUCT.md). diff --git a/docs/docs/examples/midjourney-prompt-chain.mdx b/docs/docs/examples/midjourney-prompt-chain.mdx deleted file mode 100644 index 9df732026..000000000 --- a/docs/docs/examples/midjourney-prompt-chain.mdx +++ /dev/null @@ -1,46 +0,0 @@ -import Admonition from "@theme/Admonition"; - -# MidJourney Prompt Chain - -The `MidJourneyPromptChain` can be used to generate imaginative and detailed MidJourney prompts. - -For example, type something like: - -```bash -Dragon -``` - -And get a response such as: - -```text -Imagine a mysterious forest, the trees are tall and ancient, their branches reaching up to the sky. Through the darkness, a dragon emerges from the shadows, its scales shimmering in the moonlight. Its wingspan is immense, and its eyes glow with a fierce intensity. It is a majestic and powerful creature, one that commands both respect and fear. -``` - - - Notice that the `ConversationSummaryMemory` stores a summary of the - conversation over time. Try using it to create better prompts as the - conversation goes on. - - -## ⛓️ Langflow Example - -import ThemedImage from "@theme/ThemedImage"; -import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; - - - -#### Download Flow - - - -- [`OpenAI`](https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai) -- [`ConversationSummaryMemory`](https://python.langchain.com/docs/modules/memory/types/summary) - - diff --git a/docs/docs/examples/multiple-vectorstores.mdx b/docs/docs/examples/multiple-vectorstores.mdx deleted file mode 100644 index 2e554bbf1..000000000 --- a/docs/docs/examples/multiple-vectorstores.mdx +++ /dev/null @@ -1,58 +0,0 @@ -import Admonition from "@theme/Admonition"; - -# Multiple Vector Stores - -The example below shows an agent operating with two vector stores built upon different data sources. - -The `TextLoader` loads a TXT file, while the `WebBaseLoader` pulls text from webpages into a document format to accessed downstream. The `Chroma` vector stores are created analogous to what we have demonstrated in our [CSV Loader](/examples/csv-loader.mdx) example. Finally, the `VectorStoreRouterAgent` constructs an agent that routes between the vector stores. - - - Get the TXT file used - [here](https://github.com/hwchase17/chat-your-data/blob/master/state_of_the_union.txt). - - -URL used by the `WebBaseLoader`: - -```text -https://pt.wikipedia.org/wiki/Harry_Potter -``` - - - When you build the flow, request information about one of the sources. The - agent should be able to use the correct source to generate a response. - - - - Learn more about Multiple Vector Stores - [here](https://python.langchain.com/docs/modules/data_connection/vectorstores/). - - -## ⛓️ Langflow Example - -import ThemedImage from "@theme/ThemedImage"; -import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; - - - -#### Download Flow - - - -- [`WebBaseLoader`](https://python.langchain.com/docs/integrations/document_loaders/web_base) -- [`TextLoader`](https://python.langchain.com/docs/modules/data_connection/document_loaders/) -- [`CharacterTextSplitter`](https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/character_text_splitter) -- [`OpenAIEmbedding`](https://python.langchain.com/docs/integrations/text_embedding/openai) -- [`Chroma`](https://python.langchain.com/docs/integrations/vectorstores/chroma) -- [`VectorStoreInfo`](https://python.langchain.com/docs/modules/data_connection/vectorstores/) -- [`OpenAI`](https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai) -- [`VectorStoreRouterToolkit`](https://js.langchain.com/docs/modules/agents/tools/how_to/agents_with_vectorstores) -- [`VectorStoreRouterAgent`](https://js.langchain.com/docs/modules/agents/tools/how_to/agents_with_vectorstores) - - diff --git a/docs/docs/guidelines/api.mdx b/docs/docs/guidelines/api.mdx index 6ba2c3a72..25dbeb31e 100644 --- a/docs/docs/guidelines/api.mdx +++ b/docs/docs/guidelines/api.mdx @@ -1,6 +1,6 @@ import useBaseUrl from "@docusaurus/useBaseUrl"; import ZoomableImage from "/src/theme/ZoomableImage.js"; -import Admonition from "/src/theme/Admonition.js"; +import Admonition from "@theme/Admonition"; # API Keys diff --git a/docs/sidebars.js b/docs/sidebars.js index 07af44af3..7b2a4b956 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -112,8 +112,6 @@ module.exports = { "components/text-splitters", "components/toolkits", "components/tools", - "components/wrappers", - // "components/prompts", ], }, { @@ -124,13 +122,10 @@ module.exports = { "examples/flow-runner", "examples/conversation-chain", "examples/buffer-memory", - "examples/midjourney-prompt-chain", "examples/csv-loader", "examples/searchapi-tool", "examples/serp-api-tool", - "examples/multiple-vectorstores", "examples/python-function", - "examples/how-upload-examples", ], }, { From 4c04b1ef1c91c9c7dab93de47b0026b589bdce14 Mon Sep 17 00:00:00 2001 From: Matheus Date: Thu, 4 Apr 2024 00:03:45 +0200 Subject: [PATCH 20/54] =?UTF-8?q?=F0=9F=93=A6=20chore(pre-release-base.yml?= =?UTF-8?q?):=20add=20pre-release=20workflow=20for=20base=20project=20?= =?UTF-8?q?=F0=9F=93=A6=20chore(pre-release-langflow.yml):=20add=20pre-rel?= =?UTF-8?q?ease=20workflow=20for=20langflow=20project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{pre-release.yml => pre-release-base.yml} | 6 +- .github/workflows/pre-release-langflow.yml | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) rename .github/workflows/{pre-release.yml => pre-release-base.yml} (95%) create mode 100644 .github/workflows/pre-release-langflow.yml diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release-base.yml similarity index 95% rename from .github/workflows/pre-release.yml rename to .github/workflows/pre-release-base.yml index 6ca9aa67d..762bac3e9 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release-base.yml @@ -1,4 +1,4 @@ -name: pre-release +name: pre-release-base on: pull_request: @@ -27,7 +27,7 @@ jobs: python-version: "3.10" cache: "poetry" - name: Build project for distribution - run: make build + run: make build base=true - name: Check Version id: check-version run: | @@ -46,7 +46,7 @@ jobs: env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }} run: | - poetry publish + poetry publish base=true - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx diff --git a/.github/workflows/pre-release-langflow.yml b/.github/workflows/pre-release-langflow.yml new file mode 100644 index 000000000..102004613 --- /dev/null +++ b/.github/workflows/pre-release-langflow.yml @@ -0,0 +1,71 @@ +name: pre-release-langflow + +on: + pull_request: + types: + - closed + branches: + - dev + paths: + - "pyproject.toml" + workflow_dispatch: + workflow_run: + workflows: ["pre-release-base"] + types: [completed] + branches: [dev] + +env: + POETRY_VERSION: "1.8.2" + +jobs: + if_release: + if: ${{ (github.event.pull_request.merged == true) && contains(github.event.pull_request.labels.*.name, 'pre-release') }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install poetry + run: pipx install poetry==$POETRY_VERSION && poetry self add poetry-monorepo-dependency-plugin + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: "poetry" + - name: Build project for distribution + run: make build main=true + - name: Check Version + id: check-version + run: | + echo version=$(poetry version --short) >> $GITHUB_OUTPUT + - name: Create Release + uses: ncipollo/release-action@v1 + with: + artifacts: "dist/*" + token: ${{ secrets.GITHUB_TOKEN }} + draft: false + generateReleaseNotes: true + prerelease: true + tag: v${{ steps.check-version.outputs.version }} + commit: dev + - name: Publish to PyPI + env: + POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }} + run: | + poetry publish main=true + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + file: ./build_and_push.Dockerfile + tags: | + logspace/langflow:${{ steps.check-version.outputs.version }} + logspace/langflow:latest-dev From 6e131120af399b605c3117ff0e420c5a15938126 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 19:33:03 -0300 Subject: [PATCH 21/54] Add ChatLiteLLMModelComponent to models package --- .../model_specs/ChatLiteLLMSpecs.py | 2 +- .../components/models/ChatLiteLLMModel.py | 191 ++++++++++++++++++ .../langflow/components/models/__init__.py | 2 + 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/backend/base/langflow/components/models/ChatLiteLLMModel.py diff --git a/src/backend/base/langflow/components/model_specs/ChatLiteLLMSpecs.py b/src/backend/base/langflow/components/model_specs/ChatLiteLLMSpecs.py index 5c1463b71..439266fbb 100644 --- a/src/backend/base/langflow/components/model_specs/ChatLiteLLMSpecs.py +++ b/src/backend/base/langflow/components/model_specs/ChatLiteLLMSpecs.py @@ -118,7 +118,7 @@ class ChatLiteLLMComponent(CustomComponent): max_tokens: int = 256, max_retries: int = 6, verbose: bool = False, - ) -> Union[BaseLanguageModel, Callable]: + ) -> BaseLanguageModel: try: import litellm # type: ignore diff --git a/src/backend/base/langflow/components/models/ChatLiteLLMModel.py b/src/backend/base/langflow/components/models/ChatLiteLLMModel.py new file mode 100644 index 000000000..5266c6935 --- /dev/null +++ b/src/backend/base/langflow/components/models/ChatLiteLLMModel.py @@ -0,0 +1,191 @@ +from typing import Any, Dict, Optional + +from langchain_community.chat_models.litellm import ChatLiteLLM, ChatLiteLLMException + +from langflow.base.constants import STREAM_INFO_TEXT +from langflow.base.models.model import LCModelComponent +from langflow.field_typing import BaseLanguageModel, Text + + +class ChatLiteLLMModelComponent(LCModelComponent): + display_name = "LiteLLM" + description = "`LiteLLM` collection of large language models." + documentation = "https://python.langchain.com/docs/integrations/chat/litellm" + field_order = [ + "model", + "api_key", + "provider", + "temperature", + "model_kwargs", + "top_p", + "top_k", + "n", + "max_tokens", + "max_retries", + "verbose", + "stream", + "input_value", + "system_message", + ] + + def build_config(self): + return { + "model": { + "display_name": "Model name", + "field_type": "str", + "advanced": False, + "required": True, + "info": "The name of the model to use. For example, `gpt-3.5-turbo`.", + }, + "api_key": { + "display_name": "API key", + "field_type": "str", + "advanced": False, + "required": False, + "password": True, + }, + "provider": { + "display_name": "Provider", + "info": "The provider of the API key.", + "options": [ + "OpenAI", + "Azure", + "Anthropic", + "Replicate", + "Cohere", + "OpenRouter", + ], + }, + "temperature": { + "display_name": "Temperature", + "field_type": "float", + "advanced": False, + "required": False, + "default": 0.7, + }, + "model_kwargs": { + "display_name": "Model kwargs", + "field_type": "dict", + "advanced": True, + "required": False, + "default": {}, + }, + "top_p": { + "display_name": "Top p", + "field_type": "float", + "advanced": True, + "required": False, + }, + "top_k": { + "display_name": "Top k", + "field_type": "int", + "advanced": True, + "required": False, + }, + "n": { + "display_name": "N", + "field_type": "int", + "advanced": True, + "required": False, + "info": "Number of chat completions to generate for each prompt. " + "Note that the API may not return the full n completions if duplicates are generated.", + "default": 1, + }, + "max_tokens": { + "display_name": "Max tokens", + "field_type": "int", + "advanced": False, + "required": False, + "default": 256, + "info": "The maximum number of tokens to generate for each chat completion.", + }, + "max_retries": { + "display_name": "Max retries", + "field_type": "int", + "advanced": True, + "required": False, + "default": 6, + }, + "verbose": { + "display_name": "Verbose", + "field_type": "bool", + "advanced": True, + "required": False, + "default": False, + }, + "input_value": {"display_name": "Input"}, + "stream": { + "display_name": "Stream", + "info": STREAM_INFO_TEXT, + "advanced": True, + }, + "system_message": { + "display_name": "System Message", + "info": "System message to pass to the model.", + "advanced": True, + }, + } + + def build( + self, + input_value: Text, + model: str, + provider: str, + api_key: Optional[str] = None, + stream: bool = False, + temperature: Optional[float] = 0.7, + model_kwargs: Optional[Dict[str, Any]] = {}, + top_p: Optional[float] = None, + top_k: Optional[int] = None, + n: int = 1, + max_tokens: int = 256, + max_retries: int = 6, + verbose: bool = False, + system_message: Optional[str] = None, + ) -> BaseLanguageModel: + try: + import litellm # type: ignore + + litellm.drop_params = True + litellm.set_verbose = verbose + except ImportError: + raise ChatLiteLLMException( + "Could not import litellm python package. " "Please install it with `pip install litellm`" + ) + provider_map = { + "OpenAI": "openai_api_key", + "Azure": "azure_api_key", + "Anthropic": "anthropic_api_key", + "Replicate": "replicate_api_key", + "Cohere": "cohere_api_key", + "OpenRouter": "openrouter_api_key", + } + # Set the API key based on the provider + api_keys: dict[str, Optional[str]] = {v: None for v in provider_map.values()} + + if variable_name := provider_map.get(provider): + api_keys[variable_name] = api_key + else: + raise ChatLiteLLMException( + f"Provider {provider} is not supported. Supported providers are: {', '.join(provider_map.keys())}" + ) + + output = ChatLiteLLM( + model=model, + client=None, + streaming=stream, + temperature=temperature, + model_kwargs=model_kwargs if model_kwargs is not None else {}, + top_p=top_p, + top_k=top_k, + n=n, + max_tokens=max_tokens, + max_retries=max_retries, + openai_api_key=api_keys["openai_api_key"], + azure_api_key=api_keys["azure_api_key"], + anthropic_api_key=api_keys["anthropic_api_key"], + replicate_api_key=api_keys["replicate_api_key"], + cohere_api_key=api_keys["cohere_api_key"], + openrouter_api_key=api_keys["openrouter_api_key"], + ) + return self.get_chat_result(output, stream, input_value, system_message) diff --git a/src/backend/base/langflow/components/models/__init__.py b/src/backend/base/langflow/components/models/__init__.py index 3efbe4b6f..9db6caa26 100644 --- a/src/backend/base/langflow/components/models/__init__.py +++ b/src/backend/base/langflow/components/models/__init__.py @@ -2,6 +2,7 @@ from .AmazonBedrockModel import AmazonBedrockComponent from .AnthropicModel import AnthropicLLM from .AzureOpenAIModel import AzureChatOpenAIComponent from .BaiduQianfanChatModel import QianfanChatEndpointComponent +from .ChatLiteLLMModel import ChatLiteLLMModelComponent from .CohereModel import CohereComponent from .GoogleGenerativeAIModel import GoogleGenerativeAIComponent from .HuggingFaceModel import HuggingFaceEndpointsComponent @@ -10,6 +11,7 @@ from .OpenAIModel import OpenAIModelComponent from .VertexAiModel import ChatVertexAIComponent __all__ = [ + "ChatLiteLLMModelComponent", "AmazonBedrockComponent", "AnthropicLLM", "AzureChatOpenAIComponent", From 6c7b20b4e76a111628cbd978d8eb8ddf71f51d19 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 19:33:15 -0300 Subject: [PATCH 22/54] Add frontend installation and build steps --- Makefile | 4 ++-- lcserve.Dockerfile | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 lcserve.Dockerfile diff --git a/Makefile b/Makefile index 67b48917e..40c53075b 100644 --- a/Makefile +++ b/Makefile @@ -169,6 +169,8 @@ build: @echo 'Building the project' @make setup_env ifdef base + make install_frontendci + make build_frontend make build_langflow_base endif @@ -177,8 +179,6 @@ ifdef main endif build_langflow_base: - make install_frontendci - make build_frontend cd src/backend/base && poetry build-rewrite-path-deps --version-pinning-strategy=semver rm -rf src/backend/base/langflow/frontend diff --git a/lcserve.Dockerfile b/lcserve.Dockerfile deleted file mode 100644 index 883a2c040..000000000 --- a/lcserve.Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -# This file is used by `lc-serve` to build the image. -# Don't change the name of this file. - -FROM jinawolf/serving-gateway:${version} - -RUN apt-get update \ - && apt-get install --no-install-recommends -y build-essential libpq-dev - -COPY . /appdir/ - -RUN pip install poetry==1.4.0 && cd /appdir && pip install . && \ - pip uninstall -y poetry && \ - apt-get remove --auto-remove -y build-essential libpq-dev && \ - apt-get autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* - -ENTRYPOINT [ "jina", "gateway", "--uses", "config.yml" ] \ No newline at end of file From 734bef80133186405dc51e821b55e79548a133f5 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 19:50:57 -0300 Subject: [PATCH 23/54] Add Dockerfile for building and pushing base image --- .dockerignore | 2 +- build_and_push_base.Dockerfile | 95 ++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 build_and_push_base.Dockerfile diff --git a/.dockerignore b/.dockerignore index 130ca4c2c..7cae75457 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,6 @@ .venv/ **/aws -# node_modules +node_modules **/node_modules/ dist/ **/build/ diff --git a/build_and_push_base.Dockerfile b/build_and_push_base.Dockerfile new file mode 100644 index 000000000..1aa7ee950 --- /dev/null +++ b/build_and_push_base.Dockerfile @@ -0,0 +1,95 @@ + + +# syntax=docker/dockerfile:1 +# Keep this syntax directive! It's used to enable Docker BuildKit + +# Based on https://github.com/python-poetry/poetry/discussions/1879?sort=top#discussioncomment-216865 +# but I try to keep it updated (see history) + +################################ +# PYTHON-BASE +# Sets up all our shared environment variables +################################ +FROM python:3.10-slim as python-base + +# python +ENV PYTHONUNBUFFERED=1 \ + # prevents python creating .pyc files + PYTHONDONTWRITEBYTECODE=1 \ + \ + # pip + PIP_DISABLE_PIP_VERSION_CHECK=on \ + PIP_DEFAULT_TIMEOUT=100 \ + \ + # poetry + # https://python-poetry.org/docs/configuration/#using-environment-variables + POETRY_VERSION=1.8.2 \ + # make poetry install to this location + POETRY_HOME="/opt/poetry" \ + # make poetry create the virtual environment in the project's root + # it gets named `.venv` + POETRY_VIRTUALENVS_IN_PROJECT=true \ + # do not ask any interactive question + POETRY_NO_INTERACTION=1 \ + \ + # paths + # this is where our requirements + virtual environment will live + PYSETUP_PATH="/opt/pysetup" \ + VENV_PATH="/opt/pysetup/.venv" + + +# prepend poetry and venv to path +ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH" + + +################################ +# BUILDER-BASE +# Used to build deps + create our virtual environment +################################ +FROM python-base as builder-base +RUN apt-get update \ + && apt-get install --no-install-recommends -y \ + # deps for installing poetry + curl \ + # deps for building python deps + build-essential \ + # npm + npm \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN --mount=type=cache,target=/root/.cache \ + curl -sSL https://install.python-poetry.org | python3 - + +# Now we need to copy the entire project into the image +COPY pyproject.toml poetry.lock ./ +COPY src/frontend/package.json /tmp/package.json +RUN cd /tmp && npm install +WORKDIR /app +COPY src/frontend ./src/frontend +RUN rm -rf src/frontend/node_modules +RUN cp -a /tmp/node_modules /app/src/frontend +COPY scripts ./scripts +COPY Makefile ./ +COPY README.md ./ +RUN cd src/frontend && npm run build +COPY src/backend ./src/backend +RUN rm -rf src/backend/base/dist +RUN cd src/backend/base && $POETRY_HOME/bin/poetry build --format sdist + +# Final stage for the application +FROM python-base as final + +# Copy virtual environment and built .tar.gz from builder base +COPY --from=builder-base /app/src/backend/base/dist/*.tar.gz ./ + +# Install the package from the .tar.gz +RUN pip install *.tar.gz + +# Now remove the .tar.gz +RUN rm *.tar.gz +# Remove the source code +RUN rm -rf /app + +WORKDIR /app +CMD ["python", "-m", "langflow", "run", "--host", "0.0.0.0", "--port", "7860"] From 4d0832061b5001145d463047cf9e29778e1bd7fd Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 19:51:01 -0300 Subject: [PATCH 24/54] Add emoji package and nest-asyncio dependency --- src/backend/base/poetry.lock | 16 +++++++++++++++- src/backend/base/pyproject.toml | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index caf2af880..141f67293 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -1186,6 +1186,20 @@ six = ">=1.9.0" gmpy = ["gmpy"] gmpy2 = ["gmpy2"] +[[package]] +name = "emoji" +version = "2.11.0" +description = "Emoji for Python" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +files = [ + {file = "emoji-2.11.0-py2.py3-none-any.whl", hash = "sha256:63fc9107f06c6c2e48e5078ce9575cef98518f5ac09474f6148a43e989989582"}, + {file = "emoji-2.11.0.tar.gz", hash = "sha256:772eaa30f4e0b1ce95148a092df4c7dc97644532c03225326b0fd05e8a9f72a3"}, +] + +[package.extras] +dev = ["coverage", "coveralls", "pytest"] + [[package]] name = "exceptiongroup" version = "1.2.0" @@ -6061,4 +6075,4 @@ local = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "5473eb333e6fd18ecc70e845f0a34a2d0d267f5a5055e31624453dd9a5485f0e" +content-hash = "7a0ea99c42ad306b5452228d05dbf3afb35713e1dba8e0b56aa63d987663a16a" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 471477d82..6d97897b2 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -60,6 +60,8 @@ pypdf = "^4.1.0" chromadb = "^0.4.24" langchain-anthropic = "^0.1.4" langchain-astradb = "^0.1.0" +nest-asyncio = "^1.6.0" +emoji = "^2.11.0" [tool.poetry.group.dev.dependencies] From aa7338bf6752341f76757d2b393333f65ce526c8 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Wed, 3 Apr 2024 20:45:53 -0300 Subject: [PATCH 25/54] =?UTF-8?q?=F0=9F=93=9D=20(components.mdx):=20update?= =?UTF-8?q?=20margin=20style=20of=20ZoomableImage=20to=20improve=20spacing?= =?UTF-8?q?=20=F0=9F=93=9D=20(features.mdx):=20update=20margin=20style=20o?= =?UTF-8?q?f=20ZoomableImage=20to=20improve=20spacing=20=F0=9F=93=9D=20(lo?= =?UTF-8?q?gin.mdx):=20update=20margin=20style=20of=20ZoomableImage=20to?= =?UTF-8?q?=20improve=20spacing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/guidelines/components.mdx | 3 ++- docs/docs/guidelines/features.mdx | 5 ++--- docs/docs/guidelines/login.mdx | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/docs/guidelines/components.mdx b/docs/docs/guidelines/components.mdx index 32ec00615..16aa83eff 100644 --- a/docs/docs/guidelines/components.mdx +++ b/docs/docs/guidelines/components.mdx @@ -26,13 +26,14 @@ Components are the building blocks of the flows. They are made of inputs, output {" "} +
diff --git a/docs/docs/guidelines/features.mdx b/docs/docs/guidelines/features.mdx index 6f50abb35..d4998edb6 100644 --- a/docs/docs/guidelines/features.mdx +++ b/docs/docs/guidelines/features.mdx @@ -1,4 +1,3 @@ - # Features
@@ -9,13 +8,14 @@
{" "} +
@@ -63,7 +63,6 @@ The example below shows a Python script making a POST request to a local API end
- import ThemedImage from "@theme/ThemedImage"; import useBaseUrl from "@docusaurus/useBaseUrl"; import ZoomableImage from "/src/theme/ZoomableImage.js"; diff --git a/docs/docs/guidelines/login.mdx b/docs/docs/guidelines/login.mdx index fde7cd09a..1d5a1d031 100644 --- a/docs/docs/guidelines/login.mdx +++ b/docs/docs/guidelines/login.mdx @@ -105,7 +105,7 @@ Users can change their profile settings by clicking on the profile icon in the t light: useBaseUrl("img/my-account.png"), dark: useBaseUrl("img/my-account.png"), }} - style={{ width: "50%", maxWidth: "600px", margin: "0 auto" }} + style={{ width: "50%", maxWidth: "600px", margin: "20px auto" }} /> By clicking on **Profile Settings**, the user is taken to the profile settings page, where they can change their password and their profile picture. @@ -116,10 +116,11 @@ By clicking on **Profile Settings**, the user is taken to the profile settings p light: useBaseUrl("img/profile-settings.png"), dark: useBaseUrl("img/profile-settings.png"), }} - style={{ maxWidth: "600px", margin: "0 auto" }} + style={{ maxWidth: "600px", margin: "20px auto" }} /> -By clicking on **Admin Page**, the superuser is taken to the admin page, where they can manage users and groups. +By clicking on **Admin Page**, the superuser is taken to the admin page, where they +can manage users and groups. Date: Wed, 3 Apr 2024 21:03:08 -0300 Subject: [PATCH 26/54] Fix module import error in validate.py --- src/backend/base/langflow/utils/validate.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backend/base/langflow/utils/validate.py b/src/backend/base/langflow/utils/validate.py index b5363dc8e..0871dbd82 100644 --- a/src/backend/base/langflow/utils/validate.py +++ b/src/backend/base/langflow/utils/validate.py @@ -203,10 +203,8 @@ def prepare_global_scope(code, module): imported_module = importlib.import_module(node.module) for alias in node.names: exec_globals[alias.name] = getattr(imported_module, alias.name) - except ModuleNotFoundError as e: - raise ModuleNotFoundError( - f"Module {node.module} not found. Please install it and try again. Error: {repr(e)}" - ) + except ModuleNotFoundError: + raise ModuleNotFoundError(f"Module {node.module} not found. Please install it and try again") return exec_globals From 5b2bec1cb640b55dfb6a6eeb1358f4f478eb1990 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:03:14 -0300 Subject: [PATCH 27/54] Fix error message in directory_reader.py --- .../interface/custom/directory_reader/directory_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py index b4ebefaf1..e9f3f6ceb 100644 --- a/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py +++ b/src/backend/base/langflow/interface/custom/directory_reader/directory_reader.py @@ -246,7 +246,7 @@ class DirectoryReader: filename = os.path.basename(file_path) validation_result, result_content = self.process_file(file_path) if not validation_result: - logger.error(f"Error while processing file {file_path}: {result_content}") + logger.error(f"Error while processing file {file_path}") menu_result = self.find_menu(response, menu_name) or { "name": menu_name, From b040b6e0dc56c656d94e1573e30d7aa42bd98dfe Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:03:25 -0300 Subject: [PATCH 28/54] Update version import and handle ImportError --- src/backend/base/langflow/__main__.py | 14 +++++++++++--- src/backend/base/langflow/api/v1/endpoints.py | 12 ++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/backend/base/langflow/__main__.py b/src/backend/base/langflow/__main__.py index 34ed75f9b..96f4f1575 100644 --- a/src/backend/base/langflow/__main__.py +++ b/src/backend/base/langflow/__main__.py @@ -246,9 +246,17 @@ def get_free_port(port): def print_banner(host, port): - from langflow.version import __version__ + try: + from langflow.version import __version__ + + version = __version__ + word = "Langflow" + except ImportError: + from importlib import metadata + + version = metadata.version("langflow-base") + word = "Langflow Base" - word = "Langflow" colors = ["#6e42f5"] styled_word = "" @@ -259,7 +267,7 @@ def print_banner(host, port): # Title with emojis and gradient text title = ( - f"[bold]Welcome to :chains: {styled_word} v{__version__}[/bold]\n" + f"[bold]Welcome to :chains: {styled_word} v{version}[/bold]\n" f"Access [link=http://{host}:{port}]http://{host}:{port}[/link]" ) info_text = ( diff --git a/src/backend/base/langflow/api/v1/endpoints.py b/src/backend/base/langflow/api/v1/endpoints.py index cdcf40443..4b032f6cb 100644 --- a/src/backend/base/langflow/api/v1/endpoints.py +++ b/src/backend/base/langflow/api/v1/endpoints.py @@ -372,9 +372,17 @@ async def create_upload_file( # get endpoint to return version of langflow @router.get("/version") def get_version(): - from langflow.version import __version__ # type: ignore + try: + from langflow.version import __version__ - return {"version": __version__} + version = __version__ + package = "Langflow" + except ImportError: + from importlib import metadata + + version = metadata.version("langflow-base") + package = "Langflow Base" + return {"version": version, "package": package} @router.post("/custom_component", status_code=HTTPStatus.OK) From f20bbdcbe7d346b819bd33f4b10cec44c09ff725 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:03:32 -0300 Subject: [PATCH 29/54] Add cryptography and langchain-openai dependencies --- src/backend/base/poetry.lock | 195 +++++++++++++++++++++++++++++++- src/backend/base/pyproject.toml | 2 + 2 files changed, 196 insertions(+), 1 deletion(-) diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 141f67293..a0d213615 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -2539,6 +2539,22 @@ langchain-core = ">=0.1.37,<0.2.0" [package.extras] extended-testing = ["faker (>=19.3.1,<20.0.0)", "jinja2 (>=3,<4)", "pandas (>=2.0.1,<3.0.0)", "presidio-analyzer (>=2.2.352,<3.0.0)", "presidio-anonymizer (>=2.2.352,<3.0.0)", "sentence-transformers (>=2,<3)", "tabulate (>=0.9.0,<0.10.0)", "vowpal-wabbit-next (==0.6.0)"] +[[package]] +name = "langchain-openai" +version = "0.1.1" +description = "An integration package connecting OpenAI and LangChain" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_openai-0.1.1-py3-none-any.whl", hash = "sha256:5cf4df5d2550af673337eafedaeec014ba52f9a25aeb8451206ca254bed01e5c"}, + {file = "langchain_openai-0.1.1.tar.gz", hash = "sha256:d10e9a9fc4c8ea99ca98f23808ce44c7dcdd65354ac07ad10afe874ecf3401ca"}, +] + +[package.dependencies] +langchain-core = ">=0.1.33,<0.2.0" +openai = ">=1.10.0,<2.0.0" +tiktoken = ">=0.5.2,<1" + [[package]] name = "langchain-text-splitters" version = "0.0.1" @@ -3423,6 +3439,29 @@ packaging = "*" protobuf = "*" sympy = "*" +[[package]] +name = "openai" +version = "1.16.1" +description = "The official Python library for the openai API" +optional = false +python-versions = ">=3.7.1" +files = [ + {file = "openai-1.16.1-py3-none-any.whl", hash = "sha256:77ef3db6110071f7154859e234250fb945a36554207a30a4491092eadb73fcb5"}, + {file = "openai-1.16.1.tar.gz", hash = "sha256:58922c785d167458b46e3c76e7b1bc2306f313ee9b71791e84cbf590abe160f2"}, +] + +[package.dependencies] +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.7,<5" + +[package.extras] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] + [[package]] name = "opentelemetry-api" version = "1.24.0" @@ -4734,6 +4773,108 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "regex" +version = "2023.12.25" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, +] + [[package]] name = "requests" version = "2.31.0" @@ -5076,6 +5217,58 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] +[[package]] +name = "tiktoken" +version = "0.6.0" +description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tiktoken-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:277de84ccd8fa12730a6b4067456e5cf72fef6300bea61d506c09e45658d41ac"}, + {file = "tiktoken-0.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c44433f658064463650d61387623735641dcc4b6c999ca30bc0f8ba3fccaf5c"}, + {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afb9a2a866ae6eef1995ab656744287a5ac95acc7e0491c33fad54d053288ad3"}, + {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62c05b3109fefca26fedb2820452a050074ad8e5ad9803f4652977778177d9f"}, + {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ef917fad0bccda07bfbad835525bbed5f3ab97a8a3e66526e48cdc3e7beacf7"}, + {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e095131ab6092d0769a2fda85aa260c7c383072daec599ba9d8b149d2a3f4d8b"}, + {file = "tiktoken-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:05b344c61779f815038292a19a0c6eb7098b63c8f865ff205abb9ea1b656030e"}, + {file = "tiktoken-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cefb9870fb55dca9e450e54dbf61f904aab9180ff6fe568b61f4db9564e78871"}, + {file = "tiktoken-0.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:702950d33d8cabc039845674107d2e6dcabbbb0990ef350f640661368df481bb"}, + {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8d49d076058f23254f2aff9af603863c5c5f9ab095bc896bceed04f8f0b013a"}, + {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:430bc4e650a2d23a789dc2cdca3b9e5e7eb3cd3935168d97d43518cbb1f9a911"}, + {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:293cb8669757301a3019a12d6770bd55bec38a4d3ee9978ddbe599d68976aca7"}, + {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7bd1a288b7903aadc054b0e16ea78e3171f70b670e7372432298c686ebf9dd47"}, + {file = "tiktoken-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac76e000183e3b749634968a45c7169b351e99936ef46f0d2353cd0d46c3118d"}, + {file = "tiktoken-0.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17cc8a4a3245ab7d935c83a2db6bb71619099d7284b884f4b2aea4c74f2f83e3"}, + {file = "tiktoken-0.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:284aebcccffe1bba0d6571651317df6a5b376ff6cfed5aeb800c55df44c78177"}, + {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c1a3a5d33846f8cd9dd3b7897c1d45722f48625a587f8e6f3d3e85080559be8"}, + {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6318b2bb2337f38ee954fd5efa82632c6e5ced1d52a671370fa4b2eff1355e91"}, + {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f5f0f2ed67ba16373f9a6013b68da298096b27cd4e1cf276d2d3868b5c7efd1"}, + {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75af4c0b16609c2ad02581f3cdcd1fb698c7565091370bf6c0cf8624ffaba6dc"}, + {file = "tiktoken-0.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:45577faf9a9d383b8fd683e313cf6df88b6076c034f0a16da243bb1c139340c3"}, + {file = "tiktoken-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c1492ab90c21ca4d11cef3a236ee31a3e279bb21b3fc5b0e2210588c4209e68"}, + {file = "tiktoken-0.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e2b380c5b7751272015400b26144a2bab4066ebb8daae9c3cd2a92c3b508fe5a"}, + {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f497598b9f58c99cbc0eb764b4a92272c14d5203fc713dd650b896a03a50ad"}, + {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e65e8bd6f3f279d80f1e1fbd5f588f036b9a5fa27690b7f0cc07021f1dfa0839"}, + {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5f1495450a54e564d236769d25bfefbf77727e232d7a8a378f97acddee08c1ae"}, + {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6c4e4857d99f6fb4670e928250835b21b68c59250520a1941618b5b4194e20c3"}, + {file = "tiktoken-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:168d718f07a39b013032741867e789971346df8e89983fe3c0ef3fbd5a0b1cb9"}, + {file = "tiktoken-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47fdcfe11bd55376785a6aea8ad1db967db7f66ea81aed5c43fad497521819a4"}, + {file = "tiktoken-0.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb7d2ccbf1a7784810aff6b80b4012fb42c6fc37eaa68cb3b553801a5cc2d1fc"}, + {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ccb7a111ee76af5d876a729a347f8747d5ad548e1487eeea90eaf58894b3138"}, + {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2048e1086b48e3c8c6e2ceeac866561374cd57a84622fa49a6b245ffecb7744"}, + {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07f229a5eb250b6403a61200199cecf0aac4aa23c3ecc1c11c1ca002cbb8f159"}, + {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:432aa3be8436177b0db5a2b3e7cc28fd6c693f783b2f8722539ba16a867d0c6a"}, + {file = "tiktoken-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:8bfe8a19c8b5c40d121ee7938cd9c6a278e5b97dc035fd61714b4f0399d2f7a1"}, + {file = "tiktoken-0.6.0.tar.gz", hash = "sha256:ace62a4ede83c75b0374a2ddfa4b76903cf483e9cb06247f566be3bf14e6beed"}, +] + +[package.dependencies] +regex = ">=2022.1.18" +requests = ">=2.26.0" + +[package.extras] +blobfile = ["blobfile (>=2)"] + [[package]] name = "tokenizers" version = "0.15.2" @@ -6075,4 +6268,4 @@ local = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "7a0ea99c42ad306b5452228d05dbf3afb35713e1dba8e0b56aa63d987663a16a" +content-hash = "27adc9d6515d9e92ee01a6aae0c9a8162aa403456134ab25a8dd98909ecbe5f2" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 6d97897b2..9b164e369 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -62,6 +62,8 @@ langchain-anthropic = "^0.1.4" langchain-astradb = "^0.1.0" nest-asyncio = "^1.6.0" emoji = "^2.11.0" +cryptography = "^42.0.5" +langchain-openai = "^0.1.1" [tool.poetry.group.dev.dependencies] From 8466958436f3d9e27f180895bef579928cb8ad39 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:04:15 -0300 Subject: [PATCH 30/54] Update poetry installation and remove poetry-monorepo-dependency-plugin --- .github/workflows/release.yml | 2 +- Makefile | 9 ++++----- pyproject.toml | 2 -- scripts/setup/update_poetry.sh | 8 -------- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b373b859b..8004618f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install poetry - run: pipx install poetry==$POETRY_VERSION && poetry self add poetry-monorepo-dependency-plugin + run: pipx install poetry==$POETRY_VERSION - name: Set up Python 3.10 uses: actions/setup-python@v5 with: diff --git a/Makefile b/Makefile index 40c53075b..e5d886652 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ path = src/backend/base/langflow/frontend setup_poetry: pipx install poetry - poetry self add poetry-monorepo-dependency-plugin add: @echo 'Adding dependencies' @@ -179,16 +178,16 @@ ifdef main endif build_langflow_base: - cd src/backend/base && poetry build-rewrite-path-deps --version-pinning-strategy=semver + cd src/backend/base && poetry build rm -rf src/backend/base/langflow/frontend build_langflow_backup: - poetry lock && poetry build-rewrite-path-deps --version-pinning-strategy=semver + poetry lock && poetry build build_langflow: - cd ./scripts && python update_dependencies.py + cd ./scripts && poetry run python update_dependencies.py poetry lock - -poetry build-rewrite-path-deps --version-pinning-strategy=semver + poetry build mv pyproject.toml.bak pyproject.toml mv poetry.lock.bak poetry.lock diff --git a/pyproject.toml b/pyproject.toml index 5a2dc622a..5e34c2a0f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,8 +23,6 @@ documentation = "https://docs.langflow.org" [tool.poetry.scripts] langflow = "langflow.__main__:main" -[tool.poetry-monorepo-dependency-plugin] -enable = true [tool.poetry.dependencies] python = ">=3.10,<3.12" diff --git a/scripts/setup/update_poetry.sh b/scripts/setup/update_poetry.sh index ecaf21356..94c51fd56 100644 --- a/scripts/setup/update_poetry.sh +++ b/scripts/setup/update_poetry.sh @@ -146,11 +146,3 @@ else echo "Poetry version is $1 or higher. No need to update." fi -# Check if poetry-monorepo-dependency-plugin is installed -if poetry self show | grep -q "poetry-monorepo-dependency-plugin"; then - echo "poetry-monorepo-dependency-plugin is already installed." -else - echo "Installing poetry-monorepo-dependency-plugin..." - poetry run pip install poetry-monorepo-dependency-plugin - echo "poetry-monorepo-dependency-plugin installed successfully." -fi \ No newline at end of file From 16830570dd0a5221d284f716712ccfeffdc0d9ff Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:10:12 -0300 Subject: [PATCH 31/54] Update workflow and Dockerfile for Langflow base pre-release --- .github/workflows/pre-release-base.yml | 9 ++++----- .github/workflows/pre-release-langflow.yml | 5 ++--- build_and_push.Dockerfile | 7 +++++-- build_and_push_base.Dockerfile | 6 +----- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.github/workflows/pre-release-base.yml b/.github/workflows/pre-release-base.yml index 762bac3e9..60872def3 100644 --- a/.github/workflows/pre-release-base.yml +++ b/.github/workflows/pre-release-base.yml @@ -1,4 +1,4 @@ -name: pre-release-base +name: Langflow Base Pre-release on: pull_request: @@ -20,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install poetry - run: pipx install poetry==$POETRY_VERSION && poetry self add poetry-monorepo-dependency-plugin + run: pipx install poetry==$POETRY_VERSION - name: Set up Python 3.10 uses: actions/setup-python@v5 with: @@ -61,7 +61,6 @@ jobs: with: context: . push: true - file: ./build_and_push.Dockerfile + file: ./build_and_push_base.Dockerfile tags: | - logspace/langflow:${{ steps.check-version.outputs.version }} - logspace/langflow:latest-dev + logspace/langflow:base-${{ steps.check-version.outputs.version }} diff --git a/.github/workflows/pre-release-langflow.yml b/.github/workflows/pre-release-langflow.yml index 102004613..57f3b3e1a 100644 --- a/.github/workflows/pre-release-langflow.yml +++ b/.github/workflows/pre-release-langflow.yml @@ -1,4 +1,4 @@ -name: pre-release-langflow +name: Langflow Pre-release on: pull_request: @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install poetry - run: pipx install poetry==$POETRY_VERSION && poetry self add poetry-monorepo-dependency-plugin + run: pipx install poetry==$POETRY_VERSION - name: Set up Python 3.10 uses: actions/setup-python@v5 with: @@ -68,4 +68,3 @@ jobs: file: ./build_and_push.Dockerfile tags: | logspace/langflow:${{ steps.check-version.outputs.version }} - logspace/langflow:latest-dev diff --git a/build_and_push.Dockerfile b/build_and_push.Dockerfile index 136f34f9e..1c595e180 100644 --- a/build_and_push.Dockerfile +++ b/build_and_push.Dockerfile @@ -65,8 +65,11 @@ COPY src ./src COPY scripts ./scripts COPY Makefile ./ COPY README.md ./ -RUN make build - +RUN --mount=type=cache,target=/root/.cache \ + curl -sSL https://install.python-poetry.org | python3 - +RUN python -m pip install requests && cd ./scripts && python update_dependencies.py +RUN $POETRY_HOME/bin/poetry lock +RUN $POETRY_HOME/bin/poetry build # Final stage for the application FROM python-base as final diff --git a/build_and_push_base.Dockerfile b/build_and_push_base.Dockerfile index 1aa7ee950..f5092c81c 100644 --- a/build_and_push_base.Dockerfile +++ b/build_and_push_base.Dockerfile @@ -74,6 +74,7 @@ COPY Makefile ./ COPY README.md ./ RUN cd src/frontend && npm run build COPY src/backend ./src/backend +RUN cp -r src/frontend/build src/backend/base/langflow/frontend RUN rm -rf src/backend/base/dist RUN cd src/backend/base && $POETRY_HOME/bin/poetry build --format sdist @@ -86,10 +87,5 @@ COPY --from=builder-base /app/src/backend/base/dist/*.tar.gz ./ # Install the package from the .tar.gz RUN pip install *.tar.gz -# Now remove the .tar.gz -RUN rm *.tar.gz -# Remove the source code -RUN rm -rf /app - WORKDIR /app CMD ["python", "-m", "langflow", "run", "--host", "0.0.0.0", "--port", "7860"] From 2674f2f8b892b82b282003b85db35b07d4c78376 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:53:04 -0300 Subject: [PATCH 32/54] Update display names and descriptions for AstraDB components --- .../starter-projects/rag-with-astradb.mdx | 39 ++++++++-------- docs/static/data/AstraDB-RAG-Flows.json | 46 +++++++++---------- .../components/vectorsearch/AstraDBSearch.py | 12 ++--- .../components/vectorstores/AstraDB.py | 12 ++--- ...-Flows.json => VectorStore-RAG-Flows.json} | 30 ++++++------ 5 files changed, 69 insertions(+), 70 deletions(-) rename src/backend/base/langflow/initial_setup/starter_projects/{AstraDB-RAG-Flows.json => VectorStore-RAG-Flows.json} (93%) diff --git a/docs/docs/starter-projects/rag-with-astradb.mdx b/docs/docs/starter-projects/rag-with-astradb.mdx index baae6288c..3c3868bf2 100644 --- a/docs/docs/starter-projects/rag-with-astradb.mdx +++ b/docs/docs/starter-projects/rag-with-astradb.mdx @@ -3,13 +3,13 @@ import useBaseUrl from "@docusaurus/useBaseUrl"; import ZoomableImage from "/src/theme/ZoomableImage.js"; import Admonition from "@theme/Admonition"; -# 🌟 RAG with AstraDB +# 🌟 RAG with Astra DB -This guide will walk you through how to build a RAG (Retrieval Augmented Generation) application using **AstraDB** and **Langflow**. +This guide will walk you through how to build a RAG (Retrieval Augmented Generation) application using **Astra DB** and **Langflow**. -AstraDB is a cloud-native database built on Apache Cassandra that is optimized for the cloud. It is a fully managed database-as-a-service that simplifies operations and reduces costs. AstraDB is built on the same technology that powers the largest Cassandra deployments in the world. +Astra DB is a cloud-native database built on Apache Cassandra that is optimized for the cloud. It is a fully managed database-as-a-service that simplifies operations and reduces costs. Astra DB is built on the same technology that powers the largest Cassandra deployments in the world. -In this guide, we will use AstraDB as a vector store to store and retrieve the documents that will be used by the RAG application to generate responses. +In this guide, we will use Astra DB as a vector store to store and retrieve the documents that will be used by the RAG application to generate responses. This guide assumes that you have Langflow up and running. If you are new to @@ -23,18 +23,18 @@ TLDR; - Create a new database, get a **Token** and the **API Endpoint** - Click on the **New Project** button and look for Vector Store RAG. This will create a new project with the necessary components - Import the project into Langflow by dropping it on the Canvas or My Collection page -- Update the **Token** and **API Endpoint** in the **AstraDB** components +- Update the **Token** and **API Endpoint** in the **Astra DB** components - Update the OpenAI API key in the **OpenAI** components -- Run the ingestion flow which is the one that uses the **AstraDB** component +- Run the ingestion flow which is the one that uses the **Astra DB** component - Click on the ⚡ _Run_ button and start interacting with your RAG application # First things first -## Create an AstraDB Database +## Create an Astra DB Database -To get started, you will need to create an AstraDB database. Visit the [Astra](https://astra.datastax.com) website and create a free account. +To get started, you will need to create an Astra DB database. Visit the [Astra](https://astra.datastax.com) website and create a free account. -Once you have created an account, you will be taken to the AstraDB dashboard. Click on the **Create Database** button. +Once you have created an account, you will be taken to the Astra DB dashboard. Click on the **Create Database** button. -Now we are all set to start building our RAG application using AstraDB and Langflow. +Now we are all set to start building our RAG application using Astra DB and Langflow. ## (Optional) Duplicate the Langflow 1.0 HuggingFace Space @@ -77,7 +77,7 @@ If you haven't already, now is the time to launch Langflow. To make things easie ## Open the Vector Store RAG Project -To get started, click on the **New Project** button and look for the **Vector Store RAG** project. This will open a starter project with the necessary components to run a RAG application using AstraDB. +To get started, click on the **New Project** button and look for the **Vector Store RAG** project. This will open a starter project with the necessary components to run a RAG application using Astra DB. -This project consists of two flows. The simpler one is the **Ingestion Flow** which is responsible for ingesting the documents into the AstraDB database. +This project consists of two flows. The simpler one is the **Ingestion Flow** which is responsible for ingesting the documents into the Astra DB database. Your first step should be to understand what each flow does and how they interact with each other. @@ -97,7 +97,7 @@ The ingestion flow consists of: - **Files** component that uploads a text file to Langflow - **Recursive Character Text Splitter** component that splits the text into smaller chunks - **OpenAIEmbeddings** component that generates embeddings for the text chunks -- **AstraDB** component that stores the text chunks in the AstraDB database +- **Astra DB** component that stores the text chunks in the Astra DB database -Now, let's update the **AstraDB** and **AstraDB Search** components with the **Token** and **API Endpoint** that we generated earlier, and the OpenAI Embeddings components with your OpenAI API key. +Now, let's update the **Astra DB** and **Astra DB Search** components with the **Token** and **API Endpoint** that we generated earlier, and the OpenAI Embeddings components with your OpenAI API key. -And run it! This will ingest the Text data from your file into the AstraDB database. +And run it! This will ingest the Text data from your file into the Astra DB database. -And that's it! You have successfully ran a RAG application using AstraDB and Langflow. +And that's it! You have successfully ran a RAG application using Astra DB and Langflow. # Conclusion -In this guide, we have learned how to run a RAG application using AstraDB and Langflow. We have seen how to create an AstraDB database, import the AstraDB RAG Flows project into Langflow, and run the ingestion and RAG flows. +In this guide, we have learned how to run a RAG application using Astra DB and Langflow. We have seen how to create an Astra DB database, import the Astra DB RAG Flows project into Langflow, and run the ingestion and RAG flows.import ThemedImage from "@theme/ThemedImage"; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import ZoomableImage from "/src/theme/ZoomableImage.js"; +import Admonition from "@theme/Admonition"; diff --git a/docs/static/data/AstraDB-RAG-Flows.json b/docs/static/data/AstraDB-RAG-Flows.json index cf96c6841..8068ea4a9 100644 --- a/docs/static/data/AstraDB-RAG-Flows.json +++ b/docs/static/data/AstraDB-RAG-Flows.json @@ -20,7 +20,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Interaction Panel.\"\n icon = \"ChatInput\"\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n", + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Interaction Panel.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Message\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n", "fileTypes": [], "file_path": "", "password": false, @@ -44,9 +44,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": [], "dynamic": false, "info": "", "load_from_db": false, @@ -1489,7 +1487,7 @@ "list": false, "show": true, "multiline": true, - "value": "from pathlib import Path\nfrom typing import Any, Dict\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\n\n\nclass FileComponent(CustomComponent):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n \n def build_config(self) -> Dict[str, Any]:\n return {\n \"path\": {\n \"display_name\": \"Path\",\n \"field_type\": \"file\",\n \"file_types\": TEXT_FILE_TYPES,\n \"info\": f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n },\n \"silent_errors\": {\n \"display_name\": \"Silent Errors\",\n \"advanced\": True,\n \"info\": \"If true, errors will not raise an exception.\",\n },\n }\n\n def load_file(self, path: str, silent_errors: bool = False) -> Record:\n resolved_path = self.resolve_path(path)\n path_obj = Path(resolved_path)\n extension = path_obj.suffix[1:].lower()\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n record = parse_text_file_to_record(resolved_path, silent_errors)\n self.status = record if record else \"No data\"\n return record or Record()\n\n def build(\n self,\n path: str,\n silent_errors: bool = False,\n ) -> Record:\n record = self.load_file(path, silent_errors)\n self.status = record\n return record\n", + "value": "from pathlib import Path\nfrom typing import Any, Dict\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\n\n\nclass FileComponent(CustomComponent):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n def build_config(self) -> Dict[str, Any]:\n return {\n \"path\": {\n \"display_name\": \"Path\",\n \"field_type\": \"file\",\n \"file_types\": TEXT_FILE_TYPES,\n \"info\": f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n },\n \"silent_errors\": {\n \"display_name\": \"Silent Errors\",\n \"advanced\": True,\n \"info\": \"If true, errors will not raise an exception.\",\n },\n }\n\n def load_file(self, path: str, silent_errors: bool = False) -> Record:\n resolved_path = self.resolve_path(path)\n path_obj = Path(resolved_path)\n extension = path_obj.suffix[1:].lower()\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n record = parse_text_file_to_record(resolved_path, silent_errors)\n self.status = record if record else \"No data\"\n return record or Record()\n\n def build(\n self,\n path: str,\n silent_errors: bool = False,\n ) -> Record:\n record = self.load_file(path, silent_errors)\n self.status = record\n return record\n", "fileTypes": [], "file_path": "", "password": false, @@ -1498,8 +1496,7 @@ "dynamic": true, "info": "", "load_from_db": false, - "title_case": false, - "display_name": "code" + "title_case": false }, "silent_errors": { "type": "bool", @@ -1639,8 +1636,7 @@ "dynamic": true, "info": "", "load_from_db": false, - "title_case": false, - "display_name": "code" + "title_case": false }, "separators": { "type": "str", @@ -1763,7 +1759,7 @@ "display_name": "API Endpoint", "advanced": false, "dynamic": false, - "info": "API endpoint URL for the AstraDB service.", + "info": "API endpoint URL for the Astra DB service.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1850,7 +1846,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"AstraDB Search\"\n description = \"Searches an existing AstraDB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within AstraDB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing AstraDB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the AstraDB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within AstraDB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain the 'content' field.\"\n )\n else:\n raise e\n", + "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"Astra DB Search\"\n description = \"Searches an existing Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'.\"\n )\n else:\n raise e\n", "fileTypes": [], "file_path": "", "password": false, @@ -1893,7 +1889,7 @@ "display_name": "Collection Name", "advanced": false, "dynamic": false, - "info": "The name of the collection within AstraDB where the vectors will be stored.", + "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1978,7 +1974,7 @@ "display_name": "Namespace", "advanced": true, "dynamic": false, - "info": "Optional namespace within AstraDB to use for the collection.", + "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2090,7 +2086,7 @@ "display_name": "Token", "advanced": false, "dynamic": false, - "info": "Authentication token for accessing AstraDB.", + "info": "Authentication token for accessing Astra DB.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2100,12 +2096,12 @@ }, "_type": "CustomComponent" }, - "description": "Searches an existing AstraDB Vector Store.", + "description": "Searches an existing Astra DB Vector Store.", "icon": "AstraDB", "base_classes": [ "Record" ], - "display_name": "AstraDB Search", + "display_name": "Astra DB Search", "documentation": "", "custom_fields": { "embedding": null, @@ -2213,7 +2209,7 @@ "display_name": "API Endpoint", "advanced": false, "dynamic": false, - "info": "API endpoint URL for the AstraDB service.", + "info": "API endpoint URL for the Astra DB service.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2300,7 +2296,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"AstraDB\"\n description = \"Builds or loads an AstraDB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within AstraDB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing AstraDB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the AstraDB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within AstraDB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", + "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", "fileTypes": [], "file_path": "", "password": false, @@ -2343,7 +2339,7 @@ "display_name": "Collection Name", "advanced": false, "dynamic": false, - "info": "The name of the collection within AstraDB where the vectors will be stored.", + "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2428,7 +2424,7 @@ "display_name": "Namespace", "advanced": true, "dynamic": false, - "info": "Optional namespace within AstraDB to use for the collection.", + "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2495,7 +2491,7 @@ "display_name": "Token", "advanced": false, "dynamic": false, - "info": "Authentication token for accessing AstraDB.", + "info": "Authentication token for accessing Astra DB.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2505,12 +2501,12 @@ }, "_type": "CustomComponent" }, - "description": "Builds or loads an AstraDB Vector Store.", + "description": "Builds or loads an Astra DB Vector Store.", "icon": "AstraDB", "base_classes": [ "VectorStore" ], - "display_name": "AstraDB", + "display_name": "Astra DB", "documentation": "", "custom_fields": { "embedding": null, @@ -3400,8 +3396,8 @@ "zoom": 0.2687057134854984 } }, - "description": "This project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an AstraDB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the AstraDB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", - "name": "AstraDB RAG Flows", + "description": "Visit https://pre-release.langflow.org/guides/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", + "name": "Vector Store RAG", "last_tested_version": "1.0.0a0", "is_component": false } \ No newline at end of file diff --git a/src/backend/base/langflow/components/vectorsearch/AstraDBSearch.py b/src/backend/base/langflow/components/vectorsearch/AstraDBSearch.py index e2d8e61e9..83ed42daf 100644 --- a/src/backend/base/langflow/components/vectorsearch/AstraDBSearch.py +++ b/src/backend/base/langflow/components/vectorsearch/AstraDBSearch.py @@ -7,8 +7,8 @@ from langflow.schema import Record class AstraDBSearchComponent(LCVectorStoreComponent): - display_name = "AstraDB Search" - description = "Searches an existing AstraDB Vector Store." + display_name = "Astra DB Search" + description = "Searches an existing Astra DB Vector Store." icon = "AstraDB" field_order = ["token", "api_endpoint", "collection_name", "input_value", "embedding"] @@ -25,20 +25,20 @@ class AstraDBSearchComponent(LCVectorStoreComponent): "embedding": {"display_name": "Embedding", "info": "Embedding to use"}, "collection_name": { "display_name": "Collection Name", - "info": "The name of the collection within AstraDB where the vectors will be stored.", + "info": "The name of the collection within Astra DB where the vectors will be stored.", }, "token": { "display_name": "Token", - "info": "Authentication token for accessing AstraDB.", + "info": "Authentication token for accessing Astra DB.", "password": True, }, "api_endpoint": { "display_name": "API Endpoint", - "info": "API endpoint URL for the AstraDB service.", + "info": "API endpoint URL for the Astra DB service.", }, "namespace": { "display_name": "Namespace", - "info": "Optional namespace within AstraDB to use for the collection.", + "info": "Optional namespace within Astra DB to use for the collection.", "advanced": True, }, "metric": { diff --git a/src/backend/base/langflow/components/vectorstores/AstraDB.py b/src/backend/base/langflow/components/vectorstores/AstraDB.py index 6dcbe3d57..460d1f6db 100644 --- a/src/backend/base/langflow/components/vectorstores/AstraDB.py +++ b/src/backend/base/langflow/components/vectorstores/AstraDB.py @@ -9,8 +9,8 @@ from langflow.schema import Record class AstraDBVectorStoreComponent(CustomComponent): - display_name = "AstraDB" - description = "Builds or loads an AstraDB Vector Store." + display_name = "Astra DB" + description = "Builds or loads an Astra DB Vector Store." icon = "AstraDB" field_order = ["token", "api_endpoint", "collection_name", "inputs", "embedding"] @@ -23,20 +23,20 @@ class AstraDBVectorStoreComponent(CustomComponent): "embedding": {"display_name": "Embedding", "info": "Embedding to use"}, "collection_name": { "display_name": "Collection Name", - "info": "The name of the collection within AstraDB where the vectors will be stored.", + "info": "The name of the collection within Astra DB where the vectors will be stored.", }, "token": { "display_name": "Token", - "info": "Authentication token for accessing AstraDB.", + "info": "Authentication token for accessing Astra DB.", "password": True, }, "api_endpoint": { "display_name": "API Endpoint", - "info": "API endpoint URL for the AstraDB service.", + "info": "API endpoint URL for the Astra DB service.", }, "namespace": { "display_name": "Namespace", - "info": "Optional namespace within AstraDB to use for the collection.", + "info": "Optional namespace within Astra DB to use for the collection.", "advanced": True, }, "metric": { diff --git a/src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json similarity index 93% rename from src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json rename to src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json index f80a20d15..8068ea4a9 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/AstraDB-RAG-Flows.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json @@ -1759,7 +1759,7 @@ "display_name": "API Endpoint", "advanced": false, "dynamic": false, - "info": "API endpoint URL for the AstraDB service.", + "info": "API endpoint URL for the Astra DB service.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1846,7 +1846,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"AstraDB Search\"\n description = \"Searches an existing AstraDB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within AstraDB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing AstraDB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the AstraDB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within AstraDB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'.\"\n )\n else:\n raise e\n", + "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"Astra DB Search\"\n description = \"Searches an existing Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'.\"\n )\n else:\n raise e\n", "fileTypes": [], "file_path": "", "password": false, @@ -1889,7 +1889,7 @@ "display_name": "Collection Name", "advanced": false, "dynamic": false, - "info": "The name of the collection within AstraDB where the vectors will be stored.", + "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1974,7 +1974,7 @@ "display_name": "Namespace", "advanced": true, "dynamic": false, - "info": "Optional namespace within AstraDB to use for the collection.", + "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2086,7 +2086,7 @@ "display_name": "Token", "advanced": false, "dynamic": false, - "info": "Authentication token for accessing AstraDB.", + "info": "Authentication token for accessing Astra DB.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2096,12 +2096,12 @@ }, "_type": "CustomComponent" }, - "description": "Searches an existing AstraDB Vector Store.", + "description": "Searches an existing Astra DB Vector Store.", "icon": "AstraDB", "base_classes": [ "Record" ], - "display_name": "AstraDB Search", + "display_name": "Astra DB Search", "documentation": "", "custom_fields": { "embedding": null, @@ -2209,7 +2209,7 @@ "display_name": "API Endpoint", "advanced": false, "dynamic": false, - "info": "API endpoint URL for the AstraDB service.", + "info": "API endpoint URL for the Astra DB service.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2296,7 +2296,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"AstraDB\"\n description = \"Builds or loads an AstraDB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within AstraDB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing AstraDB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the AstraDB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within AstraDB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", + "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", "fileTypes": [], "file_path": "", "password": false, @@ -2339,7 +2339,7 @@ "display_name": "Collection Name", "advanced": false, "dynamic": false, - "info": "The name of the collection within AstraDB where the vectors will be stored.", + "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2424,7 +2424,7 @@ "display_name": "Namespace", "advanced": true, "dynamic": false, - "info": "Optional namespace within AstraDB to use for the collection.", + "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2491,7 +2491,7 @@ "display_name": "Token", "advanced": false, "dynamic": false, - "info": "Authentication token for accessing AstraDB.", + "info": "Authentication token for accessing Astra DB.", "load_from_db": false, "title_case": false, "input_types": [ @@ -2501,12 +2501,12 @@ }, "_type": "CustomComponent" }, - "description": "Builds or loads an AstraDB Vector Store.", + "description": "Builds or loads an Astra DB Vector Store.", "icon": "AstraDB", "base_classes": [ "VectorStore" ], - "display_name": "AstraDB", + "display_name": "Astra DB", "documentation": "", "custom_fields": { "embedding": null, @@ -3396,7 +3396,7 @@ "zoom": 0.2687057134854984 } }, - "description": "Visit https://pre-release.langflow.org/guides/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an AstraDB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the AstraDB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", + "description": "Visit https://pre-release.langflow.org/guides/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", "name": "Vector Store RAG", "last_tested_version": "1.0.0a0", "is_component": false From 229cdc6571bbfd06da7bd7b12d2fd567e1fabcf3 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 21:53:48 -0300 Subject: [PATCH 33/54] Update installation instructions for Langflow --- docs/docs/index.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index c5c818d6f..d19c28e4b 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -28,19 +28,21 @@ You can install **Langflow** with [pipx](https://pipx.pypa.io/stable/installatio Pipx can fetch the missing Python version for you, but you can also install it manually. ```bash -pipx install langflow --python python3.10 --fetch-missing-python -# or pip install langflow -U +# or +pipx install langflow --python python3.10 --fetch-missing-python ``` Or you can install a pre-release version using: ```bash -pipx install langflow --python python3.10 --fetch-missing-python --pip-args="--pre --force-reinstall" -# or pip install langflow --pre --force-reinstall +# or +pipx install langflow --python python3.10 --fetch-missing-python --pip-args="--pre --force-reinstall" ``` +We recommend using --force-reinstall to ensure you have the latest version of Langflow and its dependencies. + ### ⛓️ Running Langflow Langflow can be run in a variety of ways, including using the command-line interface (CLI) or HuggingFace Spaces. From bf0433e3da973e34352ac82ce5b74e4e90770ef8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:22:35 -0300 Subject: [PATCH 34/54] Update Astra DB links and remove unnecessary imports --- docs/docs/starter-projects/rag-with-astradb.mdx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/docs/starter-projects/rag-with-astradb.mdx b/docs/docs/starter-projects/rag-with-astradb.mdx index 3c3868bf2..3afd81fd6 100644 --- a/docs/docs/starter-projects/rag-with-astradb.mdx +++ b/docs/docs/starter-projects/rag-with-astradb.mdx @@ -7,7 +7,7 @@ import Admonition from "@theme/Admonition"; This guide will walk you through how to build a RAG (Retrieval Augmented Generation) application using **Astra DB** and **Langflow**. -Astra DB is a cloud-native database built on Apache Cassandra that is optimized for the cloud. It is a fully managed database-as-a-service that simplifies operations and reduces costs. Astra DB is built on the same technology that powers the largest Cassandra deployments in the world. +[Astra DB](https://www.datastax.com/products/datastax-astra?utm_source=langflow-pre-release&utm_medium=referral&utm_campaign=langflow-announcement&utm_content=astradb) is a cloud-native database built on Apache Cassandra that is optimized for the cloud. It is a fully managed database-as-a-service that simplifies operations and reduces costs. Astra DB is built on the same technology that powers the largest Cassandra deployments in the world. In this guide, we will use Astra DB as a vector store to store and retrieve the documents that will be used by the RAG application to generate responses. @@ -18,7 +18,7 @@ In this guide, we will use Astra DB as a vector store to store and retrieve the TLDR; -- Visit the [Astra](https://astra.datastax.com) website and create a free account +- [Create a free Astra DB account](https://astra.datastax.com/signup?utm_source=langflow-pre-release&utm_medium=referral&utm_campaign=langflow-announcement&utm_content=create-a-free-astra-db-account) - Duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) - Create a new database, get a **Token** and the **API Endpoint** - Click on the **New Project** button and look for Vector Store RAG. This will create a new project with the necessary components @@ -32,7 +32,7 @@ TLDR; ## Create an Astra DB Database -To get started, you will need to create an Astra DB database. Visit the [Astra](https://astra.datastax.com) website and create a free account. +To get started, you will need to [create an Astra DB database](https://astra.datastax.com/signup?utm_source=langflow-pre-release&utm_medium=referral&utm_campaign=langflow-announcement&utm_content=create-an-astradb-database). Once you have created an account, you will be taken to the Astra DB dashboard. Click on the **Create Database** button. @@ -191,7 +191,5 @@ And that's it! You have successfully ran a RAG application using Astra DB and La # Conclusion -In this guide, we have learned how to run a RAG application using Astra DB and Langflow. We have seen how to create an Astra DB database, import the Astra DB RAG Flows project into Langflow, and run the ingestion and RAG flows.import ThemedImage from "@theme/ThemedImage"; -import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; -import Admonition from "@theme/Admonition"; +In this guide, we have learned how to run a RAG application using Astra DB and Langflow. +We have seen how to create an Astra DB database, import the Astra DB RAG Flows project into Langflow, and run the ingestion and RAG flows. From 18ff1378db4b1b34c24dd77d9697a9989049ceda Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:23:16 -0300 Subject: [PATCH 35/54] Rename AstraDB --- docs/docs/components/vector-stores.mdx | 128 ++++++++++++------------- 1 file changed, 63 insertions(+), 65 deletions(-) diff --git a/docs/docs/components/vector-stores.mdx b/docs/docs/components/vector-stores.mdx index 0fd1fd89b..23cac871d 100644 --- a/docs/docs/components/vector-stores.mdx +++ b/docs/docs/components/vector-stores.mdx @@ -1,41 +1,42 @@ -import Admonition from '@theme/Admonition'; +import Admonition from "@theme/Admonition"; # Vector Stores -

- We appreciate your understanding as we polish our documentation – it may contain some rough edges. Share your feedback or report issues to help us improve! 🛠️📝 -

+

+ We appreciate your understanding as we polish our documentation – it may + contain some rough edges. Share your feedback or report issues to help us + improve! 🛠️📝 +

+### Astra DB -### AstraDB - -The `AstraDB` is a component for initializing an AstraDB Vector Store from Records. It facilitates the creation of AstraDB-based vector indexes for efficient document storage and retrieval. +The `Astra DB` is a component for initializing an Astra DB Vector Store from Records. It facilitates the creation of Astra DB-based vector indexes for efficient document storage and retrieval. **Params** - **Input:** The input documents or records. -- **Embedding:** The embedding model used by AstraDB. +- **Embedding:** The embedding model used by Astra DB. -- **Collection Name:** The name of the collection in AstraDB. +- **Collection Name:** The name of the collection in Astra DB. -- **Token:** The token for AstraDB. +- **Token:** The token for Astra DB. -- **API Endpoint:** The API endpoint for AstraDB. +- **API Endpoint:** The API endpoint for Astra DB. -- **Namespace:** The namespace in AstraDB. +- **Namespace:** The namespace in Astra DB. -- **Metric:** The metric to use in AstraDB. +- **Metric:** The metric to use in Astra DB. -- **Batch Size:** The batch size for AstraDB. +- **Batch Size:** The batch size for Astra DB. -- **Bulk Insert Batch Concurrency:** The bulk insert batch concurrency for AstraDB. +- **Bulk Insert Batch Concurrency:** The bulk insert batch concurrency for Astra DB. -- **Bulk Insert Overwrite Concurrency:** The bulk insert overwrite concurrency for AstraDB. +- **Bulk Insert Overwrite Concurrency:** The bulk insert overwrite concurrency for Astra DB. -- **Bulk Delete Concurrency:** The bulk delete concurrency for AstraDB. +- **Bulk Delete Concurrency:** The bulk delete concurrency for Astra DB. - **Setup Mode:** The setup mode for the vector store. @@ -49,16 +50,16 @@ The `AstraDB` is a component for initializing an AstraDB Vector Store from Recor

- Ensure that the required AstraDB token and API endpoint are properly configured. + Ensure that the required Astra DB token and API endpoint are properly configured.

--- -### AstraDB Search +### Astra DB Search -The `AstraDBSearch` is a component for searching an existing AstraDB Vector Store for similar documents. It extends the functionality of the `AstraDB` component to provide efficient document retrieval based on similarity metrics. +The `Astra DBSearch` is a component for searching an existing Astra DB Vector Store for similar documents. It extends the functionality of the `Astra DB` component to provide efficient document retrieval based on similarity metrics. **Params** @@ -66,25 +67,25 @@ The `AstraDBSearch` is a component for searching an existing AstraDB Vector Stor - **Input Value:** The input value to search for. -- **Embedding:** The embedding model used by AstraDB. +- **Embedding:** The embedding model used by Astra DB. -- **Collection Name:** The name of the collection in AstraDB. +- **Collection Name:** The name of the collection in Astra DB. -- **Token:** The token for AstraDB. +- **Token:** The token for Astra DB. -- **API Endpoint:** The API endpoint for AstraDB. +- **API Endpoint:** The API endpoint for Astra DB. -- **Namespace:** The namespace in AstraDB. +- **Namespace:** The namespace in Astra DB. -- **Metric:** The metric to use in AstraDB. +- **Metric:** The metric to use in Astra DB. -- **Batch Size:** The batch size for AstraDB. +- **Batch Size:** The batch size for Astra DB. -- **Bulk Insert Batch Concurrency:** The bulk insert batch concurrency for AstraDB. +- **Bulk Insert Batch Concurrency:** The bulk insert batch concurrency for Astra DB. -- **Bulk Insert Overwrite Concurrency:** The bulk insert overwrite concurrency for AstraDB. +- **Bulk Insert Overwrite Concurrency:** The bulk insert overwrite concurrency for Astra DB. -- **Bulk Delete Concurrency:** The bulk delete concurrency for AstraDB. +- **Bulk Delete Concurrency:** The bulk delete concurrency for Astra DB. - **Setup Mode:** The setup mode for the vector store. @@ -118,7 +119,6 @@ The `Chroma` is a component designed for implementing a Vector Store using Chrom - **Server SSL Enabled (Optional):** Whether to enable SSL for the Chroma server. - - **Input:** Input data for creating the Vector Store. - **Embedding:** The embeddings to use for the Vector Store. @@ -129,7 +129,6 @@ For detailed documentation and integration guides, please refer to the [Chroma C ### Chroma Search - The `ChromaSearch` is a component designed for searching a Chroma collection for similar documents. This component integrates with Chroma to facilitate efficient document retrieval based on similarity metrics. **Params** @@ -154,7 +153,6 @@ The `ChromaSearch` is a component designed for searching a Chroma collection for - **Server SSL Enabled (Optional):** Whether SSL is enabled for the Chroma server. - --- ### FAISS @@ -171,7 +169,6 @@ The `FAISS` is a component designed for ingesting documents into a FAISS Vector - **Index Name:** The name of the FAISS index. - For detailed documentation and integration guides, please refer to the [FAISS Component Documentation](https://faiss.ai/index.html). --- @@ -190,10 +187,8 @@ The `FAISSSearch` is a component for searching a FAISS Vector Store for similar - **Index Name:** The name of the FAISS index. - --- - ### MongoDB Atlas The `MongoDBAtlas` is a component used to construct a MongoDB Atlas Vector Search vector store from Records. It facilitates the creation of MongoDB Atlas-based vector stores for efficient document storage and retrieval. @@ -214,11 +209,8 @@ The `MongoDBAtlas` is a component used to construct a MongoDB Atlas Vector Searc - **Search Kwargs:** Additional search arguments for MongoDB Atlas. - -

- Ensure that pymongo is installed to use MongoDB Atlas Vector Store. -

+

Ensure that pymongo is installed to use MongoDB Atlas Vector Store.

--- @@ -245,7 +237,6 @@ The `MongoDBAtlasSearch` is a component for searching a MongoDB Atlas Vector Sto - **Search Kwargs:** Additional search arguments for MongoDB Atlas. - --- ### PGVector @@ -262,14 +253,13 @@ The `PGVector` is a component for implementing a Vector Store using PostgreSQL. - **Table:** The name of the table in the PostgreSQL database. - For detailed documentation and integration guides, please refer to the [PGVector Component Documentation](https://python.langchain.com/docs/integrations/vectorstores/pgvector). - -

- Ensure that the required PostgreSQL server is accessible and properly configured. -

+

+ Ensure that the required PostgreSQL server is accessible and properly + configured. +

--- @@ -290,7 +280,6 @@ The `PGVectorSearch` is a component for searching a PGVector Store for similar d - **Search Type:** The type of search to perform (e.g., "Similarity", "MMR"). - --- ### Pinecone @@ -315,11 +304,11 @@ The `Pinecone` is a component used to construct a Pinecone wrapper from Records. - **Pool Threads:** The number of threads to use for Pinecone. - -

- Ensure that the required Pinecone API key and environment are properly configured. -

+

+ Ensure that the required Pinecone API key and environment are properly + configured. +

--- @@ -348,7 +337,6 @@ The `PineconeSearch` is a component used to search a Pinecone Vector Store for s - **Pool Threads:** The number of threads to use for Pinecone. - --- ### Qdrant @@ -462,9 +450,11 @@ The `Redis` is a component for implementing a Vector Store using Redis. It provi For detailed documentation, please refer to the [Redis Documentation](https://python.langchain.com/docs/integrations/vectorstores/redis). -

- Ensure that the required Redis server connection URL and index name are properly configured. If no documents are provided, a schema must be provided. -

+

+ Ensure that the required Redis server connection URL and index name are + properly configured. If no documents are provided, a schema must be + provided. +

--- @@ -512,9 +502,10 @@ The `Supabase` is a component for initializing a Supabase Vector Store from text - **Table Name:** The name of the table in Supabase (advanced). -

- Ensure that the required Supabase service key, Supabase URL, and table name are properly configured. -

+

+ Ensure that the required Supabase service key, Supabase URL, and table name + are properly configured. +

--- @@ -562,9 +553,10 @@ The `Vectara` is a component for implementing a Vector Store using Vectara. For detailed documentation and integration guides, please refer to the [Vectara Component Documentation](https://python.langchain.com/docs/integrations/vectorstores/vectara). -

- If `inputs` are provided, they will be upserted to the corpus. If `files_url` are provided, Vectara will process the files from the URLs. -

+

+ If `inputs` are provided, they will be upserted to the corpus. If + `files_url` are provided, Vectara will process the files from the URLs. +

--- @@ -586,6 +578,7 @@ The `VectaraSearch` is a component for searching a Vectara Vector Store for simi - **Vectara API Key:** The API key for Vectara. - **Files Url:** The URL(s) of the file(s) to be used for initializing the Vectara Vector Store (optional). + --- ### Weaviate @@ -613,9 +606,14 @@ The `Weaviate` is a component for implementing a Vector Store using Weaviate. For detailed documentation and integration guides, please refer to the [Weaviate Component Documentation](https://python.langchain.com/docs/integrations/vectorstores/weaviate). -

- Before using the Weaviate Vector Store component, ensure that you have a Weaviate instance running and accessible at the specified URL. Additionally, make sure to provide the correct API key for authentication if required. Adjust the index name, text key, and attributes according to your dataset and indexing requirements. Finally, ensure that the provided embeddings are compatible with Weaviate's requirements. -

+

+ Before using the Weaviate Vector Store component, ensure that you have a + Weaviate instance running and accessible at the specified URL. Additionally, + make sure to provide the correct API key for authentication if required. + Adjust the index name, text key, and attributes according to your dataset + and indexing requirements. Finally, ensure that the provided embeddings are + compatible with Weaviate's requirements. +

--- @@ -642,4 +640,4 @@ The `WeaviateSearch` component facilitates searching a Weaviate Vector Store for - **Embedding:** The embedding model used by Weaviate. -- **Attributes:** Additional attributes to consider during indexing (optional). \ No newline at end of file +- **Attributes:** Additional attributes to consider during indexing (optional). From 347e9bf21c586c4b7a8fecca53b594d5f7cb1bd8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:29:25 -0300 Subject: [PATCH 36/54] Add new components and images --- docs/docs/components/inputs.mdx | 134 ++++++++++++++++-- docs/docs/migration/inputs-and-outputs.mdx | 2 +- docs/static/img/chat-input-expanded.png | Bin 0 -> 92523 bytes docs/static/img/chat-input.png | Bin 0 -> 54171 bytes .../img/interaction-panel-text-input.png | Bin 0 -> 120285 bytes .../img/interaction-panel-with-chat-input.png | Bin 0 -> 127949 bytes docs/static/img/prompt-with-template.png | Bin 0 -> 55738 bytes docs/static/img/prompt.png | Bin 0 -> 41403 bytes docs/static/img/text-input-expanded.png | Bin 0 -> 55994 bytes docs/static/img/text-input.png | Bin 0 -> 39820 bytes 10 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 docs/static/img/chat-input-expanded.png create mode 100644 docs/static/img/chat-input.png create mode 100644 docs/static/img/interaction-panel-text-input.png create mode 100644 docs/static/img/interaction-panel-with-chat-input.png create mode 100644 docs/static/img/prompt-with-template.png create mode 100644 docs/static/img/prompt.png create mode 100644 docs/static/img/text-input-expanded.png create mode 100644 docs/static/img/text-input.png diff --git a/docs/docs/components/inputs.mdx b/docs/docs/components/inputs.mdx index 78ca6f0f6..de46f3ad7 100644 --- a/docs/docs/components/inputs.mdx +++ b/docs/docs/components/inputs.mdx @@ -1,4 +1,5 @@ -import Admonition from '@theme/Admonition'; +import Admonition from "@theme/Admonition"; +import ZoomableImage from "/src/theme/ZoomableImage.js"; # Inputs @@ -17,42 +18,147 @@ This component is designed to get user input from the chat. - **Session ID:** specifies the session ID of the chat history. If provided, the message will be saved in the Message History. -

- If _`As Record`_ is _`true`_ and the _`Message`_ is a _`Record`_, the data of the _`Record`_ will be updated with the _`Sender`_, _`Sender Name`_, and _`Session ID`_. -

+

+ If _`As Record`_ is _`true`_ and the _`Message`_ is a _`Record`_, the data + of the _`Record`_ will be updated with the _`Sender`_, _`Sender Name`_, and + _`Session ID`_. +

+When you get it from the sidebar, it will look like the image below but that is because some fields are in the advanced section. + + + +If you expose all its fields, it will look like the image below. + + + +One key capability of the Chat Input component is how it transforms the Interaction Panel into a chat window. This feature is particularly useful for scenarios where user input is required to initiate or influence the flow. + + + --- ### Prompt -Create a prompt template with dynamic variables. +Create a prompt template with dynamic variables. This is a very useful component for structuring prompts and passing dynamic data to a language model. **Parameters** -- **Template:** the template for the prompt. +- **Template:** the template for the prompt. This field allows you to create other fields dynamically by using curly brackets `{}`. For example, if you have a template like this: _`"Hello {name}, how are you?"`_, a new field called _`name`_ will be created. -

- Prompt variables can be created with any chosen name inside curly brackets, e.g. `{variable_name}` -

+

+ Prompt variables can be created with any chosen name inside curly brackets, + e.g. `{variable_name}` +

---- +Here is how it looks when you get it from the sidebar. + + +And here when you add a Template with the value _`Hello {name}, how are you?`_. + + + +--- ### Text Input This component is designed for simple text input, allowing users to pass textual data to subsequent components in the workflow. It's particularly useful for scenarios where a brief user input is required to initiate or influence the flow. - **Params** - **Value:** Specifies the text input value. This is where the user can input the text data that will be passed to the next component in the sequence. If no value is provided, it defaults to an empty string. +- **Record Template:** Specifies how a Record should be converted into Text. -

- The `TextInput` component serves as a straightforward means for setting Text input values in the chat window. It ensures that textual data can be seamlessly passed to subsequent components in the flow. -

+

+ The `TextInput` component serves as a straightforward means for setting Text + input values in the chat window. It ensures that textual data can be + seamlessly passed to subsequent components in the flow. +

+It should look like this when dropped directly from the sidebar. + + + +And when you expose all its fields, it will look like the image below. + +The **Record Template** field is used to specify how a Record should be converted into Text. This is particularly useful when you want to extract specific information from a Record and pass it as text to the next component in the sequence. + +For example, if you have a Record with the following structure: + +```json +{ + "name": "John Doe", + "age": 30, + "email": "johndoe@email.com" +} +``` + +You can use a template like this: _`"Name: {name}, Age: {age}"`_ to convert the Record into a text string like this: _`"Name: John Doe, Age: 30"`_, and if you pass more than one Record, the text will be concatenated with a new line separator. + + + +The Text Input component gives you the possibility to add an Input field on the Interaction Panel. This is useful because it allows you to define parameters while running and testing your flow. + + diff --git a/docs/docs/migration/inputs-and-outputs.mdx b/docs/docs/migration/inputs-and-outputs.mdx index 8a9ce10ed..5db3f3af2 100644 --- a/docs/docs/migration/inputs-and-outputs.mdx +++ b/docs/docs/migration/inputs-and-outputs.mdx @@ -33,4 +33,4 @@ Outputs are components that are used to define where data comes out of your flow The Chat Output works similarly to the Chat Input but does not have a field that allows for written input. It is used as an Output definition and can be used to send data to the user. -You can find out more about it and the other Outputs [here](../components/outputs). \ No newline at end of file +You can find out more about it and the other Outputs [here](../components/outputs). diff --git a/docs/static/img/chat-input-expanded.png b/docs/static/img/chat-input-expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..befe5afbd10525ab0267c9be02c482fa354da64e GIT binary patch literal 92523 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�r-6)nXKI+8N?D(6)ma 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 IDLx7NA6-e)r2qf` literal 0 HcmV?d00001 diff --git a/docs/static/img/chat-input.png b/docs/static/img/chat-input.png new file mode 100644 index 0000000000000000000000000000000000000000..29605c1b1c6357a0306ac7cda8db7f6bfa430c1a GIT binary patch literal 54171 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 fl04QSI-5N-6DjBfP7 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/interaction-panel-with-chat-input.png b/docs/static/img/interaction-panel-with-chat-input.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f7c79980793efda2bb3f79cc99c324cd43e901 GIT binary patch literal 127949 zcmeFZWmHt{+dd2kQc6j;ARsL*4boi#($bwnHwYqKN_Te+AuXLlcjpX9Ni)E}JKn$d zdEWne)~(N%_v8P=thE=jx%PGTaUSQjCtOuo<~ar_1_A=Yb2(W_bp(W`V(^bA+Ee&n zhUhRY5fGk3-7_q#5ePGh{c{m+^!p#V}=DWTE zJrT8h0DxCgeNGT^+!JW=%=3RD?4X_Za)|q1oXQQks`LFocpeudKn&UhN2I8!86za+ zUY+d1lmca!ZLicT1FjzD^SZVnE{I}z)XKZNE&yr~Gz7ywg79+$YI!f@JM6v6^y_Hj4)bdRIy8poqgzvYf0`BYHfZT0}fJ-bl8F* zgC!I87XFvY+-NkDQW4rq)Xa-c>mn>$m$&;pA4G_B)Xs=@BI@|L9>!hoPZAPYNzRPX z%jG}6eJd?snbNeZqajiF0cFe3*hcbIZyHVj{x7pDocyoP%c6{HF2i`}tl{q-_mwYnfuB!Qi-S;Q z@DrwbRcvwiS>D!;^HykTM%-&Jp&JaGryqV$O#~s&y?;Ysh9vIeXv*G}c#VvNh4abv z2kI4ug_UGpg$!DCZ4S;oIxf`?R_uA=<(at1PA3-dtXx<&@e({DZ5CvS0|``(dwxP! zr`B!kh`zyShWz+zEa)5NHt4hF(&GvA<&|Jhh+;}`{4=kD^5;5uPrf|#el($;d^$hS z?yMs8%+Sx+t()Zg-Gorb@{2570kl|jKD5jbK@DW7t?ayKsF|vws_~ICRDdA8cS=Mn z*w?{7RY~T%E`x-RpTXWZQ|&FH)UimdOjS$-Og$_=^YEVU{B z$yq@Ix{QU!52OiXILm*-=d5KD{NqVM?CJDoklSX7WqZ_j2i9TyArhL zlM+$5n7vre?})$f;RS}gL^Ghsp8_uU~wysY;t!2}}4gx;6C@ey(da;fdMYRhPgUQz5&Jf^`` z<$kS&&n{0+m&lo|u3Va*k-Jjdrm3aHtLd&Cqeb|7T!T$}t=!iT8h^$>phTcYkTfhw z5I)TLje?0m^SGp~P`xziy^#$kPi#w+u7t3XpDe6IUc*h*y!`Avq)e-fx5QA>uTWYG zsA^iKq{aN6Swk?#U8hnzv%;ZtOdV1(u2%hCw8CGZ-RM&hhcvA^t&C}DKU*{=>1x_5 zB?Si*UaXC za@HpX-wdjneP8=kZ(JQ86JM=XG)bDjEiK&7ZR%(mbV|DYqMv-B8)F@H&+^ z1vy<-u`#7S{aK1`YJWOm>Rh_WoBR}x(W%k7l!lbcRI>E2^l{E=o=#iw#*ZJ&K2!kT zTAp@I4RcPq#GB`vH+`!jST36=oBP?pGrKh4o#xhX=|-0KyoY|o;uDBKZ)UEKx2JLH zs*b`2V#83g{BfQm;?1z%SEu)vC3;s(SBiJOce-~nSOQqaSW;NgSk=<$vC5R~E*H&{ z>*NOHK#C^*HL`qudNakz6flQlhF#`&IS3dW<)+edE z%_BgcjM=vj-|e@vJX5`$+ZsLHyrEAQd?82 z@5y1k{$ckbH9{YNIt(z5N9sqs$14O-;7wpeU|3L5(0))uke@i4IM*lTr!RsfK50K) zHzBKQJ|uNF`l2^@7&oW-ZDL^}Vq(C!(Rix{?8Ghf%Gd1%h8BrtENS}ciS#AyirWVdyozavO9S(?zb*+YpM_)(md88ht2m6|UA>MjIPSP8WT>4FkynwB; z-m%mCfpN+JMmbTrxS6kt^2)MnSu3J1KXxyn8@w=}Csb+UAF@&JD!@##6vgSES$haqu4s}I)ZgifiHjufUhpQ{DT=Y{Hy>Fm@Q+Ohuvyz4EhzSa~{C%!lJ8r;UK;h z3=aK_31Rg;Q@BC^+wVkcyAFyeF{x}{r}_oO3Ipimf*?_}9!Yri>2 zF&YV=&`)Zt@M}Iei)Q}99K!5Sb)nM?_|{+6t*N3FR_*XX!bqbIyt>3_%l?%=*i|=q&)iw7rEKXMgj*So zJL(1kR5UXER+GFlZ>QQnR-2tf`Z3-)9AmGpy97Gt9Ov|Pl}Xe~&^?#!iTd2pAJsor zR8SPt^D;~?O*kE!!uf68cFEA>u<6o35>+v|k*Du3$<6SG#Jt4z;wcqj>(nWilZ%__ zdA)qSq00K=G1rl@zh86~QPt7&T&cVFC}tyx`RL~%cIUESDm>Ss{hSB<*P;#Yp{J|GD3V1=o{u-74N zR5z+;YA4%cDp4vB5e9#MkvA~ReFdm?dNpYMUFRy*C9No3%32-j8oOv*VaIdCyYYzh-*U zPEB}-QbSZjO^D3=K~3`EJQH9sew?)mP-&00Jcg{SW@g?V9v+U~DO=ZG)kG7ek)~1q z+IU5&vlLC}942L09GZMe*-X|v0gIA~aEm`Ba!QITEYZAR5-!-9Zhn(qd{L7&pGim` zYCI_5ktT@ggSklmgVC3->xmXlAObS=L=N&<$Iti~WDiq@W6nEvkE*2Lb{E1)01Bxu z0C-J{TWGK_E)O0_fOUjazZfS_b)vn8Vwj-i#b$mVsW5m;wPqUUuY>FlTkRhBVsyZr zm_GXWWxPUj$A`jDRHy7C+R_wWv7j8DH9&Vvn@Dlre>=uGDAtqol-NV_A4`T1eKR(ic?<^Icpx?sb|!uYnady}GBrXF z{kxn85d?9?F1fw(Zw=?`6+ec$M|GTzN|wrNq*QrO8Qf~dq1dR2;Gxho=toNt0+PrL zq5DcT;^y}|V|m7wCeOF9lsT(RJn{`;nxnBzRYM#J(bP?;C3V-FVR1b>(@d|}@txGI z7MG2+Q)%Awy@AkdvAArSVA=&I7D#gYwazJtVixX-q0oC4#bbsh*2>nhvF3fZMIq(l zFJI9al^Zti_lvYso;uGbrwgOF8Jd(0XLdN+j#<`*2qaf2dJdJcb5yBPhnJ4G8kyX@ z4TBpUE|r2J1|KF;tVdd8pQI$$C2Sl$>@hdkz64z=b5mnMK^b8BJtEQ$OE zb=t=C0kpop<-qd;52Rk!Xb{u_m-m|0e z556~3QFrclM5d(e+BNEh?Y5RwD)DB5R1vqb#o|MDg|@g&<4p|KBu?dqZ^sP4V>F1x zA7rK(sa#S@Kf3PLZNj9_3R=~+Gf@ciF5EvE>`rMKjFK2MnM)prk`V*Mjo zbXZ{Z>cP#Mr|3y{cH6=L(v_hMN!D2>cX^!EdbJ(WDV-qG(WcJP=8>g^j|6p()sa7x zw%RK?ze>=vq`%4xAw|OrVY0I%P_7078dGsrOR?!>HT~^$5KRXyv(gn`H`io5@gb?j zUd76k?soAyqzhp1V4<-O+NKs-+)HCd3E=8Ar=7s7thC3#L`sl$+~0ipM>AFsnBb{?NKN-f6GA4z_$ z@NlL$$9cAbUjZOqsn^C$S9}vBNM$qE-g!YXc&l926WsD6>+L$PC@yE0l+Yn{LZ0&Q zl|kcxRUKznFVcvi^l@K?q{Jo$((lChGdu9E`{_Ep=JfHjnMz&uN1udR5U=)=COK=? z_aM}4A+OQTr9UvBL&~$ynorlK6%SEh^mK1(M!-XcsQbeoP}p4YtVJb{@dM(~MadK< z(b;eSyixk9&0NW43+9_&`zcVlF?=G|qfrw*)&g)?^G^m{Fr~>%-bA*;# zSk<3YESG!4XH1Q*ntXEnjDZu&0DJuw*OQSjd~Wk2ZBU3q!9=XCOf}LvfMkBg^Cfu)(}d(AOJUvO`;fT-Tm|*5z}}O{hq8q7#?4x zpV%?b`>Y$Fv?nXlu7$57J)UXh1Z6&-rPvur8-3}4d()_O>O(@c`KS{RqHzVv(uz2;u)2- zvHo1E`v3!E2TnfD>tF!nEo9B8CEw%gP;`}xJPyB8sRtXtO%Ep>I8ILwpv+5XczqkU zt+NoR;@q!!QC2ffb7Ju+>N9!6=&Aycos%s?909H`u_5I5=Pi!XPI=UIL|t8=0oS=^ zhmiKv_BfzR)OGTm1*0OB`WUb2iz9C4@nqu&zXh{pBftHoR6_u;3k7RWinMEN?2V43CXn}hFDgM1^C17km9D}Al9ScF!#-6PX zz?D%IFpd|G|0{HYfew(?fQHp2cX5yi9DAD7fQFLE|9m;jBEs7?d2du|!l5QP-qC$9 zy8FVAR*hd2*C>8@6O&4BK{-ge=ea?saz6UVD%#ZX6VMtHo77sOFxYFb57$L=#u_RT zi6OG6#!3S+%_{-m?v5oSzAv_C3EVTk7!D<<8_ooebvu|eGRiTIX+}W$?JFyqAw(Hw z)8)EMWqVE-F%^0c-FL)}ht{gqUah}4BHsW84e;9Wc=3nr z{+AGO${X`WL}^BZEN?`|AN%evrhU(+$IqV(c&s=lH=hlc2OpRyN2mu{%?+r@z{V=R zn}`yDwQVxo^K)y8~wc##p_1 zWy=lQwcpmNMtwrX=48ma@c@o;3M-NcPUqVu$0$Q5>&!>qt$j!RqhkJJieY+cVM)PO zjBi?bX^!7s8YF$_j#_Y%IKNtUOdl70%o}sUwBg`B-~PV+U?br6(`uGf-qU9Z3wO1!J{~M_6+r3T;l)K zOAaA&LGds7xcnG_y0O>l1k_8v^nLuT7MZ_Nxw-Tr{>}IZNIdk^exVnHu*wIMN7!{! zZG$X~j!CTkVm5^%-+(iDZzi{Yh|cqWv9u~VVs+Dk^S~rZa<}~ZKs!-yL81}3C2Juv z&TY;p|1IvnxuKXa&O{dVl+j?+nn?b*Yy__g;#7wpDwoSSC}SD!2})<5DE=-2j@26^ z!vGGK9Sdpi=vRrw2){$ENGg)B=*Yxg@nEhp;r`?QW@gf;zzd=&Q`u||yY_|`)A7X! zB%Een01J)w>5|wV-u-J>{&$9K#L_{mYC|bb?{%q_XlzHz}{qgSiC>2gRab1 znk)Z-m`FiBR=vhAt-GZEmQDV9+lXk~7)XY(o0p`gk|@ymg~ zE03E9i6v-OKkF6rcmMn6rKza{kzR>)q5th31SC+X*vK#M4#E=YLv|KM3@}6+H(*$2D7+|DUGrPtn4yhxA%3?I@ql z^bhO&qlX}=WCV;jsq4i=z~5{m2BgE$2xPHqB>DSta39e|g5E~Y_19ZfHPadW?a_#6 zEP2Q#Tw;W37-nRDSE7X!0*WlqJHzZh5cZGe!xck($NzWx<}Bh`QLG`E89z|I1hMs) zq5b{IV5yIr-GuP$u$KiHMX)v;Px)VJ%t!Qktc#b5k2zxhN8tR+v0L z2+8=V>rycsc{w2{uE+|G3!s9lP z{{CdJ7+n7V&xjqwzugxnwgGA?qFW$zqJC>038JAcY!Z+$a zI>K)iMMsN$Fn%c|%?K3l9>(5fCf70@vDEce4J?T7qWqg26Cvob*14%vYxw2J;mo4l z#y2%--MA>S8lLh6xPSXc)u%z~->Bt=V~gJ2NtCDtepUPU3+Yes`P(O~n2;khgSi=Y z!?L0^0&5VxH5iKuUi|eD0zoZbsXme+Dp@nqG5tpKi$^_$Hr+^Cf{?^qIo@UpfvB@;La^4?`}0#n#+hNPSGAzK!XLcm;hEZqhfqHTn<7%@Ade z!`b}uarXaI&ytrxd}|pN9a&t(pE-zuX31<8-@2aIlA;Dl{44C>7D4if5~Pv+$}5;0 zoKLJ#wpEbw#&**Jd|0htv+O8JkLMdn$f|hoRZA?%uqy-%J^Qp2GP6-|&qi8>cli9a-%&aMo2F`5qaZ_=d|5`1% zb&%kxrCLM(eO{Z@=rA^X>BT&`ZUwqu6Fsr%&UcSvzX3kPt<%q)=aK)YSN&6$9~Yg| zKEb?>(xssI@zbjlTP#u6^^F!074Gw%^nh&N41+8ix&WQTZ8Aq?o`Ec<2uwX^F3bY@ z6mdh>MYQcpXfV7>Dn60yx~E7w1e&yPIT(;E(1k`ZBdySvo@ zh;os3HD!@w_HNV|N59b7o`%JJNH}6dv`oc3H3rTRbThd<;cPqZ(-qd#`|`x+pR2cn zlkg;+nV%n`t1~Z!VE(J$PY|PV`=AW=GGucF2wY|3&Z&raqhiFN#e)GHC&k$`sXD(7 zkj_W$jcDAJpeA#NLEePWa1|l4<`|=T>**yseiu`~1fmZK`aQ>U73#K4uS!e* z5CB;WbH?Wyvavq^wh4W-dOJ1}YddJ1s(0Z_TAEI6Lmyx*9Z;^o60(XN<0Q0KBU)H= z_ed2%+6JhoG2d%|GEozEs>|-)?ACgVPgSz}CU>&i72ktZ3z)HO zI*50bdiE&Kb30+An#*WB)t2qy#5&UCDqS(_(eD;&(er$chYZW8X{aDI*wPlcPnk8FbS?T z2aHE3krB$ZtILS}bs8?&GcKQ#W+gO+P-2bB*%Mui-TZ%rz&cv|lX@)m!1t zevu}3o}@<3^1cnFHe`HfrW%Ya`}PloT5J-IK0ds6RPmd?zdyf6SejCB;}Q0`a+((% z&vulVRN+2pyX#2hf{;yDpPX3~2Ejl-%b)WeEjMA_@9o^31iU$E7wuV8dfdn#6gFr( zKX#oiQcC~P@fg9Jf<>`}I=}e>y(+stcmiAWw%1p{woxY!U^(rxm}Rk-R-OirjL=MQ zCed)L#S=x}Et2!e0WPI-t;*3NGRKeHpQs(aCc|?Tm!l5v$&zd20MjSbG)>fMyQB|! z8Y^C12Pl|?DaF~DW^l5@*ur06c{KexalgZr4|spp4zftM`$%ZiCXp53{GQaz|K@aH z5a!qkTWh;r(hD+xw@0lI8qCl~DXV^o<;KWGNQ21+@4lqMH{rW`v-2T_?6g#%2v??{ z8}|rXYZOWS83GXevz*=w{jm4cwpB8j53Yh}A*#^3vytj_70Un%Z?@^43cG1evq5U$ z`=+Wj1*O6Ri|;D6Wj(==1sQ~TG2}#VsE$TKdcLIq7dcZ8tjy= zIBq=%aL3f$D|Hf~8bs$AUMP!VHP#ufHdYXDyJi%+TFL{(+Zzsud$*RW~ zJf>Iesyr@otqxfHHjlb?TUC>hdcPvk<#r<}|Mf8gQ0ujkD-+F&p~9&iOz!)`&|=-$ z^o6BDhWC;exIg^_qfI`Q+qwJ59leZwbU_%Kqq_aU-Dy0#-gbWM9(I!t%0)fOBrfvM zt~4D??wnOljOof~^9uc+x*~E%m0EJIiYJ=NKXO>V zEDjzncP!J5F!H~A4qTjTO=GTV;n0NU4syE$Sdv}yLyWXsSH^`!`|e>>#WG*1jK@14 zZp)!3q1tKDGRKD&7;pr$Ba?q0d$(L_5$i0IV&t!bgGK-L@ngS?MfuUy8_NtgwX!pb zn8GOB9t!uhb>CBS*XjuB8qy4Xk8KKGKcBSL6N>Dzd)4|h{?jm1W$rt2rvm74>q(^i zP@C8JDCHe_Jbb?hE$sfNR1c86?()z1-;PG3zoRq5xXZViWGEc3Rv>((!`RSyJ4(hF z_r+}-0CTb} zIuCGBpq4rz44?}gaW}o<$X=q$*rM;4Njg?AK8;O$H03VOXQLIrekpUmh+aLtl4WkG ze9tN+K2@Z2CYg&KD`Kq-?F5_$X9!;FB`43Xr=)qXgSMbVMJe%mCl(gIH_mB^WsA1` z{U`nbzGa-R8T0NaJ$o5ZF&IDZsEoK%xb$*>=~@pp4Zv4|Cru+6!bZu!vXv9FWc0}N zZ2t%Tnx*TU_4EVB7TWJv*#*Ln0kAvr^TB+T->FUelML&6bQ>}sUSvSFf5$TNDuYaV zuIV2<1R-b&?Uh2K0%rbVb5f0-^a#mO4Q$Th#@kk~>xye!i4$VvDP`6l`1KXU$f@w3 zmdbX)Pn@z1A^^D#B{FJESIIsegLMMOZ^F=Hd*{#OIn^!h`!RL`ZeF&`_u+;eS-LMc zD72mo;51eDZL0{`KAc27l7gy!feSRoc=hZ=x{oI(=Jj?dPMS}QEsG1|o??@JoFi>% zA$gmVJy{Y^DDL%kTa-xp{<6-;A09oTADYUWVLUrv{}CymY&S;sNOeos{pod>^wsIj z!Md`uk8{YA8TI$A(W_l{zabPH{fxG1Z2~3>AGv-vlN*W=#V=F@ruDt{b-+=NcdgK? z<&%~6bqW|?6KbSK2{-J3D&RC(`c5C;w&2 z#~{{4f(~uac~fzFI#EWFb7DM=Z62$halZK+7Eqz9(q4z%{@NBg!)ENhJIl93*TWXh z679Z*lAI3W8!^Hd3DabZ)$Jq`$&B7FaRDcHsJ9f{e}tCzUxdhF{%c1jrtuQaL+#4R z?K_PhY0K~mBEZW9qt~}jLW8H}Uil122MtUfd2O8<|F&WI{Rhp-y zSQ6|dJ8jj3jLn%LjVPrO*sg3C3r-Z%75-y9w^}SD2(BNyyiB<)_AB-peAo!olGI)X#d&% zyS$DB{K%nN2%y&2>$3Xc)jovD})G{j*-(9@{VDIYhp@>Uu{8-9Bkxm?z)noKi_O-Q`(0UCO zw5;~wuIboy_@hGd*G+b$Hx-K8QmwCh7|obA)u>LSbL;tfg+W)}mzgG1{kf6-w*I|o zwNge-K}`6?je2o%V1f8*#YM|@X%TZ=M3nz~B?+c(S#gHi{Svb8eF#HvjccBHqAnb9 z)?yk}bgt=cDl~olb~Qm<+g0oBPuk_>R&rQtN3%L?Lzy*^?sjKmuv16aj=#V30 z+T2I?eCf}XG!Va}6MK3gCsQ*mNzWqLUguCE-ENjP-{jzBpYcqkR`(-y36Yz?_OmPg z_-<>Ta&CF9o_Qm|qa+5pY&DWFYfZ0hXZN92+V=FD4;N&B&{7#R#d;eM?;P;BG&7W?5C&*nHa! z>3nE;6&31An=o+%QX%9nww10L5sA;ByIYKNZX9o zN1acJ*e`fL7di z88p~))t6;Uds_h7o4${{URSpu4u$#JSQg1P7n@gu{m-KXMR-s5YZ3* zST3(PwE~Tz;!U=f$Q<~7BS3l;FA$Tc$QL_L18w3ol=IzWBbkiK_hG>=x4!oi0pH0# zqniCeGsQqBcf%h#?gu|2ypsUsdUY>MvHZUFFrv;Ry`&}98dEN6Acm6qCZB020=Pi*}2o?Yn?M;^j_ z9Ts?5==XN5*5jYy;@!49UUBU1;tmHKK{*_%4Mx!iC`lFpeGLA223q?$Jr8Cb_e^C! z&aTO}7Cx*+e}?;7#^ZJMcCPa34Ji@TSQ9!ncg;4f-$Y6{qHuoKsZ$1A;oM_4uY*>D& zt!N_OdKw{C-rjkxEfz<6@)3!1z;7Uz9q?e@%jWAm#b_DEz6!-!o?k!AXd5iI!wq<- z)NSA#xjgJQu zNpi!1@Rncl5Z0#yF*I>sI-&+H8-_J!e?`S3Og2r@Ez`?tI(?Bf2uuvU!hkjzJe0*P zy3fc0Kcw^GG88{T-kl$wC(^pN++5BZfhGeU0^)tKD7h!B(2Huqff+mpT<2%yjv<-& zZdHD)?rYA=U-TG7v0z6=ic^OfdJe7g`T^4vxYxQ#)^Nxsd6;%4bq_5c6+T-?4A*J- znU)S}zgCfL(`Fv|?8|5KjiEdAPmJ@=FflLn^IJK+#F)Z>PJ*+k$KNcc8{fj5o#i*= z)fRUS!394NZd&6V3))d$J$oBU&%N3ou`3Rp(;ajETwEqS#_*wbBnhK*RmT+}*J-%r z6AuBBCdk--7|K3FD^uH}%U{Y?*7=Wyo`sX6ft8I5y%oT#pAK?Ntcit-c;{e(tkgW1 z#KRe6J>}OZI{K`~+R;bgkn};Tulyd{%exSnEZ6k7u<4d2kiyDE6Ipkp%t92Y@R-Z; zL`BoFDs7>pel4y$nTY7^;3rUJ)4HulDnE10oL!n5AF+Akl8Xj#U%F?NQ)S!UcU*{% z(P>*nS#TFQUk4A=_sqalbGpTi`Fw;OGnnOfcV%&1E11G6?O=8-vu|3|c2VYMsFDgV z--1pWMhwrP4l~-6;i!KKfRg8k_|y%XKd&x{JJy!G-d(_1SBEi?6Lq2kRl(^l_953R zl1Fa#_B!C?;Zw%~*DojInf-Fwcx>x5UyMsF^*YFBp z-IFWef&Emk>oUHRe}WZ6pxlbjpu42d$xUnMbJStFcErlNJ}Arh0!};taW9q!nZ875 z2D%=v4BcO^Xn?AG$W8pSL`Big+OI8BFxgs$VMrqj;Zu!%cHz}2iS!oQgSq*JQm| z_v;xNDDFF~Xk>IDGhe}n0K;e9xiwADp}E`j=M2YqDn2>tag$7zUo#=b$?jCl7(w3j))y;(Tl_)T2(z%;U17oR{m-HjvO?f6TeJ zzq!rN6?eZWowIuhaBQdO3@cZ|%@#%QLcuGmX#oL5%T)80bf1&9{tUl<(NWU!O1$sS zv#px*jNKQD1s&U`R@}D>rMXDUjIWkV82~*zM5K)T-TUtsmOgF6QSqCmrJIOVTS@uU z$VZ>F=Bu*vRXihBJ$j;sZ`wak&X`~N=GLe@Uaya`&Kqrg712FoA~)p6$Z?z3nHGZX zQGma9l3OPkIV?(sz?nHW`3%&P=CS+Bly#{s#fu3^R!u@pu(HT0vG(!Sxbbf$IK8@a zq1L8^g?Fb_EmDYmu}}f$5I%o+K4$BO_nS`F9Z8%ZPF|R{e%D2P1PLg(q}TWIlALS1Cl)lC3S1STSwb}n6=_$ZO3!wQx~jPG z9@B^8i&mjfrP58tPA-xAUYCa%R&n}5_3EqIVS`sIrm>d5ZZ5 z?8D82#AO+EN<>1@ufLFoNT_$Qxf`jD?C@CZb6rl zDE@r&dvTU`$OXugC((Sxi*&2t8E(kZx#?era$-3g@Use2DOpdg;e0!x9MWrg!l41> zqJQ71jbb2Ojm@)^jer08zoMoj;CF@3=I8jsh~obp52~8NZ~MQi{eLz0|LX03jFkSb zhy0HNJO96X2rJRj+smH+@s$5z1%x2*yFe0Z(5_s>T0_rA| zy`X0Y%|+W=M@p@Ykvwo-`bF(;+2*IC zNE+1g<;lVsV}4Atx7lQ6UbHM)weyU&NT3oyO3}1uUpLL7<$o!dYfVfx3K(ePw{O{B zadrl-CXvm&dZ6;ZA8Nb5>p%iEXeUH{!isuRLn;%7`^0P_WUjx}SZt5!W zkQI<2T}pq&3|z=FUXyiC$eq@6|| zDz0hK`x!+)kIy8Wo>IUqjFF@?;T1k=#P)f_UzoD-MJA_VI}mv!=`&RJ%}5ajhi|ABlnzvF%9$jEB?Niftn6ZMAQo z&4LXF_&%FV%q;U;KMSad05?_O=!3(kAkC&ckDB?u+FZiVNwiE^Bt~3MY;+s#jQwG5 zx%=j*c)icZ*_8_(s!P`ovb{`Woz)y3d9N%bZvQE|Ij6W*R~T{DCjn+-orhY#nPz3; zmR`_-lz-I z3go`@J#IKpvH-n&qI8nAn!dv+;6||GB?>znZe5XsPOjinyQ?SjAD8%nmffF@=L9j& zgnqhH3JFZAi`Q}6B>)BaIAkaPG?vijSZ!ss*461V2QW{2rAF&;UkflNty=i;kHlnY z`AAyqNFRJHMz99E`I^2)P-@SdR()2k)>#=Dy-!mmSw;w$ZzQvExz|;5fEV~5ay>MF2ZT}*nGLT++|HiCy)Wk$d4_!o8%{xTQy@j!+%@eB zy;R5e$1S7bXL9=!;&clnG(sD)KSf<3p}`ODomw~NXEv?RuvX_ipSj1wH|ERu=bV%n z?8SsXn{I-HbcEfre;vUfAV<*Qj3U%B4{!^fuVRZn_0p}<-fYLJe|eo9voLaRmK?jc z;&uAN=w4ExR_J!ejBAw=G76n@JzQ90vAvF7u!8Z7#)-p@9$xZO8Ts-L+@H*aW%Ok< zueWU5I<`BGwcOBqtl1BZS!5eD4SBtGx*8@sNs-A;GahlF?ZQc$zjL9PuA;Im0q`@^P|8-LqLAHUZa(@_kwwsbVXB(j%BpCJH^J9 zo9Q>O2HCd`kxRex7=tRsySj=6OC7F{eY>O52bF40qJ+ZCyPKiOYuwp-bC~`H8`4#k z7JTgMW;d!pNvl|d@!YEXZuJxjB1cE8H6Pav{rrh>phD?T6lrq@$$}&Qc`tx{88juz zeWLuhPzX$3ed7vq`&{7g(RZ8T#b~knI7y-7Ij$|4^Rz#?`jnsj$W(%XKxz;(o8!ew zeSp-8FZ5C$00LnP90+?Xb=$wC@W?-~WN3HDO27ZClQ+Eu4is(zC>#32D9#tAH4ecW zoydmuPaBeq<8=JKJxJN(`;6Zd+xd$+?=Sl#R|eN?G5jt!RrSC!v&Ka`VPM_rmpL+4 z89w7J_^WQI;6$D5bT9X97gqj8{S(TnLu)Oqm0sxeetVP;c5%mbZmNiBk&fT&L)Vln z{I`;fxJ0t-wT{;r+_>yGytj|8SEoFT#-RPR`u>Z@?u!*2QtWEQN^?}6J33rFRm+bc zzV-B~D?dukl5D+}qKrDoxxPHbHtc3QD%P?Y@|Y`ZJO3Z&9ukMzF#q?UuMk z+kUN!A-PV}_q#Nufe!E5^sA3WhI{je_j}yEXoc5LI_@T2jl73)qS)4Q{qnL+Sf+on zKr6M@5~tLn9fvi>J53CIq4uqgDh&CB48==@2ZlB4PbeCO+LM5o)sC!EDOsz(al^%E zC-lmv>HQ|>YHRAIEw=L$ih32rmEP%F_=`M8(xvQ+Ff5Cd#q5CH;a|Vpv;Ye4y*rr> zuvL7!e9!hF$E`CSP{T(5z3mRxwP?})9`?&S?~|Kikl>ZzStTfzFWJy1nKd?*e#u?$ z8Q+sbzT!B>rWoy|Nc-uVo9%I>^%}@wYgzO_K>cO&TB!XICA~MF*~Lnh?}Itt_Z^M9 z6@ev^M$+1{#U?lcnnxug-`=!cB=W0XOA%Q0waC^+Ek`r(Uo^KfXm!uj4;Fi&EDy!{ zx;!@71e+|TZ>|rpzRuMf6`3wf{%P{LvLT{8k;rzM{-rrdxvrM^lFxtr7Qif|6qoQj zF8j83(URRw<~~&__Tl--OzkHh?WRRvSX*@12;=(hOjBX~3tz1UzKswDBkt@4ci<9j zrLK9B+KhUH&HVf&D^c=*{qk_r_6(NlUBStju)SZM_fERH1Id~7<$xS}r}=uZwvx;p zCAp9Tsv`wIJW7Nc{qMU#pI2Q!<;MH8sJ45+j<5yqe({~JC^$CS?}r|*lA0_(=iC(% zg-kxYST8p8?DKP+wNUq48*eXY-crd_U5FB^^qlFp8|z?MAEXT>cC?n3y>F|FHL-VNotiyD%U~ z5CjpFAW3poq7nzuA*Uf{k(_ge0hAy}juHnXXC%i#K|skF$pVtY5QhxsaqqR(yZ1iM zzRr*D$2r%x{td&^-PP4qcimlGPYGfuWKs_NP z|IVQ|z;gROwoL( z5QYt6;#@U*a?Ly<@KXm_uDNB*RGk8Ve>ATfra5h?u? zA+t@jW)xIOK|_pP>_#ekTH*>$DmJSSVoKR?4c;#4e0dHi6+zLJzSoKm-r zxGwE@ENRIhg<Q` zy>U#De!LSra@I1traka%9@pN7oQRv%E%!NEyW%LW(sv7)8f4!f5L|B9a|(xE zteZ=m9-+4$e`da_?yr6KAW^j|Nq0UFmI|j|)pLrAiET?2+^!m|Q+_>GqoF&QW{a@S z^cNKWeyom&xG8RtDbWlk3@P`yocEl#xy=-mB@mL)l+ktNZDU=1(~C7P4FP((ou*X! z;jsFk+*OtiCN>r{550a*wdg_?Y2fpb61tgbJUNG76f~#n_Ky0vkfMV>k}HN@lDFvc%uiM(=Ad~_ z!(n)mwzIqb0d?D%)O~@5(|GYMtgEM{i&sNwrt_B$-bzO)P{^yzCe0$^=dyvqJE?2& zVGD?pW}9>E?yQM9=)i;8fyhvAmUZ%r)en>rQ=xMOTe8VzLe>DfPf5sL-heMiNY42_ z-6lUJNE(2g-^m?E)D($#`qG3W&4je+vyhvr1pot|wPQmgCW*4z!lqOFkWeK-|cZtO;5 z4!T7Rn_R9K<;)-D_(c+#HMo6R1z`UOR{XxswfVX_%9`RKUcuR?pSS9_J6+lC#O`PI zpI=vIBlxY%OZhe2vfrEO&~^9J-sM{O0DdC}+LF?-j-QA5RVCfpskBB27*1=`T4`D5 zd<-{p<_lEmg0z`Mz(-TgC}J3MLjuRU^M#mtCWm%YUZ{k#3c_A7VRhmNj~I_7oHweR z5OZ1P|*&8FB!~ z`Lag=T=gRCF|nHEXr>UZ)gx;rx!57mxGZ!Jp!>W$ zXS`{VIR{P~WHgbOk%A^t&SkbeqvN%aG0NKXI`e5~0Ykl1xOqFU-EeYYA-3itBL*r) z4rOh%QyXjYa$!DIa|^R?scwA8ceM|S#bh@4PItR~4FxOc_pu4IK1*jgMp7lP(PLGa z$$X11`s#^z6IBY@h0%t9Q_KER-+s`D*bKNp#-t zR_Alnn^E_SDr})BW7SBq}j3N4dzD~02zJYuS z+hv~5IZ%Bsai2YW#JlBn>3y9kLJzGNzhg`JDOHDEE4J#{Mzh5dNQj~Dx2}X7J4csthk)#Qv_tZR~i==P(n%ZJfn|FgZy+< z-h+F_wUb|MKJGQzWd@V<@(`z40!TQgK9u-62)OR%26NGBb5DOG*68{b!U{7pJZD zDzg;nrIY;j-^sHfd~y|D+nj_?(QDxL9Vt%m8@aX4YIy^7c%sWjmOZBR=>c_>oPzVv zK%-SHmOOzwO{6iji~Y18GJ zC7cB?$r8)XI>q968)C6qaBTCy8K^BB14{DUjit=CNU8r6Zz zn)5!b2j$7w5HkEq%8+7t_?ekmVpiMJqZ#X7@oT4wP4{@6U>}1;sa(zNA{uC#`Sd=` z3M<+XaPN(+dX3CQ)h=@5##aVgx1HG&J2qS*!Us6}O3U z^^cV*ZKe_j!G4|ngX5oA$s^7*pQ`HaNj3f4+tjekZPY^~nb8*CCZNof2@_@&9~IX# zkLbm(o^$I=iT`0mui&%7H~}U&zXeO0&cF@HI`{>bqrc#i&DUJy4P=uLp@jFM{9;hJ zVtj+WLAx5#+=#5RZQb;Sl&R3XxG^%CXJKrk!ZS5Jn%W_&>E%TB+AP-DUP$_qMv6J~x z!dzNTRGQWe*k0CGj3uiZ>pgqaH@+(es_thK=3|?k&h5~&_U0#HlpYNywI4+vtagkT zO*0c-7Mzaxd09eab^0(6Z+S&ELf$nqS9%vrzg_*HPkf-c4L3D@d>3Ni7x8L8Ft2pXAJ11}o)=m92gjU`|MFwW>b1C|fOa-~2Md?H=}w zm3)|lR_ECZxh|QPDq$*AnYrT(Uy~m4mHdeNq4?TWL0mHggb~QM9Ephyp}6{n*F>5a zKFpR?(hW1qm)^~av1*DU*H$C$DK+-_VX(j;Az$BI99IDAmDF&|F|TMBpx2xId3jH0 z&ZDdSv-GKNNi>(<3ZsKsx?@;6)k7nz6xL(ku>y_DwruCzQP!H?GZ#zbTX5UXJufCU zcQ5-Ijx6x8<;`KPX~_4&RNm5$ zKIqb0GJaC0W~diE8=OshG@37C3VpBs9CkIo*>^Fx?{WpLiCkW3`F_HFnOATy>sy$y zQir{>XlC2FG-hGON^8R4GKeE@e^@$}`6icoZ85%pIQno4u4eL-9ibt`8o)o&#eF>3 z!v)JSeXl6C$tKt&={hZBecP$(gaJPxCN)4~(0g$`slmK3CdCpj+DYr=&I%;QYb4)Y z={S9N!j(#{aEZOt-baT)ZOBRBOi`wgBYQQ={SanuuoHMqu~reHU-`IMBy^4vHz7wP z=7)J_7c3=VD>lfHo~~)}q{Y{sZ}&?o)a{gmGv>6ss@(1M$vd0#tuMy6@ivSRT=>v zKajuI>3%GBLsqWin}sJO=U&dHhqnxGhiPnLrnBI)Ygtd|Tq@>g$Q70Gv<$p#OteO- z(RJIVtp3X2c&EQ&dwsWQ`;wW8G!L9zJj?$DE{VO<(4uPMQRfBLp;p3EBnTcp7Hm!{ zkH1|G-z#%2V>~+)Jq8b`$e|g!PkRWz-7vLJcju@Ry-Qdy3VqIcs=5sw{ytCRy9T&+iE1EZkW2MSRqKF~?rxt_~}-FGO5p z>L!kc?9PkQm^UoLbuQ^)ktZr|NUOIt5Zn0V^Y$^6N7_@CVGL`3hQKEpBt&xSOMN!)w`{HVnJdUR7!P?fL2iPjQv_E9I#|CQA0R62aLI z+q(&Al7{IPf_pGgX+j8 z2P=szO|Ks5GJ8oliu88w!q52DJtJ!H_86){`(WY2>PwebFmi)aode1&zqhrERCzTa0wzhm_AUL_n>Il&UQlC(9PB+W99f@8R?EYUajNZ|>U z4%Z_t%wd1D(jKntOIraQ?gMDhB|)t$bF1PtHccPid{~-&>vC`?1_T%Lc-~icRinz< zmx^pJ%|WFU0eUtVkN}T>dKTO$iPkV>wmU4{?ZNMu))C_#D;rp{WI6WAN$*<85S1|+?gjiX}*H2+U zY`#R?)VAD>3=Ac9)0{r3Rc|i+c}A;oQjRQ$Kjkr?TO7$Wr(ga6pO&$;K$HzHS)A{5 zZt4UTCJz`a@MV8$qKPtGznrE)x(_J$CX_&h7UioVP5GKQ`Y$<~NGikO%hQp)tm0{= z$a!kvNc@e{ikAN3$&5m<_`?h_KmFpf>{$2Ce1$Hj4MJ9?FNTPesWhvQu8654neEZ~ zrX1^UH~ByiaCdh-L{g2I)l|rUzDZK^$f*kG#a1~O0kmdROuEx};<9Mu+PP>jZzjd|dOmi&NV}^wg zAyOGIm1iqvJ3f20eXrS(IyQsbgLpGnjSFeP`Q1WwgKBM~lpzQ@&%w&2O%mPLh_JD| zrH$`jOXBtMy7a$Xo!;S~2talu1tr{hT<&UcPthIxiB-ZPW${HAI(LCwm`%;+8)-F2 z>=?9~kK~-5S?;o@-s@vCVh_a9DH2$+*OwNC+^?Wn*?xjY26^PRb_VQANt+Pz)Z-DQ z&>`T2%Cc@$Zc)K{UHHcorb<;n*yDup$I!$Ol6yr1MOjZ&$&u^Fp0eHVFbz^9;!G&o z&o@SLRbD$vl(ybiYy~rW(bG++HHl=(XPtrDK!$F7I^QW@qMSFxr+ZsP&raKGFX+0AJO zpD_z&X;0?68BdF?`*xy->bMnTa?gcrn?h4R)=FnS#HnU_sVa z&s|w|hH;twY{WbB;?0UeGw-|~!tu6Bq#II!Bc$T?U(ec;@*kahoZ+pA=3Wi*#PjqZ zb*7HQ7mdy~`M2=UmdX0i#v$)`f~Jhm<}3?U`yL+oUU~S`upM_CMlD+IO~k4cP`x)H zDZ5_j*xU~0kdv|Oxc$d*7;C_I!p*_>i(>k+`5m{wD9oM>mS(eK{lS~-Rwot&-><*- z4OGuO^B9f2|JJg_thFBsf!DZ1h6_9d>~)f4AyTPI$d%%8UT(XUWp%Ar%3j3d*@?FT z_7_!yM{#Z~NEvSP!0juzxK#s>Jzs~I<Y2EOeL&9KXHXK^+^fi zQRza7g6$^H6f7G;{}~Q;lv8HQHD|hlJ)|to@Az2qt4bDEygX_f=VMN;{^FHy16N(- zq)U4i@XnjqN3g3Ecsl)9+(?6JbfC14n=T8P!7>&|nzHgNF<#9nV(Wz{Phy-`lf*EVr{barjuX{$zIfNrL>Sl+%zWO`c??g5B zsaQxtR*T)<3QQ{UE^^ZwWo_8a@07go%}5M(+PXEy4ByVXq?YAR7_VD63A1G`D9yY2 zbVz8P!VOO`p2iSw$W0yP+Iu$PP%or;{sJs#${#<3LbU^bx*Y<2`l7$C4{*}!Q(V|06Ai#3Cb9TAiwtWs6{xFHQVZA;JJMTM2CQl0F z_?lhKz6;3>P`;vU@hLZvs5s8fjgOUovL!psn}DQ`9bVnG()Wu$=s&4m*HXM(n1*!t z7`8i-dhg6zHcV`lJ1OvY`!Zf;SG!n)o(-3fBMcDPbAms!)n!hP!PXL*Bk^%N4i{5hnbAW|9KMNDS19VnxJHe zWOyz^%n)*!Z#z6gHm3>e=RfcK8sS26H<%>Ek{8TTI&<%2!kmgrkQ$DY?84O7~tI5t3sygSo#ROiqN@LQaw-G#50^cMeaCVprH%Vxis%nJ-fH?=EV+<#-qjF}Q?b(! z_UQ|U@AZf1PXkwOe2dC5*PF=O1m5C8xaM9)$)4W{svobsVp&ZO&96y2lRV0n*GHtm za>=8r$~F=39(*y@ycXRjCHpPa$#LanhL9rOr zR;)oqzfeAh8(}pL(b|x2F-?LG#v?7=ay~+{>nIkGH(2AT{RZ;&t?8}FKU6PY{}hXm zQS~!yU!Rz}6O>qXaHQZt^Nz8K*PgGkfr~!NMwP$jBCnco?9^G^ovHlg@?cPp(aGc( z^Mp=i0a&a^eO`^8(>3T0G{e%ah0@S4x8VRec6R$@H#TyiGGFxJaCkYdi@1ol%mhFP zNzIG}jqH9M5B@~t2{XU%%E(x3mVTVccsr?*@!^xJ<=-kEBb^@gmctB76h z1DOUn-@q(w8gm1OH>w_1{>h1KI>6zlp0M1&mp-f)|%6JHkt+>P~u2p^6fdoFs}KPwSuUEFNF<^4GZM{y3EL?3f+fXv{j7 z3ffnHSEsc;o#5W1%}uXR#Rf)& zQI=wB%ZxKwP1Zf1eanU14l}>Kgv}h*-mgH`CEx`G7H}$dE#~Wc#wWh~z1%#h-U*MW z`0%?;d(Di{C~;%4@rK|V!jSW~v+_FKgse(ed#g9@CTMzfS(#>}9tNvIS$w-_S_~Jb zX7>mx;)XvQ=SS}$qGq0F7@{kUl^9oNl#?i*6_$BiZXfrh6N)T=!{#mrI4hDYZo7)zXHQk^!gmlOLqax;hC1({)O2$LFmPj*d{L;|MdA(8RK z=at}lL)(O_LTQ)z)CzHXO`0yinl#Rewdd8?6=W9bkK4Ee)huwuTSGuo)I56*#Ya?c zLnz_M9_~V}vg$sq(le1Xc&C?vrLV3HoG)`dbk)GE|0sRNy-p?6py_+9-|%pxmtPKA zVKHYknFT3l4J_uSg(Wi1%-8CvVV|-#e|2?2ViqJ-PVS|pL!jZ6RkS`u)yIB_lH_4z z`uc}S1D>T$yQQfoj&+t84o7=@?AllPy7yA?qt1Kv^ZUNogl#8VjnO2)d7m~erx%K{ zEvJ_wMxLFTn3WMkuP}Xs;x^@^30e)@n>y%gDqi^rm`cabTpiQG_w^2cykA&A8qoWC zyaul&pnZ&F*)PK}=yWw%voY9D|Jx}a`w7BCDlnuEttq&yH$2L$q5s8+LE&l;=0s52 zKIKg-Uq#Nz1e2TxDmOlIEeXaeI5DHw?6cmz=g-u@X`*Q-b}OjR`||wAZRFfljK0>f zU@PVI(C{nEbiUl{%PpQK6qetoxfquf1cg&(1~}Ll3XXerJp3%B5|U(lb&AVvrnHtn zbjR&yi?T2{OjP1QSqW+2OJ;h8^o+lrqxQC zblJW^CVZ5i{CICQly|gPeJrSkYRnC{6{!2F-p$A&Z`j)vKVRH@89MxGnjHY6Cvesq zcSHN9rL{`6*XXa)Uxe{|ISfIDFPvZ;`CZZ@>hJA=`X=&%jk;7s2s2&df-t=Pnz8L|^{Y`>lR# zCa=w}D(UZfw&pOHVXg@c+jCtHk6jk>6|H}&JY^DTROy*!Nbbr=vEh5s%ylq&P~NDr zAhToFg!uUK?q{fPqJk4-ux!}p9{$YS=vUWkAHE{dW>%x`V}A7EjLMQ9rnI2s3WV;O-#NiGGvkWEaem3kYs2gG|W3iFd;X|u-yBuTf{~4$_h5| zn;3|qH_o^C{VO#{m$b5TC)Pw0EN_T8c^CWzj?dU|Yr1e}t4UAE+;zTPX*$Lo*wn5~ z8aiIK6dox$dlm&YWnkyTrJAyg}bas4B$H3uw zn66;qrVdmU^VMwD8!AHF(&}=B*yLB{A5Qnn&6%*AB;U(wJ>OUriWjx?d>0r4=>qbQ zIUTy}-nI`jszuTQ{Qwrk*C;##W{Xb*7?j9THFC!4%^9|>m@oTq;LOr?-80+xDlYi9 zJ|fk|VilNmydT6@|E-+w%)tyvlBP!IQfUr6A|%0W_VaDUU9jyj!vRo=5m%Bv`)Il| z2F+ov8P=yRI0t+3NY*y_R$24x3{XsL=X~VxGUJ5~d03ND6VlsPzD72^E)V)6v38@$ z$E?a3Aw~J2$ATu>vexFS#c2s7LaFK^SF{z<&e750=YBtL>m$qOleo!bQJDq1x{jN6 zyYDg@kgwx(=R*d!u0xpNKj0lur6v!uh%C{&o;Puiy!khxJm9YS>%ws)W~^@PWzno7 zQ`79FEji?CkSB@8LatjxTcHO)$!vr6Gns`MpNZ_1L~m+-tGiv;UW^Ugon?;?qhg1( zEwzUQb@s!mB~oP^U;S}gZ2^CPSt;6(MdjE{^TZwx;0(04A!+tib**(hZxP`|wua-b z->UwmP$n^nU4x9v^Y>t_!Uc|lLE`~o^crwh!F*0|b>8RebvlKx;rTo_m2)>Rj z+-6r;M6b54d%x#R(!Af<1YVGq(2~{04_QAx^Z4Q>H22Xn2J)PjW08p$@;F;dtxLl4 zsEVc9?r6!4({8y%d1}ch(Q6wEi+ehmjiP0_2Oc;Kffw99nRLqpHo~pXz0+qL&fD#t zVzq=&te-E+*(d+1ycy%(kl$_?Np!^`ohi?WR1sx13h#~$-0GIAk5o-}o-HLuZ<-re z-ZlVtq&OPaxnYn#Zrt4v*7Ja3ssUImIp{>4I(b_))28q(iOsvozIg| zt4tP=E|5Mp$CHx2TcaKuA~jwlf-s*q#$BqB|HfGB(|p;Fe>^9vMIUhWLUVQ@QMC}k zpFfhJ`4kB-2Nuz3n_7d4Lc~#Bgy7U$_3l^X1oDHt4MN57qtgA`bu)vr)^Gh1DzvN$ z<%K2IHK_S@be9!dUnx9x^79J9l?yTrioM9&%0BD0su?S>rzoV@;(-JxUd(P_&POu&3f zl<3NHh4cmMVewvC7(w>?eSH~#k_eqmii#hGo0PR2NoZ#HP)gr0E30x1$1H>nf<^SU z(?9kgQ-wBxijuBIzeg6gEWmHOH+~)Pvo@1B{W=c@uSk5=JuJ1dZ_g7 z=Jth3Dz@z4!`uMy_Byi>!lw!IH7t^yE-5erdU^x6`Gr4`@0mK7K=9HFxn_1X54-K+ z)^Q>1fuQQ0bj!)4@Ltt6jg04~xU-DakPR-g7j~k-w!X*<@?3)(r?r8paB{U@*FD0v zMZ%B2&%{2pTws{gq=(5Y1aBXvjfM^txVutwSH9L3RduyvkUs{Wzj@GnY~eR)5m`LN z7+Nh78?ONYSsZ{_>8dZ@3!Z=HFRU?eoGBP7&CQ9ok9gL&4eyE=@5@M4FOWH@`=EdS zEI=wF!keJ%D4e8@M0(@VR~r!@g{lzJhY41EVanZ4xx@9Wk0ihmrwqJSKOF=&pPMRR z&_zsb1LfJE_a!QGUcm;qNhDxKx0K}l*Hj(c0dav!XO<(XEfd6#HhgCsM>`cmm02 zE1o+R{q?(Enr;_slB^A*PmyhwEnTg`7B&X?9>5y_eFc3Xspm{0OW+??BxRUQty9PP zyht@{n#O@hjfOInkOqVbaZjg}CP4Z2OL+1X%yTVC-JTbFc46DJ6)ULox^P%j+DB{b$vsv0FA6D>zY#}OH~D?WLh#uHK0a&s zXome*rMfa~tEERn1NStx_#m!r)LqFIo8b9S3HRmby=aUtes>v4#DE)+^hHStv)}WO z9LKqo+EGrG~X-72gQi6tC+T zB4L!q^0cf|IPRX?N2IZo{mRWv%iz|V#2feR{5CI+L$=JW96OggZjw9ZBfrGd+Ivo& zPBdtT0DuKkWh%1Gmr$Iuh)#mT#`p+k#btZs8cb!JVvehL<8w|X(CBJ{9{*9V8q73U zV(yPqM)3t(i}5S416UWrB^IzetQw!9-mWk{5Kz-eG~+Z=@lS-S?K!L}P~7gY8n-zOFDm z7cx_zxh=OlL4W+%dRp{BJl=o=l@cy?b?&@r^SbCkQH8hv!FU_FGbVvC+7ox2UsAG1c9Imvkwd3pu}zDt8`mB zny9`Yd_+N>W>QDc^~)Zn4_DYe=80ESMjDqodaO@IfvJc^)bUPCB?dHHV6wd@+~X7o%!JdCaLLH zNs51ST*M0I=A$=r%z<*|FZ^$Yn4upSnr z9}IRTUk_4V#a^r4vQ-12zcJ3)*rT-Kd)5^M_C~ zugxCsrb~&p*|0e%&G>2NSmMi9A6oV=Y9mhMSDE!&%LA4)B~gC!Utp`> z!8XGE-aa(PVOy@*2h=$*p>tN%qj@RSBgedfTr!rl-ecS@u`yZkFwt+vabnCIJ^K8_y4n z8N}sXG$WA>$8J8`5#r^=RcH*F7vpcGgs_x=L%Ps{LhRMPbsJ30mozrz>8*_Xa-KTWznp zeZTw-spe$o#7bTB8RP7$Jz7`2OES^L^I8!^Q)9y649ns%s1@P7XuTgXIRL%Tzwd`U zXrAak_o7}EDNAHMaQ7m#o)SeG~xyhtjPo(?zou(b0LF=F6zTxcNORS1ZAyRX`7vgr8yE%wrsQAdh zruW=Ll+2B^#Z(DDv%G>@MAH&BTDh*PD%k*h$1zFYxg`TREv=_cBL19Yx?Z=o(S^y+ z_-Iy(M6PW4ss!gtXTomWZ5`qc`&Tg|mT1`=L|soGFxihetWDK8wbQH!ev`oUC_9)IPa(zL#*#Lqw?ODn=?SeQn-oU;Pey z;^yot(LIpf9FeQ{_U$u@yP9|%elP6z{6QCjU&jw&6DL#CV%ySgM7)S`v6JMWgmi11 zpR=vF%c@t3>*3II zpT6S6<@3AQTk)oQm#gohMEJHEy3()h-Udt$RE;Ee*cOfPwHOzjUCN7>BRmboy}AU) zwtp>5QQiFcQb=Mgzu)D~yix-hB;U?h_p;y&k!^ca=xjK*3dzW99SJV~V+lalJ@+8U zXS4tK(;p4}A1DFJd>Md^aBoF2pDkgPio5Mkw3k;}@4A*5-q$3#U~Q`X5(>L;s^@5` zcf+rtPFZS{!*W-5{i_RH%#^*yA2DxeGXBxsKl{b616>@R#S8#HYP_B*Zi7v8y?1I~ zgZ)4}ms)9TWODJCySJ?4e)-ZXde9$&kWr(ff8Fg}uBH#o$6rsg7t7db(}06Se5KOf zcnaGzymdMi9efB35_V@-c=@)}J$Ee z_NNzvn}+3#z*H zr-*+p?O(Fl2WS8nmb1f~Wb7e+vJn0JNaY9Sn@<#)0T7 zl)7rb!lZ5Zw)HyBK}R|e{^?>iTSq(7=LTwmudZfpoPqY@)L)6 z>iKHc65TqwlKDr}on3-K3aNsGU7x~V|A!O)VUuPppT4hISk!d3-FDVBnrm*z;ujEL zS1?mYBYqR5J6=LyUA5be3e5B(#IT;1e-p!Z&L81VUxW6@PHp*7fU zpE-SYLwBg%S0S zINrCmKf?c5{`&7`l?dYV;}B=oaX+RH2{!vVse-})yg(+Fel@-flgJ z_9mTU3?NuEzud~` z;>Jcsm33Uyn zj-305Qcahn_tqW=A|6Q5jAz}pMdJ~JFJo|(j(@M{ zPj^JM$}<@0ODpM1YYprcUvC3bvYBdb5XDmT8;dsoVE22h1hM|nCYMh~f*xq2_Oeh0 zCGIi-xSJv$X!kqN{>NN9aB)CkRcd$tn#O;8P`(Rg1Nk=bb$Opj)0Jh9AnRazZ#f0qt8KTkhsu60+iEy0to4tX!Y=ak4*pk z#_Az0TH&|nYd8O6c7HvuoCXN_M2;WDLZM^u-vJ`I$wQYnsHVxH2nd;$n}SkLDL6PF zE1o-z5~!w0!c2?C+7D4csV46V3!xIlY=9ggPPxd=ds>|2FOY6Q z#Q=4@D)8@h@$x-ZEh+TNUPjHu)@~YoB;KB*ZUbNfPAxSk&{dMD!u8~%&E&_0o_t@f zFJm<6oMrfTUc2yhpKg#yAIWU|c^81z@)PTz->*=xa;D(L+kh@jMd2FZ?p!$~+YsvX zkyoy8_(npPOHX}_;wQXlms+delOVvk-*a88;R^>-IlhoKuOiN&kGU#FV`%w!55*+E zVxHlO3rXI4?ZVJ~$%e){p=)S9jfvns83Q1#KF)BA^tC!#?3~sul!HHPi@F^^1k48s%%`+`3ir2I zk-32JBAA8>4;cI5tR}j&kS_o4aS+sw1qq~~inR@*P4Dud(gUb|eHH}@CE;K}fKJOw zC8NLRm68EY{5aBz?k}hO*AD@7#7{1sN(J3jx^VD*j?E=X>$6;~8W+J8Oq;%4QZ=wX zbLa{Jwp0H8Zp{DM?k|TASRj5|{HR}SGm>`k(+%omAOFWDq0`zu1B!FwHkN>tx@J>P zen0n@O&BftEgK|}>=F=IO3_^(m)FsX)A0UZb8{B<{yk2ABEmfkrg{8Ut9I-A&Ke|` zwq-$}4aGhsa3K$D0R_|qY~$HbK@SZMvYk1j`zPkC-E8U>w@JP?&OY3nQyh`J zt{|nA6z{kx{ri<4!3A8nKmNW*RKWA11X|q?nwG2{m&+q9KfuGT(&B#)kpXn1C!esz zhp8snqlELko1E!i;5@uoTgy9VLz6KtHv2uGSonhwSYMO4e18gf>zM!zzB4&4xZ{EF znAPe2()+)C;8S_&eV>;5A?6)u{BbXlf4q4q-28OP15wXOQi7Er`&M3Zk1K)HMk9{Cw8 zot3r!zHj9+Q1i*@b241>bXUdt#W42v{VG55+kWFlBW@quVOo!NC^y$yqP_InqiU=t z>be9tv_B=mU33I8Vvz3_ufbsOYf@VM+bD4QrNFJjvJIA3jM6~+NuDla_vsP5=t-W* zP8k$7@#}dq6UMLHm1DGq*HePi5mfbu{<{eyis|r$SehD)9218=RQ6be6{dyjh zOKIeS)EL~fW}dB>Zu_?=0nmXwoG(NSc6*B}doEgj$HyT-cO(5~t7i?pe$clQB4?TP z96kqaJ2h>?y*-v4y8@Sc>H_ITc6`p?oFlF?AK7PE>mD1|wD4d=Z{vEV{T|BAazXYu zPFJV*16Ln7s&R#EmN#)7ivjI_ICQQXejAHyo4)68=g_vPKI!)z-~^Jr7TFlWjG>PZSnsv(GM6P7E6aN zJboqzr3mO4mRKcdGMmM2sK&^|0JMO$mcsB`K>wu$JU|O)Md>J3nWz8+XaT*E>Gya6 z2w4qip&D-W`-lMyz(!;d^k`_r2C<#dG>cLU96o7)JKR)AEc<;Z0K~flX!e;iBn*|L z7SRCzl!(hM{ym@oB>BJMHy|nn1CXN`G+Ac@KL2*r2VuYv;>@|f{U@N|fSZ7f6nxr^ zvcE?WOq@f2pso+du%Z|MlqrEx8k*4`c{t-1hiam>#i9=)Bv~t*90T9iwzG z)k_OwksKvk#t-qH`bkO)bdzBv ziOSuoq+S-InIQ3jpG811QosVKMZ?XrUB$8(R5&`x_Grp`ym;=BN$qPg!QTr*L_6pc zz?uIk>|4lT_Gy(R=I@shFbCb2`~09l+KhXsp7=zBBYztd{1Oz5%6o8#zG4vdh=~xO zw1@@b3JjC_l@SY+PsoGN7A;W@fS>MW{KL2O4=6%H~95Y(R!K*h+{X7{%fd zy~T*TLG(^SgdODwbVL?4U9=};uM7DwQ5r5iur#>_H`7KQWpI8 z%omVR_f|NbcrDYOD9Yt^3HWwj0wGGHF(Q?BjdJZuNWUruj5Xafc{Tow>3>g~fu?53p!0`oarXjxdC=M!Q7JoE>1DOxMFpD43DfttD3tlhhQy*A z?T$}xXQ3bpN=W;t86&$bY9U>Z9;Gv>zubQ@XkPr<5v3X>8EMhTi`MzbP%Q>60Q@3^ zD8xhy$O87k__Og8M5r`Ji?;UwW#|hAcJe$fs#YLW%j1vs#TgYw5|If7XyDLG3bNez zJ=OlTB6R@ksPevw$UtG%__=`Ju;hL|4#4vgfdD2pQA zqGJ#c1KO~tbV)$rWkhShsnswn4&{=7-u%)=3Wq*Q)I0-#=5RHK1f@1;0U6&g$!Vh2 z1~A0sQ`Q%#@PrRIEB*h48i3uxp(X?+xAX^0vjn&r`}sN(N@cf#dVn0q$9R-PJ%#Qi zmNf5*3^&Tb4w4+Qc_MvD8p)1c(ZL zmF66!-W5ef2?}fl&iX>BQSzi4z-HgQBzfw<7=MPe-Lf$8TKuC1-ZADZxXcVAokk+R|^r)u!^1mMb08`rl zl2?WEX=`^-P4iJEu;~JUno#aaj{veaYOi?s7L`?yDFd4-+RRy$f%^=|ux$u3d!an( z#%BRGzC?pNsPqK71nA=5=7976h&g1Ewte+i|BlixXqCAEHo3u1}=W2NQu4 z{;lJG^#fO6vo&fdaERjc9fyeJIpD!K*|I1>MCg}u@KK(jIMT+%ApwdwSOZlU|H~{e zX3Pds$0T>eM3x=bdW)MKV@r=}PQGtjuGk}%pW|D>|r}+%< z;GjoEf&Z$!f1Oc59H42%sx0n*{qkRPRUkS*$Y*5gDD^Zd186#ba_~ONY5v-y(}lC4 z)YArVmhiVZfc`cIfKUAjoqwCdFL(Zb#T-gQpB1T~L?}?E7{G2v&AARyLJ*5|CMgFx z>stsvN(|Ef6)<|_*RW9n;d>Cfybi{zr_x51Y$(Yq+g%`b@puuS_9(GED%Y4qNubBUJNo4{3r_ua!4$+(PCpY z|KoM6|8Z^*DS%CCS!F1XKxhj=J*1%6vmz9wK{!Co2OtFAAV13dYz`^lkVopMx4Qv= zLt?lnpo9!dV7F`OJBD(vss_9*Q;4RII=`y}V3Lku4NA}>1xO|vXaeOKOSA@nN#mN^ zC@~2Oz@)!b@V5&7wt~MM;r{_F2pE4pb%q*GiCFXjNFV;jkD}xm;8^!8u;f4x%3>I* zT{Vj~&_(QLeyRV7HUIu-&V7p@895LKwv194%Cbz_8Xy~67&NAYs+V{!AVra`_XZ_0 zTLI8-WpsoR`g4K0PFdy&T2yQ?S_goB9j!~01FQoU|KC*wM8A6)C|;HVZcu0hqMwTs z0m|rC2t>cXRq(e8{+F;(rQ+F8t~ z<}yl9#lp}nLnlu1*SZNoZ$({APJ$7~{hA9?#;8OQW$M)=fCDYYE8gb6RMvm|Rj>Ih z`b&2a%4x}xzW2f7D3*}zm>@$rE%3|Hqk;d$-g`zhvAuDlfHXmh1yH&LQK|(*YCuFp zML?u?LFq+WXh|pnDpCXimEL>rT|l}JkP=!5p+f?p2M9@SJm*->|6E<~hr8~l_e<8y zWY3 z0cYVAA!_teTK)EcmyD;w$S#c7AHBQLV)NU?=smXgoWAd->ZyO1M`aX@sp-tMk;%*=>Im37D-p`B}#toh>A^t^KbjP z;I~Fc>PKbf<8K51k@Rocrxo|!PU;=`vCxuKg*DHf?tSS>VnmG;^wea{{P^py1Kt-S z7L*#D7EFjA8Rm4>QIA!bY zWz*UAP-JR|2;(B2aOi|of-t6;nq3hjM zbxYUH>;0%0>xi(Vm{2Wda2!r-#zK$P3F)0M#vVunsexzG*9(D-q>Y5>71~RWpp@)q zXX9FyEq$sC;F<)2iW%Y16OMr|sZHnRX$M)#;grnUGGf)n&9*XCqbMSxY313CSl`Z)l|+Mx zxQC_i5eZ1+UgUbvEMfq>be3sKjjUAo0`>=mzethv$np!GG6yvEkIZc&PjE=nu z%fJCH?9r{Y%BN31F+ldbMz@SzN?Ca0T2}-gGFH9$LLY*0aT>Km(7eDlVP(w*_dGnt zdQ6T_9cIq9E~?4$)lUbC3gmZe4C!}>c!R1Mm4!jKS$!ufa19(2Y`UJk705HeO;-%P z##rDjX=!O@1F3)p1Q7gYantB*yO!yy*t}_ISFr9Jy!%_ zAo@&}t`8>R#qxDap0tCC%{M5rk~SI~_DZ(;qysepTW^bJW=sMBiNuig5s8M{J?h}} zb}VRm78xii=@5rhJ{D0qH6!pgfDx>{htA2e$E%w+CcS@88xB}1UTf+ps?NO%f@ypg zKEDMzJ5L~2025N##Zm+MU6YBk={6m-7b7dh%`CPSicMn^ZdD_L&3cs(wAj4~^Oku? zt%#kWi^1uxsc;eFYyA0AxCRnS?U+@;-I<7sN}_c9kONJ#u1KTSv%xZwKC`wa1^ag` zb+BMWnHO?7SWZ%gw0%)Wyrj!Bwp)Dz1O%*+uO5r%L9K}c*Cw5|HK2@$gZ3O`J>u|! z;X$lRYj`8E!j5XlpcM)A(%*F{nP;j99ka=XH6T}!@1UTXI>#u7&t!9{0OLt~l^H(h zqMM1y_sLMQ3tSP{vs(JHeB&P-N_qik%e@X#y?fw^tmJTHJUQk!87M7$j6($HI$ADS zH`RPToI%IXRqHh3CbzrpO#r%dDadKn5ir0FC#T^&&5EfuzquG+)~cDfIfR~GRzmu3 zL6gKbH+Eow40&L#8%0~MHdU_h`E1oClFdZ~@aWtM>2)|~OiS1@+0zFy z*>IOGqK|?(L_RZUllHrX`1FOUec=le(0i}6cqY}hrFJ+^u~XY$Xv$4v)T6nsH4-Ny zkRM0Pc50252p-^KeX)O^HCPe`7R@)_NLr<4^7`70R0bR>=vG^4khB{Qn@An{tAnz` zO{}Kbswk1~#eF%>b_j9YX&wWa1bqqJrhpld#P2vPYw3~QR=cq6h((s0w;kXJlWE~GvK7{Et}v?!iVd!g7&zJ{ zg)JS@6Hec-%U)c5IkQ*Tuy(K>hafcCS0BWPU*~d|$KgA&nwV#lW@lN8ww}-6rfyh2 z?Qm^OrX2si7Xa6rvt1<}_2~w4@g|8JeE?$W8g`=YxLOj6=wo7@2~ot*XM+z}IWgkk z7<-u~92&hB|7wR}^DwTIoatx&|B`yLmZ?$hPs@8n#dPan7+Hzd=P^G?_;IJne;i^7lgkVlatyePLHagnh0is^8p~Zfk%pcp)ZNUeF|h$y^970 z*2y99W=SCI>Ig^Ct75ZWE#yc@6RSIDx}h~_2US)J3)a%frwfUBmZu;vHIiRb0SXQF zK&}Ar`=Vy6<8G_mZML%C>_rfboD*WbG*$-ipyJ87AU>#9U&sV*5>zDH`T-#+Y&Tvm zS-%M4VMrp*=(I9Od=6=M9Ag!F&%;e9rU{04qfjmQHE&EGToW8h-hBpfV0?2~GwY#L z=-1Ivt5M4&T(Cr=gPsQ(A(z`ge5*`U+*`#|#yg--@_4K5#VPYJ&x|s9Y{!rZu-5Y7 z8q2u0=UOLdcBK(b`+E?3lh)KNP-4;I)2xvL^yRF;>y4m=1jZ3e^amNDC-j)I99D14 z?McjJ&NxJ7K^)lxuB<1`2!V@n>Wt!sWL-;;4)Y%7XbmT9Wvx2Ka^b$Ne~slF_FQ^s zf`H7ZAP1B7pWq1Q#N{?5i>P;VLiYn;2e1*>y4DKqD_ku>fN`!(n8kJtWjR5g?OFa{ z5^TscI_v=KdwP62vYY4*JFQ)hH{v;FLg-#bF2t2Z>r^>zh#AnxA{|?8jT7+oPoZ6_ z_E$f9JMJFh@H`^j6b<+5%%;LZ*eW_UB4{vdFy(C@suX z&a}6;*R}!NzT#TaV&qaurt=2|p?u9e>U@0roXw-3=~KS~N{2dUPhDW|8M7(IG&AH( zh1p>wS`*_9mv{r8^)#F36Kq{zK(%!03JSgVR?!8{V_UdsEZCHw52M5f^xq}W*;W)@UO2}PTf7-HFDiiA7Y^EJ*$cw>BZ7XWA>A!qlLG^NZb&=zQ-?n z-sc?sX)thVAHIHm_bm6DFq++_^|qqGEG~D~o49zFs<8^yv8)}Pg4z;1CNr*-yUkJ+?A^YQ?u2C?X=Oq0PJ5@ejy6l zj|0*Hp70cQYJaLnApo4*TYFi7OAR}fM8#dy?yTj9-p2-uE zMLh7VLZ9buB$hv|0IS`19sf+K^eCc4f=IziESMMq(UdrG6T+;zc{ z(q9;)?Qcp<9uUXsm~LL~#)Z!U*21Q|qs}R*zkB9)S3~}Is1;iL>TdRB$e{OwCtgoZ zq?OpBUm2mPC>4b6YI>bi_rlCi?*R~t@6Fam8%nF{(5oPBlb*i5hn@?vW!|W*xW)Z> zu`>JKJEOTuJo+dHuKb5-2Qf{X3==o&8pNeG1(70jbnbdPE1n|0rSKiXsC697zA8wT zar*%++k@E`L2R|tGqx?s@;mi15a3}6$Xj0)XnDA3B2-p2#g5_#9p3Xs^1;Rfu=v(@ zvuBORP(l3%69~-atFnp);|4F?rjubi&F>^#7AIa{3y2CL=fy554-7jt};b&SJqMI+_l(#<;$k0H>wN0T;jP?>47MbWKCgqZ zSRt!wIqx~zJcFu-d&aRM!NG%16ZVj5V9g6E9%*+N?Dul`4RG%EpergJ`SLIP+32bb zea75&`|(w{S=!yJb8~*rnh0f(oY_}8nGf)vZ#Yh!Xq2`7`gpL|bikZ;>al2|^&s8q zV}2^VZq4@k>vD$m3IPZ1b_io6YV*M*>ssy%mYwSA`6@_-hG>HsU3_*U{^1hJd);a; zmv^tyebuXOI?~o|$R%8NqOyQ#9Gw7^wP?b%B3k!XkONuJ0SE7nYTGLaRuO%>w2pcd zv?G6P>p_E*vB$2NCNv}2&=o0J2{r1V%e<7$@=i4Ad9JuCtAh1#uF{pR>lC!SzGQ#@ zsGQ^_ixj(e@sq^0zn{Mvs**!z?Fh@)KvqjVSM$?S~E zNO}r~Ll!TBZg;IDL3%6StwT}Tr;iIL$4m_fliH;9M%Dx~v7fl>7ld*=^b7R{rZPR5 zJitxdJLa2R72tK->U|#ROHdPHbL!=9lGalurm*$_DDpJkPDcnZPSy$IM~yPogQxH? zfDJc>L(mdchy4;^G(AgtH8+On=a?V|S;P5y*AHTn3g`O}2*M`HiO^G2e}-BfyitZ} zx4X^6Ch~NqpsIuADA;E{e-Pg&_C=@M>gGj;XZG`)0h`D^$fM z41jR%FA+7Y9;ML`6N{~MgTaX<2*kmlQ$rJBSqH4Y@03a&kyMSWnxPtRiT)r@Mo!86 z_fN7v#XN4_xH+Lj>c^tXvz&C=m(s_|OgI}DIV6c1+V6Jd>xk^0{81dk8G z22-7t`I;iHR$)TK~evL3;E%F5$6WGeHRk{)zdayE-OU0JHj}4=M>Lpc zfg&`j>c-w6*MAFIu%Rzm=UD*N;~$ID3HIAZcLf)^83QwjH5%++VD^6Ye5w;l97z9?CJ+0L1t5C4~{2$oUx# zBJt}ugg|NN%$Z?jn@!uI=F*7a)m{qGRBpd8Cy_fAnic#Wkys{N8NgGGp=UMFTz+?I(_{^JdM!x$}r`Y%|A z#HR~5KynJn-2~mO+q)PXnx`upk z@gKhbM&z5fDK?1EMP{v+@N?hQ9j!%{d`C0vLq&bRwveHNHxRw95ZbPa9c`QsH|Qbg zOw4@Xuv@$syDgm+q~$mr^f?#SInU_S%D4(&Ep^1WoQ<;4E^}ASgJ-`r_zW*G5r*<9 zK;5|RO{$H7jiI72jdgS-LSRi>CpY-eJ`)4P#+{)?eQ@nSl;;+#@@g3<*}H@@p|Ig z3#JE(*K&?=T5Uc?U-dChk25GM)*VjHAn^np$xyxJ@@z zO8qGwpPLyEh6f__*f(>^PpI-1ynqj!=mk74=g`j;%DBJSYJTyEXix1cp)`weh0FIN z9fc?A^)y3vGu1_2CtuP7Mp*eQ~=^ozPs7B{NBOb``wBq_c?f%X^{h!*+`? z(b`o?I>ZBY!gb&j#bCrk&F%LGuX>)Besv87_0J}Iz)x|$(qUg!Lvvy9reKFcdfK+j z?2(r)J!SB{)CCMrtDR7e>SoP8TA8%8wK7Z-w7N3YaQ}nEV1t2z9kp_ru863U^uA(_ zQ(}`-wQi`^<;SY;GGfDb6AXeZ(CmFS)=C!Oagy-^U!`3J5X?(YaTfIa|=` z^W7AYnCj74d9n*ExppUiFdgry(HfT!7Q0D1aU1axFIAg5LmsR?{tnw{dxE0fPRqtf zsf#olEc>Z_tw4A%y%l=G9=8dH&*3K5bp#4ygDJSXv1T>mbOF4z%|1yBH5Zm0z@hq{ zm7pzs>HaVIEQ1D{TU)DHB5$$g;ee91|zRWe=l z8fsC2bN86ZG#nzq{M$QQB>YVwq@Y(iw`F>5Hi<>1ZlN}Ab+&8pdSl^Z<{z^r^V6lE zAvj(dsr#b%L)PSZ75r8ws_Nnw_O*-f@^M(gc?Ut;e1};t?II0O>^tvwtJYGVEAzRm z?gO~Y?dz(5k^n;oItEZiBF}<9&&rt;ZXShoMNP?JxFD6vknJrEW?8x$ncilo34b+7^wV3s9=5ksPUV6h(c_Nwe-0hsf4#jr1E$lmaj68XkKBD?V6Xzr5eu)A6Rqi&f&VE;r<#oF0T?WjWn_L z$OnnA&YVcE8>_1-e0XQ)-ISio;_28IPlZG+-4N3(8}L}a{d?Gbe`)E-qdCNLDgg%`s#_rOFz{e?FBW{p%Bs0BUprGf)uclRak$V9tyA= z=BO-PTO{_3J!7!dh6D}gm5srzO(qz;D_YyG8$y|st`7~iG5|9! zEIQmtcc$||KQ{}fh~@q){s05Fr}C!D|1?i`d9?9tsi7CYiPwIwQ*aewfuD~WP(FP~ zl@!>MC1ujGj^q!IQJDvxt-FiFb?CB60}Ni2>nk2Io9Q*+7+_pY_GhN@Sb1gMh?>&(j^2A+bTtOa<>& zY^6MvyJLQWk5VHNM^+}8g)x1n=iRbTN^B-}QT!0QGRxjl(ib=eF23P$Jc)=i6<-lA zb6`U}wY}k9QgI)qOQ^KhZg|Kgoe#f*a(yhzgDs|rO-q$mV8&k8l9fMH*I8LknepeL zsx#_urMkCk=azHJaM}X)um_Rg=xx*&0m?L0IS2^~d3})`Gl+YCLNJAzz#^y}UH#x1 zg46k{uTwQ26`5GRMt=zJ2$&nPN&3Q^U&oV%=u*$D@YAdgxWO}J_Vc-4y|?Pc58zH* z^P@M{MyHS{(_6Cg{!_Gc&n}s~461l^Mk@UZ|J~yJ#DI8SDdk*6X0qkcl!RrCx6T7p zmce<@cyU;w$7apCo8HAlr$thrw+)$kK8T4SD@vBMe`~i>l>K;lX^im4;39L?H=bEn zOi!U2Jht3d-IJcu{Sag_ip#7d2la{RjqvZr__4U(Mb(evPh*W7Ah-z=AI1ot!=;Yh z&Q_+0QDA#D=R(D5Cq2<&!kK1#B?Dy#tt^n6erwRm;2o_qh&@zKZp9v~E1D{K`J&wz zV1==rjYe^B^R(5mk~a4mYCK#TScfcfH>kK1%yYtqAuV0{Frd^z<&c||ii*k|+Q38; zk~v>*eq#5}>{n`=Opd|1WcYbs)7J75|q5A|=Hx#m?%pv>CXT9{ZC6xui zYoe+3>73h_tAQOXeGg_{Y^1OwgB2rrIKKc5Qrc3-n!sa%RgB}yR!#&_CPZhp*xAww< zQQtwuJdDSzXQ7~+D^6l!%1ESGqZmddZ^(QBDqg=h;>@H9d+s>^R~#(Vc^T6M>{)a6 zi{dh<9INbg7^ebMI>K#3$GLc_Xo%0+Y3MeMZ;-8cN z9}zddhCnNhw+6qEX2-7G#(n)XX#Y7@v@)-#ZcLA}I1HH6 z={y*C!QSDxKg`rppmyN#k;#ctlCMQ#^7F?E6gtGH zHk6YzItXQDToo@LUDs)*3nhJfvk~NV5L-n+@*w5>Q%d~jPk;!6JYb{?&wG9&9(`Jz%8>9p1%b+2&el_BoX&|-uLj^KKmAkG7Y5AXsVu9lLM-3 ztcn^`w)9CY+GdhA`MAt=uEB~Mbh!L}La4`Gm-@TrkSFsirJIX(Q;7KmEF{ZN=oq_I zz=0Uq!siDQyHQE_N$^IGfgPdV6M2yluo_%xVQ6k3g*t0HQIRw3#!xqWYP~abTgGV_ zuuJu--(}Nh>cyc^oiJkOV6+AlyE<7u=8NSbo~neQ^+`n1oC}Z7=CY7V`9NZHYkZJbm9lcVkr?6r9=V#Cli;-2((r7`ZV>Fq@*MRVSOX*bGMQ2Q% zjNnj?=0xGa0iQdL3yT|e6}i)}9h87BG~x?3S@3eal=a%V+YZs#+KBJ9J-oW~Q6PsC z6Lgv0Ii!AnM3=*Br6!XSRbe|^USteb=nl_IuifDOq3Yz_N$yuy-&VKA+3zBG=B(4I z8*C!ZvEHHSa9_=S&-y(2k%X9bx$DhkeS@*$K;gta9n{hc+s;QFi9C&Ie_r-S0w>;# zqD~}Y#*o27kJimQDibPg2SpG#bNtB1ku9|29f`PpSG~vpWr=)hbaHmA-w7qimNZ}^ zbgTRNRfj_y;kZ!RqJy$)i8tICW(;w;Dcz}YyzlP7?L_*u!yUDz(xRH61yXG4vmEIw z$2~gvu9p|`^k`z`4QuW@5c+l+kIN}(U2-b}P7;)1=Gi5(>-{IedOKIDrTZex*xeuW zD0^3a9#=rfHRLPcz08U@RXe)bPUK5}nWx^LO(L??i!n%K_{x`ds{}M!h{|A#jdm+I zTBh4;-8j%C9rQ;uH+IuLjV0hfGs00{_5lQB73k9jV{EaJlA=+=lE0eQ?VkO`(DJ0i zCFxyE9S@ylM_ndl4?+|1;$Z66R|qp#A2OcyQCg`i6|uQ zKCz_L-C@FPqN>`G?Qpa~9I=yqsrYh=F)m`WHWYy zl8w*7OuUtDQa+MGvBGtr=3$!*%OA6(cd<3Mx9Gx7iSF;yI6Hl|?H6f$sAM8YY%gfq zf5iZBdnvn}#E&i*m}O+YnDZ^RJP>G7l2=qeBvlT`A2M1QrDjAs7B%ixnz$F!U-&FF zWvVFa<%(5l3i!O+#ZC|yZA^>~uxJ^LMRyTp9hqeIs)da=J-1iS4cbpsRtgqXk2)N- zN1NTko}*7+3hdj5f}P9U)_kg^+0@3-V_UE1o>~KSIdIEr1n7`UR=!eebSQZCOx@GtCWkgT6HOD)hdM<|6FgKL}&CvOPP0?#wW^vx~K=Z)Z2#O=RciON%f z{{&IH^mckzVG97FqI7;MqiuhF;(eP{_W5XRE5q4}4)J!3v!e0p=!zHE&Rx;OzOQN+ zm8Vzb0=6yiPKbFPbkAK5(tOUK(k{czwLws-+>z}ftgpJeJ*QtomS!x7fdgNchVU7Y z81K*%ds@bF`%$So-%pd7+Ft4S!iqR5KM~cNHck7J!FU@eP$O)N zxR1gmzHiS%-F;~s@&{C9DdoRK zM960Rd8Idvrp>GD^{OUr3@=%L?hsno-Bz_)Mm+9Qtjs?rDWw|D(}A*5?+|IKaoT({ z4-$5B60UAOYI@`K^h?5iqjl%yU$GUfMYy~ct*-^NKy%Cm{`|sstS=wUlC4*ivvV-s zWH&WRW4G~Uv0z~>I!32;hvIpw*y?Cy2c5Hl0X)%id|I=xbdtRyH(%3}(UANNRiQ+; z3ohy-)LHQi+#6=1+SOnlP1@LcLc-xtVJ{|V_uSrb=PQ2SvD~*bL^P?E|1O`D-eZ>U z!k8^Up&aj1VK2QaWFP^FoG-#px>uhq*1xf8D(t;o_Hidphb1VTYf)9gn2TE87-Ie= z!M$DShTRfx(q28VC=KMRqNp0mB{9Iq3z_skAdx?( zxA7;-bqlG(sH9eQWz)X&l$rXF^T7$d!T{%^<3yzMO?2s)%K}dMQ2dL{NWL`|4vKTb zjAW#@dHe)S-*iW(u3!9{f-@|?SZgxB^rME}JM%XVLM>PKX1!vod*kCdIlwDjHypmu z-*D~xbRu?M_1}YwqFN%4?6M55{b3Ghc_VK7Jxq`q4S~u&VPCT$94g&F%u^4PIp>o? zGeeAk`hbLMuEiuj@WLzar<&ha^Dkn5N;%F;=4>@NCiuhPkWmERPS&rm8EG^!AgXgS z|BEwtBMK;v`9&94#?0ROt`L8c>7S!yI(m}QY~fE*RQ_!nUIQu;hoL^qSO4esANORp zkQO3$y=$@m_%FGOAAkRKty7zvf_Kd8nWV_S$n>v9xy2*^E8w#!>H7ONrCKC*t4!1j zqyNrs|9PaJfRH>{I$e?vBiHZS*s+lOlK)Gd-z=)%|99kZ-hGOC``qwf-2AKlAZ09{ zQf<1Bt|XHHr7_}S9W?s(@$n(=Bln3=LGX0ZGDkHqnR z)UMz`$J!3PL&T*;XW z|1*ML#@s1I&PJ9K<3`i=r(WcTS(9n*4$BcaWq;AdKc4aTHNDH~Vq~{0Bl2asI8Xh) znU?CbJlTtBWi4qer|9pS=?O-#sgmD1cEJ{UohIn#tpDdoKKcZ$w=eTy_M^pwfFC&c zmkIvODZF`9o3uU_JNxs~|M~C7a%M+Tm@!4Pr15h;;wz$HWdAMQ{De-9@{nmv2TUu+ zBp5K#{Jx=p;4}p+fhIQ_K{_M1wS96N|p8%6971<6Xs6!Y{X`Yw_~)cR0Ja4rgn?)v_um z(8vB-QNL5Pr0gQOK-}$bEOIy8*Plz;eXZQ6Zga3qarf6$TMXUO#dEToTiDTEF6n}2 zy(`*v+QJlP^}HJYQjN*Eq>gd~EI-bE>#6jC>0%+g(taXrJ)4Be%*1mS^^A=Rm)FGq z1!vwF$v20~dhd=qu#t_;gKbe4&&#fi6xdfxI@Y79q#o5|rE0boqyj8G^=HG0T zZAT)nz{HufMiPzWS=iK}Om1B|IR+i@Q0rv zRwAJ=Ml&>#SH=CA%U?9kVKaRbF~m_u^UXf^T{wDaQTYm*r8)dUO6i$jOvViD(zEmU zHSGb66P`QkZxP9h@Hv--J3co6EzinE|rluY5cw^q>tCpgF zjkt@1IU_lhEB{*Eh$nvVI{E;fTHFKk6aP@?AAKTAae(LArZ@_Y&9a1||Mr>uULWoE ze|!}%@>e$cZj?MBQ5LL5THXxnaP+^d8in69&||$$<~{VE!ln--_;w)*%INkN0;i?& zFWmL?tU=2BS{xwHD@)OgS)T@adhK=_|Fd52Nka8{zvM5$lmAFbM@M&u07^e+c`%Y znPM4i^Lu3AD}ReZ@;2avvpL@{>i&QANvEk_3n%Xi#Vv`5V{)pG8UFLIpEq=$R~I`f zr4X?>S|aoZ7-5n9mj~0?@1j`o^XC5?@hXrfQ6})-_4msElO8;CS>2UZ$Sc5NP9^ox zAM~8MoFC_AQY_P(jGyM|zt7zI=5tt3bR9-1G5n!jvK@sacqk7)z~s;SRMGtMpXg`j zS4=~@47i57ts(t~c9-ft`H{UGNuj?xHm`f)4^+OUooq#R!8}i;?LWi+MKAf4(pQtw z!sWXA+9Ll%l{1t}KEiulSuB^mYqgN~}n z?p8P#d}{f_n0)0k>HCjd7=$wK{DI5;oassKT>qK$N#FecL74wK{lM?UOLlAh{8k^M z`0pc6WPUFwH&ZXmzx2Cc(RuF=gNraDxgpH{JZIdWWi$SP$u9^+C{Ld^lh*zdU5~Ml z+@n(?;ZAph68Uoj|E*O2HH&%X?>>#>r0%IdafdF+e-#A-f0~BxH^={F;05_k zfj>2~rtoaMMJab}wO*a)56qkGE6;e|R7*Zw>kmT1d!EXNiCN0mVy-6TPm&suEYH{+ zPC2jpCtdSR3QlalDY*Eru;_mX(=9@ZyrH#)Uj2c#(WE_-@A64%kiJy>`zijPb;Mf~ zITU5{Pj#p~6%`%bt{xcNNGcOg^EY_nM)FgtK21{HxBIdeUSKp4<38R`D#Zy;+E|vO zX(kwZnb#-T4dj>XNbfG0y6Y!(sK!5utFkNmC~h;leir{4?Y%S3uzRrdDkd(@HY>?F zRor?gxf9prq4AXvRf6AiI6t_eIdxDb^MfztS19)YSwmx`Pye17W6q~W5YBFMTk?i| zyNp4-YmGg;vQ@0eYe&X*JUxZW#exk5nH(6&S4mUUS91>|qu`@Q!|Pz&pcSo&Qn$L^ z4^5*V^NaXMi{5MUoN_#B*rSaq(MeQd(8Y6MD-Mt*wB0d zO3Qg6*;h|Jb+Ea2SrDg_nX3t-qkFeAiNf|tpOoA6MuEN@C;4GZ zeJg*D%_5Bi^X+8vI8T0~yL>dOZiQC^9J@qc`3z2tNj6j0udsSjU~r?1DQ( zIsi|Os)KwkJ}J1F&s+~L-wCG|V^0$4 zwFoE3{xT=Lag?sHdkx`ojl+|6?$ml(h;ozM3iYzL35 zRB+hE^ji;PuUhx7!hN1z2_svC^zwp7jEWR+GkN`l|BahWT1Ka@xx zTM(Y`DaF0E#3coK|*Sc@z)ZBDNnE$Q9<_6 zMn2Rp$UFb8$_P+H#qDnU4v(E;NBo<}FS8?({fI$}SgWG&C0A?QSgD)$I7IE8HviN= zAz{BETFxcWj~`ddwEod)chf%g-Bko_Jqz>;jdU+c6$ok@rE{0Juig zpfV_~dJzEq(B7b9O?r#Rh`94P$nV3!vLVi6#m~M}14yn$dQ!C2VQ3nfl^c zrq}ElSzsw>JLF1ljIfElO>y`0SK#?{875_(v6=^p+`UG{pD+5{gfB>Ac-7BiSbIO} z5@*A9kDA%Sa?h|U@xQa!1*kQmEg1-p967c#cnh5sMyZyOVfhDOqW; z4&QX0U~W*n7g9V>`Yd#1WPaV<{i|=|NWuN!fRTYWx*eMv4ZU^c}J;;9WAeKeKZA<>mz=SMV-B&|%0 z7}eRscdm_osJyhRH)NSs55v$Gg;jiTk=v@n6I5gM*7X=xj>`ykKq-N$s!5Uv8gns| z91#1BY)6o{yGzHA^s}NX!fZXoGO&P3jj70&CdJ`IIbvqr!`S^;0B$WhlWfKc3s1Av zL9o$z3>Rol@I$#JpA-`fsZi}++R3}Em#?qFv00;}d^G6FErwiseeo(yqr`LzCWXxQ zc`QH3hUZ}-5@1VrYsd)})`%VF8R-tgxV&4I&Z<|Ed}|EyPBmHeFAJ{0@bOv?^bwcV_F>%w_vYY1mSd5FyVucu z)k@6hG9kvtjvkJEDHnH8m!8th=!j^CFqOL?N;0BvH-+4raM;GbHY5(LetF-}KjrCI zD*PPQK!{m#tZS^=kudH2G&_lCO)gsJ0+@QV^LLYS?l7S0Fk7u?^q|@%q$f>UZEg~U$qZ9ltWM|TJ@8pB zlXYxkls8eLblQ5q(ted8+zRQXVE%BLWM|7qJ4OwZlzF1hkYCSF_ z4Vf!`-!)Wak2td?fe^m{Aa+Y5H*QyDk*Ve%6igIfuGOu{8aBlaWmnmMqVe4-1guvZXl^P5zvO8!BHMZx-I}Yxo>dJbalHW&cIqp+W zkm`wr9rPe-O=(VvL;KiQZSUP0hy)EeuXIa!$wq$vCyATmt2$Xj!+}?kqb!yLJcOJ-C zo2M6&hkeKXVh8WE?3q<#dKVjTLu0bI9@eVBA@uZ4D!BQXgx#d`r_V+JCL)GKQ(jPi z$f?kG5P|WUgq%gu8h_slAZGi+Ypo$uFs2ncVR=86&C@`E1vG_$pq1Dt(a&@YeV)C= zo&=SA7Vkz$%gY9(D#=Fp+bSmohCsQD*V3_4G1K}36|8yb&cyMgNsPy|HPI*&Q`FN3 zXm~)X1kS^BBon*}QZd0x^}=nFbg=@5IH)+s}xJ&vNec0i$F+Tt{-?tviRY;^^Q>IBD7 z(JXW}fk|$a=x|3c3v+JRdSnucUg?4EHb+e3Z$m+(w`{RM$Er3Id1{l!0k|KNYBhiu zn08#_7qRl0(rfJuWTkrYcRI#T=v#o6k3X{YZ%0y|B0;K>;p|25_A88PvUGosfmqmX zpo!#gQD$8Zzgp62R`{x0x|=)Dftqi;Og{7>PnpC!&Oa+91@DbJk`eM@5A9Zf!g!c1cK?q zgqscAjN=*>?NMuCo5|!_iUDq@@n#9bJdLM29~la>+Qa}4dX?8io{J~vN!;@cVZTY* zH2?ydeK#_ka0oXl3QDU5Is=Oq_CK|G^MGeKm^*5vyUc^)iPDokJtS$0F*2 zJ}#!M9edrT#JX0uSG~`f7;?&{#J%vXs~Ba(f&Qd4u_9E|Q1l&;|6zrco6Xo;WzIE@ zjJX11j+1il*PzJUVH7CfBYVG=D{S@o+Q-up&tE$lYATlWY1OAv16ZggUt{O?FfNWS zn&b8R=4dTbpAJQ2-4PUjl6O^yVJ|m!?P9o2Ol@8K@Muw;w_6q#xoTjLFkVrhHyDHz zP?Nz0sXEIVJ$6-1m|0tgB@k??jiw7d;YvlkFZ&c^VLi)3QMf>q%`M<{!1m|+;KaiD zv|6sUqUaIfxc#6e$t||Jt?Na_XZHwM=sF2QcIuQN=?i;4e5iwAqY-GMSUap^qgwi- zLG6?vSH4kPj7WdwyW;3W93-xH%tPf9XpS0mc3eX-gw!^TU!A@{PFW%$0#$j zLM}F2ytNc>L>*`|C8ur6E)-IM8e#bpOLCa&MhPPaQ>G+VeFMU@_Y|niQY($XLM*^+ zT;&`1>yd7Fw%y&!$H15R)0?W`;Y(HpA0>7gmbPWnO{)vfgQ)KbbjdhS4PiiYo^6WIO)CgQ?U&f}N+A^06|U}_@R|7l!|$XbL{EJ;Gu(awkh2!hlJ9j`k0t#shO&{eZ-S98U%ZK(BFUbgp$3R? zKH8Y}UC0?g-T?AfvgZuF*L_5G8@Qf#d~>`gVV0xm^{PmI$DtB?U+NXI84fkWv^(dN z6ls>jAS?`uI}k+m=Tvg;UcmBax!px+?wwZ)fDbjFu;uDUOgy_U0hJ5azG!Jg%zHcB zOq;=-SvfI89An^1oeuPpTPobP3ixtL!Xhf@=A!|p`!=1nXRMjuRY=q^+2p|kF3)q|{G@(R~dV5%%wZE^Zj3)uxLuN%D)ep#^mK8QemQ*vZ zQ)C(%<}USQFZ(q56_qF6?Am;gb$ovMus_0vj@4=}COI1x%q~KF4voSE@M_}43%J!v zUbE-B6(Bt3_eXM{nkm}2O4fkUUgvVGvWt0qwwwXm>cww@8os&_79p}WHtB=R=B?B` zm;m?YYmTA#OYh6+p>p%dwtBG2wP~GVHHF|aWo&`u%;L4wNof{_O>{$~YIAIW^FEd3 zsb%s02?mqQ)a3qRHQEIQ{`t%ILG1#{8Ei`JpzabBf}hNAj%k z9}radcXwLLmqFq$8s!#105LV!53fY7a8LroD2K5Q^$h_YEsw z%kqQi*J84k>O}S$y;oPUbR3mNM}X@eE?XPed>+A8d&Mu+UDn^ma=4HK;ODiD|9z1VGPdgSC z9%bldImHl?DZlCL;4s(wt4_l=1q9i5%5a^hNAQ-@-Ct7n&->==Y3{d_!e1rnJ+bhLdy!Ii?!qo zN+)TUUyGis*KXaBFr0n0cBrbX(K^ky7`on(d?#*3;pnhJgSh`$*P$q-*_W|d*+7LW zpQ9+)VAV*#lU3!dq2!bAHrCb%RvO0dlCx7p*$-(K1p8BD1Qa5@=bd#o+g?wv1|+gX zRBz;Ng-`Ku;(cRNuyV2Sw&zEB4=N>vS}P5QGc4lo zjZy3ysm?z9v{V6dv{aU`4wKYWj zlVQO@FZMq%7_b&y@RI#JVeASPI2`iLHKb_^VGoM7y;yzSuz}|_+kE`d?u@m%`!Mf~ zRNJ|go+l9F5K)7#whXwmDRF@n;dFeP0GA;n^E{V^Mp`4qSl6YT$)*)j6+Lv%*u1;V zDS_TNR$}k%8*`cYbg&YEntI}~DG`00nno1l5V77ycx3@$V?i_;^P>(RICyxA{P>4f z8rGxW+t@rqj%EaW>2S$aAPjd77V=p3WC$A`Bt84?Wb0UoTof|yX?*{NwQf^pDAQU> zhWvf?8IXhx2yT~x+5VdEZ@=-q_99x@mzy_w(NIJ4Z$|3AkWAgwGfDg`IGQZom}dTk zriQ^k1tR5Ug$mYIx#NuZ8mUAR?Kn_hlJq#BfIW4VZ(r;D?S88>`ElKr43KnXYrc>D z`pp@elb3Ui&(oD>A9Dw0cGxDvaO{NT%skO`S#Ia^uR7fLZTn5rxv%jt2+wkSd?-7> zbTrLgfcAK=Qi`X7Mw(-Od)hRJp(qoX{8%jhLHVWRt1A^iP&msxtNN_{#)&yC$uA6D z=|PBOE1A6v+>z@xLV{geo#&+vDCcX#EPM6lIEYV-&a+cr9O=K&EXN@sa|In5nUtsS zh&*jZsX0NnE3(2)tW(#gVaayq%2=)a2k80Z2}$|Z!?H^Z>D0zM{+Dv%y%(4fxO+X> z9bx|uU+*2yX8ZP!t5P~>ZM93)YAK~^bK7cDd$ed#MQyQCdf&CF-C9w*R;(I9LhU`G zQi7-zGeHnR_@?*We#Z0se$StIUAbQ8d7a}J@8f+O$GfwbC&JzeT{CvRcEYDRFI~(> zGFOM$2zF|2v9>L2Q}>$WY!LRZ5h3-^j`|=ip}xJc&9wI}Mx%{+Yc}0ipp;n9!+KyK zG3^W9uG*s&ZMtpWkqB&Ahztr6Y6>PYp_y-rira-6i^B@tR6v@P{NFCBk;<)UcLx~x zo^<$1Q~?i!P3}Kdm%ejt-|{=wkeJIG(|7^=?QQ)-<;bywM4 zeHkd4TW{U(pEiqMkrv=+O=2AG|Lnhj?&Xrct=F30)2Dm4IjIZHHc&3lpZSz-r!a4(npPuK(YgsqCUpK>z4qT+a=E}6a zPItHPUC+~_a)x7O&U6jJ!^tQxy~uaNqmghRvZ*~chCUu_X)Sq!;qH@}FYuWI(K3^k zbbA}eWz@-zk794syZFaJ)7%z9>sH`CMQM+jtzJ0dp%r8yKZ1v!X~q6>P>~?)ajRPs zFG5xOL<}GNd_R`SHx?s89VE0<_Q^XU|5Q-ra#iJmUj@3sUFUjokCoVml3Y)f@c?ga zb+j=Es4&w@Eu3EO(TX>&0j}5?o(YgnTi#~8=xcWOg#_~q(;)<^X##5f7AwI|nV4=G z!lK>?8uQKGv`3X(i72gihx5K5lZGhG1?IJzRwTzPnTbImepiBF-7_Un;M)cJU6?>k zI=D}sX6|OHIVyJ{xa(z<=x-j5Dd&ZtH>Np0!%2VR?WQUhr1CxssJwq|6%Tx=j5s=j zFg#l0+?)D-J=AeP#$K`ctIo?*!mLz9S-_t`7hic@4)F`925t$4hz{zf-Z(X6gRv(G0R@H)DIC5t}CtuM{xaxzH7exOFwg8tt4()gHNo$Xmd zvd-9v`rxbSvL%_ZtlJjgp!j4kCnYtw)wggC-*+`^O>pJfxGIhR#(I9PltSW$m4jIF zQ+u{4T?Bz1-+cUaMd3R%w8S0N4EM*(y35&|-JpDFZ28br;YOVB;6Wb5rJ3NNCCPO2 z63y4Jo--inR;o3c%=p%xvPo6gFIJ`AmNA<))`va3C&Em2xeD*XBW%`YEG0I5l7WJ8 z2hIR5nL6{QCm;szKIvtg^O%$U5`u|dYh8rzR{hnkF(|OvQhEf9h3W4fCr*8-f0KCl z87ogY%Pe}9AIS6-bs>n)ve$M7A9+}WyFsJz(oR^%I-oB6T}N>L3d%UnT1Ii-Fj13o z1LFG<4aK%}aU@7E9X!kWb@|?hg?~R6cz+gDt@+E4)q4A;=eaqUTmib(a}7AouNjIh zFgVSXY90S9fWL~RH7Jw?jaWTRR3v6{HwYyiTtARyqeY+f+P#jpGXSlUSYApUCoR4*^*1@^Yc_0q$#4_5vDiTHW}`nY$;=-EI9ckucedoY)Zd642aOg zT3mlOCo^&2bUBEd;y^GA?DeTck_PS7kzYMYTXi+@)KJHH}=hO z&eUllBs}>bc^HmR!thtQyHXshRI{6IQQ)4>aQPFQa?Ye&VWHR3m(~OUmz~YAs^w=b^o zop)^g)-9hcsH%3X(Yofa=kW0-*smpLfRwyH&}^aPW>bSMD=fTA$P#z{1S(lFd#%|y zGzm6u+zARmYokxjH0^f?m%gT@$QvyOeYZG1$eYuQJRA4R!6a*kec=T~*M{UyI%;&( zs>P6x4OkZNXzhH|a*~U#N+~0jQ+-H&eUAOB@$~)6QK)>6Rf~qx%7-#tep{4!f72QJ zl+u`^0STI93iS+whWHJ2Px#G>2jupA)Jd+2^mzSY9oljb3Uk?&FyXNU^$UT9b`@^G zyjB2_^(-cA+TWS}3Fkf0AcZN@WWI3-{_~sa>RQ4WRH23BM$GkRX_2YXM0i4R;hvIH zW1=X?A#d!RtBDu@<}3frn`A~`k8G=U?K-kV#BP3kue$%pQBT_Up^6a?e-fD%vG1W- zg$?^FQA{11l^?oM$M@XJTx*Ah#yOv20&8$QdHt>5)cRXuda8@HddHiBmViC@IFM}; z%m6iA++GS|;p7zwdGHql+i}@XXgkus&ig<%YXRc`+UbzwehmnkbOAk*eq^sR!$qM4 zf&4J3f}XzO-j90Hoj#leA?xet9O<%pm;|7)Y3COtrIm*%xJ<8kAMl-Z_!|?mwZnAY zbET42KOJnta5s0Xu9fMjiJ@_ur_Mmi`!QM_OChF{^Fu$DW-j;migu}5CBhcFsIuwP z>k7Ncq36Ye_bmI7k7X(fTXU+g`A#b5a~LYP zy56XLHG@wNFu}-bd}CQp`dVqw{g+LTZChZZqY#<@a_e`9*!cEqo~y1g{_QV*1-wc0 zKXzNsH=y$~(Q`uwTy45bLIjVHt0jUa-Flh+uswDJ31@i^uYIkC5^_)o)49x=qN6g=mb2Mdmrt**cpedM!&a-gR+}*yt6iSw54K%`JgL!r7K&>yL8ZeLZL$czEkRpq1?tt*}(L{ z0D7=SX4_x`|ylO*?32_=)6V~*-lio7t;JIXmWcx#lrKW z6Nek1G3lR$KDM4CMkSox@N@(3QI>|>P_Vtn+qw+R95}z&w z(&#a#&TDeh=@u_Hn?!b2te?%^fh*>0vYnf^+?u)qj<@Kv|4hF<)3Dze=NfeOwW#Q! zypZ7mDeiNYa{q4Y&*K2b3%m6>Wd7VkCRNy7WYRxVoMPyDXB~4Yx?sAiCY|1+`5u4zw>;kAGI+^v?wCM9Y40#MPZs1 zSz}D{&FCNKKH@)l#|%AF{A zMl`Lf)RqznpZ)r&{2i@qRbMd`=zA}W_Fd-q+*Hj#ofyn97LT_uazLyBV!ni^qg|=f z8IJdNvOYd^%%$ufwSMU7FwjT`zIJT zjyWe`8Qc)Plb~s-Kg(_@nHg2%axSM3tv3jtp229U_pBv%9b-jGKV6Cd&Yh2x{n;NLQfopx1?>s+Mdfrt)WWF^!xmW5 zHMs%fJeW-C1bG0vEd6S@M3vr=pu44my8*o~$KImv2Sh?PnD4!{ZC9p|xnlRZ=Fqch z{BcJ)-<&s%%^!<^s@yts=xR#qONE2Q=KWT>XM6x(>;BxS`xfBDk83INiD8Y^c-a2%$xQ2yG$d&~`lB>5&O3C=FCM7?;q)NISq>C@&8n=N3s5p-_z!p5sPNPPg}SOd>l-DMjb`!$;eVwa{W zaFd_@l#%tFyjgqEB-Z#A3G*F3DuJQ+0yB&vWCpMLLXImcxm$P{P!Y%D06AKa7m zH32lTdlGy@Som?r2z=!k1}d&0({xC{8ipon#0L2b8zhnU?&`=U$jw8Sh7G2gxhG)( ztc+oc&C~XJ&>Qi3YH!L_9 zg$5Uaoh{F9uCx7VUTKMD$S(_D{?>@XC9Xkq_9|Ptv9DF~)MAslM6_FjNUvePxgk!D zH6zQeG*n*N5)nP~-jN8Il4&_~v#+7Dtu@QJI+wa8s^e30lICaO4H5eq1C3CT4=Y_AYe6#Tz6y1d3GLr zb`OQr3>Q;yV3KMGJNWv*W@k;g*Olg@FM+ZInKIh8&K~&oR&)O5W)+bgtk`Q8;`b{0 z!h0uMn7yK39@e&~r7dkMki?#KUHY_9#>x|{xrKkZN8%#?#me&^l-zoG3c7`&J$zpUayS$a|Tz@3G4r+XQBL9mc+y03`kdQI*KNWuRpW< zFS(+Na|TPk2bB;Z83bhSX?ez zjkbOJ#k-UuI{%Az8{~_7*O*xIyky(#9C2`6SJ_3 zuh}!c9%W*?1Y#?8VETsd5gBcauKGc$b4d9nU%jJxX?Ctd)zK9k0)FKro zoJ*e!78k!kjD`31wx;`{zXS#RjK0C%DrF|BwW*A7c_n|wo4WE_lH^i~4>Y8f^G6Wf z8pK#EB0oO(n~hk8{zIpQnyK!C3YkfM%dmb~S}A5A{@q{*-{**D!dNnTjny(a*xi5lR6jggo%KsfLd8M+bN z@_pceZw|Bt>O<^SWNmxBTU%|eJ9PaynMDWsm#9I><`^iLHb7wEq{=JQxVID>8@KX} zhlwoZg-cD2+tTx`PC3CueVI_2w#+suIfgFO3;W z{_U7U`o1@+Q!$vZVss{mtiMYHewX;@NGLmi2C49l=vImRlX)a)`*iMDFYFc+@wibK z`scfVu^S@RwihQcry=ENwh=$7GBy>4n`Y{5I+Gus3`$LWPEs&4>Wm0__-d|U4&OD# ziC-6noIH_{pZrkJvqHL9JZwRqy_PN&+ua|3YLJhN`;r@>%`WX(L&N?s*o5XJNsF(X zZAZFE4&fK+<|yp}ji6m|b%}e@s48WENDR8-x+X};Jb7b^w3em~fMYieRr~b^9^QnPVEbGNNXVbQX1&$gE0{hO1oMIrCp%<}A_xeP3)9v9nN9-7Zc zKvwsqo#E+~9@Gu*Myj6afE6f}d@DU?mk$x&w?`EQ*xT=If6xg!H^jmUAxuC6#1}=r zg;L$GV9LfQe$^(L5XI}oLi-!m`h^s2MzYAhOGBy8QnGMvtlBC;bx$E9NG5PAdXX7-?-yZ&p&#!!wlrfe{7xTYT z3;GztaT>IB>7w7o2l(-3X9ARe?0@jU#hTW<8$|e#WWP0-%QkihP5Jwa44Hmr2>w+! zB>u|>`1OU?9O?p}4qh^(Mo+9R8oXUF=9AJT*8s4scc(2l@w_&P@ zt{+;rvFvmIH!lBz1W`RNc2N1f2*2|kBp&CvF1>sBYHau86QP%H|20$;nfBO&Wi>;Z z|M|kNP5k-3RxXLXyKGtef9Am4APs!eo454R@6Y=$a{fQlyG?4{skL`^n*RUzk5d$B zuxm1OrvFiF^1ru_G^Jz#WwP6V^jDYv*OPxwTjD2Y{arRSsVmk0|8V^bBsPxx{O`@h7}>gNxOt1IypR*k6C*c|fseN<*pgpT&Kg%HBk9!JS2`Nv`>HdL`1tYWVnI z!(wn%uhKkGRO9~bqRChPoy4#8SvfZ`Y>e`DQQv<&;qkgasgxT^;It+k`m15D9*3x| zSk#5JK^hk7Mz>oZMBbnfie!)d?-Tm*_CoNRKW&w%|8$yY{v`VA?2%SZ|LNCAxH~3- ze?C8rJ-4i6^JCHgsTOz;0_g-rq94Mrq#L5Qg8BYG@~o9(D6U-O>FBw6RpkA`zdxQw zm7aUU7EREA z@AUnDJy8COLh|&<{jDb;M~G#k=(b3GTWv)J2hYXhgIZ^Mwk3R}?E9;QcfIfa>t_6Y z-JQ~v^`H4MQhYkme38TU?`y+zLocwZT@9j>l};7(QEl^m6|wGrB!7g*TxH}WkLA(o zR-Y#SHIGzF9^fcfaOnO?7=dKEBWv0q8GyO6`h_8x*jMAp&(GdRUXvf$_*Q9~MhkM( zD`+QCuVjIc>@%n`G}DRw!J^3Roy^eya+iwVN#JRA zJYs8jl{1_UP*jHOA6X!r)1Iq9Vla4d6N2#T)A3|l*$+zJkqQ`p&K_%|y72yy{!mp@ zI|-)vV&Hs_TH1G-!1vYlPObUV_^Tn5sO~F4PtyLC@u1r_Nc)`32|M3*xMl)|+`=~? zvk9@4fV!Tk(NKgy%ML-mK@j;XmnnRJ=f=F*A9vmlyoQwW{j+vys>%v-W))Uw5$i_( zd!$T^XDg+FOrjIT6RVZNFYe0<$>E7tvANBtx3dzOTt704To zqy99ZZv|YxW$aDLDbMe(fGs$2d%uINqvLL8v!2er0a*i(_$Y~C=?;9wk{cRhaF~-u zWu;BKQ5BiH8xXolyKfB)>bwO$=!0K6k#(W2pzG9^Uq1L8!=$w;)q!sFwozfjY$W?c zBCV@5or0w)ro7q`b+x+*AtisN#s7wh-d+7uK{;gqtyi_gsjrd3e@Ja(fwAHz4_eM* zd`ucIHju*d;*<$q&F1@B&wt=@bZi^qe~H15!tYHA9eghceeJmVAFuz1K>AzGm1dKx zU*t){v6f2xI=xPx+Y@qHZ1f`{u5jig4|pJ<1%Dv5rUpDd1pGX8LYg|Y1B#8~zMP=s zsS-E){=NRyZ9(Vu;$drd1m-mE(U7|+OjlhId|biY6e7rU52Ak{14rK*&p)NEt#rwy z2%UP8F<|HGA!3}oVrj)0F{&mB(s14E3bsdkAgbne=SBU(c0$3}HB)AHJ5UZIwnzAw zFb{PsS@)FvSJ5x6#y9NbkCpmZPlV@ow*ILS75<8`>AZ%;{oBTYIvb7iFmWg>0IB-p zM=ow9WxLcPG7=nXaM!;1@Mk|47n!mLMw9H?T2XN~=#!P5)Gj6YNcOYdzodJAr04KE z!)X;7`mtr+DqzYspzUC4R<78IKn0q9pMpg0M!?LA@|yKN z)kEzhkxz~EIiN)OGhN6@crSd&68tcNMipTv7mxDB`L10EE>;MbyG1jgU4l&GCN9?2 zFT^*(`?8ye*7ob6!g(Ou*XltB2L#tnnkhY?-1$Q~ON&4uIbB%Yj{kXJQBwnCdJQpx8${DoKm0DhKH?lpxaSp^4=;U3ae$z0f zcXiVVs~}LwfLvaPDxAVA9tF;yecnHArHt?D-=wt{*lt~#YF0QTaoMFjWD<(~zG-p; zAKLoB6}rDZFi^O&-86U9b0sPJ#2nUA78rV@5?s_toB5%*b;mepVZ7gUBUX&1mjUr4 z8_5uW66Xw<4DTk)ephJ}7}w@RPx+X%!5+W73H6O`y|UZpHT2`8D98UhWX{7XU7c#%7O#+w2|kKu z1jOYp$yR-9YM}k@+_>1{*yd*qPE6;#3!peOW)u?L(DPIvExgjHQ^9s5t*xB9_zTk?ZKy8W31&ylFG$~y&%K5kX9C zb+I_%;`o^tr{7OQ+k(g64ZfPJ=OL#nfKuT zI89(r1LqXb&Xx3X@Rs9_6W-WAs&D@8C_icbbpBM@TluNoRb}6vw&RY8 z=UCtvjx)~(-IjDlR1y=B{bMlau1!&RJqlaLoR zp%i`}JI_UT&BgA}EX(L3-PZAFY}G5*x;=)1rNbY+xk6#QrT!bykt{iQQm4MqIAUt= zI1z(y;)8}@w`bQ+zwUor?}b5H>73$5qv$wl^nJ+W57c11_IVSuS@-ycPY!d?L-5Hx5+Xs~{C0|H%Y&mD!i zoiAm;>{qR#P;k1jXtE!Tu%MtAY;x`V_@yhqI$A!>qoh#2WHot4{j=eray;c?0(Px5 zdIZU8d*gWsbd%6dJaj4T;vCx^Ux0E%g^+u zy>Xn^nFC}am;T&t6b>oCd3w{*s`onWXW51jXu5O0v~1Vg8pVHdyRHp7->T`xHJK=p zvl|^w`=IOR9$GVwE&+$bi<+{I^ObDuTO0ME41}hF>$=vS;>FZsy8S1CdmlfmYd)h; zao8USfck4VD&_8r-uFtp?7Cm77n@eqdU&`WrYO*Pl**9k@~VkYN*9mby)C;2{Gch2 zW+LGZ>DK_5cAB}Kgh-#c$++ORaBz5i#tWvL_;DFF&S>Y=g^n^|G4%M8fLWZ2Rlpo8 zpjHoR*CAeO6MTH{jH(f3<=eU$ucq5LwZtvJS$tQnTWiGd(?_j<) z7HuCQq;Rl*)iovl;av?T_m%@@S0j%)Qi5zUrvE}Nwf7uIlcy3k4fg?{}vG23)pp_4eQeS{D@^q?%@n}t@CiZA)_jTPWQx5F|l~X zD9B5($B&6mYH=oLXS^f^CoAZfg_ z8jc%rC`YAJLeVU(@Nn%=5)}L*2J2%EP z^o)Q4TE``SNSFJO|Ms3NFmn*(t?3>2CW@Z(!#Tn}+eG)WaTSBfMRkF3CE|{BH+AA# zHRMOb$&CI3Q;#}{L~+UiPam{9#cc<+9M6#5I#!sJ;ylOmXDjKvtOplQ} zax|jwfS%9ctcu;Ig#)&_eVxW{%DeYe=dkvr)V#FVJVi>yz5@0b_EbmOfj}e6t^8O6BPgB zsS~sTmhm=e7(TJxf*9#GRXN`;KozpK9klZqtbVShb@@23kt9EC7WXEGp0i#&qV%qp zt-);QA2TumJiR$YFQVE`{=P6mgnLOgmYy$n#Pv$Ot}erbb}v_^T#NwA1&9SYU5@*% z#)VhV+eeIp4uAGyz1yp=g>?Zq;rnU)5j946F{{4Ww5Wy4P2PyB$ODU0-a{ z9~cl##h;rIWVsxV+mL&vfxy<|hD8q|D?cvB9YP*C7_2XeZ9Ks-HP2_^>B5oJXQ$r? zATe^Em0)ptXV5HEsZS;Hb*#__2$k}sfx6S7TrNIp285c70}s>y=6&dFWtO<4AV`He zm!d*C5ZP-3>QyMdLNcg5)ZT1dbKz$e}Yn}~6UX0HG zjkB1#iN6kgbuGEQ;z{9ia`u|hwWkV)eHYnU5?gAs9_yC)U{wtmV;vYf5u^|Rt+gD2p`)F>gG;jn)$pOvPo7WSl*m8Wl5CET@0s>BdIDnWD9<#clpn!Tv zb#KHKBi*+^ZSFgH;!9uv29}F0A zkLu;je>g4)0qOdtc5j%)S``; z(W|cKGiiNkUR!i0ES~D``HDHVK8I{XU7WdejW^GCqa?$BAw#9nTgfY-SMc4DsQme3 zknJ7PVh3m`ULTwlGuac&V!B7?lJL}^h2yRlCe5V2TdP2Vx~3KMMFN5EoPJcC97kW^ zs;_uf-N4O_K=upN1Hs#unCXA@#x^s|3q2fVn*BKZx4}T#b`jwl0qxQPHW(;~wbC#h zlXD`D0?7O|Nf)^_=iLZs)+4ay6rEt_r0!|yD(nxXx~^DXJY)?x(x9?UT~m`^-KnB& z^5?!$pqhzIaBtMd)vg)FxX+|f>!=y8362w(0z|-CmU05{dnpRAbOu??-e)cJCL>+8 zQ@eG9H9cgd!!#MS{Bf60e4AQ(MWej9IK5zTR`lNK)dyxx7wdP!738CNG<7?_nM5nw zS~{?OS~b43?l2vfkui)gsbW{@eAF0pB{_AoJ1SnH)Kb(f?DSQbQdPWQQeCl(84H{~ zjUQu*-JXdVr+6MM^lpIuB=+>Wk;8Gp1AQ4th}*~BCSO>{l(stUdob|FWQfh%3`=y1 z-3`9hfrMlK-icG&Q{%=%cIr`o&~)f@fq^{If>EX1zd&|?DPa_jS072k0L%yQgT3>` z4l!2o3#(pL51 zYqOrBVygh;-~`B3Jrfa4%0q{A*^bjuL`!&VmCjz6JQ0YSd6gnrF&;1PSEwB-3_X|rBuj1#+`L}pOL)@A+#F_QW|hFQ)DySiw@sap$~l@ul}~^~ zwO%&LPw}_mZWxAR)T>fz?*=Xn|HKwzGQ_Q3y3q0*n(@A74S@9;c&Zf6AJzz?MBbJv zglhO8M@IcTMKAuCZiVIM!XCA`P3pID!~G7-c>7F)@cYD@u;7NZC3)e^xsbE{!)AAs z^Aaw`r zVRs+f6iy-o@C@7(;I_T(lK5HI0Rp-z+AP~Gn6nmwR1{F3=QkkG!v_V+?G}a`TSmrd zq%FXGDR6{94?)4Tzcfj!y;XRiC)5V4nxXpufvMwrN(Wz5i`ZvXpo4368&F(y2rAW5 zZquZt?eg^xO``)0H2RxJ`JqI0?LNY#;=fx@`*hv04gb1l6)!Z)Yp&+WPpU8(54t#-UJIh2@Ap#@$eHY@WcF|jQD`-#K3|1vey!a@@C~e`cW`aao&1- zQ?4rMeiVIyRuFroSw-qO$x`s{a%vvp`@N<-lm)PDwB_P1q=-H0emcZfqlvut0AmydgtS(&0bp*ckY$RCF?x9<8cVKBM0PtTIqUoH}Vbe=#5TT6)h^&tf`>GPkE@=x>)HZ>y`A3vr) zKCB-RsF5$;kXcG~^mbU|^I1f*z zg0sGEr93)gA`Zy_u4JsRP41r9e*Hay?fD-poWr#UJ&Sw!->mL?Bn0FHt44H$m zH6}42bD!LgCAl9nhwb&nmT@BV(qcoLvp?}julZ0pf#rEfq$|*@%PGeXk{o=!UnTuR zaS6xtZuckm~fI1rT2AYjDL*6x_L_3^;twgiwp4j`MNC zv`*dL3UzN0o=-eAfgKHlCQ=9-3G{r){v*wq4lhXvrahRI)ZFF=q!Xd71lx&W8X2w^ zP6*Az-$cM6o3sXAjvZU(_F~Y+;{g)9@WWK0ZS<&^+}dK*9`(@v!>@d@Z!4Gifz3~g2bdb(}29~ zH&ouUd$cGi;7;ooPmfpBf%@l5Sm^X&HE+L9ocx;G42U`9=V`9$U(2IKHre6l9lu_o z+|7*7aAwp-Uh&)cN;ELl(k%dM>pmw>XS0`Vl= zV$JJZJf>WUkDOg@b4(z33lho)`X(hkpF%QoorAM^cc)sogsZY>E6Y0X{91Iir`lwN z*Fq}twf~T#=zR9eAiT(T-^Gy7s6Nnduf+Nx=dd=T%^z9wAx20x3OkUqNVSqgy;+Gk zOITQw6nV?)b<(h>Dw6hIBRPcV2ckPX&LCa+8 zNLe6PN8+XjwDCiX$RT$_fi%1LQ*NmsQv~!525JH(2wYmcIOy6L#HPmx68FMiUhgky zDMmEkN`%OqKQ1|VlrI?JA+Bzj>fV$1SUi3@({zz7=XCa}kny)JQx&=`7xS;r@i~oR z$pyV9bg8dc$fEI8&7@SaVX@FE&6F%`V0Dt_^Nh<#Mz~$KztLjL(r4$r-DU65w+4j| z^c5k2^BAC4Tk2*{Y1-PKiS#O23b-%~#M9UdaYDjw)AWZqe<-9q1~-Y%;dfHHkt86k z4&GoL?`HW$39UAGsjYQw^k9B)b&xov9C(OU6~H{ar5Ci=?C`DJvsKQ$@qqc>_DpNy z5%hfcIf6M>U-od!ch-nX64o{`Y7asj*xr^QFlbnaIKbLw=2xABkszM&w zo=nz>6)M>WILoedb!N!49#tK~zXaT^n)ERf0^WOme$vYYosUR=+HCwjJug1YKOfRHMDLKbNs^w1%gru?OQ80B-z z+>_7{+B;kIol^jhBRW7PCQr#aaMM`4#}bpcyyuX!%XsCEv`lrYt2L zLeqe7N&pAiBiq2sqi62Nc5!U*pJsF$grpJ}C?{CK1VGLV^lCZ32vFl>!|Q zDN<|a;=(HpEnK2|{aw#OSGGnAqX8SAG5qoa*;nYEM)8;%@RP?QP?>rOc2l?arqq=4 z?~+g;XF`2o9PV%MWoBU{n0r`zNLojetJYvpc9&Pf?{sy-jlFk22b?orJMxSQlZF|- zkV+jm?~PUkq>g;&V4VK+JST8>jbZd*1h;r{N$?Ke)cU9l-R42bJ~{|H8g|?=LQ-@G zfEG-vJKc@gBo+9JAz|``lE%w+>aQ0`2)L*}OS3AiLiHEo$#M2sD@>Iulpao|@i7&~ zkSOzNdOS?LXxw2BbJQ?^V%aeTWFUt|g(8=eY{5ex zt#v(Ffb44Rf_p`&()_+5E2QQte~W1gK1!=#UaJ%8slJQ;hX0r*?U`aXaJz}$0}B{0 zhZj5`0?&88){o}Op-1M7x>M!HJEX@}hO#Syb#mVc(F-bNUA+1?5;V7GYC-qfB2|u` z52QS+u7v&q=+^9&d{mNMy=D7Z&O=GDo6(Frtf_jfG>$f#bk^<#G`OeAX`{5^KJOQc zk=%Wp(w*$^`F+!jCWeO^NorMb)DgO)e2*7Pn!9qA#hp+8%CLjC2Bs+_j?;`^=FC|h z?>O~Tg4JuOwHb{RNIZ+Ij8WE{)#Eg|(5)4*mU_NUf=&*H{iYRBm9S?cA8))%%9AY? zi>8MUaC|F<2j+>;btE>$LO6aH>KjSV8?43^M^Y>}DIE$uhvmLZ3to#G;n9LD zwqc=Oirvj$p3qXa;xNJLWBUV}SeM&Picd+AP>#PC!{~UT=~U>(V(GYkLib6*Jmh>{ z37W|pf+v_SI0-&|UeJIgNTGplr)4n{X{?K8HW4O?l&0D6miukV;J4P;uqH40A6)K} zHj9rEl#bhd^|<11@K>QDxsb(2v@u4e<2|GLAB`xg2euXcy3SVM>Ah#!4ENag_wtnx z!D3lrc0i{qk!%!03OmP0t2L^nT zq91*A0S8}v4Ep&Vo>}NRGX(7S82H?j4>UX;k#Sy?3j%NZob8dW(QWsSnnttfa)v+Q zPq*&A)Fi%#qTVmMY>&&meRXkOy*Rq&i=y6sU2_{oye^DNMx+uYC;nE!Z>yB9!;T0H zaLNoD6W`mK&VJL+Y%dwa(CnQ*91a))u4JbKXXlpMc=B*@51Y)V5){jBoKmMOCCKwA z?0tXGP5qvlSwqv~lp|TrO$j8oI!K>`u|GW}h4y67I&le6Z!}NqMd(hW{7A-SFH1)R zyH7rjTGEabJn#PGuhh7BkQBL<^%D=`Dz6R8-4NAqCE^mpkmcG(Ies(7qpO@6&IirT z+3!UOOYz;*3Dl|SCJ9ntmQlX@dk13KGofC)$4z|KhxpW)i`YHdU@ir$Nz6)fk0~rh zhkH3_w{?J{(f&w(`zh3B+ljvjE+|j_ME2bW#qCY|NBp+$-|BgB=?!;`AGw-4=zN_Y zDey<`2UzNoTBLszV1{4lq0VEaF;1Ws!qXKPKye4~36S@jO4$s>G zc_A;KKT>yMvKV+_#;5blWI`6FzW_^%zsOaG-h8>@x1IU7fSR=6!8CA51iprdC#HYM z!A8UjIptS;xpICKCAWHh*n(!lC8F?S41*K`4$J)=C)-B4G?Ui6vuk(bKLb2QImeT( z-?mUVzk3WiFzPLPTW}V= z>`1&H+sd3o#hYESD)&jrLL#DowHQt#RrT2=gB5^VTN-7~*%~hI+P944t~Z|nV&`Vu z=UX=fj^#%{2EdK?@>Y(>Z0>~w-e^B_uG~3tl>x(>`%id39HF52w68ni znz_Q{87mLHhPnOL6xXXS3LJjm4( zuLYOP9R~`XE%dYyJSNF(MQ41My<;pTL9Xz-eRJ!{(q1;hT%$W4LXrzD+h#AOe_AuR zrC=#&$=8z~Bq(^{sbvgKFi}?iu0c{G0wb3mYu@h|cNja)X>J!x!qAIOLs__)FMKjF zc*L95{Fhn(g^Evd@z_GK96w_(U$1!0uq+H*KOF{iC@O-5PmNuXx%-b5lgCFnHRFa- zRkAyd?CD)EE3djMEaAW3&YygG+v&yddgeSYM#uE0pO%NC%*RQ^U=K!K4X#N7PjUic zY5V*l@!7Zic}OW1!dK@*M21JBEf52IqKo=#Yj0j*ma(Jg?tRV&xYRqbKKu@lvUzd= z;=2Yj&}9d zScc6lS#6hxoWsuD=uG23*PU&g*0GfX_s19IiQ}h>Coj70urm=PA!zcK6| zz&h;7GNmQ3&CjRWbIIX2pUVvEsOaH18??^-AkVMx$kn^XGEO#nT{%ctoKnk| zO!MZ0mj|~Q#1i>8Si(O+b%yL=ytJX)jbMDiQq$ch*Td8l_}ZsHJl6HSrAd4-pox+c zZpXqN<>gB;>+8Jd%Cs5a`y?geklA`<`O!E|xsT7%tYIIYy*7#_Edq8F`rD!sPg}@* zt=F{%-L-x-kN9Es|JeJ=u&BDWQ5Zo{3_wb900n7K5$W+!LMf333F$^U2N;WHK%`UY z?oOpcI;0V#JBQ}%(MLpH=KFq}yso3aw!_+M-RtgJYj5sjX$f79x(PG`u}EqbNW!h4 zbZ|GO1bHt=doAf@N2g2*fkD!rJA)WwyzPpQXL$U}H}VGgwQUChZ9>71b%EZe&TX|l zBR`DtU8;x6~EC4K8JGb zZiI_Yy`gTcs~)mZ(z(+zxNREi>Ex_pzm{fm;ho6Siqe?8WRoPPf6-fsh2?V5E2ivM zj#vqUx@ZniY>|tl8H}y9hX>!@)Q~SK8yDI2^TG|>^b4&UNXE#xYnF!e_8B!d%$XludNMe<^6?xp6d z(qb#IKR|{_5C#|Sz7F@-8?tPtOrL9f<-hjrVI_@IagZjQ7aUhH;<*dsTwlfZYT8E6C+6WsdP4Y* zQVBp9J9L>q^HS%Sqs?|=Kyzn%g=7vPI;e>;vnpRXzTz+}Bla9+M7U0?9p4u_V^w<& zN$)%<3UV$WrJh?8EJYvhF-R>S|EqYC@)UxmB|F>yD~$}sHUioQW`e6WHSfDrqMZ+i z_Gg{Rr7NL=sLP(e*c3y0g%6^dB0FJN@h=Y@Vw~MDE3t$#~*$ntOXYs5T0)y`+L?u$3g^vCX$`=+8qCeia&k*e=}dm zq0tr?7!dA+G&1^sQ@j7N{O=)clE`ZLKZ@S}@$SDvr^$c;E&7bYzr^MDyZ`!i>(anZ zqn^mo{QLi39DM}qUsU{mfQl!#VTj>FaM|wgE~CmET;Sl|7ob6L=f$_rs)#(>mAV;k z&JhVp$FIBgWsBDjruEP5E|u=8dPD`#Ki~THxQlK!%XVcffD2>b znCvW{KYwxiHGgm2@85vjW3#-fXvNNu?3=1@=N1Ak^XO^VPemX)I5>wQB5myraJ}3( zT{CV2WwbTx8EN79sJoPT`alo)uDxDI=MR-b&szGP8t27mc}ao=zs<9zP1C8?62zyv z&NFb{0M)1hu+8Swv>?l`hSQn0GYDkIX}WfpH7ozlbj&&s{m1bvg}v8lvF89jXMXb% z$(_V|!z<%LM0FLrECU4tx!Qee+X|*-Yai}t_czVFy28&iOnTRHA$R|-ay-rDJ|6L} zPAP#K17)@vtMAvB$6I5AbXp!+SVVjTR8p;e^CV5@hja5G*8R`tG!#n?1^1Vb&A5Z_ zuj$t|_X&b^mq$P810AXzh3sK*KuYwcH(8chi8%8yX;i;-70|p@B-P)JM6*j6{1PLh zoIfLRdB85VswrnOmhxaPn_8hg73Y&DQjtXA_u#f4;9$rAFab$>-;r>#KkV}|^Oty^s^PdHP zFT9y)3dO0=8u`~6mn(*@j*058TCm33t&NCLLUZq_ylCLCdnnR7?G+iUQ+kJI=$)`s zb^ROWwP{ZvY1Tl){Wifb%%tnuopSsdqXK`yuRl`0B+1Ispcg?c^_*{0Vbz{sO>puN~JC+MnGXY!~Q_;2K zH8OGqL;El67dEzM!qoWFc1=2Jg4CiGTVtMlO!Y@(X$}i}ZMw~rP=i+nyROx^`4T_J zg9Ud=^4o_%pRK#jc|xR0*$uwa*0_aa^|8gb1G{UQX|Ic7ehD@so6F$jC3pCa?hSoi zRk62a<842mJ$`q_1!^rCvsw@5%J{-8)cz21^Q9Eg{z0+E;eZ$Az}Mlc{~cmAUO#+K z{4EPG-Xx%_h~Ou@hboJMa4Tx?@-CyPg!5q;YeJrD?x6)gh?dm2&}pYdzEva)u4>(w ziWQ55ndB4PT3VCbxeGQ^b1kQ%Vt@V}HI_NhwA7(mvJh-tkN$4bd}71q?#r`b#>J0z z4s0r(i1l@swzRu01ReBVK{oADyd!SF-8H^U!3%Vn0zG79WWigk&SoY}ccj^8HGAfJ zJ1Y*p+lamd!{ecwgY?Ej_%3e1Eus46D_Jo@J|c%3tgWIC*18n6-Ssmr_c_DYD-ISu zYgjg^*u^%myDrI#brQ_+zI#QZjYGE=L*97nu4DuUkmS~%B75)Q$Kp5seba$LKj}eH zy6|yik)c0o>kZF;as9}?a}c>Xk^&7eIzG20_-KvUt!1)q#+!Ta5&^kmjai2g?gZmy zn*5OPS2(y&-0-%!`n~7f5Y!?oMgBe>34#fS;spXvcv%mLXc!ymQ>Z2DI9qtELPmvC zNx8&YOd9#jr^?`gB{wND%C;lN*yCfl4?Uxd&pW+m6v7!xnFQjz%#jXw<4IPUwR{YYWYXE$0a*kXWs`}vL--h;09;dg*c z$KLWQ#3K7B9%Hqo+{pe;2#^o?BwoY`R9EFfSIp%XeHZeFKlVxy_`T}Fd#3AlTQO+=<~QRp8udx1^^=~+H& zZhJ(t4IE-VgHCE)VbeTvPMw_EfzH)CPx%6{uCL357LX4B8P)u2JUUt{a$*r2;}d<} z-5Lxj*+zbAf$Or?gC>ss(4YnB@4Yugzfay2Hp#^ndp{QdpI8ynSnpL;d%_~2xhkWk ztv(qtl@J$ou(L{SDk65RCn|fWXPhJjIPIV^vzlTeo-@^K%(V9Uw+{zvxylBLUF&bg zz52^vlX(J;x1CK%Em&O6MV`Ol9I>ZE+F-u)^3As4!)E8T1se}zO*QSd=(>mr&RQ>u z5L)JI936W_rsW&fnmM=F+7;Sb>7;_PtMQd3r}l1?1%zZUMI_IreWXw^@gv?(nTiZ| zvi?LcQ}qVhvwFo3`$lvAmrvdc1%1>DSxuMue7xMN*XSsn6?QCI^zqpJ>sN3E{K%Y2 zN{z3(j?kPl)!=4*b9@Il)B9>d5mM)bA02tE(c_rZFk9!xsYLf*z40U@Am0a$#Dq?l z2n-0nPzQX8n&kb%W^d9Gr`-qyN$ZFmVt>p|jDy3xTF85%Y3=)hjnWyeFX%qyn?Ryg zB}y%wh(_#Sb+0u6C?J9Pw%4%*-y!Oy@wT6iO##)frcYkXoxs5u|Ne>PtuCPN3;i9> zQp9`JVE&x13&`kh%Wl*!p+nn_B%An?`Mlq`*aM8z#_?5=BXC_R>1e=cs||&_GQZ`X z8MHQHn=@f0$vVk8tz^19dSBn}6=hcIR~^8T3%-aRl$VT>Wr?a7OWr)uJDCUNoW3pg>Ou(n*Ef#;Xb z-WI+a0Wf&5hT&{(kmtDPc=+mPQRK0gIG`dHUvJt0J%_CH`zcR!_f91sOZ^(VMDbsk z%%dK*%>YLf=!KFTcT*A)(gqxz5c_uG$9F}C+*RMM*6&?iLY@^c8++30U?X2irmR-xM z>?Kv6pc1vDy5ODJN~jI1lZJ4PT141l@nM!_FVue(U!F3dDZR8v#B#Wk9Zpj8h{S5T z+%C7iyk-X%qX=ljmHtj-2b5?#knP7il+K7R0o+2QM-qSo&NRTheqSxGd{g3RH_>V! zTrD@;3uOV5R-sovBJ#yc5c$Ld0hzq~O95oW(<$%KeTi+^P1fSvzt&B)6KaQW?RKx~ z!{NC1+~{*d6WTonNww|td%{;|Tm*z(OnCXjC3feFq%}ucr`o~$^z38TS6v+Eni4q7 z-5#RNY!r$5XCib3dVWRVfJ>&naRJLERn;^KxWVpUha@@;;#FNZ(QaZqUgJG66g3|LFJhX|3rz&hI1bbuI550Ad+G6)#j@^# z1gOGqjJj0LBK=Kh55N1b?YKZPK=MN`bnRKrq4x*OnU-;iJ1y3Xr3DY`XAIdG6)05% z3Q{k5bM{9oaB?4HR7?!#4+v6tjXbk9rh%AmeY&dL<2jSrh)dvS0i3KTyTx(tMq_|x zUj}d=sz^UYlMlbq$ZFcyO6IHLO;VbN2jfA`de^8rN;STZZ?!wC2C|f{hg#Z1wiwj= ze)2Ae3cE$Kzy4An9?++7r25onS~}1I@(-MZ-sD3Zp*Mu`2d#UnYBmM7`febdBjeQ0 zz3b*Kydi5ZfnHE5_T<>2>iR%rxp=?H`Pq9~zLjTd%8|#|Z23G^J^JeT=v|TD0y2b2 zy=~*gzqS2FK32u1KV9T3|6NH=jvI9Ik$dx=GeE+YG%Vcw^YbJz$gn~ondI9`Dm)R; zely^(&d!6ZZmWVpe+`V979JDeY?*b_x>966y}1hD2Y0PIQG@`k2ee;kggxGDJ4fv{ zOVwok2(D_Ixn?MxU)=B4>|L-R&lkrgVqpMr`&;-CG`g_*1l&g@G)0>fLhC#>*_jW{fwLHB*@Mt9_KV8~Te`tlALH#%1_{{9im z@iWLTYRt64LA4ktBzpK!ej#5Pw@CLI_uWM(eAwtA(uMXlso3@71&w9l$J}qkL-zzuYZB6M`|z#0P=A#w@7*gr zu&?U0sc_QC+E+n{H^Sa;e=$w?VAs`n0Gw9J5}qFkE>F>Zv!?-^y$}Q9gs=nK4P$-4 z5J_7=G#02HbWFx@iUYxbuMfXvh4$=KX(i~6wCi_2&VhKK7eY96yU~z7{yW0}Sjhb0 z*mlg75mq=;U;eHzQ3jmfa^%iJoMO#QzpAxdRhqkfnG5zuZPGxZCDR_`N2!74Y<8?; zczXG4yC77FAquTOX)X)jqDC z2siKEx8PSD?sa5?iEZcX@ITMXPsP`G5)nQ6Tq0S}rC{a~S#2rnhwu1_)RZWO@NS=N z75;tq31-i=F6p23iI{sm4fkKw`?K3FclZ$k#Rv@YVf)>PI|6jF@I5LT&Y^pfoOuVg z?t7MR642b&m`w?0G3wF@`###VN?!MpbC}^>HoX2Yp4g9XM_Hpk)9US|g{9dZfc+tL zSX*JGnxTy_Wb#=JG=Z>})j+3HZ1Rj<45F0GAcq14N`ToAe3hab0YDekS#KUmhZ z%S{zM5-|1d^Oi#(g8RPlX5f^?@%fNnl6N%X*F)wkrc#{?_RCazvnW()L9A4B7#SMw zhQdT6|F8G{W2{0N=s_{RIF43c@-EwNZK?=<=S7)`NPklUw6L%rv!wt@(eV}V(C862 zah^W5y?!)dW-_J_pwE!;OUjPseAIE!^YDrBsjfVSE9I9xKBmTx-US|DjTi2`i^hH_ zlkY9-b^P690@x*?{)Bx`^U?YPoLK9HjL*mZbd-1j9-`lYym7&kpOUq9lktBgAWlq~ z7+2YWCL%L}j!Ens?`eR%&Z5s(%lF~w#>mNTKWgD?@65}A3U5GcOngZqZe`D_t zz@9t@LK=p_!sOrH$Dh=gWdOch+Z!nVvuJ-DDL;V+CP4SSz?q(mA{h=Vz5p~ZDOshJ z*rPx$I*5P(2vTa)wBKt*w}8^nabDe@b!188L4`9f0B3Ha!rCOVg2zzsEB--} z05bG%XLHi-O!NV&wMdZkc}dx=_ayK5%YWebDGBxRw>v2R3{Zv`y+fA$n{P5l=FV~I zAHyw-`vTK>mxrSdmScSAT)0sn2gU%P&#h9JfK)C5)wUuql@coPu#?t`q8Cx^>K5pM zM<|w~O#FS>V}atIxD?U%y_Ok%7R3}UkZueQT<}>JnKZ?2R4mt}tnNE1TqcQ@NB5h2 z$2N@)lEv2(f2mqSl6>{g#eXC72@k+g{TxLXP@!ZN8@N2F!n@n|51RbOPL~8wlCTy} zM=63kAP~6QRFmVke)tpEJivoZQt?k=Ljhu9IdH$w#(=`5Uk%+SPzG553NHq|-x^^j$${_#CM zq%0>!0GeST^w}F=?zRw+;gxGo$+ld9&xYw>l5req6WC?Kf8QHTzGwO4JwM<*ZxUr$ zHGG>=EL3s6TJHTqY|Ld zi8*GHv(ZDUN(Ovswww+tJDxLm{3vjn)`MX=RgVlwjV-;15#TQ7BIgB=VnE*(AeA2| z`_oC8eh32`UU5p+gL}vrsz#ue5V|gubw%jiq{U z7W?fz;or7{DFK4PN65T$6I%E}ie?$N#LbWLC1sPlz7=vN1xk_yEfFUsVaYNy8K6A@&~GLKwM}VUtOh9u9Fz( zf(!08kj(od9y(5}Y!@`Q&Qq5E33*~TAjT7+GH?Fa;<4cX4HZ2>$0z(_Wb{*zkc&(* zm+Y^r82l3G^gn|C5XU{pBBZ5sM2r>^O9os6csw z39H4z`2=UUlfeBa2OWEZitXWOmHU6d_-k1iapY;I6phbRvWDs#s8DK!3^v^>T}Oq< zCDE*o)Y7j>{#{%azaAY224}dN%8e>W;>OOEfZZT`I%RQx=s)H42c99?7;o`8aJLf0 zUL|84+sGeW;@bhft zJT0M>e~tpgCr}{Bm@UX6`Q1?R2i0KxfCcGFZ;%cCW7^+{l~DtNj2+|Dw}0UOH>}Zr zQScW9kiRJSivqwS`+qn32jt>>gSCO8{jDSJMSn}__hGS#^%%K4|^9~wb z00&0wS@CoaR8a2#8ByQaUU^h0C^Q%e7LYi6PRXICD~mGEg$Lwa<-Vk4qgsUmFyk9~ zx_PK40L-|oMG6xtGwuo`pi^bxp~*MUL2W}H@BX?A;PeHbkOIkQgU+s_=KPafHcJDf zyxECk`I$4~PoDx3{rO)X(nLoVRdlm~N8Aw(dU!Eb)jJ~})jY{R^T4vk8XLchDSvYP z##LhKWvL1wc}-OGwgTwwo9=PJRi^9{YPq@(9P+*n0^&?7y%$!faBYS2!;9p;lgo|D zXW>5o(~C^VmzPHcks^#r@Cyb%!$2hi%9Q_2w)%?-Rz}t+J=$)J0yxblExiSmIvE2vjlfjB8$9j0r0G% ztXhW3r+5QIp8uN*rvKMbP#Fyukf1-5-|Hf{j|vgMDZ=v?>Hnd`MQ@lG&nu?bN1eL@ zGTLd<>NPKLjwLfspug=K(xJJW;Z=pIaEO8R8pvO*{plPS2y94Ua#g zCwf34K`D$N>O(u(P#L~sfBC%|00P(zE=V!$XFLqEe@=0ae-4$!@x>^+kd}D)7>s`m zhIm4x(H?TI6JBFQxek!uz2IVLL{4@O6>cHXg3-!o)i-?!$^VOK@TUpUX6m_rmSq0e z%CC7Lo`95NyAq*|jGdt0+5iX|GwVb^YSSi=Oi-Ow=h@*;p@0aPPQ( zbW^_WG4?KaIxO)~^RAZNNFlG?&`aW&NBHADAHgrpKHa!^(eouWsIh!$&WMk%^Y;Gm zNLqO}@Q<%dzIUb-I-OL!%N1o2DzI44$_MiGG5v?&RGvhF6pH!wEO@OHC*@i__X$vs zII+zRq@u4*xURI`K4Qo5L<1FmTp<3Cp!<~K)N&|H85+!oh(g+Ao# zhEEAl1&kON;GI8^dtBgrft>gC5?Wa*R0IW7-6zTi^H6MS?$C2at*JvK;$6pVBjpkpY`HL6+2DwL? z;@87p^YPbw{Ne?mB>gvyb0Puy*L?gnAAilq$x!PkUH;d6{52nc&Bx!`$B{z#o2dMM zvcy)5gQG_{y|iRHtQB#pGS87yA1<}a$v3*t!;g+GvO7QEqFZftDCZIzp8IvWfM_|5U0ekOkb&#hAP zU~elVs<^oLDdJ=Ls>6F>;*NAV{Shc8cp)chg-8CI&}(u&zB0kBET`J0(bG?~1hc?w z&lW#_uxBJT*NY%%y)TXXl1WT7&@$-08;(}-cikx~OmI$)N_?q|>{k0g2}>INXSe}0 zXN<_%4DmTPQ{({=Q?S4U!s`C1<;~_;$TcT?(=x?@l5$5v5@)RPbgTzsih4E(YMT2x z+3fv}tmq((8ORr9G=cX5v=W zlHkPcwty6eMzGdKXkJnkYA&tzxIVt z5|O5IdRvn*fg77v3Nt6`uuBe@ugF|{+bcJix?03HKfkegXpjdE+z4B{BvUrYK+6g5 zRjr}k3trKAaq4;hekL4e9Ew&UO?TZmc1iP%z1%N?7Q6cRI4)u|COoVv`>VB6{dsv@ z0%LjdLQc6kvV*5J$HA=6SLd|b3X!ym_2Oq#dBoZK^rzn{T3Ww=1&Qx1NRx-F4F@mN z(QdonnB2=e)t;)SUyx}P(R{jYYi-b=3_*Kmvm3twC2b@T%D%Q#l7s4<>f0T*awMX! z!GWciytu8IP|fec8=bxKyEjw^%h;+ylkrYa1rani22Yd@Fo#Yi8;Kb2d)-vHhn%KWgo8D46TaMv4XLJ;!4SYbN&RjsFSF5{Nb zGuhKh@alu0?wpRXr8?#iY%Itv<57cYIY*^q5_c>tQBQR!u834`t z7Y{!<^?x%S*!W>hfofdkSINZHeE^A>v_1C(dYVA$R8+bO*voNGboIuOTMyIK*kGfB z!U%C(jQZ1Vtz5;x{w`2<+$$rZy>-w4hFbsJ`C;MZ$6Wuyk> zuwy0pxJL-R?s9hwc?IY;uCLQMS&e07Wx#!e6q5V<`#D**R~b5My-7QJ%k8ALEqaF# z;?pD&r|7)4n@`HlGUm(1Ku8e6IOYeO$9ei!iav*8{|75`I~2?}g>Ay*(jM zu!r#h{Ar_Z>Js}nP=E3UN9Kx zv>X!^cO_ywY6f6(}0 z_wmD!Md#5EiqA*|PwC}n%K@d)KA;pmuY^fu775m3viF&J2rNXGuXHYG`|Zf^yYz~c z`0TTFl+Lya&F*eU5xN*RrvJE?|Jj+A3~%*lH%5F@15Agz=PK zKv)t{A}zOROPtjKPNnSoj$0tB;UynY)PI}i!44aUN*m`eVk~idFN>@If)YI<< zobTYFQsIl|{fqPiu{4(ju9I)1KIr@?i0v9-F*SsUH&t7>*(HP{Ck4_%(`!k(RMy zBA=%-!e%J!qY=+Sp$hlR>v7?T!qSS0ity_FjtK$DEBI@{>wy1DZu6Ce+-ds$3|Aem z;a4bKHdUkLM60uG`Pq4ZD;_lk8v9ufXxHV|EtbTN!}+q~8uSqE;F*zwanT7XR{L)& z`WXp}ku3CkP7a;MGd?^^kCaWzn8*tc%V%on_zQBq&QLmiZ(ko7sff*0%rmg+&kK${ zNYV_Bb)q(w4uIA)%4!!a7EhI1w(=no(lze1vG6SUQWHCTTJuQ?O5-ly37@tzJJ3p{ zv|C?U_m5JIbdtX(R8}yk;rVfCUgjQu#{AW$j8a+^=ohQFCH)LLMcF~BDE}1_bE@N) zJ0e}L%5WUwIjw2UPe}EZMEf{{KjlU2c44iBBOMzl<|Mgwwb}kF%sELSRonYT#cP)b zE}AS>nj-kN6clHT3lw``aZ$E@;~yNE*xPOQQWX@j$#g^=4%RzTI*O(aZ4_$}$9|=OQSD%t=Iym9mF4}_4~WdGo|j4pscNFi7B*%~55GN_SnQN^5aiwqIak1) zJCTpYz*0Cpc55)HKXNh53`|0?IXIUB(nRB&o z$@85b+mFwwaiuPat(P_^!R30VA2{#z2gU6!I^R^;8yD@|954<$I4D~pmdj{Q$2|w{ z3UXDcKYPN)sY{%%p7xTKfT}1?Iqy_B2VLfVaVXy73@9#>)!=*Tc4iB5b+ypp&A`q& zOYc6%CmVaVDcYiQrb+GvJy~^ z1uH}JmpKh5c=%zNI*q4vMwToojoj^FW%TsJirQ%oYFefdawM~={-9rxun-`Z_AJ85 zVa<4^L*rrH7eEmLAK-hVA6rofcYrQ>u0%s+xwo&V1#k8_z;o3PURn;2+r%w7F3}|= z=o)h$ex{6lb)}z`dBEJ0O0Z;>sJEvI&SyPvgKw?vOsCT>KL_9XvL-z!Pz~RC;ZRL& zuh!S1HphHBpn@sgSDkXvhWl=gm@efSbcb4MOJ%4%Tbr{4u4oSY^kh)8j{1e|qM2|&3@Zh* z5ce}VFP*I~8x@SNJeCed-*u!rwU0Gv_3JG353e^!I#Z>w3Uxko1GFRS;}Rko2@Nge z)}`{BUe)M@u@Y{r^DDOf()6RsCBIsq65nPE!~cm8ogIlk!I@GAoGA> zq$wXxeCL6Sd$`h<5no5)@X^t`hiAlT$G2CX+;Y^Z#_*%{V>Rw6<%zkNF)Q&p{*n#G zq%jg_DY0sbmU#a45ThT&T;$CHQX50nnWsTJI{3sh`aTAVev zJ>nHc@(N8c2&Lc_ttsA??hE6JADsjkRZ|FP7%%fL>(5-ua1b;Qi=tucH_Ev&Q;Jm5=kFQ<1LcgmX29p9`u za{%oKIov5S?`mGCG0Y(eYRLa$YEqbVQQ#v#aGz*&pX1t>#wOF=A(hg8qk+{8okOQh zF6}n_jCl`vjhb8SYqW;s(0Ra_Vcl=FtxEC0G0Mp1U6EXeP4Q19ex!_00eqD5m~Ty5 zWh5*Uj3?|An=mF2O*c%`&_%HM7g(@@{PBRW$)mO5Dz2Lyt_DARi6G|O80-ELqY!De zBvTeNgU^O>>chR+dfoWAGgm4}mn?S4ZF!^d|n z%*NQ9@3T(@v+9+*{pK%lS0AEv04b0mm1aL&iz!8+Dz0*?DU@0)A=L3bVEEt{BZqKP9wjxaRxu#oUBS6-AQb5Vv^9^blymjc$DGP z%_#K74VNZNX)KgIX=imJufSiXu8tQxiI#N7(b}VOnXVw>srkgb9*kJZY>-_z*3iQR zOuOwGR0L6V@tt&Y_$J{xAr z?{yD$`~urwzOv1e!vMqiR2_&^t-Ku;9isP0&>QY5o5~tfY;JqKisJu(ruFrWl98KB zv{Iz4xnMtyw*Z1J7|WEYki#J=uPR~5$R#i5N=MwYeE+U-|5Ki&SvgpshKPN2ba{`2=;ctWp*j9DXW(*Xt7t7^e?|R%ef)iSn&~F5et7*G~O*c749I# zRb=^^jJ?Q`KqQrkmOCRbm{F5Sw0WSN0WC>&=uV)aOdap?D9uFgLcu_Of7hyo^saK` zoy@EZEcvhZQqa(7Gao&?FT;jH4KcHD-|!72r$sSQ!BF<_mINt z7I6n0z4Y+qgY7y>6(6+ZXSDXJ;Q~@~!M1#X=^EFc%J;rp-4!`xVwq&q&lBrO>E-~g zjz1O$075bOw$k<7XSjQh+|P}@12*QbWOzAXBlE!(2DP;Hnv8I@a+0}xjbZp1#7F`D zv?}iw+cvYQ;}^EQMr z{2I5GA6&M#?=K5Bf~KV9Gd+mLdO1m;>%2E|U|4OKYgi|fD{h1MXgS-Y8m@Zq?rNuZ z4KGVKWBZt_4z8BUi}sp{JqBI;wTwGHPeSVL{IiCky%CQm3u|B1xW%>aC~zpn7OBL4 zPT3CaIgv$z716Op7I9%vT4XpkPmo|kCe7zsUkr`2E&vW})@nMtjSz1pg)!Hb%l>T1 z67%FxBFI5fYfO~BD z!CTqqyi?+}_65{v?zj(ea|Io|@m;F1B1;z2%UDv1GNos_9gXKs1dNbj&^UBIV3cO* zAlf<&lSK9V$PSwFd9eV97_-@Ag%b;Ox#}>m{IDv@WHlSXiE&Z+Zu1E4+WqQm9dSwA zhrFszQ4P*xpKO>A!@CeD-n<+FZpTEMJ-9WX+|>E8rImYrG%zS}l2gAZ$D1@E$JlyE zJ7FC#1@EZ0JSKYBcYLe?ZCm2mt5m~Sq){}=BOuo8NHOvDt#i3jv*uN3UiYmC)wD(3 zli`!EYo)EKGr_02CP_Z#2=m#wj@1eIE_5HR$?5e`XhH0X7e!LkJT~kyki)YSc`)&$ z*;b|fn=84D+(fp9`CPjYdv*1A&@+2kJEOgTeN~4=Il6n(E(ruN!Uh?ic2;{?Zce>O zTr%2Pt%`aUc(5H4B@wmNHRURdhVFkZcG*gPlHhs%>tsrwN+;vT${QGL)?%h1I zoG)i-)mViHs~IyxgM#r7IzF4;W$`x-%c*!_!kuHg-&^1b`Ou9Q!!t>=PZhWjl`X#S z>mJFeI7j^9>b`w?*5v37znvqtif5tQmZqp8t5^t9ubTh9kUL6V@tL;_`bweL3I! zx^g)o<+hnTA~*+BM`oq4-5+f$vUhNZXjso_a*C9@!&~Uxt5q}ivV~!?z|Fl)(|sF~ zKXO2Cl~Yqg1~z4xbar$7wsIk+)#+evf*04!gb6n_-1*y;M%U?;*;FW^FGt(=NyX^B ziun>mR9{J9sY@x++1xFEL-+xk=^Y{}aPM(mY#_JUd&DVLr1OP6A|6p<+%4bLx4@=7(Y z4h-C*zrFXDOqQDiK2h91Jd>B<_-LntYvgf7(YN?jx&u7tZ=c^xsEx{>t0lvwi+JIf z$E_VD6(4-&`=qjoq`>wJ!GvUKC_TkjVH~`XkrlcONy@D@x;kiU@G`F|bi>myol*FT z3=LKfey?hQiHcILp45*2ZPlB{ zu0*>mNk83sAQ~sP8J1SP1*#nITxz{%d$_|)TT%vp@NKsRIS!cZ=q~4yy)yUIpl1hjjT*4-W;~FKYKpo?eNgPY zyO1wV$9wqIa@{ZO(460gXV&e3XJt$ZG5rfgE|4a41?`@bMqiw*p3~U*x_}srF?;E< z>Xf7w+kM8)HzWII*Pd2aO$AR;EfQSKso0C7i`S+p-PDuTb~h~jW|bkrgCCHHyk=^*{N1NZzd9dTg^Hf7^p=03rU&Q8W$8A4uT?%ECS zYV-?KtR-0;8r+jYUE`9!KWq(Sn8Uh1rmM|vFy&4s7t37mEHu!#NKm#kHw#Np<607{ zL>D8df{1r17(c^d09p{yiN3p}T%qe2GJiltlymZ6d-DaD!Ri{;T@75vW)B@HH$?`v zrA!*16uuBfY#^Ugy8Lo=poQmRxteoeAhb(k2r;TTabR3m@UIY73<*-WD`#a9lZ{#=RQ*3bW_(T(J*l%zQHan zx)%WLqWZ@di#dL0c;#_M9T1(B7#Ac-qVY>xg?a3X#T#o>H=Vh{|1OYah{-r-Lr#;W z1=v5!Tq|^Ca4f*2H=!!Z?gjULuDq8L+}&1|=9N(KvK9hvsWNcVz=jaGWzx{zhR0oi zB=>f^Nx5w$KI*5J3DTpcM857&Y__Od^ zTXoCrkwPwBvh8M_)Ho4rAkVFkW;`0Su>^8p6Z;Z8CIZF z+|_>JKRq9;=5S=PJ#|EESt?=qO{E(Uy5j23BXdgAAXlaYug!dQ{*<5 z{hA1sj*c&!j8m`NxAj?ehT+m;qZC&omnuevW7OJyT&jD_g?6dD3F@B9Ah`lyM5@XL z^Z*c<2Yji(Eeh(*pmV&?k@dkTvH&OhKG~UqijurNcYn?6B4V#qnb|+jq?y_q_kRo~ z9y-ZWIKgg^(t~6(T*o^GTN2TEfVYCQe|& zQclGT+02s6d*Q(eeeF@>&6{emku$r?<0s@#41+2hCguSg$q>lRL|}1=;V@_2%WyzO`sznEiyvrT3A#{ zORYI$=N6!a#yRH_Zx<6X-E1n!w}A==C_g_{nApgXeF3w5GnRu@9J;Q6&{*eIy$_DzWqvqbltJ`fQl z=`gK$9#ngDPhx~LynVrXnhw)>2A7y7(5H=LasE+iCou%06hAb7N>?+V_o0UYA9v=l9i9l~S-A42!P^u@RS7HaB-Q zvhH?=AT|;HH(}$kwb_uFT*B&_0TwWtzQa{9N%S$ILZD(q;nW-@aPO;b!0Teu_4+dvP^s`0=oQPG9_A46ra z@CJ&DCy4}x^v7!ta-Waaj@@?JX==N!iFfLagJ4Y<)*TIr?_1BFye3~M3tf7! zDEn1vUou)L0|cMV8E1&EJoSA&96iUg{abvOlX^%mBRDjHnr5x{z_UDtb-leC8RgiJ z(7e=>;R$l0Hg|x#TW{`)jPPWsHu5?FRq(AZ+&f;iYFo7)Ub$r}#3QFlMcX4#q=WTS zLvg4gCRp0EpIx48CTIk>`(6JZ%+qcZjK(3JQKSnmVg_VqU|}SC^FX)#UCqfT^k3aE z4Tfz4fw$mk6a5_G^$2hWXlc)(xC#m#6mcEsSBmXq(7PIKg!^-(E@A}988Alt}86dpV>T7#Z!3+m_ZjA3$3C2 zlPs!lN;UJrjL!ICt{KV>6q=0>8p?8@y19x5OQ!Wp%G5LsSC(>=pv>|#WI(sLY|5eolJxOT9}*`r?qLk$d0MoV*PT;=U~q;W3-Mu_4`WM zg(a^QIy-rEaL%DnOt5E|$x{<6d%Te`Q>9v@E)QdjvnjVK9G@YFDr};QjW&(&0~;IG$DV}Nap~!ppM8B6KVLu*X?cTi z?bkPqMdo@C-LK$ZDQN^WTp*E6rO&%VucC`|ag$iJe@xFc@9yu)$q%%ab?;>(ApJ#$ z6Fdo_1+jm#Yu;ujQg!J5s%1fo=KffC+@#ECE&D@nx=NINZyKv~<|RQA9aR0OTv$vu z<6YbeD6LqPf(cnw?@hggCtsS9L3^5EiTj#qh}VfwKFkpXY0*K~&Ih08jj5F(K&dE! z8*AIIq5vNaHV>%LK8_?*cPOHRKsZoT8WyKs0_Zwc@lQr+Y=EWD{ayOVE+VzSUxc4( zum7jmtPS6#ndUz-Qb$h9G#l*OwvaSh$MX%TXQ<@F1%eIuci8x0DEYMoXpptE-lgY5 zVYt9;z-@CKpc-0KOGM`YF>b_=(_<8R2?Hw^2WS|FWc~gW_X%808v!ut7DRQN=DPo2 zGiHppm|&pgl=*TF%2~i{yBI=^9KgU7xil8h3bPon)+R>`9!lq#>d6GLYGAiR(&qRtYSiVhWVnO^4DS#b9F)d07mQdt6lo9bl*jX-yxb5S1XM>F z*-c9FfI4(sC?}5NMN;(Dxw&*k_{@Te8u^_630xeJ7tEG|kxUlT$PtRo$%Iz4>XGtP zjJTu31UfsnMv|(-cCui3G!Mi9le)rj z%;(bdp?dn z6+DfNPNY%+r9fT71x!12RN`kiqHO7mwo_J880%NNAijgvKX2*DbNm2!SGGTj7_>1IQwVqRxwLey@B*xg;xf>gh(i=}FpDIDhX~G2b z?Uo~)*@hg~m?!%3K2f}~6EZR)L%+4OOaot%6pU^cnAfQZ?02q-><{9MSc$i6q-RZ` z>?_lIKD($IOvpUX0P@2W1m9X0+BgG6WzaFOyr?sQQ(m(JnI9al%9<|ibOF4$KOMZh zmlMV1FuEXjM%tkZ&v%F2Py6B(h{w>rAl5BQ{fiI{NnUxV2QKz_>499OP%7L;!+Sn9HC3mY52l~~w=p?4 zoL&DwB~p|}M*MU@RltCaBk6A50og?12YDmt&U>S@k;DUSpp!oB)nWC$V5;X*G9Mga z3XX(~-H2OHJT}ag?VcJXM+m&|-XebHA(XVwxvWU~Svp=;P*l$Q+FYKowtp{anNi1A z`3m)_joAT`ii>1iw*QPvoSLTy76nbbYE68x--O>=&Ub~nX)2FKCM8uLs6NSY>a(TF z)x3Q^Fvh^l>0`dVLa6m#lw*-(NxM#FzWs7C-&Yn-w)M>JZo-Ve}@ zyZU6SRn8~9!iv%i6)EP`fyaxAH)?KU^UTrg*Jz&b>B6BbmEK1$EG&E;NfmDV5%*g^ z?9}Vy&u&f4zJKcKFUPOV-Di96XS?(M-Cp)j!`I+T0oF|lDcS*c$LCzTWombR&NXS? zofUVsu8ID8`oX)R;LG14)=rz~Bh|mMPgnk)nD*>@*FSaqN?o+&>!)MaCURXYI99PQ z@7245uDl%Xv5*9_@0r&5k~m{;BlqBkzqn zYa-%nG-oG2II>FPtNWjgdm~o8?G;}yA8eg+?Voi(>!upVfO!2dr3Wi+i&!u6OXUgT z{iE|* z?+@tcp4R{MwD7C@S)3jlvmd;B>h8NoN>E6hhtrCUulMcOL&r~foYu)Wu!)2BY2P9~ zvDH7q+C;YYnoeqyn*ONJXXE}Kaql$4lMi25DmGW-xXAZaw~zdMYWnELg#K@m7VC9_ zHwL}a_tz>5d4AmRDI@cLzB$HEl7oM@%j94`etojQ3fulUM_AP=vP$naKHqjV>+sc8 zzE>B&Yhypa>uy>rYq8R5duIOOtiM2F+r@o+`;*>IEclwR-hf?Akh!`B$TCSu`(CEc|n5%5@pp4PrZb>UuzvcZjM9)=GX+()j9R_Fg&P z^BJ%EgS+*8cfVSGWcsf{=WS+dcw{!5d@SWB`S!KPb;-3oi(~UweeVs~ckDM$^{Ts{ rmb5K?^*cMhZQZr&Qu!A@{r=BBeWDGs{3VSt1|aZs^>bP0l+XkK@Q?id literal 0 HcmV?d00001 diff --git a/docs/static/img/prompt-with-template.png b/docs/static/img/prompt-with-template.png new file mode 100644 index 0000000000000000000000000000000000000000..0312b899f3df655791aa561271d2d527128d588f GIT binary patch literal 55738 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
Sh^;(IC4kdHc9dEX@(>ON2%4<3zg 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 literal 0 HcmV?d00001 diff --git a/docs/static/img/prompt.png b/docs/static/img/prompt.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4260bed1db131c81a035fbd024eb1579ccf3a5 GIT binary patch literal 41403 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≪zEudLq3!66E`b8P&qb)L>Ml3 z?f3g#MGZ-ga7cjoqvSj5_qq;7lfOvWWPQc8%6^dr=yEH8<{@$ARGJ>xu51uO1%l;@ zK0?zpU3t;gxxB=;Gn%y=FuVx2NI!rHeMI-Z&+k>RZG9Da9j@bDFei`Lq|!5N9|&kt z8TElWX<5WWb=WEv_GiloQww!r7sJu0!DY2lzL-)W@RE&Kd}&u9otHm zUp5x^%6fGI))=5Ae{L1HJ9n&r-rDY3HWxx-&i4*-m+{Ix;QcE1%M(KpR7HqbOHL?g zQX5wHtr^y2ZhK?*XHkj`)af4M$LBUA5zk{)GxX1eB1*4bS?b{F@G>SbgqeQ81M|Jy zp&>wg3l%kaKnl&x$&7K*P$I~Q%<;(0zvqsA_;L3Hg|X+8(pN3#Pk_x9h5MB|P0Jmn zEWfpD;pXBWW0(bC+_I#Ko|`g0tJUt-m0b`GG6%qZ|V z1T96=(ld+y&YnK$opY)BY#MyJuXw`ah*$S9v@{FYjE+6#>8wSKDa+OB$)sfch-Kzf zc9`L~>mY!tBM7*lXg{IRRuJ~aMxAX~izOpL4KnR}YvF4JO^m5tM zPhO3q$lRB5DVT%opv|8BPAPT7qwtbq4uZjz2T1}EN9)&g210l2vkkkMPTtcZLTiV~ zU7qM|xVNx=dZcbxz*4=#wKr`V$@bj}vLFryuI|9%xCzgai4=-4 zUxcF^YEk&`mDOAUr+txZrebiFwLy!7>1;Fs<4?BCd!VBh}B; zSUL5dvk1PoRO0Gi)aI*!Y;Ge4-jRU2AWobFxn7gn0%-qSS*DO9r?9aO*n)+y9dg@U~Ib3avSXsa;vF{ zhUU?(>Z#o*m+tdwt661rCI^Ovi(HV+-C@Hw8>@orhoN;$4FcK;r|;)W^otp6T9n*Y z@SHL1xmc*+xYdP8RMMr!Y2-7*{=9e+a{7TwFYfM*kEh7o+XuZ_dg+dSGUOA4q)+Of z+}_wesj8cD36g)l&XzvIlzenGfSs4UX+7Q&s(L`Al^Q@!>*SXEF6-{PNvBo;Ob^}^ zPolDWk1>o#*lc1~?ssLMQ<^+rchw%hUYWuAY)Kg0-<0Sy+vcptE|7=uo18QV%hsMz zuE+@(Sd(uHdt1?0u^znDKG+yj<`w4zyj~7VIPP$>&|f2?a;jm4P7nJ&q1oDu)sJ!K zrd@x}A|2_fl=KcWmh@<~X=TK)iHw_F!>t;{wnQz`b+TG=QIQn(xhFC4+|`-^BI$?Q zpG?7e4{yT)4CNN`?&5&#yH>mT@>+>3Kb5W%2Ks`PGN%x?5+ME1FtG65^Qfq(z@_ks z2a7b|2Tm?cvr_2>hP&sw)3?Bmm>mvLOx9HJ_cVoe+HM_d5t6Rlyi7KU33wQbp{+i@ z_P%QdG}!str(t2n`oT;GQ&7@W^UlNYU67uAaI95D6Vd@qd+Tt zsofNT3oQiJ-?vg&DmogKm(6K#>y4DrhsUa%(pwn1k(AUgm5n+wx+yBI}7<1ly z{f0+IN~8xJ!h5Y>xzM4gRcJ3&(6F!n*~seS`C8-H3H*Rtk)T7-Y>_}uk00%3ByzE| zWx^AdrUlKDqO6$Xh56tfjLOX(Z;!qo(C7ixmYAVD?7H^_F1qy6vUKi(q|xc_{cAbR{_F@Mn&W~ZFd z!grZU<<4aZO;kaWMEUalqtnCy!{g(X$E+IU6aoqk-x;=saA>%%VLmlMP4dQMNln{r zP)2OovA$tvW#vL${E za9977a<_s0jHPjtu|>W>aaVO4Nbj{2f0OdwPoqJsno%i=)y_~-m()BTW4=p&iKNHS zn%wxC#+ChBu$+Ut+Ko=z7Jk(wh|f+>b|smSC&h*MQ_hls#=)0sO2hx&uo}u&@We1K zMnmV5Pm*FrZAxi}#=N{x(>!Hm;=2;Xn$s}YP%>h~^%Xl;R>3*Cv}wn_^p;PsmRVh; zH5G@z5)p}^Xs1cClyCfWMTXOHL4I4&C6e~-wtXjkZsqZDUH6j=qtS331w~xtb~2nj zmgaXc?lBAT(+yg*+cT?g4=`0F;R#j{FSaN37vJ60%g% zHUJOl^G3Tj!z|ZuS^$e^Z3)L z+VeMpk~-?|GfvV^sQ)ca z0EJJWr54cpgk4hl&40z(5M>+yUx2e#lAkGn`2W&Tm5xng{ZlPf&h`av-HGV2vrPdT z0bSOPbU^&!PXPiD$Oonpr|R;jiuubvpyJc>abETBXQ$r_RAd1VYa_lzIk%|S{;7i~ zXY-SJUUN%>6W>u$35B#JMG2(On0Q?{GYBU}D*vH4<1(K}`+5~7a;nM@&dW@UZ6ZyL zABe8K--!NiXcaExccvtM8kUsvD2kdjH6Cg{)eWI*HPdsqzJI?`BdevN^sw0T{+}w8 zKR?}8!L@RhE!cR(J0IdOlhERhf;<`DC2FQb6Myo2s_~tVv!?%!A=I2fC)2=RpL@>G z7WKBO@F(Z(1fjp^o}^e#LoX*WFdwD@{jOf%f1Kq?a zYioVn)8o_?RFOq`^4gEYd(zL&06#)07#}}2a;;7}^~OGgVsaZDI|`*1JJU9- zO_(_k?vRb@nD9^I11w#2O-%A3%KDhQ0>b>Y$-)oI^71;Ie8o`_Uq1Xt@lxh|Mkc^4 zEavkR@o6{D#K`i;x`zLtp0THn`OgXV`lSQyJxss|ITiGYU2Xk&%lk495$|%7Uo?~D zRC&IGSpUd5q&YYXkRd(KN2lXgkiYh#rXWc)y4*4^;hUw4^t2-@LC54W=huf9n2;W& zyPS!4;aDYwrPn%OfnUxQ}L>m5u#5jYmM)Fk57Bw830FUKClsWf=2gDCcK182-Q-`bdPt4 zzlDYCJfXuI4XF4yD64;|I(p|}`S0fCM3X;ZG=2g%KE^Ttlz#D_y4Aaxvm_DM?q*gB z*Nw}Stlg(o{;cwx&PFkjC1Sl4!7sw}r|dC){@!-RfTM-`d$(HVtj{mLkyBl9!3s&g zR-j5^6necpIXd&L(oxc(;H7SLpo=-fzy2KOL*l`Gt}>SlLOU>L;-`O(*?fAc!g%zH zham5x%z5dh!G^nE3dY6L-8II&ewg$B`~O0ejn3J5z5YDxDBk2#&Ym&*-7A;u+FH!y zqh(4)W@_%Ww%h;xC=m%i*&SRWLy4DzhZY4@ahCSU?Xh8s(zEa5515xCO`s4ab#3G>IeD< zS2z=ynCB*YJkK_A;Eb~j5l~$Udi)3a5~6JR%TUzpy!{zNABX~joQi~>H6RHvz*520 z_0IwWa@fDXYX46@7gv=&^et*=y~Fg(FzJAxEfHuRa{uWXM%eEUPy$F19LbBGBqm2D zoi*SW(k@uRZSAZ9HGlz*{*V6CDP%)TcIZKUUWysEbY`{ixVklt%_7T*Cq)ISKqpK+f6A0uFPmIq|l zV0p8jdC=4J=mdD?QIRe{>jF(wW+2On#GovAmr|RE#6gL@(0RY;2#6yls`X7$z`DD z(cZ4Mkn?*b@^^b{hnu0NiaYffPjr)%>+!vn$%c<*b!$XsuxGT8)d||S+hSynLn!2>DgPn*guefKe((J{!yf!Sy{aU27>^c$ly4&l(fP8r&k`9n zNJIiTzSRS3`XL3$qd!^aGb`RdPvbtkD*yG%3u@d~{SzC}rsJ0&_#7v4rV26)BD!Jq121V$6&oI?gzj2A zTB6ZQ`lP6FQ!ei?+I8b13{D) zeoC0xok9WbS^89(Ag*qI&HvD>w5X^eoEEQyKS&T=-GUHWV-%O;YG{o@!xevZ93^aj z5wv*y#T$G)04}YUSvjpv+G{rX?cblO0RGGAP_Vp9MAPZ#LVh-E&^j0L^s^e_2+$;M zb*5lxaD`^f?7*YMMTRhu)(YgB(JnxR_o9G!rY@>_IdVU^04Z`!NGb^s)<}^Xu7Mz zLS~R&bolp7g;Cd*ZQ>U5)GzQ6^QJZ_!SYFDn;4UwNH*v53c;qO*{kW!AsgSTMbSfj zjdsk(+i&H_DOFTjGN{`!Y*H+P!*LZDqgrW0EC~(vw^b7L%DrS%g0TK>gF1N=0YSm) zD3OK{_TzQiJz$m4zvxtI9RBWAnkGitq0v(2qdV%45_mL=&(ryi`{Uo12ywGV9Ug;!VleAWrH z=tz#Bwb<%zE%Z39&XTPztJiA*bGm7vu9YFzW1yfRRhW4!y)s;EJ6Wr#Aa3*J26CY} z62~?w-3)yJFrdB|XNzhuurk_Pp}GJw~!ud^xtlp1+PP%C=qs| z%9;bL}4sceT9U|`#if)@jYm!#9$ibPZ_RE)PDu3k-&;Y%zmML6{78)~wQV0$h@cS^WFDvF zXk&5Y@Z3;rzPQj`ek@vAd$_$|tm%Bmur$W^O84RhGgmYI^N#=O<}+L>FUMPSGyk*T ztGfvV|Grk2R&y-wjj4(p9n0B&u<-mbZc}+0!%~vbZ8$plL>lYqH!1a5$I#mH`JRn4 z24OgPG+}QC`F!8_@GporT0NogJpvy%Nl;`DI_QP!-2{D{3bF6~UG_RvJ)B8j)K_G!Jy9i`(%ae4fQC|m)n zh=#vE?+0&~;Kj#3Nr7|Dv`;nqXgqplBZPL4LTM`xY-{OyH}iR~uScI+lj$xFSw$Ta zT$AqF+?^tV3F?D@oJW;TebKJ(cCN-MZ8k3XFG*j2CfRGm|Mhe#5NJa9!;s_s2jBU_ zg3JIh><}jLiG)lfLASo3tjt%d#u_n>{}N@R6RfnZ<-W0pq}VG=wc2)Uux8rh$RM zL|Gkn0b<)NJleX3ARwSasu~~cJdf2E4yLm$(6!Afr&4Ba^QUZ!G%X}%HX+m$g4z*@)Q|W*VUG-Wi!iLx3&u} zkryP@{c=+jZWfN(j&dUheJeN4bLkRm?|a>W*cZxIht)lO}FmKm50 zjpQ~I9rtesfg*8rRlq$nK+cLCOI%`h1vPX7S`9;tA*7kPjY2P>B)!R*hQVH3PScU)wcHH4+SJAAnOW#a5GG{*$WX; zSRP2q>&l669i|l@xH%`yPfA8kiFRpfz(-G7!Xc;dqw!|^s_Sy}QUL@zry;k7d0xTh zwUcvl04Fr`?QWNc!1v#Dt+|8bF71!Le3s=OCfYDiGm&eT z25X)n!7oMjt>R7<^go_YjmhDZG{Eb^a}hk`fyK2RRr(W`E2qNmXA3{Czl|@YSY(e=B zO($P*6c+%r7mp>n(>Id4&++*kh10LI!#>SJ@wL3E%}-<5t!PG2C(7zHrTY2PB~qN% z-amqaERxHSy`}{#7YvV=tK4R4 zv|Qp7;BLfC*wx2U-$79!n)wf$P9rIlZ2A=U9}eE_RJuWELowxD8{C6sM8)@lN3QS+ zp{}*UBW*=cpU1BJ^HdUl{^z5RY^c1kMR4$>ra(0#i{hR~bW|(r%%W=7Ur^=`al>dG zkUEHJc(Jp@UTjUd%FJZNR|8kZ%ySzuge-Zke}F&aAdgT9Zx-wdTk z7r*i0I>pSd?4lgnQu8*zopu18dI)k7i!5{ z>3Y3}1B3VzKu+?i79(ol@BY(M>H2FdyH+2QFQp_>nshNHn7`IVBo$}b8RB_sq9lm-zDR9dM)5ExKFN^dBhBlFq6c8AtXXu!rh7bh=>29QJ z=+5(E0RMCDy}x@uoDcV2KaRZn-Fv@luf6xP*7K~rebO9$0X20MIMNbqnVUJHzPE|h zi%bRbG!CU95Xx1??q7>by3Zr(E2r8)d_&Icup%>!Mt zyI=e@EPRmtgb(E&yx6*`2lKh>FcI<=IX2a$mnO>TUu4!M^zc26mO8xKkfRC~f9z z(QBkwY8Y}ic@zoTE4_D4QXqZz3bJA^9e4ZXbmFYXn#zxs@8^vaI$Z_>kDRmSUv05^ zzi<6mj)I*)gBz4j667*R@?t0T=SUxB)oR?tQvarh9 zlOnd<)moe_@6j~_L%GfDYR%=B(aKevku+O&oz2I_aRSJAh=?y zLK9T_VQB2u04IH?e5C;azh{XG-zSgW?RL{4cF7RoR~t*d1mGY`DU!UM~<>> zl8o&{%Y%a#l{4J~OXy>;C7St_u*yNhuxfh5f7~6c2O}$ao)D`$VaoMW40=K~?h#wj{^f>Cq&|Q)wuDu%R{* z9<)1JxwdJQl-B%0+X#1mueR|Z&N%3;-A{Y7?XU|Qx=9yedYP^>}RJ}k1>XzS-VKkyS^25!bTG2ZNK)owx(BNWSRO|f+wjNDJ zlJW?(qM5-0#m$bQgEqKrsW+>09a80vvk5X;e)s;-cC?4bA+u^^ikih_B!Y24-w~U2 zSgO`=iA;!JI4>L4u;kra{hDc-Z|Ji~k5ZG2?c5}CdPGT-j;Z{hH z@)%x)7!qoH&@N#Ze_v_R-f>wGoEC?Q-u= zmPh5IvLl$;;XS5VZ&y~O~Yg`Io?Nm@jhQ6ScgW7SApnjp0OmE2-I!;VHD z@BCH}0Ber>Sxqmm(>rTm_ZIX*r zPt0!)(h4{#(qp9&vL(U#ShD9uD^paL;P(arc z4c42VLF{@OFB-GhRkYJoLR-Vtm~1f;f;=wtTd$8C%a}iCLQts+$i*pjR>lyr3Jwd` z(%Gk86PJkk4z`Akj{&2RI4{>-Z01DiYWZI9Jht^Af~Z^0<%+;AZ2gxAloX_-Uzl9| z-NRlc=IGiYy%qccJ;I6e98p7r)y+xTM8*aGgkmN}d#NKEmwtOjk%P|hg@(q%S@GCz zUO#`Sfa%shJ9zS?J9b?ZG}1kaAFs@ZSIAAzmA18Q?A*jtE?5{ z$mvav`6{2S>;kAmI8|$X$XUGHuV|ca`_MLtMY&5qVzC&@&;j?5B^j-KPd`t@r)pYp z4Ply58iLn5>AsoX#+oB;LFnDdlua1Wv2+{K?p9keGPA$424ndWM)B{aIT8IEohI8l zM*nNiQ;Z3Hlz^v#5jdZxqBu|D2>H@15FjKEd7nS6Y@hP?_;Q^5#VG=S@+M|2F=yg4 z<}P^lxL-qAF^T+T$O%6R%~yDq3rOMJ-9kI(y?1I8 zqNn)wubF?XgZVB2sRw*+6uN|G;tUFGfLu~)=alZhKLa{poB`Hl4B*5Nai0lx5~4G~i~mnG_>MA! zuhR2F6I)KS;&! z$BOp%rD8+|+%dx6vW(6|i~wZ;IrwNfkUM#GqwdrDMTBj%AgZMwV;w(9OvQ_5bmPnm zVl#eQU*yKI^^uVBkzFk8QB2*_GmKxChJvI%mnR!p+W^n}F5cRm_Wf z8kN9!ukGsobNPG-=l>+XkZze=-o>s5jf0f+`6OV+ZOn?TqL-UzMzEN~qc=K-Q|TjF zMva#TtiUK4d|=%%4FNs(vg|#l zgOv8r!RQPuP>(j8F@7*y7QVdC)boV?iW+qC78UqYWer33a3sT{a0KI7ZuaqDNHi9D z*~dlNP<0n|@7wIz-fk{TOlu0#sXc45#{vux#sGO9Z%WYBue*(|g*kOC>HU+9d3@H9 z%}~Tt+|swPDGv)>`hUwLSDqlu^=W}T&)aYwN?&0j;?f4LU8lFC6jFy`9x=L}h;VLw zT_$34_YYG@+LZpF$&-P5krvZ^&V^Tz4Bk$janh`HwIS`~0JqjRwDH?_`^_xy#_C&N z`q%r80;}f_(uB6FV9XIO7Tu3TEf44PS09fo% zR#P*EY8T}KSs|Y5WtrJQYbR+!eRts6bjLX_gFB=Lfj##fr^;A9w`-#hT!h-n#)L=is?kG6G|4tgCeKM)@=0ZI(ME%*Ndz$~`s*2f@joUE8o$S}u5%_`xw7MntS+^;%Gso(Bx zD4G{uLFZpGT~AVD&q+^5sCSka=>TZkrKfe*PQFMvjZzVGvM53=4F2GwN`3ea{o%xW za6Ep%?bpHRZ|qX|8i3{@OWr70{K)}0Qfi!KPJsP~1u3q~EWQUfSkYcIZ8DZUIhjX9~R9kZGkG)Kcr;~EH z0#Z&jr8^sao#6*Ry~yo9S@M3;6h&*cJf^13!);Z&9ekRv(8`b3 z;L+qP`h=Y)wLHeXOoI)N$2zXIlC4>#t0@D|hqf|qLOkZvcCjza`e0JTG~dGCCW#sD z_1-XG;&KlG?Z4|T5HqtlCpj$VmZwRbgvWf7zp3xOoGP&z0dY)1rt|=fOESlOy4C_% zY8iinOJ4gqJ~D!*CsR&g&fpumMdFs1dY{A0Le_Wepj&HLpZQ{T!%L3+6}*ja0ejB(S@6A0wF90a)ul}*U~f*R}YVQK+KK*FY)Ec_0R*>^Km6%KBW;?Z%Wj^ee7)GA4=)kq;PgOW`W}v zj`bR*T1w5fzl_#}-jLd-K>v8hvHmWuWr`jzz}m}Q7bw5{_Ytr^=^dpfk(;8UGYr)d z2xx)xeLWnL`S9`5e~SY5T&x<9>Qv}t*jg17yS}gB%qvR~D;v9Z`cnRMu%5>ilG_@! zhnaj&i3{kDbF<76yvj$G#uY2-&5x}6-{4$}OQ7jF&1M`O8RMwYA4#r~?0VAoNWk6L#_NJwQ7lcsG|uzD{;x{%@Xo| zACiUq+?S!ySC@U1hSIpv%$o{mMKMC6RY2Zp3;B%cbjSslo_Nk5b&hX=`imy5>{yf# zbOQY?@9<9@DStAUADph3A(7e>)>7^Jo|uC7ASL%q6V0R(9(Hgdd7scVaYvhf`2&E6 zCMB+)|HsR?lD8^pP$x%1ih2v*-E%}S{7%hM{0wYnA z;2U&H+=MzZlHOX&G2DN%zuMhtUe}R8jzaVL@=A0KbSm>cQ187A*x1%+ISZu|-D=p` z*`b30Y^ZACgUsS$Vx7OUSFZ%GsFqk?E}^`IOi?DDdYKZcwlYJqeQX3GGj{Y~micm>C=VR6g#Wql`~$ zyUUQFk`r|YF@FrWF)9T$?9&yy;Q8r~{I0JxE%4ycx!Lb`FyvOJ=I!tV7`ZQ@McLx3 z0mmoTH?oxcfTkt7J^4H%FbBUhQV}fPBG!r;Oc^E(<6_&ra)Pj_D;f}ER?-xj%HVkO zmSTOIh+vWDipOfluSw)HGDuA&c?QM&J4V+W9PtmoGDnD!vEO#$``q z6f5$8h-m*Ow>21bdIblM?LY~;3diPL!fL;z&ONJ5UDrf|{*QU#3+R>btmNX}D1+>{ z4Xuo5Y~jW&b(OH)G(qQGd5@)WTkGxmMCk5&EmXZ;+FTd1;isT~H`+!|gjMvwsAa$9 zmaxBb_uM@41?-+va%Cm6u5%ns3M=YeSq|o?u*i9i4mp*w$&ypPlLtE*&k;14yD;*? zGjbSX9oN)@P8ce?DGC&j?BaT`_U=g;AS}B3O>E!uqj())vPD=_@7>8Av7=oN#>1Kx z!MW+Y!$Fva_OSYV*_Wl1bg+1G!1}t}QtwCmaA*)jBVQb9pw}O{J)l)+p67aXqfv8j z1O2u;8)`M*Re&5Y3(YE&YzatGZ?UZ8dF5rx?8)1C>p-ljp`j64a#atSCroOc;{H%}*})|_>z|^A?aZkmyeVl%BNC|9 zca5xzmJK-b9YX{Z`KmtD?be``y26-EtZNc>={B>?_s5T2nxOs)zVc5j#lN&@)Oh9c zg@_B8*s3}^$4&WtTK@U9b*%HBI`O6cSwZH4cpGFFFWZ7y0g?H)>_2;Cz_wpCmde6f zz--~s?BMOy0p@-Cu2HwDSR`Ofya@49bVFQbWfYmF5%tlghJ-I~aYHgve4jdc$!5S> zo#|NsKIX7F4N_g5%D9Ox8af=(+d}p)sYaJv9p`P>da(W}9yaz_hHv$k(A$x@jOnQ| z<}J*FjC0SAL{SC9i_k*eG4WFH)J~7sGAmO<`O(_?jd2$Zsoki(gym|9>8IEOSk|O0 znHtF|KpOps7dSE$cQ~-<(a?NY2m1D!oO-J`@(|gC8IVOAQ zP+GsR;c;MQyECM02_RyE21y$lpuMi*eT++9Q#l*H(gyjJi4HFYH!M=cY#2+kr8cCz zng`un>ik=_jTTYkrl{^Y*uK+i7wEq0SYpoW19KxijTD{Il?#NKZFNMPrQVTZ`|I;B zj`mAkvDPBc0-3SwqGk@C4!%A!bQZJ-;;y5t{8@a8GzVk5HpNqzrtdirRFjKvHXjjO z)U++%bA#CB_Oo;J@8YYwR!&pvW%3P0e%l}O5*g|9epP-2P5w7=kROC=GPiMl_Gd>3 zx}aI;+RxQ^7VvpVyeCFKFFMgXV19L(WqX9jWyUH4;H|$A-Cw=5-+ioUE1wCCT6*eSghqXY-J|FC$+a+^laAz zrfO2W#kpdHz@m<6#>1(7ic2SA7qo}C>QslXxCiQTAJ1f$mPMc( z0+CU?HINK|UX>DWKPb`N<=jEvj)18z(@%2P?1wbD&_f}HB>*Ss7PeNkC+q#v(*bJ+ zm#t}K>R9PSuNn`22Rls?cQqi2Y*sWY7C z$73u;_cy@R)wy|(`Rwj;nU>dO@j-Km#if?|wmq(W*`~HK4TVgOKt7n1#|IBpv7aW_ zlV-UzppQ4cX}CJqBvniFO2xQAa8=rM4$g;rks~b+u8MfQ8bWQ>)Ai*`wXeaSyZcrj4Vlu zrcS^&(!18k?~Q~ECDHUl$z5X{-eU3GCNrc zjo^-C&&um>sHiUJzD+0wkfUv<22d6zDJdyl1!CE1tXe9O@u5>q1{Aj#hqC4#eRwM- z)2|iKHB?$FtD$BhJ2c-dkRrMn78YmGVfLMAQ=?~8*TQ70Ojdo4T2SAkNi&psYUfXJ z4)}eN3HLJJSNu8Iify6NlbQnO2%$n%JsXPZO*6>Pd7DJ|LxQvItD;7>?yArvQ1y*L zoy}!+gMlVHvX>A9e7)N2;W)$W?#mD2*Zeclou)uBI;K(H*9~xF@V*YS=j=Q(r_a_z zb%TlECPylrs3t45EW-gvk6hZ_DoYB3h|9Se9G2n&9k{7;MJM$OWwc8Cja_x!t{_QE zYqVX$4B9@iPv-4%l^pG&CYoSXl)dF@5AR(_TP` ztH!!vNonKuB;f~Ygs^kNy}bd)oQfrP$=&9nypOgc!E{*hetG(iCc&$trPqdpvi1Dk zdzDo(WS}xZ8PqHRFw238YuzA}PQDeVJmf)y^|&y%T(_tt^tIA#xJn=ms|Bdb7VI0< zANj8~0?QsisEVDTXZJ_V5+1-p_zk4o`ACAoyE>F-a>Tn>Guo`m1XuL5q|ovA`zqYTDiO9QwgnAr+Bry>TD@? zC>a!9!>%J4p!sY=4A@&yt5uc;U%-k+3IU_{`mRAR@BdxnOKt!t@h#6NgiX?`Z=XRo z3^4UU;&66`x!H8odPmN`zODZEEJ;U1>o#Fc}BBITzA$eYCZgdFAP#k=iB7CE- zWg{g=ZBdHx>U1fcLZlkrXRqDJ&Lc0?lvgfDJEObCIwWLeT`%rCg~z=hC($-=AFuiL z{SWmKpv2LTQn2u^)R2;WfHXb%e?)|5cr+iY!;EUQ@ocTwp4u~xyQ!C2-PIZ5g}9I` zOD%b@MUg%Op4&-1rNWbYpHShkZ2zUgd&Pw=P&K*7l>6_@FL|1_RO~14P^;+JK=#^k zJkY~O$zAFja#)p4jIEp7W@%U!wpLH6HQ9GE z)-x2_fep0yoOHj}23Ap?c_=y|E6lIlQBmwCcg1E!GCB!+c+7tH*vNOTrkDN> zmPT{7L%#{&x)n6}GPhIpxzt!`c&w2MUKqu{lpuF68;eHZu*>F=Zq+-aVSE z($izBCWYXJ%aTyZKa!)m*k@*DFh+rPr2NSrFhCQRJwFhi9x#>gI&n(_vtc?vQ0=kQ zd(Jg?J*{<3Xk`W#y{;ng6}VNyObx32`{T?frdvJK^9wSNofPtSDAaPPpyw(J=fmT} zO@6!65)OFYg=`?m>Fv+#z4~}@c!sxv4+sn`Zi}ihn zS8TBl(TNT9HVd-1Hiw<(5&C|YLsHNcbHVE`d&CP{Dj0t8jWP_%%fwVkFp}9N@snp3 z-A?&7j?hQ}R9HIoz1EEOCIWv|#D@D(utwg@oN@o!*Rx^MDf0aVF~eJQadExA$DS&) zak@u$XlJi`9aJy_F-I8%n%rtH#a4_@9UcxJJu*`Ixst>}oBrlzU>M=A4)Y!oOSK>c z3CaHhraCH>)JH&bMBTp|$XhEMYR?Wy2>h)Mw$RKPM8&TZ>H=3I_kdUss zh~3xOliyNA#}Dr#5n*^l5JQBVN>vhW=X!W&#cZilR--+m^*8MoK$Qqi9r<=gYP*2|u3F#=0J$j$r8?*JMQ|EuRg+4l5n#6h~Wx^R{^0<3I? z;c@_=W*$gL6cle5k}&`GnEhE|$xQ32^<1ImUe~vMepcef(Twsrpm0N0(QboI#5h#iR}h+Q$#~x;lz7&UUoQ#DF2r2t}3J``QP|Vs+*}VNu-*Et$#C&HZpynO2Oy z!E&;9zt=MeZPD9WTkq{igU&9D+7p3gz0y&z2oHAmo7MB*)F2jDf(V%q)BdE6AXpCo z^CTC%vtqjsaHD2XCPOMDGi0mBCkuqm{!~a|9MVft5?(@*If{6}HlBUi?{&h9u3>v$ zA3s6}n+jWk)S$Y@M_2K8LCu(7rB?hsI=@PP!|)DIz^sInbr<;vNE9N!-jAE}Y}|d& zw>$bX{c`9Sq3$~|q*~I)GtFG-WPB3cBqxX6Xj@IfR zGEXMIG$3lR+UZvlH+$V02}OARl7!%bxR|D%v^+TqhB6XW=vE15cO3!ov3}4?VUxzO z=MEd6+{Y2PDG{Boo&_rO<=Af!S%OICat=PQ!VmEC!)wtiN#`Z)D>44p9E%7*`{tPVp1;OjJm-X`MaA+B z&(DtU@yk3p9-iA^;#;S&tspLnRsCx`>adFKa_tR=)O-b&K)e7tY?vQD2m3p{-Tjv) zeWuMDCt)isj^BSzvudj4@lf{#nQta3#ZMCX$J(sl^W+S2;XfNV?mSLkG5#aVay%>i zxjw794IXT4JTyqtM?WO+`FPf9ObmS}_&Dq!?`7Ww?*9Y?#G>xsr2T`)0*_3Tg6kdG z$WzPd*gypNi$4%_a%~8)l$7s>9@SqR;sngRY{afDo{+1}3Go`N*jlKY{J*anH;s-J z2M|)%BXA_dzbbuy((#hp0jkWv@%SU3YX#}$J2K|221GrbmVX@yU)4>?o`4tE7m3<+tR#LahT2@e9tzO& z5p*$J*}H~_H*zu{mCpRuXcjef?p5)b<)lr<<vIv9RbL51U*uD&eui%ql>Yvqv{r(&Eid`sfYk|!OV_?JCwt}QJ%d+yM@LX;uY}cu z8&7gBaPW#q10F;A(UmlQk%mze&wXCM%z`Te~n_QDb9 zu@4-1-Yqw^gtxi9^SH7av7ERP0nxA53{wv?B(`lVHJe}mTg=8tFuwtHeD^`Xjx`39 zUFLFJD$FS`j~UTG67>kPXtgrdTgbq#T9dxXjHh!Fb-Db8L*@-N>x+*w4#^HWEVuCj zdT*$Rmh?v8`Q6Qee|8r}Gv9JOc?o|Z4l5xUSO0!U^g~=p0hc*u2j{?mxvZGeeSYnlJpXTIk`E6{jPkNPi8CU$nKC;B>scy2rI&yKXna&N^K3 zV}}dRBmHNbfD0*M4|TW_u-&ZaxUpHnb7sCM-jF0;plD!cPa61(mi)C8Hx@8;(gQ%} z@cNl%VgQjNWA^VZXJ&K47wFa12gWvM_W^m}O3WMiT;$A)R>6QPC%?*zKD)1^0xmyB zHt#gn1u*}Q6M=}xV{}gI*@0P9ff324^jk~r+ zjOOaG#z^(UDVoz53`IR4m3>W>4Rzx1fLIziU^uIz*Bk@SjLn!G=t~CGz?sPnB?7wa zwj5gW_{`XNkH3Q2JM5W{RgVvJ`TzIRM?uSSfqqp!b?-l)n0NvXw!b(`iT;NQ{GM{Q zb5l`}{)Ly5f=2o!MO*?tqT?;7jJ1Zb#V=NID)S=+ z7&7gQKxnR{^bPQv@zYF);{(d2ZI>~55BJ`4dlqwp?`b$MXO!b~%9L}%4UzA~lL^@gRT_~-hI5Imd*%yoLWUbA= znO4hz8PBP@&Q$ez7DN2WbIc$-!F90sZ63~NBO(!O#CVuZ%~wlbX75BJ#S%fHw$2Pl zMttrLJIW?!BA$ZnS*w{GEqL&-ttEox(aIl@us?2;C63_oz!f0H{rU7#@vE%fJV+Kg z1!ruZsT)w;fV}%F$8`L+`BI~CpKGuQ9?bbUmGm~0x1OT7^@RHv4%CY(uXw?+#WmgP zN=i!3JTc9wDHBGUy#-loU&k$W>v z{u6(ncjZp^9_mPvHzfUM%w zN91dd{^QXOipqby`(xd09!tK^86Hwpnds=ywF}T33V}OhpCeDXr2*_93tF<1it=k5 zlGY`a83e~)az$)J zFPX=!FJ3`&h65QB@)5l!sX1V{7OCfMpN7k>7VWOp6@I%L1CAkj);D?zTDNXU_i^N4 zOn53+#mjc0%Af#FjrBR$$}EjWW($oJ=J0M$C%9&i9WF6J=1p5-jHdPMUM7l7Crn{EZvTWr|nan^;wl1 zKH6?89+%Vo8w`&jP7fGOH+ovMy6P}s+335uowT*f{`g=o$8Zn3X9fhV7_o5t%~cH~ zLV|=ra&Cq}eB=czQ#e$XKEZ2qGPfbSd~QV0qMb?=Y**6Z{1yj?tV!mPgj(B<8HCFg zsA32$Z*xEF$bZa9H`84t*Towt&lz}}?N;28-It^{=$Xp*KW!f10;(5d8Pm|+b^7iK zJ)N@YY{snO;`CZ)eaDT*-AD~Zj-2$|t&t-kn*)FWY9oEsKGeYF*LRH_ql|_&@2d=B zNU9;v@kyZ0D>le;{9@?^(<#pPOSe#R^ShD8O5e@tA3S(^s)5pKhnIsn3>NS0x5}CH z4=|SIX5&UV54uMRUT_{~znMzfBHl5)H)^!EGkvcD(Kgdo*$W6j$PeWp3RxIcK3nf z=WFhB*XgS~UV!Prw_>4_Ezp;cwzZhhlKHM#v#yS7{Gm*aEL&z%NKFW0RLb#w7ez>}ZU!4A51;ej5+T z-ntj(Q0L3xjCx(kpyMnHx##XM^J2huXc8G^!mGTcP8xG15_)F8Hoxu*P=hwj7%$#qw~yY)TBp(FJ>-QET!NBecNhj)8)UE>ax$7i(3wWdln^?+m-AWzj|W6?f( zWxLgWvpaocJSruw4F%}+1ZbX~LRuFHHv6nJyo1K;6bm`BOW9^O5bkX&w-by+7RnR# z9A=&E2i`M+s=3Q&EGy-GCAMtzu*)@@=wtnehK7cPiH_!ickddCVPECrP|*DeKw*O{ zFlu&7%!GV_YU?_50>R#NIf6(U7#&^B^Jet<>~(3Zg|m~P%G$kLOu`IlCHe4=ku z8QlO4=NZ;iq5*}4euEIP>t$<3S@ldJr3MMEBoZ??p@zj*d*1_*Yk+MavkZw8(D$^597o#rXM1zkZ-vq~H;4sBzv0kC4@5HwWOu z8VFMemL3aA0NN#jLE+1_R*IUHT^eM_eYEUNz*5D;xBDAg#4W9In8amQ%a&lqL`?3w zgJQ>QhGE!zU$KdT=vp<8DmGiuE2GCE--_!V^gNPz%29XVWw6A z%uZ=y7-5UX(rk`7lGhOs0W=XSNMtf)usA}>4!$QcUN{bA)nJFSOCcX-l5A+O(0#h?jq`# z?QmYgKjG$&YJSw$^;y15*d9tJ0A>7g+ke7_@TW%!bjGrPS%ilz@SG%%no+CPw*9j6uv z15VvDAwC0Vb_|yI-#O)T`l7;hP$|a$dy+xti0!YO%>fS`0nXn$2m2)+C(Z}=+!%0n zKjufA-UL}Hfg8x`-j3tendAI70LA)dfA@^g7}yI42Tg3PO)sAA{1k5h5bJ-l))EUh zn2vWMX1{y%?2GFifjj557OrC0nX#?v!=L5JDZd0j>zzK}!10Kd?^MbVSj_it-gWMm z_Xc6yor23aWdGka55P67@_)bP)Q1>9zxoT|XDopwlopQ-KcIc=OF7Qytux;q4A%y< z+q!7v&tCbqj<0-2lsKp6h2v`pT<S7=6#u`CVeqac<~*oeJ$#!X zmli0{Q4SfT*Lt{1zA0;(Sb8LU%>OjjU(H2S2lOGqWc+Xf0h4~>~LkEX#PI7t0 z>i!Rv)fAgX6jXaxSSB(u(0cdhebkGUG2^|03#TX!knUaLv%32GDHo!K`7~KTI0W08 z2V>-5^Jf+Z7(PqTISlT4M^iHQm|+d>_!^~NX#8wKO+(en2hIfh z@GY|hRTU4;cx>_3wzD<=@!P~{^0W5B&+JQJ11L|c7v^#bqO|0;{3^pa?kkN?^s7kW zN($8j%oXV7ryVi8Hr~g~B*4jrUuEGP2MM2$p%Beq4Y5C{YU^D<-8TjP?wzc7aEu?Y zfK*h-;4V-dtvJ>iI%5ZvFafbJT$XaGS;u^hhI5_v!w;D=H$%V|#Xbe|Ea{-Fe_0+B z)~9!}xSKd%r1&C&)cY#A#m1B4q%51l=J2JD{h;J|L034;8~R2hbBb-gq(4NK42qY2j!3AtUICA0Kge3;0^MZKimH}vx4}e cs*dnA77E~o$v-~e0RLnjKYf%f`ONQs04;En<^TWy literal 0 HcmV?d00001 diff --git a/docs/static/img/text-input.png b/docs/static/img/text-input.png new file mode 100644 index 0000000000000000000000000000000000000000..e8f8da24891524bec276d80d9035c97b6a82830b GIT binary patch literal 39820 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 literal 0 HcmV?d00001 From 1dc0254ade586cd58c48c000ff93488586b61a8e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:37:18 -0300 Subject: [PATCH 37/54] Update HuggingFace Spaces URLs --- README.md | 4 ++-- docs/docs/getting-started/hugging-face-spaces.mdx | 6 +++--- docs/docs/starter-projects/rag-with-astradb.mdx | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8d243a0dc..894252501 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ [![GitHub fork](https://img.shields.io/github/forks/logspace-ai/langflow?style=social)](https://github.com/logspace-ai/langflow/fork) [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/langflow_ai.svg?style=social&label=Follow%20%40langflow_ai)](https://twitter.com/langflow_ai) [![](https://dcbadge.vercel.app/api/server/EqksyE2EX9?compact=true&style=flat)](https://discord.com/invite/EqksyE2EX9) -[![HuggingFace Spaces](https://huggingface.co/datasets/huggingface/badges/raw/main/duplicate-this-space-md.svg)](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) +[![HuggingFace Spaces](https://huggingface.co/datasets/huggingface/badges/raw/main/duplicate-this-space-md.svg)](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/logspace-ai/langflow) @@ -62,7 +62,7 @@ langflow run # or langflow --help ### HuggingFace Spaces -You can also check it out on HuggingFace Spaces and run it in your browser for free! [Click here to duplicate the Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) +You can also check it out on HuggingFace Spaces and run it in your browser for free! [Click here to duplicate the Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) # 🖥️ Command Line Interface (CLI) diff --git a/docs/docs/getting-started/hugging-face-spaces.mdx b/docs/docs/getting-started/hugging-face-spaces.mdx index c61a99f32..aa71db6c3 100644 --- a/docs/docs/getting-started/hugging-face-spaces.mdx +++ b/docs/docs/getting-started/hugging-face-spaces.mdx @@ -2,7 +2,7 @@ ## TLDR; -A fully featured version of Langflow can be accessed via [HuggingFace Spaces](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) with no installation required. All you gotta do is [duplicate the Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) and you'll have your own copy to play around with! +A fully featured version of Langflow can be accessed via [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) with no installation required. All you gotta do is [duplicate the Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) and you'll have your own copy to play around with! --- @@ -10,7 +10,7 @@ A fully featured version of Langflow can be accessed via [HuggingFace Spaces](ht HuggingFace provides great support for running Langflow in their Spaces environment. This means you can run Langflow without any installation required. -The first step is to go to the [Langflow Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true). +The first step is to go to the [Langflow Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). You'll be greeted with the following screen: @@ -27,4 +27,4 @@ From here, you can rename your Space, define the visibility (Public or Private) import ThemedImage from "@theme/ThemedImage"; import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; \ No newline at end of file +import ZoomableImage from "/src/theme/ZoomableImage.js"; diff --git a/docs/docs/starter-projects/rag-with-astradb.mdx b/docs/docs/starter-projects/rag-with-astradb.mdx index 3afd81fd6..54aebd2d2 100644 --- a/docs/docs/starter-projects/rag-with-astradb.mdx +++ b/docs/docs/starter-projects/rag-with-astradb.mdx @@ -19,7 +19,7 @@ In this guide, we will use Astra DB as a vector store to store and retrieve the TLDR; - [Create a free Astra DB account](https://astra.datastax.com/signup?utm_source=langflow-pre-release&utm_medium=referral&utm_campaign=langflow-announcement&utm_content=create-a-free-astra-db-account) -- Duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) +- Duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) - Create a new database, get a **Token** and the **API Endpoint** - Click on the **New Project** button and look for Vector Store RAG. This will create a new project with the necessary components - Import the project into Langflow by dropping it on the Canvas or My Collection page @@ -73,7 +73,7 @@ Now we are all set to start building our RAG application using Astra DB and Lang ## (Optional) Duplicate the Langflow 1.0 HuggingFace Space -If you haven't already, now is the time to launch Langflow. To make things easier, you can duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Logspace/Langflow-Preview?duplicate=true) which sets up a Langflow instance just for you. +If you haven't already, now is the time to launch Langflow. To make things easier, you can duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) which sets up a Langflow instance just for you. ## Open the Vector Store RAG Project From d976fc36feef721f89c6ea7d5a01346014c68f34 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:47:48 -0300 Subject: [PATCH 38/54] Update Langflow documentation and add new starter projects --- docs/docs/whats-new/a-new-chapter-langflow.mdx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/docs/whats-new/a-new-chapter-langflow.mdx b/docs/docs/whats-new/a-new-chapter-langflow.mdx index a11b87f50..70019fe6b 100644 --- a/docs/docs/whats-new/a-new-chapter-langflow.mdx +++ b/docs/docs/whats-new/a-new-chapter-langflow.mdx @@ -27,11 +27,9 @@ This is a big change, but it's also a big improvement. It allows you to define the structure of your conversation and the data that flows through it. This makes it easier to understand and control your conversation. - This change comes with a new way of visualizing your projects. Before 1.0 you would connect Components to ultimately build one final Component that was processed behind the scenes. Now, each step of the process is defined by you, is visible on the canvas, and can be monitored and controlled by you. This makes it so that Composition is now just another way of building in Langflow. **Now data flows through your project more transparently**. - The caveat is existing projects may need some new Components to get them back to their full functionality. [We've made this as easy as possible](../migration/compatibility), and there will be improvements to it as we get feedback in our Discord server and on GitHub. @@ -40,10 +38,8 @@ The caveat is existing projects may need some new Components to get them back to The moment we decided to make this change, we saw the potential to make Langflow even more yours. By having a clear definition of Inputs and Outputs, we could build the experience around that which led us to create the **Interaction Panel**. - When building a project testing and debugging is crucial. The Interaction Panel is a tool that changes dynamically based on the Inputs and Outputs you defined in your project. - For example, let's say you are building a simple RAG application. Generally, you have an Input, some references that come from a Vector Store Search, a Prompt and the answer. Now, you could plug the output of your Prompt into a [Text Output](../components/outputs#Text-Output), rename that to "Prompt Result" and see the output of your Prompt in the Interaction Panel. @@ -65,9 +61,11 @@ We wanted to create start projects that would help you learn about new features For now, we have: -- **Basic Prompting**: A simple project that shows you how to use the Prompt Component. -- **Data Ingestion**: A project that shows you how to ingest files into a Vector Store. -- **RAG**: A project that shows you how to use a Vector Store Search and a Prompt to build a simple RAG application. +- **[Basic Prompting (Hello, world!)](/starter-projects/basic-prompting)**: A simple flow that shows you how to use the Prompt Component. +- **[Vector Store RAG](/starter-projects/rag-with-astra-db)**: A flow that shows you how to ingest data into a Vector Store and then use it to run a RAG application. +- **[Memory Chatbot](/starter-projects/memory-chatbot)**: This one shows you how to create a simple chatbot that can remember things about the user. +- **[Document QA](/starter-projects/document-qa)**: This flow shows you how to build a simple flow that helps you get answers about a document. +- **[Blog Writer](/starter-projects/blog-writer)**: Shows you how you can expand on the Prompt variables and be creative about what inputs you add to it. As always, your feedback is invaluable, so please let us know what you think of the new starter projects and what you would like to see in the future. @@ -95,4 +93,4 @@ We also have some experimental features like a State Management System (so cool! ## Reach out -One last time, we want to thank you for being part of the Langflow community. Your feedback is invaluable, and we want to hear from you. \ No newline at end of file +One last time, we want to thank you for being part of the Langflow community. Your feedback is invaluable, and we want to hear from you. From 9de5e42cec8fe5dd257ca3ac1d7bb6db63978222 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:48:22 -0300 Subject: [PATCH 39/54] Update flow name to "Basic Prompting (Hello, world!)" in relevant files --- .../src/modals/NewFlowModal/components/undrawCards/index.tsx | 2 +- src/frontend/src/modals/NewFlowModal/index.tsx | 4 ++-- tests/conftest.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx index 8ba328cfe..e595eaaeb 100644 --- a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx +++ b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx @@ -43,7 +43,7 @@ export default function UndrawCardComponent({ }} /> ); - case "Basic Prompting": + case "Basic Prompting (Hello, world!)": return ( { return ; })} */} - {examples.find((e) => e.name == "Basic Prompting") && ( + {examples.find((e) => e.name == "Basic Prompting (Hello, world!)") && ( e.name == "Basic Prompting")!} + flow={examples.find((e) => e.name == "Basic Prompting (Hello, world!)")!} /> )} {examples.find((e) => e.name == "Memory Chatbot") && ( diff --git a/tests/conftest.py b/tests/conftest.py index b890f9b6c..7f7252243 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -381,7 +381,7 @@ def get_starter_project(active_user): # once the client is created, we can get the starter project with session_getter(get_db_service()) as session: flow = session.exec( - select(Flow).where(Flow.folder == STARTER_FOLDER_NAME).where(Flow.name == "Basic Prompting") + select(Flow).where(Flow.folder == STARTER_FOLDER_NAME).where(Flow.name == "Basic Prompting (Hello, world!)") ).first() if not flow: raise ValueError("No starter project found") From 781e7b90c478e24bb437519aa6960d5df8db3607 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 22:57:44 -0300 Subject: [PATCH 40/54] Update Basic Prompting flow name to "Ahoy World!" --- .../docs/whats-new/a-new-chapter-langflow.mdx | 4 +- .../Basic Prompting (Ahoy World!).json | 888 +++++++++++++ .../Langflow Basic Prompting.json | 1134 ----------------- .../components/undrawCards/index.tsx | 2 +- .../src/modals/NewFlowModal/index.tsx | 6 +- tests/conftest.py | 9 +- 6 files changed, 899 insertions(+), 1144 deletions(-) create mode 100644 src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Ahoy World!).json delete mode 100644 src/backend/base/langflow/initial_setup/starter_projects/Langflow Basic Prompting.json diff --git a/docs/docs/whats-new/a-new-chapter-langflow.mdx b/docs/docs/whats-new/a-new-chapter-langflow.mdx index 70019fe6b..75aa7216e 100644 --- a/docs/docs/whats-new/a-new-chapter-langflow.mdx +++ b/docs/docs/whats-new/a-new-chapter-langflow.mdx @@ -61,8 +61,8 @@ We wanted to create start projects that would help you learn about new features For now, we have: -- **[Basic Prompting (Hello, world!)](/starter-projects/basic-prompting)**: A simple flow that shows you how to use the Prompt Component. -- **[Vector Store RAG](/starter-projects/rag-with-astra-db)**: A flow that shows you how to ingest data into a Vector Store and then use it to run a RAG application. +- **[Basic Prompting (Ahoy World!)](/starter-projects/basic-prompting)**: A simple flow that shows you how to use the Prompt Component and how to talk like a pirate. +- **[Vector Store RAG](/starter-projects/rag-with-astradb)**: A flow that shows you how to ingest data into a Vector Store and then use it to run a RAG application. - **[Memory Chatbot](/starter-projects/memory-chatbot)**: This one shows you how to create a simple chatbot that can remember things about the user. - **[Document QA](/starter-projects/document-qa)**: This flow shows you how to build a simple flow that helps you get answers about a document. - **[Blog Writer](/starter-projects/blog-writer)**: Shows you how you can expand on the Prompt variables and be creative about what inputs you add to it. diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Ahoy World!).json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Ahoy World!).json new file mode 100644 index 000000000..4ef43f501 --- /dev/null +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Ahoy World!).json @@ -0,0 +1,888 @@ +{ + "id": "c091a57f-43a7-4a5e-b352-035ae8d8379c", + "data": { + "nodes": [ + { + "id": "Prompt-uxBqP", + "type": "genericNode", + "position": { + "x": 53.588791333410654, + "y": -107.07318910019967 + }, + "data": { + "type": "Prompt", + "node": { + "template": { + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.field_typing import Prompt, TemplateField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "template": { + "type": "prompt", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: ", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "template", + "display_name": "Template", + "advanced": false, + "input_types": [ + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "_type": "CustomComponent", + "user_input": { + "field_type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "user_input", + "display_name": "user_input", + "advanced": false, + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "type": "str" + } + }, + "description": "Create a prompt template with dynamic variables.", + "icon": "prompts", + "is_input": null, + "is_output": null, + "is_composition": null, + "base_classes": [ + "object", + "str", + "Text" + ], + "name": "", + "display_name": "Prompt", + "documentation": "", + "custom_fields": { + "template": [ + "user_input" + ] + }, + "output_types": [ + "Text" + ], + "full_path": null, + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false, + "error": null + }, + "id": "Prompt-uxBqP", + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt" + }, + "selected": true, + "width": 384, + "height": 383, + "dragging": false, + "positionAbsolute": { + "x": 53.588791333410654, + "y": -107.07318910019967 + } + }, + { + "id": "OpenAIModel-k39HS", + "type": "genericNode", + "position": { + "x": 634.8148772766217, + "y": 27.035057029045305 + }, + "data": { + "type": "OpenAIModel", + "node": { + "template": { + "input_value": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Input", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\"},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": [\n \"gpt-4-turbo-preview\",\n \"gpt-3.5-turbo\",\n \"gpt-4-0125-preview\",\n \"gpt-4-1106-preview\",\n \"gpt-4-vision-preview\",\n \"gpt-3.5-turbo-0125\",\n \"gpt-3.5-turbo-1106\",\n ],\n \"value\": \"gpt-4-turbo-preview\",\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float,\n model_name: str,\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n output = ChatOpenAI(\n max_tokens=max_tokens,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=openai_api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "max_tokens": { + "type": "int", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 256, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "max_tokens", + "display_name": "Max Tokens", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "model_kwargs": { + "type": "NestedDict", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": {}, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "model_kwargs", + "display_name": "Model Kwargs", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "model_name": { + "type": "str", + "required": true, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "gpt-3.5-turbo", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-4-0125-preview", + "gpt-4-1106-preview", + "gpt-4-vision-preview", + "gpt-3.5-turbo-0125", + "gpt-3.5-turbo-1106" + ], + "name": "model_name", + "display_name": "Model Name", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_base": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "openai_api_base", + "display_name": "OpenAI API Base", + "advanced": true, + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "openai_api_key": { + "type": "str", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": true, + "name": "openai_api_key", + "display_name": "OpenAI API Key", + "advanced": false, + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "load_from_db": true, + "title_case": false, + "input_types": [ + "Text" + ], + "value": "" + }, + "stream": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "stream", + "display_name": "Stream", + "advanced": true, + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "load_from_db": false, + "title_case": false + }, + "system_message": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "system_message", + "display_name": "System Message", + "advanced": true, + "dynamic": false, + "info": "System message to pass to the model.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "temperature": { + "type": "float", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": 0.1, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "temperature", + "display_name": "Temperature", + "advanced": false, + "dynamic": false, + "info": "", + "rangeSpec": { + "step_type": "float", + "min": -1, + "max": 1, + "step": 0.1 + }, + "load_from_db": false, + "title_case": false + }, + "_type": "CustomComponent" + }, + "description": "Generates text using OpenAI LLMs.", + "icon": "OpenAI", + "base_classes": [ + "object", + "Text", + "str" + ], + "display_name": "OpenAI", + "documentation": "", + "custom_fields": { + "input_value": null, + "openai_api_key": null, + "temperature": null, + "model_name": null, + "max_tokens": null, + "model_kwargs": null, + "openai_api_base": null, + "stream": null, + "system_message": null + }, + "output_types": [ + "Text" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [ + "max_tokens", + "model_kwargs", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "input_value", + "system_message", + "stream" + ], + "beta": false + }, + "id": "OpenAIModel-k39HS", + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI" + }, + "selected": false, + "width": 384, + "height": 563, + "positionAbsolute": { + "x": 634.8148772766217, + "y": 27.035057029045305 + }, + "dragging": false + }, + { + "id": "ChatOutput-njtka", + "type": "genericNode", + "position": { + "x": 1193.250417197867, + "y": 71.88476890163852 + }, + "data": { + "type": "ChatOutput", + "node": { + "template": { + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Interaction Panel.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n record_template: Optional[str] = \"{text}\",\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n record_template=record_template,\n )\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "input_value": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Message", + "advanced": false, + "input_types": [ + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false + }, + "record_template": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "{text}", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "record_template", + "display_name": "Record Template", + "advanced": true, + "dynamic": false, + "info": "In case of Message being a Record, this template will be used to convert it to text.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "return_record": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "return_record", + "display_name": "Return Record", + "advanced": true, + "dynamic": false, + "info": "Return the message as a record containing the sender, sender_name, and session_id.", + "load_from_db": false, + "title_case": false + }, + "sender": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "Machine", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Machine", + "User" + ], + "name": "sender", + "display_name": "Sender Type", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "sender_name": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "AI", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "sender_name", + "display_name": "Sender Name", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "session_id": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "session_id", + "display_name": "Session ID", + "advanced": true, + "dynamic": false, + "info": "If provided, the message will be stored in the memory.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Display a chat message in the Interaction Panel.", + "icon": "ChatOutput", + "base_classes": [ + "Record", + "Text", + "str", + "object" + ], + "display_name": "Chat Output", + "documentation": "", + "custom_fields": { + "sender": null, + "sender_name": null, + "input_value": null, + "session_id": null, + "return_record": null, + "record_template": null + }, + "output_types": [ + "Text", + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "ChatOutput-njtka" + }, + "selected": false, + "width": 384, + "height": 383, + "positionAbsolute": { + "x": 1193.250417197867, + "y": 71.88476890163852 + }, + "dragging": false + }, + { + "id": "ChatInput-P3fgL", + "type": "genericNode", + "position": { + "x": -495.2223093083827, + "y": -232.56998443685862 + }, + "data": { + "type": "ChatInput", + "node": { + "template": { + "code": { + "type": "code", + "required": true, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Interaction Panel.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Message\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false + }, + "input_value": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "input_value", + "display_name": "Message", + "advanced": false, + "input_types": [], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "value": "hi" + }, + "return_record": { + "type": "bool", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "return_record", + "display_name": "Return Record", + "advanced": true, + "dynamic": false, + "info": "Return the message as a record containing the sender, sender_name, and session_id.", + "load_from_db": false, + "title_case": false + }, + "sender": { + "type": "str", + "required": false, + "placeholder": "", + "list": true, + "show": true, + "multiline": false, + "value": "User", + "fileTypes": [], + "file_path": "", + "password": false, + "options": [ + "Machine", + "User" + ], + "name": "sender", + "display_name": "Sender Type", + "advanced": true, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "sender_name": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "value": "User", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "sender_name", + "display_name": "Sender Name", + "advanced": false, + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "session_id": { + "type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": false, + "fileTypes": [], + "file_path": "", + "password": false, + "name": "session_id", + "display_name": "Session ID", + "advanced": true, + "dynamic": false, + "info": "If provided, the message will be stored in the memory.", + "load_from_db": false, + "title_case": false, + "input_types": [ + "Text" + ] + }, + "_type": "CustomComponent" + }, + "description": "Get chat inputs from the Interaction Panel.", + "icon": "ChatInput", + "base_classes": [ + "object", + "Record", + "str", + "Text" + ], + "display_name": "Chat Input", + "documentation": "", + "custom_fields": { + "sender": null, + "sender_name": null, + "input_value": null, + "session_id": null, + "return_record": null + }, + "output_types": [ + "Text", + "Record" + ], + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false + }, + "id": "ChatInput-P3fgL" + }, + "selected": false, + "width": 384, + "height": 375, + "positionAbsolute": { + "x": -495.2223093083827, + "y": -232.56998443685862 + }, + "dragging": false + } + ], + "edges": [ + { + "source": "OpenAIModel-k39HS", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-k39HSœ}", + "target": "ChatOutput-njtka", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-njtkaœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-njtka", + "inputTypes": [ + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "Text", + "str" + ], + "dataType": "OpenAIModel", + "id": "OpenAIModel-k39HS" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-OpenAIModel-k39HS{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-k39HSœ}-ChatOutput-njtka{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-njtkaœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" + }, + { + "source": "Prompt-uxBqP", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-uxBqPœ}", + "target": "OpenAIModel-k39HS", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-k39HSœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-k39HS", + "inputTypes": [ + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "str", + "Text" + ], + "dataType": "Prompt", + "id": "Prompt-uxBqP" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-Prompt-uxBqP{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-uxBqPœ}-OpenAIModel-k39HS{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-k39HSœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" + }, + { + "source": "ChatInput-P3fgL", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œRecordœ,œstrœ,œTextœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-P3fgLœ}", + "target": "Prompt-uxBqP", + "targetHandle": "{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-uxBqPœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "user_input", + "id": "Prompt-uxBqP", + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "Record", + "str", + "Text" + ], + "dataType": "ChatInput", + "id": "ChatInput-P3fgL" + } + }, + "style": { + "stroke": "#555" + }, + "className": "stroke-gray-900 stroke-connection", + "id": "reactflow__edge-ChatInput-P3fgL{œbaseClassesœ:[œobjectœ,œRecordœ,œstrœ,œTextœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-P3fgLœ}-Prompt-uxBqP{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-uxBqPœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" + } + ], + "viewport": { + "x": 260.58251815500563, + "y": 318.2261172111936, + "zoom": 0.43514115784696294 + } + }, + "description": "This flow will get you experimenting with the basics of the UI, the Chat and the Prompt component. \n\nTry changing the Template in it to see how the model behaves. \nYou can change it to this and a Text Input into the `type_of_person` variable : \"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: \" ", + "name": "Basic Prompting (Ahoy World!)", + "last_tested_version": "1.0.0a4", + "is_component": false +} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Basic Prompting.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Basic Prompting.json deleted file mode 100644 index 9903a3ea0..000000000 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Basic Prompting.json +++ /dev/null @@ -1,1134 +0,0 @@ -{ - "id": "4cd8b920-a12d-4d98-b4e5-75b537f03316", - "icon": "📝", - "icon_bg_color": "#FFD700", - "data": { - "nodes": [ - { - "id": "Prompt-nzvwK", - "type": "genericNode", - "position": { - "x": 53.588791333410654, - "y": -105.1077989256227 - }, - "data": { - "type": "Prompt", - "node": { - "template": { - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.field_typing import Prompt, TemplateField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "template": { - "type": "prompt", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": "Extract key phrases from the customer reviews provided below. Focus on {sentiment} phrases that seem to capture the essence of the customers' opinions about their experience. Output these phrases in a list format.\n\nCustomer Reviews:\n{reviews}\n\nKey Phrases:\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "template", - "display_name": "Template", - "advanced": false, - "input_types": [ - "Text" - ], - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false - }, - "_type": "CustomComponent", - "reviews": { - "field_type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "reviews", - "display_name": "reviews", - "advanced": false, - "input_types": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "type": "str" - }, - "sentiment": { - "field_type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "sentiment", - "display_name": "sentiment", - "advanced": false, - "input_types": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "type": "str" - } - }, - "description": "Create a prompt template with dynamic variables.", - "icon": "prompts", - "is_input": null, - "is_output": null, - "is_composition": null, - "base_classes": [ - "str", - "Text", - "object" - ], - "name": "", - "display_name": "Prompt", - "documentation": "", - "custom_fields": { - "template": [ - "sentiment", - "reviews" - ] - }, - "output_types": [ - "Text" - ], - "full_path": null, - "field_formatters": {}, - "frozen": false, - "field_order": [], - "beta": false, - "error": null - }, - "id": "Prompt-nzvwK", - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt" - }, - "selected": false, - "width": 384, - "height": 477, - "dragging": false, - "positionAbsolute": { - "x": 53.588791333410654, - "y": -105.1077989256227 - } - }, - { - "id": "OpenAIModel-u4NL8", - "type": "genericNode", - "position": { - "x": 642.6764379749295, - "y": 1.4849847595449148 - }, - "data": { - "type": "OpenAIModel", - "node": { - "template": { - "input_value": { - "type": "str", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "input_value", - "display_name": "Input", - "advanced": false, - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\"},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": [\n \"gpt-4-turbo-preview\",\n \"gpt-3.5-turbo\",\n \"gpt-4-0125-preview\",\n \"gpt-4-1106-preview\",\n \"gpt-4-vision-preview\",\n \"gpt-3.5-turbo-0125\",\n \"gpt-3.5-turbo-1106\",\n ],\n \"value\": \"gpt-4-turbo-preview\",\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float,\n model_name: str,\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n output = ChatOpenAI(\n max_tokens=max_tokens,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=openai_api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "max_tokens": { - "type": "int", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": 256, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "max_tokens", - "display_name": "Max Tokens", - "advanced": true, - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false - }, - "model_kwargs": { - "type": "NestedDict", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": {}, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "model_kwargs", - "display_name": "Model Kwargs", - "advanced": true, - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false - }, - "model_name": { - "type": "str", - "required": true, - "placeholder": "", - "list": true, - "show": true, - "multiline": false, - "value": "gpt-3.5-turbo-1106", - "fileTypes": [], - "file_path": "", - "password": false, - "options": [ - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-4-0125-preview", - "gpt-4-1106-preview", - "gpt-4-vision-preview", - "gpt-3.5-turbo-0125", - "gpt-3.5-turbo-1106" - ], - "name": "model_name", - "display_name": "Model Name", - "advanced": false, - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "openai_api_base": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "openai_api_base", - "display_name": "OpenAI API Base", - "advanced": true, - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "openai_api_key": { - "type": "str", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "fileTypes": [], - "file_path": "", - "password": true, - "name": "openai_api_key", - "display_name": "OpenAI API Key", - "advanced": false, - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ], - "value": "" - }, - "stream": { - "type": "bool", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": true, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "stream", - "display_name": "Stream", - "advanced": true, - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "load_from_db": false, - "title_case": false - }, - "system_message": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "system_message", - "display_name": "System Message", - "advanced": true, - "dynamic": false, - "info": "System message to pass to the model.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "temperature": { - "type": "float", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": 0.1, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "temperature", - "display_name": "Temperature", - "advanced": false, - "dynamic": false, - "info": "", - "rangeSpec": { - "step_type": "float", - "min": -1, - "max": 1, - "step": 0.1 - }, - "load_from_db": false, - "title_case": false - }, - "_type": "CustomComponent" - }, - "description": "Generates text using OpenAI LLMs.", - "icon": "OpenAI", - "base_classes": [ - "object", - "Text", - "str" - ], - "display_name": "OpenAI", - "documentation": "", - "custom_fields": { - "input_value": null, - "openai_api_key": null, - "temperature": null, - "model_name": null, - "max_tokens": null, - "model_kwargs": null, - "openai_api_base": null, - "stream": null, - "system_message": null - }, - "output_types": [ - "Text" - ], - "field_formatters": {}, - "frozen": false, - "field_order": [ - "max_tokens", - "model_kwargs", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "input_value", - "system_message", - "stream" - ], - "beta": false - }, - "id": "OpenAIModel-u4NL8", - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI" - }, - "selected": true, - "width": 384, - "height": 561, - "positionAbsolute": { - "x": 642.6764379749295, - "y": 1.4849847595449148 - }, - "dragging": false - }, - { - "id": "ChatOutput-stoNg", - "type": "genericNode", - "position": { - "x": 1193.250417197867, - "y": 71.88476890163852 - }, - "data": { - "type": "ChatOutput", - "node": { - "template": { - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Interaction Panel.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n record_template: Optional[str] = \"{text}\",\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n record_template=record_template,\n )\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "input_value": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "input_value", - "display_name": "Message", - "advanced": false, - "input_types": [ - "Text" - ], - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false - }, - "record_template": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "{text}", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "record_template", - "display_name": "Record Template", - "advanced": true, - "dynamic": false, - "info": "In case of Message being a Record, this template will be used to convert it to text.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "return_record": { - "type": "bool", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": false, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "return_record", - "display_name": "Return Record", - "advanced": true, - "dynamic": false, - "info": "Return the message as a record containing the sender, sender_name, and session_id.", - "load_from_db": false, - "title_case": false - }, - "sender": { - "type": "str", - "required": false, - "placeholder": "", - "list": true, - "show": true, - "multiline": false, - "value": "Machine", - "fileTypes": [], - "file_path": "", - "password": false, - "options": [ - "Machine", - "User" - ], - "name": "sender", - "display_name": "Sender Type", - "advanced": true, - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "sender_name": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": "AI", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "sender_name", - "display_name": "Sender Name", - "advanced": false, - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "session_id": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "fileTypes": [], - "file_path": "", - "password": false, - "name": "session_id", - "display_name": "Session ID", - "advanced": true, - "dynamic": false, - "info": "If provided, the message will be stored in the memory.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "_type": "CustomComponent" - }, - "description": "Display a chat message in the Interaction Panel.", - "icon": "ChatOutput", - "base_classes": [ - "Record", - "Text", - "str", - "object" - ], - "display_name": "Chat Output", - "documentation": "", - "custom_fields": { - "sender": null, - "sender_name": null, - "input_value": null, - "session_id": null, - "return_record": null, - "record_template": null - }, - "output_types": [ - "Text", - "Record" - ], - "field_formatters": {}, - "frozen": false, - "field_order": [], - "beta": false - }, - "id": "ChatOutput-stoNg" - }, - "selected": false, - "width": 384, - "height": 383, - "positionAbsolute": { - "x": 1193.250417197867, - "y": 71.88476890163852 - }, - "dragging": false - }, - { - "id": "TextOutput-prj03", - "type": "genericNode", - "position": { - "x": 640.7986738161987, - "y": 724.7095283934595 - }, - "data": { - "type": "TextOutput", - "node": { - "template": { - "input_value": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": "", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "input_value", - "display_name": "Value", - "advanced": false, - "input_types": [ - "Record", - "Text" - ], - "dynamic": false, - "info": "Text or Record to be passed as output.", - "load_from_db": false, - "title_case": false - }, - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextOutput(TextComponent):\n display_name = \"Text Output\"\n description = \"Display a text output in the Interaction Panel.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Value\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as output.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(self, input_value: Optional[Text] = \"\", record_template: str = \"\") -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "record_template": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "{text}", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "record_template", - "display_name": "Record Template", - "advanced": true, - "dynamic": false, - "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "_type": "CustomComponent" - }, - "description": "Display a text output in the Interaction Panel.", - "icon": "type", - "base_classes": [ - "Text", - "object", - "str" - ], - "display_name": "Inspect Prompt", - "documentation": "", - "custom_fields": { - "input_value": null, - "record_template": null - }, - "output_types": [ - "Text" - ], - "field_formatters": {}, - "frozen": false, - "field_order": [], - "beta": false - }, - "id": "TextOutput-prj03", - "description": "Display a text output in the Interaction Panel.", - "display_name": "Inspect Prompt" - }, - "selected": false, - "width": 384, - "height": 289, - "positionAbsolute": { - "x": 640.7986738161987, - "y": 724.7095283934595 - }, - "dragging": false - }, - { - "id": "TextInput-ARFMe", - "type": "genericNode", - "position": { - "x": -496.0627119809512, - "y": 212.27354495043377 - }, - "data": { - "type": "TextInput", - "node": { - "template": { - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextInput(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Interaction Panel.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Value\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as input.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Optional[str] = \"\",\n record_template: Optional[str] = \"\",\n ) -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "input_value": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": "negative", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "input_value", - "display_name": "Value", - "advanced": false, - "input_types": [ - "Record", - "Text" - ], - "dynamic": false, - "info": "Text or Record to be passed as input.", - "load_from_db": false, - "title_case": false - }, - "record_template": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "{text}", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "record_template", - "display_name": "Record Template", - "advanced": true, - "dynamic": false, - "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "_type": "CustomComponent" - }, - "description": "Get text inputs from the Interaction Panel.", - "icon": "type", - "base_classes": [ - "object", - "Text", - "str" - ], - "display_name": "Focus Sentiment", - "documentation": "", - "custom_fields": { - "input_value": null, - "record_template": null - }, - "output_types": [ - "Text" - ], - "field_formatters": {}, - "frozen": false, - "field_order": [], - "beta": false - }, - "id": "TextInput-ARFMe", - "description": "Get text inputs from the Interaction Panel.", - "display_name": "Text Input" - }, - "selected": false, - "width": 384, - "height": 289, - "positionAbsolute": { - "x": -496.0627119809512, - "y": 212.27354495043377 - }, - "dragging": false - }, - { - "id": "TextInput-oKkcQ", - "type": "genericNode", - "position": { - "x": -501.8114356733282, - "y": -152.0266822138945 - }, - "data": { - "type": "TextInput", - "node": { - "template": { - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextInput(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Interaction Panel.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Value\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as input.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Optional[str] = \"\",\n record_template: Optional[str] = \"\",\n ) -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "input_value": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": false, - "value": "\"Absolutely love this new coffee machine! It brews quickly and the coffee tastes amazing every time. However, the setup process was a bit complicated.\" \"I’m not happy with the battery life of the smartphone I purchased. It barely lasts half a day. On the plus side, the camera quality is exceptional.\"", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "input_value", - "display_name": "Value", - "advanced": false, - "input_types": [ - "Record", - "Text" - ], - "dynamic": false, - "info": "Text or Record to be passed as input.", - "load_from_db": false, - "title_case": false - }, - "record_template": { - "type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "{text}", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "record_template", - "display_name": "Record Template", - "advanced": true, - "dynamic": false, - "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "load_from_db": false, - "title_case": false, - "input_types": [ - "Text" - ] - }, - "_type": "CustomComponent" - }, - "description": "Get text inputs from the Interaction Panel.", - "icon": "type", - "base_classes": [ - "object", - "Text", - "str" - ], - "display_name": "Reviews", - "documentation": "", - "custom_fields": { - "input_value": null, - "record_template": null - }, - "output_types": [ - "Text" - ], - "field_formatters": {}, - "frozen": false, - "field_order": [], - "beta": false - }, - "id": "TextInput-oKkcQ", - "description": "Get text inputs from the Interaction Panel.", - "display_name": "Text Input" - }, - "selected": false, - "width": 384, - "height": 289, - "positionAbsolute": { - "x": -501.8114356733282, - "y": -152.0266822138945 - }, - "dragging": false - } - ], - "edges": [ - { - "source": "Prompt-nzvwK", - "sourceHandle": "{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-nzvwKœ}", - "target": "OpenAIModel-u4NL8", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-u4NL8œ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-u4NL8", - "inputTypes": [ - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], - "dataType": "Prompt", - "id": "Prompt-nzvwK" - } - }, - "style": { - "stroke": "#555" - }, - "className": "stroke-gray-900 stroke-connection", - "id": "reactflow__edge-Prompt-nzvwK{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-nzvwKœ}-OpenAIModel-u4NL8{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-u4NL8œ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" - }, - { - "source": "TextInput-ARFMe", - "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextInputœ,œidœ:œTextInput-ARFMeœ}", - "target": "Prompt-nzvwK", - "targetHandle": "{œfieldNameœ:œsentimentœ,œidœ:œPrompt-nzvwKœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "sentiment", - "id": "Prompt-nzvwK", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], - "dataType": "TextInput", - "id": "TextInput-ARFMe" - } - }, - "style": { - "stroke": "#555" - }, - "className": "stroke-gray-900 stroke-connection", - "id": "reactflow__edge-TextInput-ARFMe{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextInputœ,œidœ:œTextInput-ARFMeœ}-Prompt-nzvwK{œfieldNameœ:œsentimentœ,œidœ:œPrompt-nzvwKœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "source": "TextInput-oKkcQ", - "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextInputœ,œidœ:œTextInput-oKkcQœ}", - "target": "Prompt-nzvwK", - "targetHandle": "{œfieldNameœ:œreviewsœ,œidœ:œPrompt-nzvwKœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "reviews", - "id": "Prompt-nzvwK", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], - "dataType": "TextInput", - "id": "TextInput-oKkcQ" - } - }, - "style": { - "stroke": "#555" - }, - "className": "stroke-gray-900 stroke-connection", - "id": "reactflow__edge-TextInput-oKkcQ{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextInputœ,œidœ:œTextInput-oKkcQœ}-Prompt-nzvwK{œfieldNameœ:œreviewsœ,œidœ:œPrompt-nzvwKœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "source": "Prompt-nzvwK", - "sourceHandle": "{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-nzvwKœ}", - "target": "TextOutput-prj03", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-prj03œ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "input_value", - "id": "TextOutput-prj03", - "inputTypes": [ - "Record", - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], - "dataType": "Prompt", - "id": "Prompt-nzvwK" - } - }, - "style": { - "stroke": "#555" - }, - "className": "stroke-gray-900 stroke-connection", - "id": "reactflow__edge-Prompt-nzvwK{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-nzvwKœ}-TextOutput-prj03{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-prj03œ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "source": "OpenAIModel-u4NL8", - "sourceHandle": "{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-u4NL8œ}", - "target": "ChatOutput-stoNg", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-stoNgœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-stoNg", - "inputTypes": [ - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], - "dataType": "OpenAIModel", - "id": "OpenAIModel-u4NL8" - } - }, - "style": { - "stroke": "#555" - }, - "className": "stroke-gray-900 stroke-connection", - "id": "reactflow__edge-OpenAIModel-u4NL8{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-u4NL8œ}-ChatOutput-stoNg{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-stoNgœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" - } - ], - "viewport": { - "x": 319.9710437562943, - "y": 143.9251365088694, - "zoom": 0.5282102678500032 - } - }, - "description": "Use a language model to generate text based on a prompt. \n\nIn this project, you'll be able to generate text based on a request and some topics.\n\nThe Topic 1 and Topic 2 components are actually Text Input, while the Prompt Output component is a Text Output. Changing the name of the component makes them easier to identify when interacting with them.", - "name": "Basic Prompting", - "last_tested_version": "1.0.0a0", - "is_component": false -} \ No newline at end of file diff --git a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx index e595eaaeb..be2c35321 100644 --- a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx +++ b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx @@ -43,7 +43,7 @@ export default function UndrawCardComponent({ }} /> ); - case "Basic Prompting (Hello, world!)": + case "Basic Prompting (Ahoy World!)": return ( { return ; })} */} - {examples.find((e) => e.name == "Basic Prompting (Hello, world!)") && ( + {examples.find((e) => e.name == "Basic Prompting (Ahoy World!)") && ( e.name == "Basic Prompting (Hello, world!)")!} + flow={ + examples.find((e) => e.name == "Basic Prompting (Ahoy World!)")! + } /> )} {examples.find((e) => e.name == "Memory Chatbot") && ( diff --git a/tests/conftest.py b/tests/conftest.py index 7f7252243..66ca01df2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,10 +10,6 @@ import orjson import pytest from fastapi.testclient import TestClient from httpx import AsyncClient -from sqlmodel import Session, SQLModel, create_engine, select -from sqlmodel.pool import StaticPool -from typer.testing import CliRunner - from langflow.graph.graph.base import Graph from langflow.initial_setup.setup import STARTER_FOLDER_NAME from langflow.services.auth.utils import get_password_hash @@ -22,6 +18,9 @@ from langflow.services.database.models.flow.model import Flow, FlowCreate from langflow.services.database.models.user.model import User, UserCreate from langflow.services.database.utils import session_getter from langflow.services.deps import get_db_service +from sqlmodel import Session, SQLModel, create_engine, select +from sqlmodel.pool import StaticPool +from typer.testing import CliRunner if TYPE_CHECKING: from langflow.services.database.service import DatabaseService @@ -381,7 +380,7 @@ def get_starter_project(active_user): # once the client is created, we can get the starter project with session_getter(get_db_service()) as session: flow = session.exec( - select(Flow).where(Flow.folder == STARTER_FOLDER_NAME).where(Flow.name == "Basic Prompting (Hello, world!)") + select(Flow).where(Flow.folder == STARTER_FOLDER_NAME).where(Flow.name == "Basic Prompting (Ahoy World!)") ).first() if not flow: raise ValueError("No starter project found") From 477f7e8e732a9ee0c0709beebbc246223483e94c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 23:12:31 -0300 Subject: [PATCH 41/54] Remove HuggingFace Spaces documentation --- .../getting-started/hugging-face-spaces.mdx | 30 ------------------- docs/sidebars.js | 7 +---- 2 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 docs/docs/getting-started/hugging-face-spaces.mdx diff --git a/docs/docs/getting-started/hugging-face-spaces.mdx b/docs/docs/getting-started/hugging-face-spaces.mdx deleted file mode 100644 index aa71db6c3..000000000 --- a/docs/docs/getting-started/hugging-face-spaces.mdx +++ /dev/null @@ -1,30 +0,0 @@ -# 🤗 HuggingFace Spaces - -## TLDR; - -A fully featured version of Langflow can be accessed via [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) with no installation required. All you gotta do is [duplicate the Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) and you'll have your own copy to play around with! - ---- - -# 🚀 Getting Started - -HuggingFace provides great support for running Langflow in their Spaces environment. This means you can run Langflow without any installation required. - -The first step is to go to the [Langflow Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). - -You'll be greeted with the following screen: - - - -From here, you can rename your Space, define the visibility (Public or Private) and click on the `Duplicate Space` button to start the duplication process. - -import ThemedImage from "@theme/ThemedImage"; -import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; diff --git a/docs/sidebars.js b/docs/sidebars.js index 7b2a4b956..f1a1a48f1 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -4,12 +4,7 @@ module.exports = { type: "category", label: " Getting Started", collapsed: false, - items: [ - "index", - "getting-started/cli", - "getting-started/hugging-face-spaces", - "getting-started/creating-flows", - ], + items: ["index", "getting-started/cli", "getting-started/creating-flows"], }, { type: "category", From 39bc9764b8e5f644c0eaffdfa959172ab080efda Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 23:19:14 -0300 Subject: [PATCH 42/54] Add new files and update sidebars.js --- .../basic-prompting.mdx | 0 .../blog-writer.mdx | 0 docs/docs/getting-started/creating-flows.mdx | 51 ------------------- .../document-qa.mdx | 0 .../memory-chatbot.mdx | 0 .../rag-with-astradb.mdx | 0 docs/sidebars.js | 22 ++++---- 7 files changed, 9 insertions(+), 64 deletions(-) rename docs/docs/{starter-projects => getting-started}/basic-prompting.mdx (100%) rename docs/docs/{starter-projects => getting-started}/blog-writer.mdx (100%) delete mode 100644 docs/docs/getting-started/creating-flows.mdx rename docs/docs/{starter-projects => getting-started}/document-qa.mdx (100%) rename docs/docs/{starter-projects => getting-started}/memory-chatbot.mdx (100%) rename docs/docs/{starter-projects => getting-started}/rag-with-astradb.mdx (100%) diff --git a/docs/docs/starter-projects/basic-prompting.mdx b/docs/docs/getting-started/basic-prompting.mdx similarity index 100% rename from docs/docs/starter-projects/basic-prompting.mdx rename to docs/docs/getting-started/basic-prompting.mdx diff --git a/docs/docs/starter-projects/blog-writer.mdx b/docs/docs/getting-started/blog-writer.mdx similarity index 100% rename from docs/docs/starter-projects/blog-writer.mdx rename to docs/docs/getting-started/blog-writer.mdx diff --git a/docs/docs/getting-started/creating-flows.mdx b/docs/docs/getting-started/creating-flows.mdx deleted file mode 100644 index 9c16d225f..000000000 --- a/docs/docs/getting-started/creating-flows.mdx +++ /dev/null @@ -1,51 +0,0 @@ -import ThemedImage from "@theme/ThemedImage"; -import useBaseUrl from "@docusaurus/useBaseUrl"; -import ZoomableImage from "/src/theme/ZoomableImage.js"; -import ReactPlayer from "react-player"; - -# 🎨 Creating Flows - -## Compose - -Creating flows with Langflow is easy. Drag sidebar components onto the canvas and connect them together to create your pipeline. -Langflow provides a range of Components to choose from, including **Chat Input**, **Chat Output**, **API Request** and **Prompt**. - - - -## Starter Flows - -Langflow provides a range of starter flows to help you get started. These flows are pre-built and can be used as a starting point for your own flows. - -

- -## Defining Inputs and Outputs - -Each flow can have multiple inputs and outputs. These can be defined by placing **Inputs** and **Outputs** components on the canvas. - -The **Inputs** components define the inputs to the flow. -Whenever you place an Input component on the canvas, it will allow you to interactively define change its value -from the Interactive Panel. - -The **Text Input** component allows you to define a text input, and the **Chat Input** component allows you to use the chat input from the Interactive Panel. - -The **Outputs** components define the outputs of the flow and work similarly to the Inputs components. - -Both Inputs and Outputs components can be connected to other components on the canvas and are used to define how the API works too. - - - -
- -
diff --git a/docs/docs/starter-projects/document-qa.mdx b/docs/docs/getting-started/document-qa.mdx similarity index 100% rename from docs/docs/starter-projects/document-qa.mdx rename to docs/docs/getting-started/document-qa.mdx diff --git a/docs/docs/starter-projects/memory-chatbot.mdx b/docs/docs/getting-started/memory-chatbot.mdx similarity index 100% rename from docs/docs/starter-projects/memory-chatbot.mdx rename to docs/docs/getting-started/memory-chatbot.mdx diff --git a/docs/docs/starter-projects/rag-with-astradb.mdx b/docs/docs/getting-started/rag-with-astradb.mdx similarity index 100% rename from docs/docs/starter-projects/rag-with-astradb.mdx rename to docs/docs/getting-started/rag-with-astradb.mdx diff --git a/docs/sidebars.js b/docs/sidebars.js index f1a1a48f1..84e1dca16 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -4,7 +4,15 @@ module.exports = { type: "category", label: " Getting Started", collapsed: false, - items: ["index", "getting-started/cli", "getting-started/creating-flows"], + items: [ + "index", + "getting-started/cli", + "getting-started/basic-prompting", + "getting-started/document-qa", + "getting-started/blog-writer", + "getting-started/memory-chatbot", + "getting-started/rag-with-astradb", + ], }, { type: "category", @@ -15,18 +23,6 @@ module.exports = { "whats-new/migrating-to-one-point-zero", ], }, - { - type: "category", - label: " Starter Projects", - collapsed: false, - items: [ - "starter-projects/rag-with-astradb", - "starter-projects/basic-prompting", - "starter-projects/memory-chatbot", - "starter-projects/document-qa", - "starter-projects/blog-writer", - ], - }, { type: "category", label: " Step-by-Step Guides", From 64ea6b95a63daa0898bf49080a13beda2268d754 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 23:21:29 -0300 Subject: [PATCH 43/54] Remove async-tasks.mdx and update sidebars.js --- docs/docs/guides/async-tasks.mdx | 44 -------------------------------- docs/sidebars.js | 7 +---- 2 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 docs/docs/guides/async-tasks.mdx diff --git a/docs/docs/guides/async-tasks.mdx b/docs/docs/guides/async-tasks.mdx deleted file mode 100644 index e865fe4b6..000000000 --- a/docs/docs/guides/async-tasks.mdx +++ /dev/null @@ -1,44 +0,0 @@ -import Admonition from "@theme/Admonition"; - -# Async API - -## Introduction - - - This implementation is still in development. Contributions are welcome! - - -The Async API is an implementation of the Langflow API that uses [Celery](https://docs.celeryproject.org/en/stable/) -to run the tasks asynchronously, using a message broker to send and receive messages, a result backend to store the results and a cache to store the task states and session data. - -### Configuration - -The folder _`./deploy`_ in the [Github repository](https://github.com/logspace-ai/langflow) contains a _`.env.example`_ file that can be used to configure a Langflow deployment. -The file contains the variables required to configure a Celery worker queue, Redis cache and result backend and a RabbitMQ message broker. - -To set it up locally you can copy the file to _`.env`_ and run the following command: - -```bash -docker compose up -d -``` - -This will set up the following containers: - -- Langflow API -- Celery worker -- RabbitMQ message broker -- Redis cache -- PostgreSQL database -- PGAdmin -- Flower -- Traefik -- Grafana -- Prometheus - -### Testing - -To run the tests for the Async API, you can run the following command: - -```bash -docker compose -f docker-compose.with_tests.yml up --exit-code-from tests tests result_backend broker celeryworker db --build -``` diff --git a/docs/sidebars.js b/docs/sidebars.js index 84e1dca16..0b370fab2 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -27,12 +27,7 @@ module.exports = { type: "category", label: " Step-by-Step Guides", collapsed: false, - items: [ - "guides/async-tasks", - "guides/loading_document", - "guides/chatprompttemplate_guide", - "guides/langfuse_integration", - ], + items: ["guides/langfuse_integration"], }, { type: "category", From 45e9a10ea54de3324ca991944126cd6aa673af63 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 23:23:36 -0300 Subject: [PATCH 44/54] Update starter project URLs --- docs/docs/whats-new/a-new-chapter-langflow.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/docs/whats-new/a-new-chapter-langflow.mdx b/docs/docs/whats-new/a-new-chapter-langflow.mdx index 75aa7216e..4ecaf635f 100644 --- a/docs/docs/whats-new/a-new-chapter-langflow.mdx +++ b/docs/docs/whats-new/a-new-chapter-langflow.mdx @@ -61,11 +61,11 @@ We wanted to create start projects that would help you learn about new features For now, we have: -- **[Basic Prompting (Ahoy World!)](/starter-projects/basic-prompting)**: A simple flow that shows you how to use the Prompt Component and how to talk like a pirate. -- **[Vector Store RAG](/starter-projects/rag-with-astradb)**: A flow that shows you how to ingest data into a Vector Store and then use it to run a RAG application. -- **[Memory Chatbot](/starter-projects/memory-chatbot)**: This one shows you how to create a simple chatbot that can remember things about the user. -- **[Document QA](/starter-projects/document-qa)**: This flow shows you how to build a simple flow that helps you get answers about a document. -- **[Blog Writer](/starter-projects/blog-writer)**: Shows you how you can expand on the Prompt variables and be creative about what inputs you add to it. +- **[Basic Prompting (Ahoy World!)](/getting-started/basic-prompting)**: A simple flow that shows you how to use the Prompt Component and how to talk like a pirate. +- **[Vector Store RAG](/getting-started/rag-with-astradb)**: A flow that shows you how to ingest data into a Vector Store and then use it to run a RAG application. +- **[Memory Chatbot](/getting-started/memory-chatbot)**: This one shows you how to create a simple chatbot that can remember things about the user. +- **[Document QA](/getting-started/document-qa)**: This flow shows you how to build a simple flow that helps you get answers about a document. +- **[Blog Writer](/getting-started/blog-writer)**: Shows you how you can expand on the Prompt variables and be creative about what inputs you add to it. As always, your feedback is invaluable, so please let us know what you think of the new starter projects and what you would like to see in the future. From f762d54b319a79b1cb94f9ffec4e0f522b97f7d2 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 23:23:43 -0300 Subject: [PATCH 45/54] Enable migration of global variables --- docs/sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sidebars.js b/docs/sidebars.js index 0b370fab2..f2947429c 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -47,7 +47,7 @@ module.exports = { // "migration/connecting-output-components", // "migration/renaming-and-editing-components", // "migration/passing-tweaks-and-inputs", - // "migration/global-variables", + "migration/global-variables", // "migration/experimental-components", // "migration/state-management", ], From e80c86a626355e7ab40478b1c260bcc50bc0784b Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 3 Apr 2024 23:49:37 -0300 Subject: [PATCH 46/54] Update OpenAIEmbeddings deployment and model --- docs/static/data/AstraDB-RAG-Flows.json | 12 ++++++------ .../components/embeddings/OpenAIEmbeddings.py | 4 ++-- .../starter_projects/VectorStore-RAG-Flows.json | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/static/data/AstraDB-RAG-Flows.json b/docs/static/data/AstraDB-RAG-Flows.json index 8068ea4a9..5706a0fbf 100644 --- a/docs/static/data/AstraDB-RAG-Flows.json +++ b/docs/static/data/AstraDB-RAG-Flows.json @@ -358,7 +358,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-3-small\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-3-small\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", + "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", "fileTypes": [], "file_path": "", "password": false, @@ -413,7 +413,7 @@ "list": false, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, @@ -497,7 +497,7 @@ "list": true, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, @@ -2628,7 +2628,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-3-small\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-3-small\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", + "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", "fileTypes": [], "file_path": "", "password": false, @@ -2683,7 +2683,7 @@ "list": false, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, @@ -2767,7 +2767,7 @@ "list": true, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py b/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py index cdeeac0e1..f177fa1f1 100644 --- a/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py +++ b/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py @@ -94,10 +94,10 @@ class OpenAIEmbeddingsComponent(CustomComponent): disallowed_special: List[str] = ["all"], chunk_size: int = 1000, client: Optional[Any] = None, - deployment: str = "text-embedding-3-small", + deployment: str = "text-embedding-ada-002", embedding_ctx_length: int = 8191, max_retries: int = 6, - model: str = "text-embedding-3-small", + model: str = "text-embedding-ada-002", model_kwargs: NestedDict = {}, openai_api_base: Optional[str] = None, openai_api_type: Optional[str] = None, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json index 8068ea4a9..5706a0fbf 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json @@ -358,7 +358,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-3-small\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-3-small\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", + "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", "fileTypes": [], "file_path": "", "password": false, @@ -413,7 +413,7 @@ "list": false, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, @@ -497,7 +497,7 @@ "list": true, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, @@ -2628,7 +2628,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-3-small\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-3-small\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", + "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n", "fileTypes": [], "file_path": "", "password": false, @@ -2683,7 +2683,7 @@ "list": false, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, @@ -2767,7 +2767,7 @@ "list": true, "show": true, "multiline": false, - "value": "text-embedding-3-small", + "value": "text-embedding-ada-002", "fileTypes": [], "file_path": "", "password": false, From 1616cdd000f17016ce317b5bb58ec9e267712e63 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Wed, 3 Apr 2024 23:53:46 -0300 Subject: [PATCH 47/54] =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20marg?= =?UTF-8?q?in=20to=20image=20style=20to=20improve=20spacing=20and=20center?= =?UTF-8?q?=20alignment=20=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to?= =?UTF-8?q?=20image=20style=20to=20improve=20spacing=20and=20center=20alig?= =?UTF-8?q?nment=20=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20imag?= =?UTF-8?q?e=20style=20to=20improve=20spacing=20and=20center=20alignment?= =?UTF-8?q?=20=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20s?= =?UTF-8?q?tyle=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment=20?= =?UTF-8?q?=F0=9F=93=9D=20(inputs.mdx):=20add=20margin=20to=20image=20styl?= =?UTF-8?q?e=20to=20improve=20spacing=20and=20center=20alignment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📝 (rag-with-astradb.mdx): add margin to image styles to improve spacing and readability --- docs/docs/components/inputs.mdx | 16 +++++++------- docs/docs/examples/buffer-memory.mdx | 6 +++++ docs/docs/examples/conversation-chain.mdx | 7 ++++++ docs/docs/examples/csv-loader.mdx | 6 +++++ docs/docs/examples/flow-runner.mdx | 4 +--- docs/docs/examples/python-function.mdx | 6 +++++ docs/docs/examples/serp-api-tool.mdx | 6 +++++ docs/docs/getting-started/creating-flows.mdx | 10 ++++++--- docs/docs/index.mdx | 4 +++- .../starter-projects/rag-with-astradb.mdx | 22 +++++++++---------- 10 files changed, 61 insertions(+), 26 deletions(-) diff --git a/docs/docs/components/inputs.mdx b/docs/docs/components/inputs.mdx index de46f3ad7..fe8804e43 100644 --- a/docs/docs/components/inputs.mdx +++ b/docs/docs/components/inputs.mdx @@ -33,7 +33,7 @@ When you get it from the sidebar, it will look like the image below but that is light: "img/chat-input.png", dark: "img/chat-input.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> If you expose all its fields, it will look like the image below. @@ -44,7 +44,7 @@ If you expose all its fields, it will look like the image below. light: "img/chat-input-expanded.png", dark: "img/chat-input-expanded.png", }} - style={{ width: "40%" }} + style={{ width: "40%", margin: "20px auto" }} /> One key capability of the Chat Input component is how it transforms the Interaction Panel into a chat window. This feature is particularly useful for scenarios where user input is required to initiate or influence the flow. @@ -55,7 +55,7 @@ One key capability of the Chat Input component is how it transforms the Interact light: "img/interaction-panel-with-chat-input.png", dark: "img/interaction-panel-with-chat-input.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> --- @@ -83,7 +83,7 @@ Here is how it looks when you get it from the sidebar. light: "img/prompt.png", dark: "img/prompt.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> And here when you add a Template with the value _`Hello {name}, how are you?`_. @@ -94,7 +94,7 @@ And here when you add a Template with the value _`Hello {name}, how are you?`_. light: "img/prompt-with-template.png", dark: "img/prompt-with-template.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> --- @@ -124,7 +124,7 @@ It should look like this when dropped directly from the sidebar. light: "img/text-input.png", dark: "img/text-input.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto", margin: "20px auto" }} /> And when you expose all its fields, it will look like the image below. @@ -149,7 +149,7 @@ You can use a template like this: _`"Name: {name}, Age: {age}"`_ to convert the light: "img/text-input-expanded.png", dark: "img/text-input-expanded.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> The Text Input component gives you the possibility to add an Input field on the Interaction Panel. This is useful because it allows you to define parameters while running and testing your flow. @@ -160,5 +160,5 @@ The Text Input component gives you the possibility to add an Input field on the light: "img/interaction-panel-text-input.png", dark: "img/interaction-panel-text-input.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> diff --git a/docs/docs/examples/buffer-memory.mdx b/docs/docs/examples/buffer-memory.mdx index 3167081a5..b196f9031 100644 --- a/docs/docs/examples/buffer-memory.mdx +++ b/docs/docs/examples/buffer-memory.mdx @@ -16,6 +16,12 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; light: "img/buffer-memory.png", dark: "img/buffer-memory.png", }} + style={{ + width: "80%", + margin: "20px auto", + display: "flex", + justifyContent: "center", + }} /> ####
Download Flow diff --git a/docs/docs/examples/conversation-chain.mdx b/docs/docs/examples/conversation-chain.mdx index 1cd59ca55..294d1b440 100644 --- a/docs/docs/examples/conversation-chain.mdx +++ b/docs/docs/examples/conversation-chain.mdx @@ -22,6 +22,13 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; light: "img/basic-chat.png", dark: "img/basic-chat.png", }} + +style={{ + width: "80%", + margin: "20px auto", + display: "flex", + justifyContent: "center", + }} /> #### Download Flow diff --git a/docs/docs/examples/csv-loader.mdx b/docs/docs/examples/csv-loader.mdx index 351e99440..25f3bb444 100644 --- a/docs/docs/examples/csv-loader.mdx +++ b/docs/docs/examples/csv-loader.mdx @@ -34,6 +34,12 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; light: "img/csv-loader.png", dark: "img/csv-loader.png", }} + style={{ + width: "80%", + margin: "20px auto", + display: "flex", + justifyContent: "center", + }} /> #### Download Flow diff --git a/docs/docs/examples/flow-runner.mdx b/docs/docs/examples/flow-runner.mdx index 38466e4b3..8a07adb0a 100644 --- a/docs/docs/examples/flow-runner.mdx +++ b/docs/docs/examples/flow-runner.mdx @@ -3,7 +3,6 @@ description: Custom Components hide_table_of_contents: true --- - # FlowRunner Component The CustomComponent class allows us to create components that interact with Langflow itself. In this example, we will make a component that runs other flows available in "My Collection". @@ -16,7 +15,7 @@ The CustomComponent class allows us to create components that interact with Lang }} style={{ width: "30%", - margin: "0 auto", + margin: "20px auto", display: "flex", justifyContent: "center", }} @@ -367,4 +366,3 @@ Done! This is what our script and custom component looks like: import ZoomableImage from "/src/theme/ZoomableImage.js"; import Admonition from "@theme/Admonition"; - diff --git a/docs/docs/examples/python-function.mdx b/docs/docs/examples/python-function.mdx index 9eadd7273..2bb4b93e1 100644 --- a/docs/docs/examples/python-function.mdx +++ b/docs/docs/examples/python-function.mdx @@ -43,6 +43,12 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; light: "img/python-function.png", dark: "img/python-function.png", }} + style={{ + width: "80%", + margin: "20px auto", + display: "flex", + justifyContent: "center", + }} /> #### Download Flow diff --git a/docs/docs/examples/serp-api-tool.mdx b/docs/docs/examples/serp-api-tool.mdx index 7e8d95936..175b6f1be 100644 --- a/docs/docs/examples/serp-api-tool.mdx +++ b/docs/docs/examples/serp-api-tool.mdx @@ -37,6 +37,12 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; light: "img/serp-api-tool.png", dark: "img/serp-api-tool.png", }} + style={{ + width: "80%", + margin: "20px auto", + display: "flex", + justifyContent: "center", + }} /> #### Download Flow diff --git a/docs/docs/getting-started/creating-flows.mdx b/docs/docs/getting-started/creating-flows.mdx index 9c16d225f..585117881 100644 --- a/docs/docs/getting-started/creating-flows.mdx +++ b/docs/docs/getting-started/creating-flows.mdx @@ -14,7 +14,13 @@ Langflow provides a range of Components to choose from, including **Chat Input** alt="Docusaurus themed image" sources={{ light: "img/langflow_canvas.png", - dark: "img/langflow_canvas.png" + dark: "img/langflow_canvas.png", + }} + style={{ + width: "70%", + margin: "20px auto", + display: "flex", + justifyContent: "center", }} /> @@ -42,8 +48,6 @@ The **Outputs** components define the outputs of the flow and work similarly to Both Inputs and Outputs components can be connected to other components on the canvas and are used to define how the API works too. - -
diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index d19c28e4b..bfbe171c4 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -8,6 +8,8 @@ import ZoomableImage from "/src/theme/ZoomableImage.js"; {" "} +{" "} + From here, just name your Space, define the visibility (Public or Private), and click on `Duplicate Space` to start the installation process. When that is done, you'll be redirected to the Space's main page to start using Langflow right away! diff --git a/docs/docs/starter-projects/rag-with-astradb.mdx b/docs/docs/starter-projects/rag-with-astradb.mdx index 54aebd2d2..01daa7b6f 100644 --- a/docs/docs/starter-projects/rag-with-astradb.mdx +++ b/docs/docs/starter-projects/rag-with-astradb.mdx @@ -42,7 +42,7 @@ Once you have created an account, you will be taken to the Astra DB dashboard. C light: "img/astra-create-database.png", dark: "img/astra-create-database.png", }} - style={{ width: "80%" }} + style={{ width: "80%", margin: "20px auto" }} /> Now you will need to configure your database. Choose the **Serverless (Vector)** deployment type, and pick a Database name, provider and region. @@ -55,7 +55,7 @@ After you have configured your database, click on the **Create Database** button light: "img/astra-configure-deployment.png", dark: "img/astra-configure-deployment.png", }} - style={{ width: "70%" }} + style={{ width: "80%", margin: "20px auto" }} /> Once your database is initialized, to the right of the page, you will see the _Database Details_ section which contains a button for you to copy the **API Endpoint** and another to generate a **Token**. @@ -66,7 +66,7 @@ Once your database is initialized, to the right of the page, you will see the _D light: "img/astra-generate-token.png", dark: "img/astra-generate-token.png", }} - style={{ width: "50%" }} + style={{ width: "50%", margin: "20px auto" }} /> Now we are all set to start building our RAG application using Astra DB and Langflow. @@ -85,7 +85,7 @@ To get started, click on the **New Project** button and look for the **Vector St light: "img/drag-and-drop-flow.png", dark: "img/drag-and-drop-flow.png", }} - style={{ width: "90%" }} + style={{ width: "80%", margin: "20px auto" }} /> This project consists of two flows. The simpler one is the **Ingestion Flow** which is responsible for ingesting the documents into the Astra DB database. @@ -105,7 +105,7 @@ The ingestion flow consists of: light: "img/astra-ingestion-flow.png", dark: "img/astra-ingestion-flow.png", }} - style={{ width: "90%" }} + style={{ width: "80%", margin: "20px auto" }} /> Now, let's update the **Astra DB** and **Astra DB Search** components with the **Token** and **API Endpoint** that we generated earlier, and the OpenAI Embeddings components with your OpenAI API key. @@ -116,7 +116,7 @@ Now, let's update the **Astra DB** and **Astra DB Search** components with the * light: "img/astra-ingestion-fields.png", dark: "img/astra-ingestion-fields.png", }} - style={{ width: "90%" }} + style={{ width: "80%", margin: "20px auto" }} /> And run it! This will ingest the Text data from your file into the Astra DB database. @@ -127,7 +127,7 @@ And run it! This will ingest the Text data from your file into the Astra DB data light: "img/astra-ingestion-run.png", dark: "img/astra-ingestion-run.png", }} - style={{ width: "90%" }} + style={{ width: "80%", margin: "20px auto" }} /> Now, on to the **RAG Flow**. This flow is responsible for generating responses to your queries. It will define all of the steps from getting the User's input to generating a response and displaying it in the Interaction Panel. @@ -149,7 +149,7 @@ The RAG flow is a bit more complex. It consists of: light: "img/astra-rag-flow.png", dark: "img/astra-rag-flow.png", }} - style={{ width: "90%" }} + style={{ width: "80%", margin: "20px auto" }} /> To run it all we have to do is click on the ⚡ _Run_ button and start interacting with your RAG application. @@ -160,7 +160,7 @@ To run it all we have to do is click on the ⚡ _Run_ button and start interacti light: "img/astra-rag-flow-run.png", dark: "img/astra-rag-flow-run.png", }} - style={{ width: "90%" }} + style={{ width: "80%", margin: "20px auto" }} /> This opens the Interaction Panel where you can chat your data. @@ -173,7 +173,7 @@ Because this flow has a **Chat Input** and a **Text Output** component, the Pane light: "img/astra-rag-flow-interaction-panel.png", dark: "img/astra-rag-flow-interaction-panel.png", }} - style={{ width: "80%" }} + style={{ width: "80%", margin: "20px auto" }} /> Once we interact with it we get a response and the Extracted Chunks section is updated with the retrieved records. @@ -184,7 +184,7 @@ Once we interact with it we get a response and the Extracted Chunks section is u light: "img/astra-rag-flow-interaction-panel-interaction.png", dark: "img/astra-rag-flow-interaction-panel-interaction.png", }} - style={{ width: "80%" }} + style={{ width: "80%", margin: "20px auto" }} /> And that's it! You have successfully ran a RAG application using Astra DB and Langflow. From f2aa71eb4722f343bbcd221427c0766c2b5582fc Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 4 Apr 2024 00:07:10 -0300 Subject: [PATCH 48/54] Update welcome message in index.mdx --- docs/docs/index.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index bfbe171c4..9357a8fdf 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -1,11 +1,11 @@ -# 👋 Welcome to Langflow - -Langflow is an easy way to build from simple to complex AI applications. It is a low-code platform that allows you to integrate AI into everything you do. - import ThemedImage from "@theme/ThemedImage"; import useBaseUrl from "@docusaurus/useBaseUrl"; import ZoomableImage from "/src/theme/ZoomableImage.js"; +# 👋 Welcome to Langflow + +Langflow is an easy way to build from simple to complex AI applications. It is a low-code platform that allows you to integrate AI into everything you do. + {" "} {" "} From d69719c987baaf270d8328374308b3601806870e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 4 Apr 2024 00:07:18 -0300 Subject: [PATCH 49/54] Add global variable feature to Langflow documentation --- docs/docs/migration/global-variables.mdx | 65 +++++++++++++++++++++ docs/static/img/add-new-variable.png | Bin 0 -> 49435 bytes docs/static/img/create-variable-window.png | Bin 0 -> 82320 bytes docs/static/img/ollama-gv.png | Bin 0 -> 50068 bytes 4 files changed, 65 insertions(+) create mode 100644 docs/static/img/add-new-variable.png create mode 100644 docs/static/img/create-variable-window.png create mode 100644 docs/static/img/ollama-gv.png diff --git a/docs/docs/migration/global-variables.mdx b/docs/docs/migration/global-variables.mdx index e69de29bb..ce6d15a5f 100644 --- a/docs/docs/migration/global-variables.mdx +++ b/docs/docs/migration/global-variables.mdx @@ -0,0 +1,65 @@ +import ZoomableImage from "/src/theme/ZoomableImage.js"; +import Admonition from "@theme/Admonition"; + +# Global Variables + +Global Variables are a really useful feature of Langflow. +They allow you to define reusable variables that can be accessed from any Text field in your project. + +The first thing you need to do is find a **Text field** in a Component, so let's talk about what a Text field is. + +## Text Fields + +Text fields are the fields in a Component where you can write text but that does not allow you to open a Text Area. + +The easiest way to find fields that are Text fields, though, is to look for fields that have a 🌐 button. + + + +## Creating a Global Variable + +To create a Global Variable, you need to click on the 🌐 button in a Text field and that will open a dropdown showing your currently available variables and at the end of it **+ Add New Variable**. + + + +Click on **+ Add New Variable** and a window will open where you can define your new Global Variable. + +In it, you can define the **Name** of the variable, the optional **Type** of the variable, and the **Value** of the variable. + +The **Name** is the name that you will use to refer to the variable in your Text fields. + +The **Type** is optional for now but will be used in the future to allow for more advanced features. + +The **Value** is the value that the variable will have. +{/* say that all variables are encrypted */} + + + All Global Variables are encrypted and cannot be accessed by anyone but you. + + + + +After you have defined your variable, click on **Save Variable** and your variable will be created. + +After that, once you click on the 🌐 button in a Text field, you will see your new variable in the dropdown. diff --git a/docs/static/img/add-new-variable.png b/docs/static/img/add-new-variable.png new file mode 100644 index 0000000000000000000000000000000000000000..178cab67c0ec12e7c9b2ae6700488f18b852fc00 GIT binary patch literal 49435 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 OM|8CfwaPReg#RxiixLz7 literal 0 HcmV?d00001 diff --git a/docs/static/img/create-variable-window.png b/docs/static/img/create-variable-window.png new file mode 100644 index 0000000000000000000000000000000000000000..75c8842b5ab07f66ea05a01d7691872d78eb4feb GIT binary patch literal 82320 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 xE@z*+cG0X)bkbc`DerSTRz_v{K2wM}Rp0oB`6) literal 0 HcmV?d00001 diff --git a/docs/static/img/ollama-gv.png b/docs/static/img/ollama-gv.png new file mode 100644 index 0000000000000000000000000000000000000000..0ee7540ee81c102fe35c553bdc98357b7c94952e GIT binary patch literal 50068 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 literal 0 HcmV?d00001 From ffad7358a59d084e139d2e80feb2fd9990af66ea Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 4 Apr 2024 00:09:30 -0300 Subject: [PATCH 50/54] Reorganized sidebar categories --- docs/sidebars.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/sidebars.js b/docs/sidebars.js index f2947429c..db9fe47fd 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -23,15 +23,10 @@ module.exports = { "whats-new/migrating-to-one-point-zero", ], }, + { type: "category", - label: " Step-by-Step Guides", - collapsed: false, - items: ["guides/langfuse_integration"], - }, - { - type: "category", - label: "Migration Guides", + label: " Migration Guides", collapsed: false, items: [ // "migration/flow-of-data", @@ -68,6 +63,12 @@ module.exports = { "guidelines/custom-component", ], }, + { + type: "category", + label: "Step-by-Step Guides", + collapsed: false, + items: ["guides/langfuse_integration"], + }, { type: "category", label: "Core Components", From 6e6a7a8631b694193475946e68f1c36b39299d9e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 4 Apr 2024 00:10:33 -0300 Subject: [PATCH 51/54] Update migration documentation --- docs/sidebars.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/sidebars.js b/docs/sidebars.js index db9fe47fd..ae444d51e 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -32,15 +32,15 @@ module.exports = { // "migration/flow-of-data", "migration/inputs-and-outputs", // "migration/supported-frameworks", - // "migration/sidebar-and-interaction-panel", - // "migration/new-categories-and-components", - // "migration/text-and-record", + "migration/sidebar-and-interaction-panel", + "migration/new-categories-and-components", + "migration/text-and-record", // "migration/custom-component", "migration/compatibility", - // "migration/multiple-flows", - // "migration/component-status-and-data-passing", + "migration/multiple-flows", + "migration/component-status-and-data-passing", // "migration/connecting-output-components", - // "migration/renaming-and-editing-components", + "migration/renaming-and-editing-components", // "migration/passing-tweaks-and-inputs", "migration/global-variables", // "migration/experimental-components", From 5cade5dca8d0532b5bc377a15fa699925fa99bab Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 4 Apr 2024 00:22:37 -0300 Subject: [PATCH 52/54] Refactor SplitTextComponent class to accept inputs of type Record and Text --- .../langflow/components/helpers/SplitText.py | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/backend/base/langflow/components/helpers/SplitText.py b/src/backend/base/langflow/components/helpers/SplitText.py index 3c823c4aa..a141bbddc 100644 --- a/src/backend/base/langflow/components/helpers/SplitText.py +++ b/src/backend/base/langflow/components/helpers/SplitText.py @@ -1,14 +1,11 @@ from typing import Optional -from langchain.text_splitter import ( - RecursiveCharacterTextSplitter, - CharacterTextSplitter, -) +from langchain.text_splitter import CharacterTextSplitter, RecursiveCharacterTextSplitter from langchain_core.documents import Document +from langflow.field_typing import Text from langflow.interface.custom.custom_component import CustomComponent from langflow.schema import Record -from langflow.field_typing import Text from langflow.utils.util import unescape_string @@ -18,10 +15,10 @@ class SplitTextComponent(CustomComponent): def build_config(self): return { - "texts": { - "display_name": "Texts", + "inputs": { + "display_name": "Inputs", "info": "Texts to split.", - "input_types": ["Text"], + "input_types": ["Record", "Text"], }, "separators": { "display_name": "Separators", @@ -48,7 +45,7 @@ class SplitTextComponent(CustomComponent): def build( self, - texts: list[Text], + inputs: list[Text], separators: Optional[list[str]] = [" "], chunk_size: Optional[int] = 1000, chunk_overlap: Optional[int] = 200, @@ -77,9 +74,11 @@ class SplitTextComponent(CustomComponent): ) documents = [] - for _text in texts: - # documents.append(_input.to_lc_document()) - documents.append(Document(page_content=_text)) + for _input in inputs: + if isinstance(_input, Record): + documents.append(_input.to_lc_document()) + else: + documents.append(Document(page_content=_input)) records = self.to_records(splitter.split_documents(documents)) self.status = records From 5df26325e87bcac21298e9c336a80e63bf63355e Mon Sep 17 00:00:00 2001 From: carlosrcoelho Date: Thu, 4 Apr 2024 00:24:05 -0300 Subject: [PATCH 53/54] Adjust embeddings docs --- docs/docs/components/embeddings.mdx | 126 ++++++++++++++++------------ 1 file changed, 73 insertions(+), 53 deletions(-) diff --git a/docs/docs/components/embeddings.mdx b/docs/docs/components/embeddings.mdx index d4ad17542..7ec8351e1 100644 --- a/docs/docs/components/embeddings.mdx +++ b/docs/docs/components/embeddings.mdx @@ -2,19 +2,11 @@ import Admonition from "@theme/Admonition"; # Embeddings - -

- We appreciate your understanding as we polish our documentation – it may - contain some rough edges. Share your feedback or report issues to help us - improve! 🛠️📝 -

- - Embeddings are vector representations of text that capture the semantic meaning of the text. They are created using text embedding models and allow us to think about the text in a vector space, enabling us to perform tasks like semantic search, where we look for pieces of text that are most similar in the vector space. --- -### BedrockEmbeddings +### Amazon Bedrock Embeddings Used to load [Amazon Bedrocks’s](https://aws.amazon.com/bedrock/) embedding models. @@ -30,7 +22,7 @@ Used to load [Amazon Bedrocks’s](https://aws.amazon.com/bedrock/) embedding mo --- -### CohereEmbeddings +### Cohere Embeddings Used to load [Cohere’s](https://cohere.com/) embedding models. @@ -44,57 +36,93 @@ Used to load [Cohere’s](https://cohere.com/) embedding models. --- -### HuggingFaceEmbeddings +### Azure OpenAI Embeddings + +Generate embeddings using Azure OpenAI models. + +**Params** + +- **Azure Endpoint:** Your Azure endpoint, including the resource. Example: `https://example-resource.azure.openai.com/` +- **Deployment Name:** The name of the deployment. +- **API Version:** The API version to use. (Options: 2022-12-01, 2023-03-15-preview, 2023-05-15, 2023-06-01-preview, 2023-07-01-preview, 2023-08-01-preview) +- **API Key:** The API key to access the Azure OpenAI service. + +--- + +### Hugging Face API Embeddings + +Generate embeddings using Hugging Face Inference API models. + +**Params** + +- **API Key:** API key for accessing the Hugging Face Inference API. (Type: str) +- **API URL:** URL of the Hugging Face Inference API. (Default: http://localhost:8080) +- **Model Name:** Name of the model to use. (Default: BAAI/bge-large-en-v1.5) +- **Cache Folder:** Folder path to cache Hugging Face models. (Advanced) +- **Encode Kwargs:** Additional arguments for the encoding process. (Type: dict, Advanced) +- **Model Kwargs:** Additional arguments for the model. (Type: dict, Advanced) +- **Multi Process:** Whether to use multiple processes. (Default: False, Advanced) + +--- + +### Hugging Face Embeddings Used to load [HuggingFace’s](https://huggingface.co) embedding models. **Params** -- **cache_folder:** Used to specify the folder where the embeddings will be cached. When embeddings are computed for a text, they can be stored in the cache folder so that they can be reused later without the need to recompute them. This can improve the performance of the application by avoiding redundant computations. - -- **encode_kwargs:** Used to pass additional keyword arguments to the encoding method of the underlying HuggingFace model. These keyword arguments can be used to customize the encoding process, such as specifying the maximum length of the input sequence or enabling truncation or padding. - -- **model_kwargs:** Used to customize the behavior of the model, such as specifying the model architecture, the tokenizer, or any other model-specific configuration options. By using `model_kwargs`, the user can configure the HuggingFace model according to specific needs and preferences. - -- **model_name:** Used to specify the name or identifier of the HuggingFace model that will be used for generating embeddings. It allows users to choose a specific pre-trained model from the Hugging Face model hub — defaults to `sentence-transformers/all-mpnet-base-v2`. +- **Cache Folder:** Folder path to cache HuggingFace models. +- **Encode Kwargs:** Additional arguments for the encoding process. (Type: dict) +- **Model Kwargs:** Additional arguments for the model. (Type: dict) +- **Model Name:** Name of the HuggingFace model to use. (Default: sentence-transformers/all-mpnet-base-v2) +- **Multi Process:** Whether to use multiple processes. (Default: False) --- -### OpenAIEmbeddings +### Ollama Embeddings + +Generate embeddings using Ollama models. + +**Params** + +- **Ollama Model:** Name of the Ollama model to use. (Default: llama2) +- **Ollama Base URL:** Base URL of the Ollama API. (Default: http://localhost:11434) +- **Model Temperature:** Temperature parameter for the model. (Type: float) + +--- + +### OpenAI Embeddings Used to load [OpenAI’s](https://openai.com/) embedding models. **Params** -- **chunk_size:** Determines the maximum size of each chunk of text that is processed for embedding. If any of the incoming text chunks exceeds `chunk_size` characters, it will be split into multiple chunks of size `chunk_size` or less before being embedded — defaults to `1000`. - -- **deployment:** Used to specify the deployment name or identifier of the text embedding model. It allows the user to choose a specific deployment of the model to use for embedding. When the deployment is provided, this can be useful when the user has multiple deployments of the same model with different configurations or versions — defaults to `text-embedding-ada-002`. - -- **embedding_ctx_length:** This parameter determines the maximum context length for the text embedding model. It specifies the number of tokens that the model considers when generating embeddings for a piece of text — defaults to `8191` (this means that the model will consider up to 8191 tokens when generating embeddings). - -- **max_retries:** Determines the maximum number of times to retry a request if the model provider returns an error from their API — defaults to `6`. - -- **model:** Defines which pre-trained text embedding model to use — defaults to `text-embedding-ada-002`. - -- **openai_api_base:** Refers to the base URL for the Azure OpenAI resource. It is used to configure the API to connect to the Azure OpenAI service. The base URL can be found in the Azure portal under the user Azure OpenAI resource. - -- **openai_api_key:** Is used to authenticate and authorize access to the OpenAI service. - -- **openai_api_type:** Is used to specify the type of OpenAI API being used, either the regular OpenAI API or the Azure OpenAI API. This parameter allows the `OpenAIEmbeddings` class to connect to the appropriate API service. - -- **openai_api_version:** Is used to specify the version of the OpenAI API being used. This parameter allows the `OpenAIEmbeddings` class to connect to the appropriate version of the OpenAI API service. - -- **openai_organization:** Is used to specify the organization associated with the OpenAI API key. If not provided, the default organization associated with the API key will be used. - -- **openai_proxy:** Proxy enables better budgeting and cost management for making OpenAI API calls, including more transparency into pricing. - -- **request_timeout:** Used to specify the maximum amount of time, in milliseconds, to wait for a response from the OpenAI API when generating embeddings for a given text. - -- **tiktoken_model_name:** Used to count the number of tokens in documents to constrain them to be under a certain limit. By default, when set to None, this will be the same as the embedding model name. +- **OpenAI API Key:** The API key to use for accessing the OpenAI API. (Type: str) +- **Default Headers:** Default headers for the HTTP requests. (Type: Dict[str, str], Optional) +- **Default Query:** Default query parameters for the HTTP requests. (Type: NestedDict, Optional) +- **Allowed Special:** Special tokens allowed for processing. (Type: List[str], Default: []) +- **Disallowed Special:** Special tokens disallowed for processing. (Type: List[str], Default: ["all"]) +- **Chunk Size:** Chunk size for processing. (Type: int, Default: 1000) +- **Client:** HTTP client for making requests. (Type: Any, Optional) +- **Deployment:** Deployment name for the model. (Type: str, Default: "text-embedding-3-small") +- **Embedding Context Length:** Length of embedding context. (Type: int, Default: 8191) +- **Max Retries:** Maximum number of retries for failed requests. (Type: int, Default: 6) +- **Model:** Name of the model to use. (Type: str, Default: "text-embedding-3-small") +- **Model Kwargs:** Additional keyword arguments for the model. (Type: NestedDict, Optional) +- **OpenAI API Base:** Base URL of the OpenAI API. (Type: str, Optional) +- **OpenAI API Type:** Type of the OpenAI API. (Type: str, Optional) +- **OpenAI API Version:** Version of the OpenAI API. (Type: str, Optional) +- **OpenAI Organization:** Organization associated with the API key. (Type: str, Optional) +- **OpenAI Proxy:** Proxy server for the requests. (Type: str, Optional) +- **Request Timeout:** Timeout for the HTTP requests. (Type: float, Optional) +- **Show Progress Bar:** Whether to show a progress bar for processing. (Type: bool, Default: False) +- **Skip Empty:** Whether to skip empty inputs. (Type: bool, Default: False) +- **TikToken Enable:** Whether to enable TikToken. (Type: bool, Default: True) +- **TikToken Model Name:** Name of the TikToken model. (Type: str, Optional) --- -### VertexAIEmbeddings +### VertexAI Embeddings Wrapper around [Google Vertex AI](https://cloud.google.com/vertex-ai) [Embeddings API](https://cloud.google.com/vertex-ai/docs/generative-ai/embeddings/get-text-embeddings). @@ -113,11 +141,3 @@ Vertex AI is a cloud computing platform offered by Google Cloud Platform (GCP). - **top_p:** Tokens are selected from most probable to least until the sum of their – defaults to `0.95`. - **tuned_model_name:** The name of a tuned model. If provided, model_name is ignored. - **verbose:** This parameter is used to control the level of detail in the output of the chain. When set to True, it will print out some internal states of the chain while it is being run, which can help debug and understand the chain's behavior. If set to False, it will suppress the verbose output – defaults to `False`. - -### OllamaEmbeddings - -Used to load [Ollama’s](https://ollama.ai/) embedding models. Wrapper around LangChain's [Ollama API](https://python.langchain.com/docs/integrations/text_embedding/ollama). - -- **model** The name of the Ollama model to use – defaults to `llama2`. -- **base_url** The base URL for the Ollama API – defaults to `http://localhost:11434`. -- **temperature** Tunes the degree of randomness in text generations. Should be a non-negative value – defaults to `0`. From c3967b6e92c5868422a5e74d44e546dcd426c076 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 4 Apr 2024 00:24:52 -0300 Subject: [PATCH 54/54] =?UTF-8?q?=E2=9C=A8=20(cardComponent/index.tsx):=20?= =?UTF-8?q?add=20a=20minimum=20height=20to=20the=20card=20component=20to?= =?UTF-8?q?=20ensure=20consistent=20layout=20and=20prevent=20content=20fro?= =?UTF-8?q?m=20overlapping=20when=20the=20card=20is=20empty=20or=20has=20m?= =?UTF-8?q?inimal=20content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/components/cardComponent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/cardComponent/index.tsx b/src/frontend/src/components/cardComponent/index.tsx index ecc49606d..9d389fb7e 100644 --- a/src/frontend/src/components/cardComponent/index.tsx +++ b/src/frontend/src/components/cardComponent/index.tsx @@ -130,7 +130,7 @@ export default function CollectionCardComponent({ return (