From 8de4812302fd2b982775b77633c862c84578cfea Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Thu, 2 May 2024 16:49:30 -0400 Subject: [PATCH 01/55] initial-content --- .../docs/contributing/contribute-component.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 docs/docs/contributing/contribute-component.md diff --git a/docs/docs/contributing/contribute-component.md b/docs/docs/contributing/contribute-component.md new file mode 100644 index 000000000..1b45747f3 --- /dev/null +++ b/docs/docs/contributing/contribute-component.md @@ -0,0 +1,20 @@ +# How to contribute components? + +As of Langflow 1.0 alpha, new components are added as objects of the `CustomComponent` class and any dependencies are added to the pyproject.toml file. + +## Add an example component + +You have a new document loader called **MyCustomEmbedding** and it would look awesome in Langflow. + +1. Write your loader as an object of the [CustomComponent](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/interface/custom/custom_component/custom_component.py) class. You'll create a new class, `MyCustomEmbeddingComponent`, that will inherit from `CustomComponent` and override the base class's methods. +2. Define optional attributes like `display_name`, `description`, and `documentation` to provide information about your custom component. +3. Implement the `build_config` method to define the configuration options for your custom component. +4. Implement the `build` method to define the logic for taking input parameters specified in the `build_config` method and returning the desired output. +5. Add the code to the [/components/document_loaders](https://github.com/langflow-ai/langflow/tree/dev/src/backend/base/langflow/components) folder. +6. Add the dependency to [/document_loaders/\_\_init\_\_.py](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/components/documentloaders/__init__.py) as `from .MyCustomEmbedding import MyCustomEmbeddingComponent`. +7. Add any new dependencies to the outer [pyproject.toml](https://github.com/langflow-ai/langflow/blob/dev/pyproject.toml#L27) file. +8. Submit your changes as a pull request. The Langflow team will have a look, suggest changes, and add your component to Langflow. + + + + From 429661a5f9043463c72e2e967afb020ed5b802c0 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Thu, 2 May 2024 16:50:48 -0400 Subject: [PATCH 02/55] nav --- docs/sidebars.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sidebars.js b/docs/sidebars.js index a8a673610..5ac73a656 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -128,7 +128,8 @@ module.exports = { items: [ "contributing/how-contribute", "contributing/github-issues", - "contributing/community" + "contributing/community", + "contributing/contribute-component" ], }, ], From 40ebdd3c1b419f65c72ec85f0bc85c3a9eea4c77 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Thu, 2 May 2024 16:51:47 -0400 Subject: [PATCH 03/55] links --- docs/docs/contributing/contribute-component.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/contributing/contribute-component.md b/docs/docs/contributing/contribute-component.md index 1b45747f3..faf7874a2 100644 --- a/docs/docs/contributing/contribute-component.md +++ b/docs/docs/contributing/contribute-component.md @@ -1,6 +1,6 @@ # How to contribute components? -As of Langflow 1.0 alpha, new components are added as objects of the `CustomComponent` class and any dependencies are added to the pyproject.toml file. +As of Langflow 1.0 alpha, new components are added as objects of the [CustomComponent](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/interface/custom/custom_component/custom_component.py) class and any dependencies are added to the [pyproject.toml](https://github.com/langflow-ai/langflow/blob/dev/pyproject.toml#L27) file. ## Add an example component From da3057fd50b002f7a407703dc81255dfde3200ec Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Mon, 6 May 2024 16:11:02 -0300 Subject: [PATCH 04/55] =?UTF-8?q?=F0=9F=90=9B=20(index.tsx):=20fix=20missi?= =?UTF-8?q?ng=20line=20break=20after=20handleUpdateValues=20function=20cal?= =?UTF-8?q?l=20=E2=9C=A8=20(index.tsx):=20improve=20performance=20by=20deb?= =?UTF-8?q?ouncing=20handleUpdateValues=20function=20call=20for=20certain?= =?UTF-8?q?=20types=20of=20parameters=20=F0=9F=93=9D=20(parameterUtils.ts)?= =?UTF-8?q?:=20update=20handleUpdateValues=20function=20to=20use=20optiona?= =?UTF-8?q?l=20chaining=20for=20accessing=20template=20properties=20?= =?UTF-8?q?=F0=9F=9A=80=20(chatInputOutput.spec.ts):=20remove=20unused=20i?= =?UTF-8?q?mports=20and=20commented=20code=20=F0=9F=9A=80=20(dragAndDrop.s?= =?UTF-8?q?pec.ts):=20fix=20typo=20in=20test=20description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/parameterComponent/index.tsx | 41 +++++++++++++------ src/frontend/src/utils/parameterUtils.ts | 29 +++++-------- .../tests/end-to-end/chatInputOutput.spec.ts | 21 ++++------ .../tests/end-to-end/dragAndDrop.spec.ts | 6 +-- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx b/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx index 3fe99b89e..028e3e5d5 100644 --- a/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx @@ -86,7 +86,7 @@ export default function ParameterComponent({ let disabled = edges.some( (edge) => - edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id) + edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id), ) ?? false; const myData = useTypesStore((state) => state.data); @@ -97,6 +97,7 @@ export default function ParameterComponent({ setIsLoading(true); try { let newTemplate = await handleUpdateValues(name, data); + if (newTemplate) { setNode(data.id, (oldNode) => { let newNode = cloneDeep(oldNode); @@ -130,6 +131,7 @@ export default function ParameterComponent({ setIsLoading(true); try { let newTemplate = await handleUpdateValues(name, data); + if (newTemplate) { setNode(data.id, (oldNode) => { let newNode = cloneDeep(oldNode); @@ -154,23 +156,35 @@ export default function ParameterComponent({ } fetchData(); }, []); + const handleOnNewValue = async ( - newValue: string | string[] | boolean | Object[] + newValue: string | string[] | boolean | Object[], ): Promise => { - if (data.node!.template[name].value !== newValue) { + const nodeTemplate = data.node!.template[name]; + const currentValue = nodeTemplate.value; + + if (currentValue !== newValue) { takeSnapshot(); } + const shouldUpdate = data.node?.template[name].real_time_refresh && !data.node?.template[name].refresh_button && - data.node!.template[name].value !== newValue; + currentValue !== newValue; + + const typeToDebounce = nodeTemplate.type; + + nodeTemplate.value = newValue; - data.node!.template[name].value = newValue; // necessary to enable ctrl+z inside the input let newTemplate; if (shouldUpdate) { setIsLoading(true); try { - newTemplate = await debouncedHandleUpdateValues(name, data); + if (["int"].includes(typeToDebounce)) { + newTemplate = await handleUpdateValues(name, data); + } else { + newTemplate = await debouncedHandleUpdateValues(name, data); + } } catch (error) { let responseError = error as ResponseErrorTypeAPI; setErrorData({ @@ -179,18 +193,19 @@ export default function ParameterComponent({ }); } setIsLoading(false); - // this de } - setNode(data.id, (oldNode) => { - let newNode = cloneDeep(oldNode); + setNode(data.id, (oldNode) => { + const newNode = cloneDeep(oldNode); newNode.data = { ...newNode.data, }; if (data.node?.template[name].real_time_refresh && newTemplate) { newNode.data.node.template = newTemplate; - } else newNode.data.node.template[name].value = newValue; + } else { + newNode.data.node.template[name].value = newValue; + } return newNode; }); @@ -264,7 +279,7 @@ export default function ParameterComponent({ 0 ? "mt-2 flex items-center" : "mt-3 flex items-center" + index > 0 ? "mt-2 flex items-center" : "mt-3 flex items-center", )} >
{ - const code = data.node?.template["code"]?.value; + const code = data.node?.template?.code?.value; if (!code) { console.error("Code not found in the template"); return; } + const template = data.node?.template; if (!template) { console.error("No template found in the node."); return; } + try { - let newTemplate = await postCustomComponentUpdate( + const res = await postCustomComponentUpdate( code, template, name, - data.node?.template[name]?.value - ) - .then((res) => { - console.log("res", res); - if (res.status === 200 && data.node?.template) { - return res.data.template; - } - }) - .catch((error) => { - throw error; - }); - return newTemplate; + data.node?.template[name]?.value, + ); + if (res.status === 200 && data.node?.template) { + return res.data.template; + } } catch (error) { console.error("Error occurred while updating the node:", error); - let errorType = error as ResponseErrorTypeAPI; - throw errorType; + throw error; } }; export const debouncedHandleUpdateValues = debounce( handleUpdateValues, - SAVE_DEBOUNCE_TIME + SAVE_DEBOUNCE_TIME, ); diff --git a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts index 50548ab21..a8ddbe3c7 100644 --- a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts @@ -1,7 +1,5 @@ import { expect, test } from "@playwright/test"; -import * as dotenv from "dotenv"; import { readFileSync } from "fs"; -import path from "path"; test("user must interact with chat with Input/Output", async ({ page }) => { if (!process.env.CI) { @@ -60,7 +58,7 @@ test("user must interact with chat with Input/Output", async ({ page }) => { .getByTestId("textarea-input_value") .nth(1) .fill( - "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!" + "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", ); await page.getByTestId("input-sender_name").nth(1).fill("TestSenderNameUser"); await page.getByTestId("input-sender_name").nth(0).fill("TestSenderNameAI"); @@ -82,21 +80,15 @@ test("user must interact with chat with Input/Output", async ({ page }) => { await page .getByText( "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", - { exact: true } + { exact: true }, ) - .isVisible() + .isVisible(), ); }); test("chat_io_teste", async ({ page }) => { await page.goto("/"); await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); - // Read your file into a buffer. - const jsonContent = readFileSync( - "tests/end-to-end/assets/ChatTest.json", - "utf-8" - ); - await page.waitForTimeout(3000); let modalCount = 0; @@ -115,6 +107,11 @@ test("chat_io_teste", async ({ page }) => { modalCount = await page.getByTestId("modal-title")?.count(); } + const jsonContent = readFileSync( + "tests/end-to-end/assets/ChatTest.json", + "utf-8", + ); + await page.getByTestId("blank-flow").click(); await page.waitForTimeout(2000); @@ -135,7 +132,7 @@ test("chat_io_teste", async ({ page }) => { "drop", { dataTransfer, - } + }, ); await page.getByLabel("fit view").click(); await page.getByText("Playground", { exact: true }).click(); diff --git a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts index 785aab408..dbb1d10d7 100644 --- a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts +++ b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts @@ -27,7 +27,7 @@ test.describe("drag and drop test", () => { // Read your file into a buffer. const jsonContent = readFileSync( "tests/end-to-end/assets/collection.json", - "utf-8" + "utf-8", ); // Create the DataTransfer and File @@ -47,10 +47,10 @@ test.describe("drag and drop test", () => { "drop", { dataTransfer, - } + }, ); - await page.getByText("Edit Flow").first().click(); + await page.getByText("Getting Started").first().click(); await page.waitForTimeout(1000); const genericNoda = page.getByTestId("div-generic-node"); From 5a21263272f03424ac9c61b0d0fe6a8d41e8db4d Mon Sep 17 00:00:00 2001 From: Rodrigo Nader Date: Wed, 8 May 2024 09:59:27 -0300 Subject: [PATCH 05/55] Refactor TextOperatorComponent to include true_output parameter (#1829) * Refactor TextOperatorComponent to include true_output parameter * Refactor TextOperatorComponent to include true_output parameter * Add PassComponent to experimental components --- .../langflow/components/experimental/Pass.py | 28 ++++++++++++ .../components/experimental/TextOperator.py | 44 ++++++++++++++++--- 2 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 src/backend/base/langflow/components/experimental/Pass.py diff --git a/src/backend/base/langflow/components/experimental/Pass.py b/src/backend/base/langflow/components/experimental/Pass.py new file mode 100644 index 000000000..1c76a8e96 --- /dev/null +++ b/src/backend/base/langflow/components/experimental/Pass.py @@ -0,0 +1,28 @@ +from typing import Union +from langflow.interface.custom.custom_component import CustomComponent +from langflow.schema import Record +from langflow.field_typing import Text + +class PassComponent(CustomComponent): + display_name = "Pass" + description = "A pass-through component that forwards the second input while ignoring the first, used for controlling workflow direction." + field_order = ["ignored_input", "forwarded_input"] + + def build_config(self) -> dict: + return { + "ignored_input": { + "display_name": "Ignored Input", + "info": "This input is ignored. It's used to control the flow in the graph.", + "input_types": ["Text", "Record"], + }, + "forwarded_input": { + "display_name": "Input", + "info": "This input is forwarded by the component.", + "input_types": ["Text", "Record"], + } + } + + def build(self, ignored_input: Text, forwarded_input: Text) -> Union[Text, Record]: + # The ignored_input is not used in the logic, it's just there for graph flow control + self.status = forwarded_input + return forwarded_input diff --git a/src/backend/base/langflow/components/experimental/TextOperator.py b/src/backend/base/langflow/components/experimental/TextOperator.py index d21d7b7cb..095a7dcb3 100644 --- a/src/backend/base/langflow/components/experimental/TextOperator.py +++ b/src/backend/base/langflow/components/experimental/TextOperator.py @@ -1,3 +1,5 @@ +from typing import Optional, Union + from langflow.interface.custom.custom_component import CustomComponent from langflow.schema import Record from langflow.field_typing import Text @@ -19,19 +21,41 @@ class TextOperatorComponent(CustomComponent): "operator": { "display_name": "Operator", "info": "The operator to apply for comparing the texts.", - "options": ["equals", "not equals", "contains", "starts with", "ends with"], + "options": [ + "equals", + "not equals", + "contains", + "starts with", + "ends with", + "exists" + ], }, "case_sensitive": { "display_name": "Case Sensitive", "info": "If true, the comparison will be case sensitive.", "field_type": "bool", "default": False, - } + }, + "true_output": { + "display_name": "Output", + "info": "The output to return or display when the comparison is true.", + "input_types": ["Text", "Record"], # Allow both text and record types + }, } - def build(self, input_text: Text, match_text: Text, operator: Text, case_sensitive: bool = False) -> Text: + def build( + self, + input_text: Text, + match_text: Text, + operator: Text, + case_sensitive: bool = False, + true_output: Optional[Text] = "", + ) -> Union[Text, Record]: + if not input_text or not match_text: - raise ValueError("Both 'input_text' and 'match_text' must be provided and non-empty.") + raise ValueError( + "Both 'input_text' and 'match_text' must be provided and non-empty." + ) if not case_sensitive: input_text = input_text.lower() @@ -49,7 +73,13 @@ class TextOperatorComponent(CustomComponent): elif operator == "ends with": result = input_text.endswith(match_text) - if not result: + output_record = true_output if true_output else input_text + + if result: + self.status = output_record + return output_record + else: + self.status = "Comparison failed, stopping execution." self.stop() - self.status = f"{result} \n\n {input_text}" - return input_text + + return output_record \ No newline at end of file From 03f781c0f447cf0406db89473001cb61467036ce Mon Sep 17 00:00:00 2001 From: Rodrigo Nader Date: Wed, 8 May 2024 09:59:43 -0300 Subject: [PATCH 06/55] Refactor SplitText (#1836) Refactor LCModelComponent status message formatting for better readability --- .../base/langflow/base/models/model.py | 4 +- .../components/experimental/SplitText.py | 49 +++++++++++ .../langflow/components/helpers/SplitText.py | 87 ------------------- 3 files changed, 51 insertions(+), 89 deletions(-) create mode 100644 src/backend/base/langflow/components/experimental/SplitText.py delete mode 100644 src/backend/base/langflow/components/helpers/SplitText.py diff --git a/src/backend/base/langflow/base/models/model.py b/src/backend/base/langflow/base/models/model.py index 977090818..b38d275f9 100644 --- a/src/backend/base/langflow/base/models/model.py +++ b/src/backend/base/langflow/base/models/model.py @@ -57,7 +57,7 @@ class LCModelComponent(CustomComponent): prompt_tokens = token_usage["prompt_tokens"] total_tokens = token_usage["total_tokens"] finish_reason = response_metadata["finish_reason"] - status_message = f"Tokens:\n- Input: {prompt_tokens}\nOutput: {completion_tokens}\nTotal Tokens: {total_tokens}\nStop Reason: {finish_reason}\nResponse: {content}" + status_message = f"Tokens:\nInput: {prompt_tokens}\nOutput: {completion_tokens}\nTotal Tokens: {total_tokens}\nStop Reason: {finish_reason}\nResponse: {content}" elif all(key in response_metadata for key in anthropic_keys) and all( key in response_metadata["usage"] for key in inner_anthropic_keys ): @@ -65,7 +65,7 @@ class LCModelComponent(CustomComponent): input_tokens = usage["input_tokens"] output_tokens = usage["output_tokens"] stop_reason = response_metadata["stop_reason"] - status_message = f"Tokens:\n- Input: {input_tokens}\n- Output: {output_tokens}\nStop Reason: {stop_reason}\nResponse: {content}" + status_message = f"Tokens:\nInput: {input_tokens}\nOutput: {output_tokens}\nStop Reason: {stop_reason}\nResponse: {content}" else: status_message = f"Response: {content}" else: diff --git a/src/backend/base/langflow/components/experimental/SplitText.py b/src/backend/base/langflow/components/experimental/SplitText.py new file mode 100644 index 000000000..bd2bc921f --- /dev/null +++ b/src/backend/base/langflow/components/experimental/SplitText.py @@ -0,0 +1,49 @@ +from typing import Optional + +from langflow.field_typing import Text +from langflow.interface.custom.custom_component import CustomComponent +from langflow.schema import Record +from langflow.utils.util import unescape_string + + +class SplitTextComponent(CustomComponent): + display_name: str = "Split Text" + description: str = "Split text into chunks of a specified length." + + def build_config(self): + return { + "inputs": { + "display_name": "Inputs", + "info": "Texts to split.", + "input_types": ["Record", "Text"], + }, + "separator": { + "display_name": "Separator", + "info": 'The character to split on. Defaults to " ".', + }, + "truncate_size": { + "display_name": "Truncate Size", + "info": "The maximum length (in number of characters) of each chunk to keep. Defaults to 0 (no truncation).", + }, + } + + def build( + self, + inputs: list[Text], + separator: str = " ", + truncate_size: Optional[int] = 0, + ) -> list[Record]: + separator = unescape_string(separator) + + outputs = [] + for text in inputs: + chunks = text.split(separator) + + if truncate_size: + chunks = [chunk[:truncate_size] for chunk in chunks] + + for chunk in chunks: + outputs.append(Record(text=chunk, data={"parent": text})) + + self.status = outputs + return outputs diff --git a/src/backend/base/langflow/components/helpers/SplitText.py b/src/backend/base/langflow/components/helpers/SplitText.py deleted file mode 100644 index 565ee1ffc..000000000 --- a/src/backend/base/langflow/components/helpers/SplitText.py +++ /dev/null @@ -1,87 +0,0 @@ -from typing import Optional, Union - -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.utils.util import unescape_string - - -class SplitTextComponent(CustomComponent): - display_name: str = "Split Text" - description: str = "Split text into chunks of a specified length." - - def build_config(self): - return { - "inputs": { - "display_name": "Inputs", - "info": "Texts to split.", - "input_types": ["Record", "Text"], - }, - "separators": { - "display_name": "Separators", - "info": 'The characters to split on. Defaults to [" "].', - "is_list": True, - }, - "chunk_size": { - "display_name": "Max Chunk Size", - "info": "The maximum length (in number of characters) of each chunk.", - "field_type": "int", - "value": 1000, - }, - "chunk_overlap": { - "display_name": "Chunk Overlap", - "info": "The amount of character overlap between chunks.", - "field_type": "int", - "value": 200, - }, - "recursive": { - "display_name": "Recursive", - }, - "code": {"show": False}, - } - - def build( - self, - inputs: list[Text], - separators: Optional[list[str]] = [" "], - chunk_size: Optional[int] = 1000, - chunk_overlap: Optional[int] = 200, - recursive: bool = False, - ) -> list[Record]: - if separators is None: - separators = [] - separators = [unescape_string(x) for x in separators] - - # Make sure chunk_size and chunk_overlap are ints - if isinstance(chunk_size, str): - chunk_size = int(chunk_size) - if isinstance(chunk_overlap, str): - chunk_overlap = int(chunk_overlap) - splitter: Optional[Union[CharacterTextSplitter, RecursiveCharacterTextSplitter]] = None - if recursive: - splitter = RecursiveCharacterTextSplitter( - separators=separators, - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - ) - - else: - splitter = CharacterTextSplitter( - separator=separators[0], - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - ) - - documents = [] - 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 - return records From fa872849373f80f463ec5989e9d3a4979ddb5592 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 8 May 2024 10:30:33 -0300 Subject: [PATCH 07/55] Update starter projects --- .../Basic Prompting (Hello, world!).json | 160 ++---- .../Langflow Blog Writter.json | 201 ++------ .../Langflow Document QA.json | 176 ++----- .../Langflow Memory Conversation.json | 241 ++------- .../Langflow Prompt Chaining.json | 337 +++--------- .../VectorStore-RAG-Flows.json | 480 ++++-------------- 6 files changed, 351 insertions(+), 1244 deletions(-) diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json index adda95d44..445f38db9 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json @@ -45,9 +45,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -86,22 +84,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "object", - "str", - "Text" - ], + "base_classes": ["object", "str", "Text"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "user_input" - ] + "template": ["user_input"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -150,9 +140,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -161,7 +149,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -222,14 +210,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -238,9 +222,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -259,9 +241,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -280,9 +260,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": true, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -321,9 +299,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -354,11 +330,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "object", - "Text", - "str" - ], + "base_classes": ["object", "Text", "str"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -372,9 +344,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -445,9 +415,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -471,9 +439,7 @@ "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" - ] + "input_types": ["Text"] }, "return_record": { "type": "bool", @@ -505,10 +471,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -516,9 +479,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -538,9 +499,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -559,20 +518,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "Record", - "Text", - "str", - "object" - ], + "base_classes": ["Record", "Text", "str", "object"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -583,10 +535,7 @@ "return_record": null, "record_template": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -682,10 +631,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -693,9 +639,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -715,9 +659,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -736,20 +678,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Get chat inputs from the Playground.", "icon": "ChatInput", - "base_classes": [ - "object", - "Record", - "str", - "Text" - ], + "base_classes": ["object", "Record", "str", "Text"], "display_name": "Chat Input", "documentation": "", "custom_fields": { @@ -759,10 +694,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -790,17 +722,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-njtka", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], + "baseClasses": ["object", "Text", "str"], "dataType": "OpenAIModel", "id": "OpenAIModel-k39HS" } @@ -820,17 +746,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-k39HS", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "Prompt", "id": "Prompt-uxBqP" } @@ -850,21 +770,11 @@ "targetHandle": { "fieldName": "user_input", "id": "Prompt-uxBqP", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Record", - "str", - "Text" - ], + "baseClasses": ["object", "Record", "str", "Text"], "dataType": "ChatInput", "id": "ChatInput-P3fgL" } @@ -886,4 +796,4 @@ "name": "Basic Prompting (Hello, 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 Blog Writter.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json index 178b7a6b3..3161b6937 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json @@ -45,9 +45,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -138,24 +136,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "object", - "Text", - "str" - ], + "base_classes": ["object", "Text", "str"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "reference_1", - "reference_2", - "instructions" - ] + "template": ["reference_1", "reference_2", "instructions"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -222,9 +210,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": [ "https://www.promptingguide.ai/techniques/prompt_chaining" ] @@ -233,17 +219,13 @@ }, "description": "Fetch content from one or more URLs.", "icon": "layout-template", - "base_classes": [ - "Record" - ], + "base_classes": ["Record"], "display_name": "URL", "documentation": "", "custom_fields": { "urls": null }, - "output_types": [ - "Record" - ], + "output_types": ["Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -302,9 +284,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -328,9 +308,7 @@ "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" - ] + "input_types": ["Text"] }, "return_record": { "type": "bool", @@ -362,10 +340,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -373,9 +348,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -395,9 +368,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -416,20 +387,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "Text", - "Record", - "object", - "str" - ], + "base_classes": ["Text", "Record", "object", "str"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -440,10 +404,7 @@ "return_record": null, "record_template": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -483,9 +444,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -494,7 +453,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -555,14 +514,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -571,9 +526,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -592,9 +545,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -613,9 +564,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -654,9 +603,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -687,11 +634,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -705,9 +648,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -780,28 +721,20 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], - "value": [ - "https://www.promptingguide.ai/introduction/basics" - ] + "input_types": ["Text"], + "value": ["https://www.promptingguide.ai/introduction/basics"] }, "_type": "CustomComponent" }, "description": "Fetch content from one or more URLs.", "icon": "layout-template", - "base_classes": [ - "Record" - ], + "base_classes": ["Record"], "display_name": "URL", "documentation": "", "custom_fields": { "urls": null }, - "output_types": [ - "Record" - ], + "output_types": ["Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -861,10 +794,7 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": [ - "Record", - "Text" - ], + "input_types": ["Record", "Text"], "dynamic": false, "info": "Text or Record to be passed as input.", "load_from_db": false, @@ -888,28 +818,20 @@ "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" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Get text inputs from the Playground.", "icon": "type", - "base_classes": [ - "object", - "Text", - "str" - ], + "base_classes": ["object", "Text", "str"], "display_name": "Instructions", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -938,18 +860,11 @@ "targetHandle": { "fieldName": "reference_2", "id": "Prompt-Rse03", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Record" - ], + "baseClasses": ["Record"], "dataType": "URL", "id": "URL-HYPkR" } @@ -969,17 +884,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-JPlxl", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "OpenAIModel", "id": "OpenAIModel-gi29P" } @@ -999,18 +908,11 @@ "targetHandle": { "fieldName": "reference_1", "id": "Prompt-Rse03", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Record" - ], + "baseClasses": ["Record"], "dataType": "URL", "id": "URL-2cX90" } @@ -1030,20 +932,11 @@ "targetHandle": { "fieldName": "instructions", "id": "Prompt-Rse03", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], + "baseClasses": ["object", "Text", "str"], "dataType": "TextInput", "id": "TextInput-og8Or" } @@ -1063,17 +956,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-gi29P", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], + "baseClasses": ["object", "Text", "str"], "dataType": "Prompt", "id": "Prompt-Rse03" } @@ -1096,4 +983,4 @@ "name": "Blog Writer", "last_tested_version": "1.0.0a0", "is_component": false -} \ No newline at end of file +} diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json index c8713d49e..94156919a 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json @@ -45,9 +45,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -112,23 +110,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "object", - "str", - "Text" - ], + "base_classes": ["object", "str", "Text"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "Document", - "Question" - ] + "template": ["Document", "Question"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -231,18 +220,14 @@ "_type": "CustomComponent" }, "description": "A generic file loader.", - "base_classes": [ - "Record" - ], + "base_classes": ["Record"], "display_name": "Files", "documentation": "", "custom_fields": { "path": null, "silent_errors": null }, - "output_types": [ - "Record" - ], + "output_types": ["Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -338,10 +323,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -349,9 +331,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -371,9 +351,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -392,20 +370,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Get chat inputs from the Playground.", "icon": "ChatInput", - "base_classes": [ - "str", - "Record", - "Text", - "object" - ], + "base_classes": ["str", "Record", "Text", "object"], "display_name": "Chat Input", "documentation": "", "custom_fields": { @@ -415,10 +386,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -477,9 +445,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -515,10 +481,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -526,9 +489,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -548,9 +509,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -569,20 +528,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "str", - "Record", - "Text", - "object" - ], + "base_classes": ["str", "Record", "Text", "object"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -592,10 +544,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -640,9 +589,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -651,7 +598,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -712,14 +659,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -728,9 +671,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -749,9 +690,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -770,9 +709,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -811,9 +748,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -844,11 +779,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "object", - "str", - "Text" - ], + "base_classes": ["object", "str", "Text"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -862,9 +793,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -902,21 +831,11 @@ "targetHandle": { "fieldName": "Question", "id": "Prompt-tHwPf", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Record", - "Text", - "object" - ], + "baseClasses": ["str", "Record", "Text", "object"], "dataType": "ChatInput", "id": "ChatInput-MsSJ9" } @@ -936,18 +855,11 @@ "targetHandle": { "fieldName": "Document", "id": "Prompt-tHwPf", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Record" - ], + "baseClasses": ["Record"], "dataType": "File", "id": "File-6TEsD" } @@ -967,17 +879,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-Bt067", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "Prompt", "id": "Prompt-tHwPf" } @@ -997,17 +903,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-F5Awj", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "OpenAIModel", "id": "OpenAIModel-Bt067" } @@ -1029,4 +929,4 @@ "name": "Document QA", "last_tested_version": "1.0.0a0", "is_component": false -} \ No newline at end of file +} diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 5cee452e4..c477eb0e8 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -83,10 +83,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -94,9 +91,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -116,9 +111,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -137,21 +130,14 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "MySessionID" }, "_type": "CustomComponent" }, "description": "Get chat inputs from the Playground.", "icon": "ChatInput", - "base_classes": [ - "Text", - "object", - "Record", - "str" - ], + "base_classes": ["Text", "object", "Record", "str"], "display_name": "Chat Input", "documentation": "", "custom_fields": { @@ -161,10 +147,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -223,9 +206,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -261,10 +242,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -272,9 +250,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -294,9 +270,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -315,21 +289,14 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "MySessionID" }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "Text", - "object", - "Record", - "str" - ], + "base_classes": ["Text", "object", "Record", "str"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -339,10 +306,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -418,10 +382,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "name": "order", "display_name": "Order", "advanced": true, @@ -429,9 +390,7 @@ "info": "Order of the messages.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "record_template": { "type": "str", @@ -451,9 +410,7 @@ "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" - ] + "input_types": ["Text"] }, "sender": { "type": "str", @@ -466,11 +423,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "name": "sender", "display_name": "Sender Type", "advanced": false, @@ -478,9 +431,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -499,9 +450,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -516,9 +465,7 @@ "name": "session_id", "display_name": "Session ID", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "Session ID of the chat history.", "load_from_db": false, @@ -529,11 +476,7 @@ }, "description": "Retrieves stored chat messages given a specific Session ID.", "icon": "history", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "Chat Memory", "documentation": "", "custom_fields": { @@ -544,9 +487,7 @@ "order": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -608,9 +549,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -675,23 +614,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "Text", - "str", - "object" - ], + "base_classes": ["Text", "str", "object"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "context", - "user_message" - ] + "template": ["context", "user_message"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -740,9 +670,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -751,7 +679,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -812,14 +740,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -828,9 +752,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -849,9 +771,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -870,9 +790,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -911,9 +829,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -944,11 +860,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "str", - "object", - "Text" - ], + "base_classes": ["str", "object", "Text"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -962,9 +874,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -1016,10 +926,7 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": [ - "Record", - "Text" - ], + "input_types": ["Record", "Text"], "dynamic": false, "info": "Text or Record to be passed as output.", "load_from_db": false, @@ -1061,28 +968,20 @@ "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" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a text output in the Playground.", "icon": "type", - "base_classes": [ - "str", - "object", - "Text" - ], + "base_classes": ["str", "object", "Text"], "display_name": "Inspect Memory", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1111,19 +1010,10 @@ "fieldName": "context", "type": "str", "id": "Prompt-ODkUx", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ] + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"] }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "MemoryComponent", "id": "MemoryComponent-cdA1J" } @@ -1145,20 +1035,10 @@ "fieldName": "user_message", "type": "str", "id": "Prompt-ODkUx", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ] + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"] }, "sourceHandle": { - "baseClasses": [ - "Text", - "object", - "Record", - "str" - ], + "baseClasses": ["Text", "object", "Record", "str"], "dataType": "ChatInput", "id": "ChatInput-t7F8v" } @@ -1179,17 +1059,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-9RykF", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Text", - "str", - "object" - ], + "baseClasses": ["Text", "str", "object"], "dataType": "Prompt", "id": "Prompt-ODkUx" } @@ -1209,17 +1083,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-P1jEe", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "object", - "Text" - ], + "baseClasses": ["str", "object", "Text"], "dataType": "OpenAIModel", "id": "OpenAIModel-9RykF" } @@ -1239,18 +1107,11 @@ "targetHandle": { "fieldName": "input_value", "id": "TextOutput-vrs6T", - "inputTypes": [ - "Record", - "Text" - ], + "inputTypes": ["Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "MemoryComponent", "id": "MemoryComponent-cdA1J" } @@ -1272,4 +1133,4 @@ "name": "Memory Chatbot", "last_tested_version": "1.0.0a0", "is_component": false -} \ No newline at end of file +} diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json index e4f6b2d2c..7f56faaf0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json @@ -45,9 +45,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -86,22 +84,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "object", - "str", - "Text" - ], + "base_classes": ["object", "str", "Text"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "document" - ] + "template": ["document"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -165,9 +155,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -206,22 +194,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "object", - "str", - "Text" - ], + "base_classes": ["object", "str", "Text"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "summary" - ] + "template": ["summary"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -280,9 +260,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -306,9 +284,7 @@ "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" - ] + "input_types": ["Text"] }, "return_record": { "type": "bool", @@ -340,10 +316,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -351,9 +324,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -373,9 +344,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -394,20 +363,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "object", - "Record", - "Text", - "str" - ], + "base_classes": ["object", "Record", "Text", "str"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -418,10 +380,7 @@ "return_record": null, "record_template": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -476,9 +435,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -502,9 +459,7 @@ "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" - ] + "input_types": ["Text"] }, "return_record": { "type": "bool", @@ -536,10 +491,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -547,9 +499,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -569,9 +519,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -590,20 +538,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "object", - "Record", - "Text", - "str" - ], + "base_classes": ["object", "Record", "Text", "str"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -614,10 +555,7 @@ "return_record": null, "record_template": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -672,10 +610,7 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": [ - "Record", - "Text" - ], + "input_types": ["Record", "Text"], "dynamic": false, "info": "Text or Record to be passed as input.", "load_from_db": false, @@ -699,28 +634,20 @@ "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" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Get text inputs from the Playground.", "icon": "type", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "Text Input", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -762,10 +689,7 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": [ - "Record", - "Text" - ], + "input_types": ["Record", "Text"], "dynamic": false, "info": "Text or Record to be passed as output.", "load_from_db": false, @@ -807,28 +731,20 @@ "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" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a text output in the Playground.", "icon": "type", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "First Prompt", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -873,9 +789,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -884,7 +798,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -945,14 +859,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -961,9 +871,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -982,9 +890,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -1003,9 +909,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -1044,9 +948,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -1077,11 +979,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -1095,9 +993,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -1149,10 +1045,7 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": [ - "Record", - "Text" - ], + "input_types": ["Record", "Text"], "dynamic": false, "info": "Text or Record to be passed as output.", "load_from_db": false, @@ -1194,28 +1087,20 @@ "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" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a text output in the Playground.", "icon": "type", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "Second Prompt", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1260,9 +1145,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -1271,7 +1154,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -1332,14 +1215,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -1348,9 +1227,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -1369,9 +1246,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -1390,9 +1265,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -1431,9 +1304,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -1464,11 +1335,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "str", - "Text", - "object" - ], + "base_classes": ["str", "Text", "object"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -1482,9 +1349,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -1522,20 +1387,11 @@ "targetHandle": { "fieldName": "document", "id": "Prompt-amqBu", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "TextInput", "id": "TextInput-sptaH" } @@ -1555,18 +1411,11 @@ "targetHandle": { "fieldName": "input_value", "id": "TextOutput-2MS4a", - "inputTypes": [ - "Record", - "Text" - ], + "inputTypes": ["Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "Prompt", "id": "Prompt-amqBu" } @@ -1586,17 +1435,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-uYXZJ", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "Prompt", "id": "Prompt-amqBu" } @@ -1616,20 +1459,11 @@ "targetHandle": { "fieldName": "summary", "id": "Prompt-gTNiz", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "OpenAIModel", "id": "OpenAIModel-uYXZJ" } @@ -1649,17 +1483,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-EJkG3", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "OpenAIModel", "id": "OpenAIModel-uYXZJ" } @@ -1679,18 +1507,11 @@ "targetHandle": { "fieldName": "input_value", "id": "TextOutput-MUDOR", - "inputTypes": [ - "Record", - "Text" - ], + "inputTypes": ["Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "Prompt", "id": "Prompt-gTNiz" } @@ -1710,17 +1531,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-XawYB", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], + "baseClasses": ["object", "str", "Text"], "dataType": "Prompt", "id": "Prompt-gTNiz" } @@ -1740,17 +1555,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-DNmvg", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], + "baseClasses": ["str", "Text", "object"], "dataType": "OpenAIModel", "id": "OpenAIModel-XawYB" } @@ -1772,4 +1581,4 @@ "name": "Prompt Chaining", "last_tested_version": "1.0.0a0", "is_component": false -} \ No newline at end of file +} 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 85fcd0b5b..b0f1ad3b1 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 @@ -81,10 +81,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -92,9 +89,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -114,9 +109,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -135,20 +128,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Get chat inputs from the Playground.", "icon": "ChatInput", - "base_classes": [ - "Text", - "str", - "object", - "Record" - ], + "base_classes": ["Text", "str", "object", "Record"], "display_name": "Chat Input", "documentation": "", "custom_fields": { @@ -158,10 +144,7 @@ "session_id": null, "return_record": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -198,10 +181,7 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": [ - "Record", - "Text" - ], + "input_types": ["Record", "Text"], "dynamic": false, "info": "Text or Record to be passed as output.", "load_from_db": false, @@ -243,28 +223,20 @@ "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" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a text output in the Playground.", "icon": "type", - "base_classes": [ - "object", - "Text", - "str" - ], + "base_classes": ["object", "Text", "str"], "display_name": "Extracted Chunks", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -310,9 +282,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "chunk_size": { "type": "int", @@ -424,9 +394,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "disallowed_special": { "type": "str", @@ -435,9 +403,7 @@ "list": false, "show": true, "multiline": false, - "value": [ - "all" - ], + "value": ["all"], "fileTypes": [], "file_path": "", "password": false, @@ -448,9 +414,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "embedding_ctx_length": { "type": "int", @@ -513,9 +477,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "model_kwargs": { "type": "NestedDict", @@ -553,9 +515,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -574,9 +534,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "openai_api_type": { @@ -596,9 +554,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_version": { "type": "str", @@ -617,9 +573,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_organization": { "type": "str", @@ -638,9 +592,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_proxy": { "type": "str", @@ -659,9 +611,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "request_timeout": { "type": "float", @@ -761,16 +711,12 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Generate embeddings using OpenAI models.", - "base_classes": [ - "Embeddings" - ], + "base_classes": ["Embeddings"], "display_name": "OpenAI Embeddings", "documentation": "", "custom_fields": { @@ -797,9 +743,7 @@ "tiktoken_enable": null, "tiktoken_model_name": null }, - "output_types": [ - "Embeddings" - ], + "output_types": ["Embeddings"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -840,9 +784,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "code": { "type": "code", @@ -851,7 +793,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\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-2024-04-09\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -912,14 +854,10 @@ "file_path": "", "password": false, "options": [ - "gpt-4-turbo-2024-04-09", + "gpt-4-turbo", "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" + "gpt-3.5-turbo-0125" ], "name": "model_name", "display_name": "Model Name", @@ -928,9 +866,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_base": { "type": "str", @@ -949,9 +885,7 @@ "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" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -970,9 +904,7 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "stream": { @@ -1011,9 +943,7 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "temperature": { "type": "float", @@ -1044,11 +974,7 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": [ - "object", - "Text", - "str" - ], + "base_classes": ["object", "Text", "str"], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -1062,9 +988,7 @@ "stream": null, "system_message": null }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -1134,9 +1058,7 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -1201,23 +1123,14 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": [ - "object", - "Text", - "str" - ], + "base_classes": ["object", "Text", "str"], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": [ - "context", - "question" - ] + "template": ["context", "question"] }, - "output_types": [ - "Text" - ], + "output_types": ["Text"], "full_path": null, "field_formatters": {}, "frozen": false, @@ -1280,9 +1193,7 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "dynamic": false, "info": "", "load_from_db": false, @@ -1306,9 +1217,7 @@ "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" - ] + "input_types": ["Text"] }, "return_record": { "type": "bool", @@ -1340,10 +1249,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -1351,9 +1257,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "sender_name": { "type": "str", @@ -1373,9 +1277,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "session_id": { "type": "str", @@ -1394,20 +1296,13 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": [ - "object", - "Text", - "Record", - "str" - ], + "base_classes": ["object", "Text", "Record", "str"], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -1418,10 +1313,7 @@ "return_record": null, "record_template": null }, - "output_types": [ - "Text", - "Record" - ], + "output_types": ["Text", "Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1528,18 +1420,14 @@ }, "description": "A generic file loader.", "icon": "file-text", - "base_classes": [ - "Record" - ], + "base_classes": ["Record"], "display_name": "File", "documentation": "", "custom_fields": { "path": null, "silent_errors": null }, - "output_types": [ - "Record" - ], + "output_types": ["Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1580,10 +1468,7 @@ "name": "inputs", "display_name": "Input", "advanced": false, - "input_types": [ - "Document", - "Record" - ], + "input_types": ["Document", "Record"], "dynamic": false, "info": "The texts to split.", "load_from_db": false, @@ -1662,19 +1547,13 @@ "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": [ - "" - ] + "input_types": ["Text"], + "value": [""] }, "_type": "CustomComponent" }, "description": "Split text into chunks of a specified length.", - "base_classes": [ - "Record" - ], + "base_classes": ["Record"], "display_name": "Recursive Character Text Splitter", "documentation": "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter", "custom_fields": { @@ -1683,9 +1562,7 @@ "chunk_size": null, "chunk_overlap": null }, - "output_types": [ - "Record" - ], + "output_types": ["Record"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1748,9 +1625,7 @@ "info": "Input value to search", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "api_endpoint": { "type": "str", @@ -1769,9 +1644,7 @@ "info": "API endpoint URL for the Astra DB service.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "batch_size": { @@ -1899,9 +1772,7 @@ "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "langflow" }, "metadata_indexing_exclude": { @@ -1921,9 +1792,7 @@ "info": "Optional list of metadata fields to exclude from the indexing.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "metadata_indexing_include": { "type": "str", @@ -1942,9 +1811,7 @@ "info": "Optional list of metadata fields to include in the indexing.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "metric": { "type": "str", @@ -1963,9 +1830,7 @@ "info": "Optional distance metric for vector comparisons in the vector store.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "namespace": { "type": "str", @@ -1984,9 +1849,7 @@ "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "number_of_results": { "type": "int", @@ -2037,10 +1900,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Similarity", - "MMR" - ], + "options": ["Similarity", "MMR"], "name": "search_type", "display_name": "Search Type", "advanced": false, @@ -2048,9 +1908,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "setup_mode": { "type": "str", @@ -2063,11 +1921,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Sync", - "Async", - "Off" - ], + "options": ["Sync", "Async", "Off"], "name": "setup_mode", "display_name": "Setup Mode", "advanced": true, @@ -2075,9 +1929,7 @@ "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" - ] + "input_types": ["Text"] }, "token": { "type": "str", @@ -2096,18 +1948,14 @@ "info": "Authentication token for accessing Astra DB.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "_type": "CustomComponent" }, "description": "Searches an existing Astra DB Vector Store.", "icon": "AstraDB", - "base_classes": [ - "Record" - ], + "base_classes": ["Record"], "display_name": "Astra DB Search", "documentation": "", "custom_fields": { @@ -2130,9 +1978,7 @@ "metadata_indexing_exclude": null, "collection_indexing_policy": null }, - "output_types": [ - "Record" - ], + "output_types": ["Record"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -2219,9 +2065,7 @@ "info": "API endpoint URL for the Astra DB service.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "batch_size": { @@ -2349,9 +2193,7 @@ "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "langflow" }, "metadata_indexing_exclude": { @@ -2371,9 +2213,7 @@ "info": "Optional list of metadata fields to exclude from the indexing.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "metadata_indexing_include": { "type": "str", @@ -2392,9 +2232,7 @@ "info": "Optional list of metadata fields to include in the indexing.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "metric": { "type": "str", @@ -2413,9 +2251,7 @@ "info": "Optional distance metric for vector comparisons in the vector store.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "namespace": { "type": "str", @@ -2434,9 +2270,7 @@ "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "pre_delete_collection": { "type": "bool", @@ -2468,11 +2302,7 @@ "fileTypes": [], "file_path": "", "password": false, - "options": [ - "Sync", - "Async", - "Off" - ], + "options": ["Sync", "Async", "Off"], "name": "setup_mode", "display_name": "Setup Mode", "advanced": true, @@ -2480,9 +2310,7 @@ "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" - ] + "input_types": ["Text"] }, "token": { "type": "str", @@ -2501,18 +2329,14 @@ "info": "Authentication token for accessing Astra DB.", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "_type": "CustomComponent" }, "description": "Builds or loads an Astra DB Vector Store.", "icon": "AstraDB", - "base_classes": [ - "VectorStore" - ], + "base_classes": ["VectorStore"], "display_name": "Astra DB", "documentation": "", "custom_fields": { @@ -2533,9 +2357,7 @@ "metadata_indexing_exclude": null, "collection_indexing_policy": null }, - "output_types": [ - "VectorStore" - ], + "output_types": ["VectorStore"], "field_formatters": {}, "frozen": false, "field_order": [ @@ -2587,9 +2409,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "chunk_size": { "type": "int", @@ -2701,9 +2521,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "disallowed_special": { "type": "str", @@ -2712,9 +2530,7 @@ "list": false, "show": true, "multiline": false, - "value": [ - "all" - ], + "value": ["all"], "fileTypes": [], "file_path": "", "password": false, @@ -2725,9 +2541,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "embedding_ctx_length": { "type": "int", @@ -2790,9 +2604,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "model_kwargs": { "type": "NestedDict", @@ -2830,9 +2642,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_key": { "type": "str", @@ -2851,9 +2661,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ], + "input_types": ["Text"], "value": "" }, "openai_api_type": { @@ -2873,9 +2681,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_api_version": { "type": "str", @@ -2894,9 +2700,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_organization": { "type": "str", @@ -2915,9 +2719,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "openai_proxy": { "type": "str", @@ -2936,9 +2738,7 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "request_timeout": { "type": "float", @@ -3038,16 +2838,12 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": [ - "Text" - ] + "input_types": ["Text"] }, "_type": "CustomComponent" }, "description": "Generate embeddings using OpenAI models.", - "base_classes": [ - "Embeddings" - ], + "base_classes": ["Embeddings"], "display_name": "OpenAI Embeddings", "documentation": "", "custom_fields": { @@ -3074,9 +2870,7 @@ "tiktoken_enable": null, "tiktoken_model_name": null }, - "output_types": [ - "Embeddings" - ], + "output_types": ["Embeddings"], "field_formatters": {}, "frozen": false, "field_order": [], @@ -3105,20 +2899,11 @@ "targetHandle": { "fieldName": "context", "id": "Prompt-xeI6K", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], + "baseClasses": ["object", "Text", "str"], "dataType": "TextOutput", "id": "TextOutput-BDknO" } @@ -3139,21 +2924,11 @@ "targetHandle": { "fieldName": "question", "id": "Prompt-xeI6K", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], + "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Text", - "str", - "object", - "Record" - ], + "baseClasses": ["Text", "str", "object", "Record"], "dataType": "ChatInput", "id": "ChatInput-yxMKE" } @@ -3174,17 +2949,11 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-EjXlN", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], + "baseClasses": ["object", "Text", "str"], "dataType": "Prompt", "id": "Prompt-xeI6K" } @@ -3205,17 +2974,11 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-Q39I8", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "object", - "Text", - "str" - ], + "baseClasses": ["object", "Text", "str"], "dataType": "OpenAIModel", "id": "OpenAIModel-EjXlN" } @@ -3236,16 +2999,11 @@ "targetHandle": { "fieldName": "inputs", "id": "RecursiveCharacterTextSplitter-tR9QM", - "inputTypes": [ - "Document", - "Record" - ], + "inputTypes": ["Document", "Record"], "type": "Document" }, "sourceHandle": { - "baseClasses": [ - "Record" - ], + "baseClasses": ["Record"], "dataType": "File", "id": "File-t0a6a" } @@ -3269,9 +3027,7 @@ "type": "Embeddings" }, "sourceHandle": { - "baseClasses": [ - "Embeddings" - ], + "baseClasses": ["Embeddings"], "dataType": "OpenAIEmbeddings", "id": "OpenAIEmbeddings-ZlOk1" } @@ -3291,18 +3047,11 @@ "targetHandle": { "fieldName": "input_value", "id": "AstraDBSearch-41nRz", - "inputTypes": [ - "Text" - ], + "inputTypes": ["Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Text", - "str", - "object", - "Record" - ], + "baseClasses": ["Text", "str", "object", "Record"], "dataType": "ChatInput", "id": "ChatInput-yxMKE" } @@ -3326,9 +3075,7 @@ "type": "Record" }, "sourceHandle": { - "baseClasses": [ - "Record" - ], + "baseClasses": ["Record"], "dataType": "RecursiveCharacterTextSplitter", "id": "RecursiveCharacterTextSplitter-tR9QM" } @@ -3353,9 +3100,7 @@ "type": "Embeddings" }, "sourceHandle": { - "baseClasses": [ - "Embeddings" - ], + "baseClasses": ["Embeddings"], "dataType": "OpenAIEmbeddings", "id": "OpenAIEmbeddings-9TPjc" } @@ -3376,16 +3121,11 @@ "targetHandle": { "fieldName": "input_value", "id": "TextOutput-BDknO", - "inputTypes": [ - "Record", - "Text" - ], + "inputTypes": ["Record", "Text"], "type": "str" }, "sourceHandle": { - "baseClasses": [ - "Record" - ], + "baseClasses": ["Record"], "dataType": "AstraDBSearch", "id": "AstraDBSearch-41nRz" } @@ -3407,4 +3147,4 @@ "name": "Vector Store RAG", "last_tested_version": "1.0.0a0", "is_component": false -} \ No newline at end of file +} From 1a54582b95bdcf331bc76a9612edb1516762f82c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 8 May 2024 11:46:48 -0300 Subject: [PATCH 08/55] Update ZepMessageReader and ZepMessageWriter to avoid 404 error (#1844) * Update ZepMessageReader and ZepMessageWriter to avoid 404 error * Update ZepMessageReader and ZepMessageWriter to use API Base Path option * Update ZepMessageReader and ZepMessageWriter to fix API Base Path and avoid 404 error * Update ZepMessageReader and ZepMessageWriter to use API Base Path option --- .../components/memories/ZepMessageReader.py | 14 ++++++++++++++ .../components/memories/ZepMessageWriter.py | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/components/memories/ZepMessageReader.py b/src/backend/base/langflow/components/memories/ZepMessageReader.py index 603e41972..bac6e9f1a 100644 --- a/src/backend/base/langflow/components/memories/ZepMessageReader.py +++ b/src/backend/base/langflow/components/memories/ZepMessageReader.py @@ -54,6 +54,10 @@ class ZepMessageReaderComponent(BaseMemoryComponent): "info": "Limit of search results.", "advanced": True, }, + "api_base_path": { + "display_name": "API Base Path", + "options": ["api/v1", "api/v2"], + }, } def get_messages(self, **kwargs) -> list[Record]: @@ -108,6 +112,7 @@ class ZepMessageReaderComponent(BaseMemoryComponent): def build( self, session_id: Text, + api_base_path: str = "api/v1", url: Optional[Text] = None, api_key: Optional[Text] = None, query: Optional[Text] = None, @@ -118,12 +123,21 @@ class ZepMessageReaderComponent(BaseMemoryComponent): try: from zep_python import ZepClient from zep_python.langchain import ZepChatMessageHistory + + # Monkeypatch API_BASE_PATH to + # avoid 404 + # This is a workaround for the local Zep instance + # cloud Zep works with v2 + import zep_python.zep_client + + zep_python.zep_client.API_BASE_PATH = api_base_path except ImportError: raise ImportError( "Could not import zep-python package. " "Please install it with `pip install zep-python`." ) if url == "": url = None + zep_client = ZepClient(api_url=url, api_key=api_key) memory = ZepChatMessageHistory(session_id=session_id, zep_client=zep_client) records = self.get_messages( diff --git a/src/backend/base/langflow/components/memories/ZepMessageWriter.py b/src/backend/base/langflow/components/memories/ZepMessageWriter.py index 248dfd810..b062f66bf 100644 --- a/src/backend/base/langflow/components/memories/ZepMessageWriter.py +++ b/src/backend/base/langflow/components/memories/ZepMessageWriter.py @@ -1,5 +1,4 @@ -from typing import Optional, TYPE_CHECKING - +from typing import TYPE_CHECKING, Optional from langflow.base.memory.memory import BaseMemoryComponent from langflow.field_typing import Text @@ -39,6 +38,10 @@ class ZepMessageWriterComponent(BaseMemoryComponent): "display_name": "Input Record", "info": "Record to write to Zep.", }, + "api_base_path": { + "display_name": "API Base Path", + "options": ["api/v1", "api/v2"], + }, } def add_message( @@ -77,18 +80,27 @@ class ZepMessageWriterComponent(BaseMemoryComponent): self, input_value: Record, session_id: Text, + api_base_path: str = "api/v1", url: Optional[Text] = None, api_key: Optional[Text] = None, ) -> Record: try: + # Monkeypatch API_BASE_PATH to + # avoid 404 + # This is a workaround for the local Zep instance + # cloud Zep works with v2 + import zep_python.zep_client from zep_python import ZepClient from zep_python.langchain import ZepChatMessageHistory + + zep_python.zep_client.API_BASE_PATH = api_base_path except ImportError: raise ImportError( "Could not import zep-python package. " "Please install it with `pip install zep-python`." ) if url == "": url = None + zep_client = ZepClient(api_url=url, api_key=api_key) memory = ZepChatMessageHistory(session_id=session_id, zep_client=zep_client) self.add_message(**input_value.data, memory=memory) From 436c290ee712ddd0e4bd6e605800ccf583a7ec80 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Wed, 8 May 2024 11:47:51 -0400 Subject: [PATCH 09/55] submit-to-store --- .../docs/contributing/contribute-component.md | 35 ++++++++++++++++-- docs/static/img/add-component-to-store.png | Bin 0 -> 139007 bytes 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 docs/static/img/add-component-to-store.png diff --git a/docs/docs/contributing/contribute-component.md b/docs/docs/contributing/contribute-component.md index faf7874a2..bd60c07ab 100644 --- a/docs/docs/contributing/contribute-component.md +++ b/docs/docs/contributing/contribute-component.md @@ -1,20 +1,47 @@ +import ZoomableImage from "/src/theme/ZoomableImage.js"; + # How to contribute components? As of Langflow 1.0 alpha, new components are added as objects of the [CustomComponent](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/interface/custom/custom_component/custom_component.py) class and any dependencies are added to the [pyproject.toml](https://github.com/langflow-ai/langflow/blob/dev/pyproject.toml#L27) file. ## Add an example component -You have a new document loader called **MyCustomEmbedding** and it would look awesome in Langflow. +You have a new document loader called **MyCustomDocumentLoader** and it would look awesome in Langflow. -1. Write your loader as an object of the [CustomComponent](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/interface/custom/custom_component/custom_component.py) class. You'll create a new class, `MyCustomEmbeddingComponent`, that will inherit from `CustomComponent` and override the base class's methods. +1. Write your loader as an object of the [CustomComponent](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/interface/custom/custom_component/custom_component.py) class. You'll create a new class, `MyCustomDocumentLoader`, that will inherit from `CustomComponent` and override the base class's methods. 2. Define optional attributes like `display_name`, `description`, and `documentation` to provide information about your custom component. 3. Implement the `build_config` method to define the configuration options for your custom component. 4. Implement the `build` method to define the logic for taking input parameters specified in the `build_config` method and returning the desired output. 5. Add the code to the [/components/document_loaders](https://github.com/langflow-ai/langflow/tree/dev/src/backend/base/langflow/components) folder. -6. Add the dependency to [/document_loaders/\_\_init\_\_.py](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/components/documentloaders/__init__.py) as `from .MyCustomEmbedding import MyCustomEmbeddingComponent`. +6. Add the dependency to [/document_loaders/\_\_init\_\_.py](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/components/documentloaders/__init__.py) as `from .MyCustomEmbedding import MyCustomDocumentLoader`. 7. Add any new dependencies to the outer [pyproject.toml](https://github.com/langflow-ai/langflow/blob/dev/pyproject.toml#L27) file. +8. Submit documentation for your component. For this example, you'd submit documentation to the [loaders page](https://github.com/langflow-ai/langflow/blob/dev/docs/docs/components/loaders.mdx). 8. Submit your changes as a pull request. The Langflow team will have a look, suggest changes, and add your component to Langflow. - +## User Sharing + +You might want to share and test your custom component with others, but don't need it merged into the main source code. + +If so, you can share your component on the Langflow store. + +1. [Register at the Langflow store](https://www.langflow.store/login/). +2. Undergo pre-validation before receiving an API key. +3. To deploy your amazing component directly to the Langflow store, without it being merged into the main source code, navigate to your flow, and then click **Share**. +The share window appears: + + + +5. Choose whether you want to flow to be public or private. +You can also **Export** your flow as a JSON file from this window. +When you're ready to share the flow, click **Share Flow**. +You should see a **Flow shared successfully** popup. +6. To confirm, navigate to the **Langflow Store** and filter results by **Created By Me**. You should see your new flow on the **Langflow Store**. diff --git a/docs/static/img/add-component-to-store.png b/docs/static/img/add-component-to-store.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccb0a0469ae26c21866e2d2652a046797d4e24b GIT binary patch literal 139007 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�iK*J|gJi-l-$P_wARjKQ*qk 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 aw>oygtRm(&@-^NJK;Y@>=d#Wzp$P!WkQ@yF literal 0 HcmV?d00001 From b0a96928f19f8f808b349657bcf325ad2ace2819 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Thu, 9 May 2024 12:28:02 -0400 Subject: [PATCH 10/55] fix-folder-path --- docs/docs/contributing/contribute-component.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/contributing/contribute-component.md b/docs/docs/contributing/contribute-component.md index bd60c07ab..398fc3b9c 100644 --- a/docs/docs/contributing/contribute-component.md +++ b/docs/docs/contributing/contribute-component.md @@ -12,8 +12,8 @@ You have a new document loader called **MyCustomDocumentLoader** and it would lo 2. Define optional attributes like `display_name`, `description`, and `documentation` to provide information about your custom component. 3. Implement the `build_config` method to define the configuration options for your custom component. 4. Implement the `build` method to define the logic for taking input parameters specified in the `build_config` method and returning the desired output. -5. Add the code to the [/components/document_loaders](https://github.com/langflow-ai/langflow/tree/dev/src/backend/base/langflow/components) folder. -6. Add the dependency to [/document_loaders/\_\_init\_\_.py](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/components/documentloaders/__init__.py) as `from .MyCustomEmbedding import MyCustomDocumentLoader`. +5. Add the code to the [/components/documentloaders](https://github.com/langflow-ai/langflow/tree/dev/src/backend/base/langflow/components) folder. +6. Add the dependency to [/documentloaders/\_\_init\_\_.py](https://github.com/langflow-ai/langflow/blob/dev/src/backend/base/langflow/components/documentloaders/__init__.py) as `from .MyCustomDocumentLoader import MyCustomDocumentLoader`. 7. Add any new dependencies to the outer [pyproject.toml](https://github.com/langflow-ai/langflow/blob/dev/pyproject.toml#L27) file. 8. Submit documentation for your component. For this example, you'd submit documentation to the [loaders page](https://github.com/langflow-ai/langflow/blob/dev/docs/docs/components/loaders.mdx). 8. Submit your changes as a pull request. The Langflow team will have a look, suggest changes, and add your component to Langflow. From 12d1a9a426e4bc90b6b4c07d85cce3baced7ea76 Mon Sep 17 00:00:00 2001 From: h-arnold <78823477+h-arnold@users.noreply.github.com> Date: Thu, 9 May 2024 19:54:16 +0100 Subject: [PATCH 11/55] Added MistralAI LLM and Embedding (#1865) * Added Mistral AI LLM Model and added MistralAI embeddings. * Added tracking to the new MistralAIEmbeddings.py and MistalModel.py * Added MistralAI model specs and added the correct models list to the Mistral Model LLM component. * Actually added the MistralAI model specs this time. --- poetry.lock | 335 ++++++++++-------- pyproject.toml | 2 + .../embeddings/MistalAIEmbeddings.py | 69 ++++ .../model_specs/ChatMistralSpecs.py | 87 +++++ .../components/models/MistralModel.py | 111 ++++++ 5 files changed, 450 insertions(+), 154 deletions(-) create mode 100644 src/backend/base/langflow/components/embeddings/MistalAIEmbeddings.py create mode 100644 src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py create mode 100644 src/backend/base/langflow/components/models/MistralModel.py diff --git a/poetry.lock b/poetry.lock index 8bec14eee..57995055b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiohttp" @@ -167,13 +167,13 @@ files = [ [[package]] name = "anthropic" -version = "0.25.7" +version = "0.25.8" description = "The official Python library for the anthropic API" optional = false python-versions = ">=3.7" files = [ - {file = "anthropic-0.25.7-py3-none-any.whl", hash = "sha256:419a276eb20cfb7ddaac03c7e28e4e12df3ace71bcf33071a68c9a03c0dfcbdd"}, - {file = "anthropic-0.25.7.tar.gz", hash = "sha256:e7de4c8ba8e7e8248ad7f05ed9176634780b95b67c678d23915d8964c8a26f4e"}, + {file = "anthropic-0.25.8-py3-none-any.whl", hash = "sha256:c7a0091916eb22a5e0012b725f5492779eedfcad2da8dc906082e1db7596a65c"}, + {file = "anthropic-0.25.8.tar.gz", hash = "sha256:93f6063e96d5dbeaa172edc177762f630e55b2f81595cedb760278b95a2dd03e"}, ] [package.dependencies] @@ -1161,13 +1161,13 @@ types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency [[package]] name = "cohere" -version = "5.3.4" +version = "5.3.2" description = "" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "cohere-5.3.4-py3-none-any.whl", hash = "sha256:2d62306ed86c346d472e2355cf653b8fbd8722330e554355d576fb6061e204f2"}, - {file = "cohere-5.3.4.tar.gz", hash = "sha256:b45a2c85b025dd15367d69bf92748de4a30ec82abb4b08fa5301b72e89051fe2"}, + {file = "cohere-5.3.2-py3-none-any.whl", hash = "sha256:98fe701966f2f39a51f86d3827339576491ecfda080ed6e9710109c3245a5c73"}, + {file = "cohere-5.3.2.tar.gz", hash = "sha256:337905bd7bd7f3958ab4db3029d3d2abc43f789c957b0deff0d603d8fabc4838"}, ] [package.dependencies] @@ -1176,7 +1176,7 @@ httpx = ">=0.21.2" httpx-sse = ">=0.4.0,<0.5.0" pydantic = ">=1.9.2" requests = ">=2.0.0,<3.0.0" -tokenizers = ">=0.19,<0.20" +tokenizers = ">=0.15.2,<0.16.0" types-requests = ">=2.0.0,<3.0.0" typing_extensions = ">=4.0.0" @@ -4114,18 +4114,18 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langchain-experimental" -version = "0.0.57" +version = "0.0.58" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_experimental-0.0.57-py3-none-any.whl", hash = "sha256:96479a2d45a35722cf2fe49655639e91d3fff5ccaba498cda32b088d5b184325"}, - {file = "langchain_experimental-0.0.57.tar.gz", hash = "sha256:d1fb452aa1f04f32f0e08b83b083f35552f4ece1077c5bdcf86327f56f1758b5"}, + {file = "langchain_experimental-0.0.58-py3-none-any.whl", hash = "sha256:106d3bc7df3dd20687378db7534c2fc21e2589201d43de42f832a1e3913dd55b"}, + {file = "langchain_experimental-0.0.58.tar.gz", hash = "sha256:8ef10ff6b39f44ef468f8f21beb3749957d2262ec64d05db2719934936ca0285"}, ] [package.dependencies] -langchain = ">=0.1.15,<0.2.0" -langchain-core = ">=0.1.41,<0.2.0" +langchain = ">=0.1.17,<0.2.0" +langchain-core = ">=0.1.52,<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)"] @@ -4184,6 +4184,23 @@ files = [ groq = ">=0.4.1,<1" langchain-core = ">=0.1.45,<0.2.0" +[[package]] +name = "langchain-mistralai" +version = "0.1.6" +description = "An integration package connecting Mistral and LangChain" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_mistralai-0.1.6-py3-none-any.whl", hash = "sha256:def19e2e28512a86cd73e8cacd43d11086d4be6b9187bf8702a7e3505d5fdd32"}, + {file = "langchain_mistralai-0.1.6.tar.gz", hash = "sha256:03bd75b4fd1bfa04e8703109a1c6865923cbdcc9e435f1fbf26b84ea150b7162"}, +] + +[package.dependencies] +httpx = ">=0.25.2,<1" +httpx-sse = ">=0.3.1,<1" +langchain-core = ">=0.1.46,<0.2.0" +tokenizers = ">=0.15.1,<0.16.0" + [[package]] name = "langchain-openai" version = "0.1.6" @@ -4319,13 +4336,13 @@ url = "src/backend/base" [[package]] name = "langfuse" -version = "2.29.1" +version = "2.29.2" description = "A client library for accessing langfuse" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langfuse-2.29.1-py3-none-any.whl", hash = "sha256:73819e8c62c9aa5de531ee9aa986b50bf6090eda300c10243fff2a0ffdb1e48e"}, - {file = "langfuse-2.29.1.tar.gz", hash = "sha256:320a5e739863f500292ecc1eeb75648eb7337af6cf38ce21c1f50f7767796840"}, + {file = "langfuse-2.29.2-py3-none-any.whl", hash = "sha256:2c289b291124cfb486ae4a2234276ecdf453111b3affc0ad0e639cd688e1e9cb"}, + {file = "langfuse-2.29.2.tar.gz", hash = "sha256:734783fa21f28f4bd171d4c837ee1c108f191d643ccd1f001704a5491f8f52fb"}, ] [package.dependencies] @@ -4343,13 +4360,13 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.54" +version = "0.1.55" 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.54-py3-none-any.whl", hash = "sha256:e8ba2758dbdff0fccb35337c28a5ab641dd980b22e178d390b72a15c9ae9caff"}, - {file = "langsmith-0.1.54.tar.gz", hash = "sha256:86f5a90e48303de897f37a893f8bb635eabdaf23e674099e8bc0f2e9ca2f8faf"}, + {file = "langsmith-0.1.55-py3-none-any.whl", hash = "sha256:c198b4019d0e0948fa2c94efcafa0312bd5e7ce36aae8d62a38af2d6b16584fc"}, + {file = "langsmith-0.1.55.tar.gz", hash = "sha256:08b75046471e3c32cb6b526e48ca4570bfe3911d6b0a3f8575ee062da940324c"}, ] [package.dependencies] @@ -4376,13 +4393,13 @@ regex = ["regex"] [[package]] name = "litellm" -version = "1.36.1" +version = "1.36.2" 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.36.1-py3-none-any.whl", hash = "sha256:3a41db4c139989ef24171a69eba72b814b1ac60591af2da7ed689e57bd62b015"}, - {file = "litellm-1.36.1.tar.gz", hash = "sha256:709cb3a9f31186a093c191c01e0df162e5b08c8cc257a2b746668f29fa99a628"}, + {file = "litellm-1.36.2-py3-none-any.whl", hash = "sha256:541b954e070b0ecb7406a57127d52661e54b0d9394a0a8d85f8cfd86256e5d36"}, + {file = "litellm-1.36.2.tar.gz", hash = "sha256:6554d298473efc9d80b127c0ded4cd47cf23e16aaef21004fd16420f84d91975"}, ] [package.dependencies] @@ -4402,12 +4419,12 @@ proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", " [[package]] name = "llama-cpp-python" -version = "0.2.69" +version = "0.2.70" description = "Python bindings for the llama.cpp library" optional = true python-versions = ">=3.8" files = [ - {file = "llama_cpp_python-0.2.69.tar.gz", hash = "sha256:b37e864b4d9f7ac286a3e926d87afab2f136ae9290e11088f7a205b80d3c04a9"}, + {file = "llama_cpp_python-0.2.70.tar.gz", hash = "sha256:12d046bed7900f46c0b6b3df37f20aa24049477e0cd93c6b69b97754cb0ed842"}, ] [package.dependencies] @@ -4424,19 +4441,19 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)", "scipy (>=1.10)"] [[package]] name = "llama-index" -version = "0.10.34" +version = "0.10.35" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index-0.10.34-py3-none-any.whl", hash = "sha256:da2fe7bf0cde25070ba144e2b8ca0fc0e0d42bff1b32521dc1a28ae4ab7c9c32"}, - {file = "llama_index-0.10.34.tar.gz", hash = "sha256:29c882665fc3a78df8682224620919dc42a95e372fd3afc3c8504822a69892f9"}, + {file = "llama_index-0.10.35-py3-none-any.whl", hash = "sha256:1e30f7dceff5e05cb9bfe8727b767487dfe4f97dc2c71a4ca8276aa983dc6e9e"}, + {file = "llama_index-0.10.35.tar.gz", hash = "sha256:cf1b9ac3b65cc4fd035bfeb0010353a65403aa202d830e21dc7beda7e6284e62"}, ] [package.dependencies] llama-index-agent-openai = ">=0.1.4,<0.3.0" llama-index-cli = ">=0.1.2,<0.2.0" -llama-index-core = ">=0.10.34,<0.11.0" +llama-index-core = ">=0.10.35,<0.11.0" llama-index-embeddings-openai = ">=0.1.5,<0.2.0" llama-index-indices-managed-llama-cloud = ">=0.1.2,<0.2.0" llama-index-legacy = ">=0.9.48,<0.10.0" @@ -4449,17 +4466,17 @@ llama-index-readers-llama-parse = ">=0.1.2,<0.2.0" [[package]] name = "llama-index-agent-openai" -version = "0.2.3" +version = "0.2.4" description = "llama-index agent openai integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_agent_openai-0.2.3-py3-none-any.whl", hash = "sha256:3782b24dd611364e391672dadc8308efd58d731a097c34a40e29f28c3abc5034"}, - {file = "llama_index_agent_openai-0.2.3.tar.gz", hash = "sha256:c899d90b32036656a8ef86d0f0378d4168e00eb2d75a10901eab58ba5b2656a4"}, + {file = "llama_index_agent_openai-0.2.4-py3-none-any.whl", hash = "sha256:b05eb7f0331d40a7a2bcaabaa84c9c7ebe6837a72038d03cbb71c083a4301a81"}, + {file = "llama_index_agent_openai-0.2.4.tar.gz", hash = "sha256:cd4a58f8bf233728ceda554cbb34de56a2b6bbbbff6ce801c3f8ff0c8280bf55"}, ] [package.dependencies] -llama-index-core = ">=0.10.30,<0.11.0" +llama-index-core = ">=0.10.35,<0.11.0" llama-index-llms-openai = ">=0.1.5,<0.2.0" openai = ">=1.14.0" @@ -4481,13 +4498,13 @@ llama-index-llms-openai = ">=0.1.1,<0.2.0" [[package]] name = "llama-index-core" -version = "0.10.34" +version = "0.10.35.post1" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_core-0.10.34-py3-none-any.whl", hash = "sha256:073eb6f2617686826065c68b0934a2cd127bf6f762220601c00d20712b48d586"}, - {file = "llama_index_core-0.10.34.tar.gz", hash = "sha256:d41beeff56f7581d924f2a27c0020f291827b15a18bb7bd80f3ab38ccc95e4ca"}, + {file = "llama_index_core-0.10.35.post1-py3-none-any.whl", hash = "sha256:1c5993946202a9aec86bd6f0943991d1fe443556bd3e6c7b345cb360a46dc6c2"}, + {file = "llama_index_core-0.10.35.post1.tar.gz", hash = "sha256:f62013217bf7c04b6adf9dc2c1b168ff957f924519f19af2f383a0f0c34308e4"}, ] [package.dependencies] @@ -4834,6 +4851,7 @@ files = [ {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-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f"}, {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"}, @@ -4858,7 +4876,6 @@ files = [ {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"}, @@ -8794,7 +8811,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", optional = true, markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\" or extra == \"asyncio\""} +greenlet = {version = "!=0.4.17", optional = true, markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\" or extra == \"asyncio\""} typing-extensions = ">=4.6.0" [package.extras] @@ -9101,120 +9118,130 @@ blobfile = ["blobfile (>=2)"] [[package]] name = "tokenizers" -version = "0.19.1" +version = "0.15.2" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "tokenizers-0.19.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:952078130b3d101e05ecfc7fc3640282d74ed26bcf691400f872563fca15ac97"}, - {file = "tokenizers-0.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82c8b8063de6c0468f08e82c4e198763e7b97aabfe573fd4cf7b33930ca4df77"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f03727225feaf340ceeb7e00604825addef622d551cbd46b7b775ac834c1e1c4"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:453e4422efdfc9c6b6bf2eae00d5e323f263fff62b29a8c9cd526c5003f3f642"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:02e81bf089ebf0e7f4df34fa0207519f07e66d8491d963618252f2e0729e0b46"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b07c538ba956843833fee1190cf769c60dc62e1cf934ed50d77d5502194d63b1"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28cab1582e0eec38b1f38c1c1fb2e56bce5dc180acb1724574fc5f47da2a4fe"}, - {file = "tokenizers-0.19.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b01afb7193d47439f091cd8f070a1ced347ad0f9144952a30a41836902fe09e"}, - {file = "tokenizers-0.19.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7fb297edec6c6841ab2e4e8f357209519188e4a59b557ea4fafcf4691d1b4c98"}, - {file = "tokenizers-0.19.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2e8a3dd055e515df7054378dc9d6fa8c8c34e1f32777fb9a01fea81496b3f9d3"}, - {file = "tokenizers-0.19.1-cp310-none-win32.whl", hash = "sha256:7ff898780a155ea053f5d934925f3902be2ed1f4d916461e1a93019cc7250837"}, - {file = "tokenizers-0.19.1-cp310-none-win_amd64.whl", hash = "sha256:bea6f9947e9419c2fda21ae6c32871e3d398cba549b93f4a65a2d369662d9403"}, - {file = "tokenizers-0.19.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5c88d1481f1882c2e53e6bb06491e474e420d9ac7bdff172610c4f9ad3898059"}, - {file = "tokenizers-0.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ddf672ed719b4ed82b51499100f5417d7d9f6fb05a65e232249268f35de5ed14"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dadc509cc8a9fe460bd274c0e16ac4184d0958117cf026e0ea8b32b438171594"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfedf31824ca4915b511b03441784ff640378191918264268e6923da48104acc"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac11016d0a04aa6487b1513a3a36e7bee7eec0e5d30057c9c0408067345c48d2"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76951121890fea8330d3a0df9a954b3f2a37e3ec20e5b0530e9a0044ca2e11fe"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b342d2ce8fc8d00f376af068e3274e2e8649562e3bc6ae4a67784ded6b99428d"}, - {file = "tokenizers-0.19.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16ff18907f4909dca9b076b9c2d899114dd6abceeb074eca0c93e2353f943aa"}, - {file = "tokenizers-0.19.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:706a37cc5332f85f26efbe2bdc9ef8a9b372b77e4645331a405073e4b3a8c1c6"}, - {file = "tokenizers-0.19.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16baac68651701364b0289979ecec728546133e8e8fe38f66fe48ad07996b88b"}, - {file = "tokenizers-0.19.1-cp311-none-win32.whl", hash = "sha256:9ed240c56b4403e22b9584ee37d87b8bfa14865134e3e1c3fb4b2c42fafd3256"}, - {file = "tokenizers-0.19.1-cp311-none-win_amd64.whl", hash = "sha256:ad57d59341710b94a7d9dbea13f5c1e7d76fd8d9bcd944a7a6ab0b0da6e0cc66"}, - {file = "tokenizers-0.19.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:621d670e1b1c281a1c9698ed89451395d318802ff88d1fc1accff0867a06f153"}, - {file = "tokenizers-0.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d924204a3dbe50b75630bd16f821ebda6a5f729928df30f582fb5aade90c818a"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4f3fefdc0446b1a1e6d81cd4c07088ac015665d2e812f6dbba4a06267d1a2c95"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9620b78e0b2d52ef07b0d428323fb34e8ea1219c5eac98c2596311f20f1f9266"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04ce49e82d100594715ac1b2ce87d1a36e61891a91de774755f743babcd0dd52"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5c2ff13d157afe413bf7e25789879dd463e5a4abfb529a2d8f8473d8042e28f"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3174c76efd9d08f836bfccaca7cfec3f4d1c0a4cf3acbc7236ad577cc423c840"}, - {file = "tokenizers-0.19.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9d5b6c0e7a1e979bec10ff960fae925e947aab95619a6fdb4c1d8ff3708ce3"}, - {file = "tokenizers-0.19.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a179856d1caee06577220ebcfa332af046d576fb73454b8f4d4b0ba8324423ea"}, - {file = "tokenizers-0.19.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:952b80dac1a6492170f8c2429bd11fcaa14377e097d12a1dbe0ef2fb2241e16c"}, - {file = "tokenizers-0.19.1-cp312-none-win32.whl", hash = "sha256:01d62812454c188306755c94755465505836fd616f75067abcae529c35edeb57"}, - {file = "tokenizers-0.19.1-cp312-none-win_amd64.whl", hash = "sha256:b70bfbe3a82d3e3fb2a5e9b22a39f8d1740c96c68b6ace0086b39074f08ab89a"}, - {file = "tokenizers-0.19.1-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:bb9dfe7dae85bc6119d705a76dc068c062b8b575abe3595e3c6276480e67e3f1"}, - {file = "tokenizers-0.19.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:1f0360cbea28ea99944ac089c00de7b2e3e1c58f479fb8613b6d8d511ce98267"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:71e3ec71f0e78780851fef28c2a9babe20270404c921b756d7c532d280349214"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b82931fa619dbad979c0ee8e54dd5278acc418209cc897e42fac041f5366d626"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e8ff5b90eabdcdaa19af697885f70fe0b714ce16709cf43d4952f1f85299e73a"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e742d76ad84acbdb1a8e4694f915fe59ff6edc381c97d6dfdd054954e3478ad4"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d8c5d59d7b59885eab559d5bc082b2985555a54cda04dda4c65528d90ad252ad"}, - {file = "tokenizers-0.19.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b2da5c32ed869bebd990c9420df49813709e953674c0722ff471a116d97b22d"}, - {file = "tokenizers-0.19.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:638e43936cc8b2cbb9f9d8dde0fe5e7e30766a3318d2342999ae27f68fdc9bd6"}, - {file = "tokenizers-0.19.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:78e769eb3b2c79687d9cb0f89ef77223e8e279b75c0a968e637ca7043a84463f"}, - {file = "tokenizers-0.19.1-cp37-none-win32.whl", hash = "sha256:72791f9bb1ca78e3ae525d4782e85272c63faaef9940d92142aa3eb79f3407a3"}, - {file = "tokenizers-0.19.1-cp37-none-win_amd64.whl", hash = "sha256:f3bbb7a0c5fcb692950b041ae11067ac54826204318922da754f908d95619fbc"}, - {file = "tokenizers-0.19.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:07f9295349bbbcedae8cefdbcfa7f686aa420be8aca5d4f7d1ae6016c128c0c5"}, - {file = "tokenizers-0.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10a707cc6c4b6b183ec5dbfc5c34f3064e18cf62b4a938cb41699e33a99e03c1"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6309271f57b397aa0aff0cbbe632ca9d70430839ca3178bf0f06f825924eca22"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ad23d37d68cf00d54af184586d79b84075ada495e7c5c0f601f051b162112dc"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:427c4f0f3df9109314d4f75b8d1f65d9477033e67ffaec4bca53293d3aca286d"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e83a31c9cf181a0a3ef0abad2b5f6b43399faf5da7e696196ddd110d332519ee"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c27b99889bd58b7e301468c0838c5ed75e60c66df0d4db80c08f43462f82e0d3"}, - {file = "tokenizers-0.19.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bac0b0eb952412b0b196ca7a40e7dce4ed6f6926489313414010f2e6b9ec2adf"}, - {file = "tokenizers-0.19.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8a6298bde623725ca31c9035a04bf2ef63208d266acd2bed8c2cb7d2b7d53ce6"}, - {file = "tokenizers-0.19.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:08a44864e42fa6d7d76d7be4bec62c9982f6f6248b4aa42f7302aa01e0abfd26"}, - {file = "tokenizers-0.19.1-cp38-none-win32.whl", hash = "sha256:1de5bc8652252d9357a666e609cb1453d4f8e160eb1fb2830ee369dd658e8975"}, - {file = "tokenizers-0.19.1-cp38-none-win_amd64.whl", hash = "sha256:0bcce02bf1ad9882345b34d5bd25ed4949a480cf0e656bbd468f4d8986f7a3f1"}, - {file = "tokenizers-0.19.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0b9394bd204842a2a1fd37fe29935353742be4a3460b6ccbaefa93f58a8df43d"}, - {file = "tokenizers-0.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4692ab92f91b87769d950ca14dbb61f8a9ef36a62f94bad6c82cc84a51f76f6a"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6258c2ef6f06259f70a682491c78561d492e885adeaf9f64f5389f78aa49a051"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c85cf76561fbd01e0d9ea2d1cbe711a65400092bc52b5242b16cfd22e51f0c58"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:670b802d4d82bbbb832ddb0d41df7015b3e549714c0e77f9bed3e74d42400fbe"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85aa3ab4b03d5e99fdd31660872249df5e855334b6c333e0bc13032ff4469c4a"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbf001afbbed111a79ca47d75941e9e5361297a87d186cbfc11ed45e30b5daba"}, - {file = "tokenizers-0.19.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c89aa46c269e4e70c4d4f9d6bc644fcc39bb409cb2a81227923404dd6f5227"}, - {file = "tokenizers-0.19.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:39c1ec76ea1027438fafe16ecb0fb84795e62e9d643444c1090179e63808c69d"}, - {file = "tokenizers-0.19.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c2a0d47a89b48d7daa241e004e71fb5a50533718897a4cd6235cb846d511a478"}, - {file = "tokenizers-0.19.1-cp39-none-win32.whl", hash = "sha256:61b7fe8886f2e104d4caf9218b157b106207e0f2a4905c9c7ac98890688aabeb"}, - {file = "tokenizers-0.19.1-cp39-none-win_amd64.whl", hash = "sha256:f97660f6c43efd3e0bfd3f2e3e5615bf215680bad6ee3d469df6454b8c6e8256"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b11853f17b54c2fe47742c56d8a33bf49ce31caf531e87ac0d7d13d327c9334"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d26194ef6c13302f446d39972aaa36a1dda6450bc8949f5eb4c27f51191375bd"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e8d1ed93beda54bbd6131a2cb363a576eac746d5c26ba5b7556bc6f964425594"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca407133536f19bdec44b3da117ef0d12e43f6d4b56ac4c765f37eca501c7bda"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce05fde79d2bc2e46ac08aacbc142bead21614d937aac950be88dc79f9db9022"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:35583cd46d16f07c054efd18b5d46af4a2f070a2dd0a47914e66f3ff5efb2b1e"}, - {file = "tokenizers-0.19.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:43350270bfc16b06ad3f6f07eab21f089adb835544417afda0f83256a8bf8b75"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b4399b59d1af5645bcee2072a463318114c39b8547437a7c2d6a186a1b5a0e2d"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6852c5b2a853b8b0ddc5993cd4f33bfffdca4fcc5d52f89dd4b8eada99379285"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcd266ae85c3d39df2f7e7d0e07f6c41a55e9a3123bb11f854412952deacd828"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecb2651956eea2aa0a2d099434134b1b68f1c31f9a5084d6d53f08ed43d45ff2"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b279ab506ec4445166ac476fb4d3cc383accde1ea152998509a94d82547c8e2a"}, - {file = "tokenizers-0.19.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:89183e55fb86e61d848ff83753f64cded119f5d6e1f553d14ffee3700d0a4a49"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2edbc75744235eea94d595a8b70fe279dd42f3296f76d5a86dde1d46e35f574"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0e64bfde9a723274e9a71630c3e9494ed7b4c0f76a1faacf7fe294cd26f7ae7c"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b5ca92bfa717759c052e345770792d02d1f43b06f9e790ca0a1db62838816f3"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f8a20266e695ec9d7a946a019c1d5ca4eddb6613d4f466888eee04f16eedb85"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63c38f45d8f2a2ec0f3a20073cccb335b9f99f73b3c69483cd52ebc75369d8a1"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dd26e3afe8a7b61422df3176e06664503d3f5973b94f45d5c45987e1cb711876"}, - {file = "tokenizers-0.19.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:eddd5783a4a6309ce23432353cdb36220e25cbb779bfa9122320666508b44b88"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:56ae39d4036b753994476a1b935584071093b55c7a72e3b8288e68c313ca26e7"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f9939ca7e58c2758c01b40324a59c034ce0cebad18e0d4563a9b1beab3018243"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c330c0eb815d212893c67a032e9dc1b38a803eccb32f3e8172c19cc69fbb439"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec11802450a2487cdf0e634b750a04cbdc1c4d066b97d94ce7dd2cb51ebb325b"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b718f316b596f36e1dae097a7d5b91fc5b85e90bf08b01ff139bd8953b25af"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ed69af290c2b65169f0ba9034d1dc39a5db9459b32f1dd8b5f3f32a3fcf06eab"}, - {file = "tokenizers-0.19.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f8a9c828277133af13f3859d1b6bf1c3cb6e9e1637df0e45312e6b7c2e622b1f"}, - {file = "tokenizers-0.19.1.tar.gz", hash = "sha256:ee59e6680ed0fdbe6b724cf38bd70400a0c1dd623b07ac729087270caeac88e3"}, + {file = "tokenizers-0.15.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:52f6130c9cbf70544287575a985bf44ae1bda2da7e8c24e97716080593638012"}, + {file = "tokenizers-0.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:054c1cc9c6d68f7ffa4e810b3d5131e0ba511b6e4be34157aa08ee54c2f8d9ee"}, + {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9b9b070fdad06e347563b88c278995735292ded1132f8657084989a4c84a6d5"}, + {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea621a7eef4b70e1f7a4e84dd989ae3f0eeb50fc8690254eacc08acb623e82f1"}, + {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf7fd9a5141634fa3aa8d6b7be362e6ae1b4cda60da81388fa533e0b552c98fd"}, + {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44f2a832cd0825295f7179eaf173381dc45230f9227ec4b44378322d900447c9"}, + {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b9ec69247a23747669ec4b0ca10f8e3dfb3545d550258129bd62291aabe8605"}, + {file = "tokenizers-0.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b6a4c78da863ff26dbd5ad9a8ecc33d8a8d97b535172601cf00aee9d7ce9ce"}, + {file = "tokenizers-0.15.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5ab2a4d21dcf76af60e05af8063138849eb1d6553a0d059f6534357bce8ba364"}, + {file = "tokenizers-0.15.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a47acfac7e511f6bbfcf2d3fb8c26979c780a91e06fb5b9a43831b2c0153d024"}, + {file = "tokenizers-0.15.2-cp310-none-win32.whl", hash = "sha256:064ff87bb6acdbd693666de9a4b692add41308a2c0ec0770d6385737117215f2"}, + {file = "tokenizers-0.15.2-cp310-none-win_amd64.whl", hash = "sha256:3b919afe4df7eb6ac7cafd2bd14fb507d3f408db7a68c43117f579c984a73843"}, + {file = "tokenizers-0.15.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:89cd1cb93e4b12ff39bb2d626ad77e35209de9309a71e4d3d4672667b4b256e7"}, + {file = "tokenizers-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfed5c64e5be23d7ee0f0e98081a25c2a46b0b77ce99a4f0605b1ec43dd481fa"}, + {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a907d76dcfda37023ba203ab4ceeb21bc5683436ebefbd895a0841fd52f6f6f2"}, + {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20ea60479de6fc7b8ae756b4b097572372d7e4032e2521c1bbf3d90c90a99ff0"}, + {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:48e2b9335be2bc0171df9281385c2ed06a15f5cf121c44094338306ab7b33f2c"}, + {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:112a1dd436d2cc06e6ffdc0b06d55ac019a35a63afd26475205cb4b1bf0bfbff"}, + {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4620cca5c2817177ee8706f860364cc3a8845bc1e291aaf661fb899e5d1c45b0"}, + {file = "tokenizers-0.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccd73a82751c523b3fc31ff8194702e4af4db21dc20e55b30ecc2079c5d43cb7"}, + {file = "tokenizers-0.15.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:107089f135b4ae7817affe6264f8c7a5c5b4fd9a90f9439ed495f54fcea56fb4"}, + {file = "tokenizers-0.15.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0ff110ecc57b7aa4a594396525a3451ad70988e517237fe91c540997c4e50e29"}, + {file = "tokenizers-0.15.2-cp311-none-win32.whl", hash = "sha256:6d76f00f5c32da36c61f41c58346a4fa7f0a61be02f4301fd30ad59834977cc3"}, + {file = "tokenizers-0.15.2-cp311-none-win_amd64.whl", hash = "sha256:cc90102ed17271cf0a1262babe5939e0134b3890345d11a19c3145184b706055"}, + {file = "tokenizers-0.15.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f86593c18d2e6248e72fb91c77d413a815153b8ea4e31f7cd443bdf28e467670"}, + {file = "tokenizers-0.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0774bccc6608eca23eb9d620196687c8b2360624619623cf4ba9dc9bd53e8b51"}, + {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0222c5b7c9b26c0b4822a82f6a7011de0a9d3060e1da176f66274b70f846b98"}, + {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3835738be1de66624fff2f4f6f6684775da4e9c00bde053be7564cbf3545cc66"}, + {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0143e7d9dcd811855c1ce1ab9bf5d96d29bf5e528fd6c7824d0465741e8c10fd"}, + {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db35825f6d54215f6b6009a7ff3eedee0848c99a6271c870d2826fbbedf31a38"}, + {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f5e64b0389a2be47091d8cc53c87859783b837ea1a06edd9d8e04004df55a5c"}, + {file = "tokenizers-0.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e0480c452217edd35eca56fafe2029fb4d368b7c0475f8dfa3c5c9c400a7456"}, + {file = "tokenizers-0.15.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a33ab881c8fe70474980577e033d0bc9a27b7ab8272896e500708b212995d834"}, + {file = "tokenizers-0.15.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a308a607ca9de2c64c1b9ba79ec9a403969715a1b8ba5f998a676826f1a7039d"}, + {file = "tokenizers-0.15.2-cp312-none-win32.whl", hash = "sha256:b8fcfa81bcb9447df582c5bc96a031e6df4da2a774b8080d4f02c0c16b42be0b"}, + {file = "tokenizers-0.15.2-cp312-none-win_amd64.whl", hash = "sha256:38d7ab43c6825abfc0b661d95f39c7f8af2449364f01d331f3b51c94dcff7221"}, + {file = "tokenizers-0.15.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:38bfb0204ff3246ca4d5e726e8cc8403bfc931090151e6eede54d0e0cf162ef0"}, + {file = "tokenizers-0.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c861d35e8286a53e06e9e28d030b5a05bcbf5ac9d7229e561e53c352a85b1fc"}, + {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:936bf3842db5b2048eaa53dade907b1160f318e7c90c74bfab86f1e47720bdd6"}, + {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:620beacc3373277700d0e27718aa8b25f7b383eb8001fba94ee00aeea1459d89"}, + {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2735ecbbf37e52db4ea970e539fd2d450d213517b77745114f92867f3fc246eb"}, + {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:473c83c5e2359bb81b0b6fde870b41b2764fcdd36d997485e07e72cc3a62264a"}, + {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968fa1fb3c27398b28a4eca1cbd1e19355c4d3a6007f7398d48826bbe3a0f728"}, + {file = "tokenizers-0.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:865c60ae6eaebdde7da66191ee9b7db52e542ed8ee9d2c653b6d190a9351b980"}, + {file = "tokenizers-0.15.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7c0d8b52664ab2d4a8d6686eb5effc68b78608a9008f086a122a7b2996befbab"}, + {file = "tokenizers-0.15.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f33dfbdec3784093a9aebb3680d1f91336c56d86cc70ddf88708251da1fe9064"}, + {file = "tokenizers-0.15.2-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:d44ba80988ff9424e33e0a49445072ac7029d8c0e1601ad25a0ca5f41ed0c1d6"}, + {file = "tokenizers-0.15.2-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:dce74266919b892f82b1b86025a613956ea0ea62a4843d4c4237be2c5498ed3a"}, + {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0ef06b9707baeb98b316577acb04f4852239d856b93e9ec3a299622f6084e4be"}, + {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c73e2e74bbb07910da0d37c326869f34113137b23eadad3fc00856e6b3d9930c"}, + {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eeb12daf02a59e29f578a865f55d87cd103ce62bd8a3a5874f8fdeaa82e336b"}, + {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ba9f6895af58487ca4f54e8a664a322f16c26bbb442effd01087eba391a719e"}, + {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccec77aa7150e38eec6878a493bf8c263ff1fa8a62404e16c6203c64c1f16a26"}, + {file = "tokenizers-0.15.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3f40604f5042ff210ba82743dda2b6aa3e55aa12df4e9f2378ee01a17e2855e"}, + {file = "tokenizers-0.15.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5645938a42d78c4885086767c70923abad047163d809c16da75d6b290cb30bbe"}, + {file = "tokenizers-0.15.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:05a77cbfebe28a61ab5c3891f9939cc24798b63fa236d84e5f29f3a85a200c00"}, + {file = "tokenizers-0.15.2-cp37-none-win32.whl", hash = "sha256:361abdc068e8afe9c5b818769a48624687fb6aaed49636ee39bec4e95e1a215b"}, + {file = "tokenizers-0.15.2-cp37-none-win_amd64.whl", hash = "sha256:7ef789f83eb0f9baeb4d09a86cd639c0a5518528f9992f38b28e819df397eb06"}, + {file = "tokenizers-0.15.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4fe1f74a902bee74a3b25aff180fbfbf4f8b444ab37c4d496af7afd13a784ed2"}, + {file = "tokenizers-0.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c4b89038a684f40a6b15d6b09f49650ac64d951ad0f2a3ea9169687bbf2a8ba"}, + {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d05a1b06f986d41aed5f2de464c003004b2df8aaf66f2b7628254bcbfb72a438"}, + {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508711a108684111ec8af89d3a9e9e08755247eda27d0ba5e3c50e9da1600f6d"}, + {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:daa348f02d15160cb35439098ac96e3a53bacf35885072611cd9e5be7d333daa"}, + {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:494fdbe5932d3416de2a85fc2470b797e6f3226c12845cadf054dd906afd0442"}, + {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2d60f5246f4da9373f75ff18d64c69cbf60c3bca597290cea01059c336d2470"}, + {file = "tokenizers-0.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93268e788825f52de4c7bdcb6ebc1fcd4a5442c02e730faa9b6b08f23ead0e24"}, + {file = "tokenizers-0.15.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6fc7083ab404019fc9acafe78662c192673c1e696bd598d16dc005bd663a5cf9"}, + {file = "tokenizers-0.15.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:41e39b41e5531d6b2122a77532dbea60e171ef87a3820b5a3888daa847df4153"}, + {file = "tokenizers-0.15.2-cp38-none-win32.whl", hash = "sha256:06cd0487b1cbfabefb2cc52fbd6b1f8d4c37799bd6c6e1641281adaa6b2504a7"}, + {file = "tokenizers-0.15.2-cp38-none-win_amd64.whl", hash = "sha256:5179c271aa5de9c71712e31cb5a79e436ecd0d7532a408fa42a8dbfa4bc23fd9"}, + {file = "tokenizers-0.15.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:82f8652a74cc107052328b87ea8b34291c0f55b96d8fb261b3880216a9f9e48e"}, + {file = "tokenizers-0.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:02458bee6f5f3139f1ebbb6d042b283af712c0981f5bc50edf771d6b762d5e4f"}, + {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c9a09cd26cca2e1c349f91aa665309ddb48d71636370749414fbf67bc83c5343"}, + {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:158be8ea8554e5ed69acc1ce3fbb23a06060bd4bbb09029431ad6b9a466a7121"}, + {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ddba9a2b0c8c81633eca0bb2e1aa5b3a15362b1277f1ae64176d0f6eba78ab1"}, + {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ef5dd1d39797044642dbe53eb2bc56435308432e9c7907728da74c69ee2adca"}, + {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:454c203164e07a860dbeb3b1f4a733be52b0edbb4dd2e5bd75023ffa8b49403a"}, + {file = "tokenizers-0.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cf6b7f1d4dc59af960e6ffdc4faffe6460bbfa8dce27a58bf75755ffdb2526d"}, + {file = "tokenizers-0.15.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2ef09bbc16519f6c25d0c7fc0c6a33a6f62923e263c9d7cca4e58b8c61572afb"}, + {file = "tokenizers-0.15.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c9a2ebdd2ad4ec7a68e7615086e633857c85e2f18025bd05d2a4399e6c5f7169"}, + {file = "tokenizers-0.15.2-cp39-none-win32.whl", hash = "sha256:918fbb0eab96fe08e72a8c2b5461e9cce95585d82a58688e7f01c2bd546c79d0"}, + {file = "tokenizers-0.15.2-cp39-none-win_amd64.whl", hash = "sha256:524e60da0135e106b254bd71f0659be9f89d83f006ea9093ce4d1fab498c6d0d"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6a9b648a58281c4672212fab04e60648fde574877d0139cd4b4f93fe28ca8944"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7c7d18b733be6bbca8a55084027f7be428c947ddf871c500ee603e375013ffba"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:13ca3611de8d9ddfbc4dc39ef54ab1d2d4aaa114ac8727dfdc6a6ec4be017378"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:237d1bf3361cf2e6463e6c140628e6406766e8b27274f5fcc62c747ae3c6f094"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67a0fe1e49e60c664915e9fb6b0cb19bac082ab1f309188230e4b2920230edb3"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4e022fe65e99230b8fd89ebdfea138c24421f91c1a4f4781a8f5016fd5cdfb4d"}, + {file = "tokenizers-0.15.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d857be2df69763362ac699f8b251a8cd3fac9d21893de129bc788f8baaef2693"}, + {file = "tokenizers-0.15.2-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:708bb3e4283177236309e698da5fcd0879ce8fd37457d7c266d16b550bcbbd18"}, + {file = "tokenizers-0.15.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:64c35e09e9899b72a76e762f9854e8750213f67567787d45f37ce06daf57ca78"}, + {file = "tokenizers-0.15.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1257f4394be0d3b00de8c9e840ca5601d0a4a8438361ce9c2b05c7d25f6057b"}, + {file = "tokenizers-0.15.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02272fe48280e0293a04245ca5d919b2c94a48b408b55e858feae9618138aeda"}, + {file = "tokenizers-0.15.2-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dc3ad9ebc76eabe8b1d7c04d38be884b8f9d60c0cdc09b0aa4e3bcf746de0388"}, + {file = "tokenizers-0.15.2-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:32e16bdeffa7c4f46bf2152172ca511808b952701d13e7c18833c0b73cb5c23f"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fb16ba563d59003028b678d2361a27f7e4ae0ab29c7a80690efa20d829c81fdb"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:2277c36d2d6cdb7876c274547921a42425b6810d38354327dd65a8009acf870c"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cf75d32e8d250781940d07f7eece253f2fe9ecdb1dc7ba6e3833fa17b82fcbc"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1b3b31884dc8e9b21508bb76da80ebf7308fdb947a17affce815665d5c4d028"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10122d8d8e30afb43bb1fe21a3619f62c3e2574bff2699cf8af8b0b6c5dc4a3"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d88b96ff0fe8e91f6ef01ba50b0d71db5017fa4e3b1d99681cec89a85faf7bf7"}, + {file = "tokenizers-0.15.2-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:37aaec5a52e959892870a7c47cef80c53797c0db9149d458460f4f31e2fb250e"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e2ea752f2b0fe96eb6e2f3adbbf4d72aaa1272079b0dfa1145507bd6a5d537e6"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4b19a808d8799fda23504a5cd31d2f58e6f52f140380082b352f877017d6342b"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:64c86e5e068ac8b19204419ed8ca90f9d25db20578f5881e337d203b314f4104"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de19c4dc503c612847edf833c82e9f73cd79926a384af9d801dcf93f110cea4e"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea09acd2fe3324174063d61ad620dec3bcf042b495515f27f638270a7d466e8b"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cf27fd43472e07b57cf420eee1e814549203d56de00b5af8659cb99885472f1f"}, + {file = "tokenizers-0.15.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7ca22bd897537a0080521445d91a58886c8c04084a6a19e6c78c586e0cfa92a5"}, + {file = "tokenizers-0.15.2.tar.gz", hash = "sha256:e6e9c6e019dd5484be5beafc775ae6c925f4c69a3487040ed09b45e13df2cb91"}, ] [package.dependencies] -huggingface-hub = ">=0.16.4,<1.0" +huggingface_hub = ">=0.16.4,<1.0" [package.extras] dev = ["tokenizers[testing]"] -docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"] -testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"] +docs = ["setuptools_rust", "sphinx", "sphinx_rtd_theme"] +testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"] [[package]] name = "toml" @@ -9349,13 +9376,13 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "transformers" -version = "4.40.2" +version = "4.39.3" description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" optional = true python-versions = ">=3.8.0" files = [ - {file = "transformers-4.40.2-py3-none-any.whl", hash = "sha256:71cb94301ec211a2e1d4b8c8d18dcfaa902dfa00a089dceca167a8aa265d6f2d"}, - {file = "transformers-4.40.2.tar.gz", hash = "sha256:657b6054a2097671398d976ad46e60836e7e15f9ea9551631a96e33cb9240649"}, + {file = "transformers-4.39.3-py3-none-any.whl", hash = "sha256:7838034a12cca3168247f9d2d1dba6724c9de3ae0f73a108258c6b8fc5912601"}, + {file = "transformers-4.39.3.tar.gz", hash = "sha256:2586e5ff4150f122716fc40f5530e92871befc051848fbe82600969c535b762d"}, ] [package.dependencies] @@ -9367,21 +9394,21 @@ pyyaml = ">=5.1" regex = "!=2019.12.17" requests = "*" safetensors = ">=0.4.1" -tokenizers = ">=0.19,<0.20" +tokenizers = ">=0.14,<0.19" tqdm = ">=4.27" [package.extras] accelerate = ["accelerate (>=0.21.0)"] agents = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch"] -all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.19,<0.20)", "torch", "torchaudio", "torchvision"] +all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"] audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] codecarbon = ["codecarbon (==1.2.0)"] deepspeed = ["accelerate (>=0.21.0)", "deepspeed (>=0.9.3)"] deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.21.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] -dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.19,<0.20)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.19,<0.20)", "urllib3 (<2.0.0)"] -dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.19,<0.20)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.19,<0.20)", "torch", "torchaudio", "torchvision"] +dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.14,<0.19)", "urllib3 (<2.0.0)"] +dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "beautifulsoup4", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +docs = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.21.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm", "tokenizers (>=0.14,<0.19)", "torch", "torchaudio", "torchvision"] docs-specific = ["hf-doc-builder"] flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"] flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] @@ -9402,16 +9429,16 @@ serving = ["fastapi", "pydantic", "starlette", "uvicorn"] sigopt = ["sigopt"] sklearn = ["scikit-learn"] speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] +testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0,<8.0.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.1.5)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "tensorboard", "timeout-decorator"] tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] timm = ["timm"] -tokenizers = ["tokenizers (>=0.19,<0.20)"] +tokenizers = ["tokenizers (>=0.14,<0.19)"] torch = ["accelerate (>=0.21.0)", "torch"] torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"] -torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.19,<0.20)", "torch", "tqdm (>=4.27)"] +torchhub = ["filelock", "huggingface-hub (>=0.19.3,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.14,<0.19)", "torch", "tqdm (>=4.27)"] video = ["av (==9.2.0)", "decord (==0.6.0)"] vision = ["Pillow (>=10.0.1,<=15.0)"] @@ -10721,4 +10748,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "3355376a653b6ca7884c09be576958a121ab965927e5e22f20a98ea387497f03" +content-hash = "d3ac1c13a79e0c368642bacb2907061361b7865b5136fdc969f5f5a28c7d2322" diff --git a/pyproject.toml b/pyproject.toml index ef058b219..dbfcee43b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,8 @@ zep-python = { version = "^2.0.0rc5", allow-prereleases = true } langchain-google-vertexai = "^1.0.3" langchain-groq = "^0.1.3" langchain-pinecone = "^0.1.0" +langchain-mistralai ="^0.1.6" + [tool.poetry.group.dev.dependencies] types-redis = "^4.6.0.5" diff --git a/src/backend/base/langflow/components/embeddings/MistalAIEmbeddings.py b/src/backend/base/langflow/components/embeddings/MistalAIEmbeddings.py new file mode 100644 index 000000000..4088d4839 --- /dev/null +++ b/src/backend/base/langflow/components/embeddings/MistalAIEmbeddings.py @@ -0,0 +1,69 @@ +from typing import List, Optional +from pydantic.v1 import SecretStr + +from langchain_mistralai.embeddings import MistralAIEmbeddings +from langflow.interface.custom.custom_component import CustomComponent +from langflow.field_typing import Embeddings, NestedDict + +class MistralAIEmbeddingsComponent(CustomComponent): + display_name = "MistralAI Embeddings" + description = "Generate embeddings using MistralAI models." + + def build_config(self): + return { + "model": { + "display_name": "Model", + "advanced": False, + "options": ["mistral-embed"], + "value": "mistral-embed", + }, + "mistral_api_key": { + "display_name": "Mistral API Key", + "password": True, + "advanced": False, + }, + "max_concurrent_requests": { + "display_name": "Max Concurrent Requests", + "advanced": True, + "value": 64, + }, + "max_retries": { + "display_name": "Max Retries", + "advanced": True, + "value": 5, + }, + "timeout": { + "display_name": "Request Timeout", + "advanced": True, + "value": 120, + }, + "endpoint": { + "display_name": "API Endpoint", + "advanced": True, + "value": "https://api.mistral.ai/v1/" + } + } + + def build( + self, + mistral_api_key: str, + model: str = "mistral-embed", + max_concurrent_requests: int = 64, + max_retries: int = 5, + timeout: int = 120, + endpoint: str = "https://api.mistral.ai/v1/" + ) -> Embeddings: + if mistral_api_key: + api_key = SecretStr(mistral_api_key) + else: + api_key = None + + return MistralAIEmbeddings( + api_key=api_key, + model=model, + endpoint=endpoint, + max_concurrent_requests=max_concurrent_requests, + max_retries=max_retries, + timeout=timeout + ) + diff --git a/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py b/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py new file mode 100644 index 000000000..2bfab4f6a --- /dev/null +++ b/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py @@ -0,0 +1,87 @@ +from typing import Optional + +from langchain_mistralai import ChatMistralAI +from pydantic.v1 import SecretStr + +from langflow.custom import CustomComponent +from langflow.field_typing import BaseLanguageModel + + +class MistralAIModelComponent(CustomComponent): + display_name: str = "MistralAI" + description: str = "Generate text using MistralAI LLMs." + icon = "MistralAI" + + field_order = [ + "model", + "mistral_api_key", + "max_tokens", + "temperature", + "mistral_api_base", + ] + + def build_config(self): + return { + "model": { + "display_name": "Model Name", + "options": [ + "open-mistral-7b", + "open-mixtral-8x7b", + "open-mixtral-8x22b", + "mistral-small-latest", + "mistral-medium-latest", + "mistral-large-latest" + ], + "info": "Name of the model to use.", + "required": True, + "value": "open-mistral-7b", + }, + "mistral_api_key": { + "display_name": "Mistral API Key", + "required": True, + "password": True, + "info": "Your Mistral API key.", + }, + "max_tokens": { + "display_name": "Max Tokens", + "field_type": "int", + "advanced": True, + "value": 256, + }, + "temperature": { + "display_name": "Temperature", + "field_type": "float", + "value": 0.1, + }, + "mistral_api_base": { + "display_name": "Mistral API Base", + "advanced": True, + "info": "Endpoint of the Mistral API. Defaults to 'https://api.mistral.ai' if not specified.", + }, + "code": {"show": False}, + } + + def build( + self, + model: str, + mistral_api_key: Optional[str] = None, + max_tokens: Optional[int] = None, + temperature: Optional[float] = None, + mistral_api_base: Optional[str] = None, + ) -> BaseLanguageModel: + # Set default API endpoint if not provided + if not mistral_api_base: + mistral_api_base = "https://api.mistral.ai" + + try: + output = ChatMistralAI( + model=model, + api_key=(SecretStr(mistral_api_key) if mistral_api_key else None), + max_tokens=max_tokens, + temperature=temperature, + base_url=mistral_api_base, + ) + except Exception as e: + raise ValueError("Could not connect to Mistral API.") from e + + return output diff --git a/src/backend/base/langflow/components/models/MistralModel.py b/src/backend/base/langflow/components/models/MistralModel.py new file mode 100644 index 000000000..d6e3a27f0 --- /dev/null +++ b/src/backend/base/langflow/components/models/MistralModel.py @@ -0,0 +1,111 @@ +from typing import Optional + +from langchain_mistralai import ChatMistralAI +from pydantic.v1 import SecretStr + +from langflow.base.constants import STREAM_INFO_TEXT +from langflow.base.models.model import LCModelComponent +from langflow.field_typing import NestedDict, Text + + +class MistralAIModelComponent(LCModelComponent): + display_name = "MistralAI" + description = "Generates text using MistralAI LLMs." + icon = "MistralAI" + + field_order = [ + "max_tokens", + "model_kwargs", + "model_name", + "mistral_api_base", + "mistral_api_key", + "temperature", + "input_value", + "system_message", + "stream", + ] + + def build_config(self): + return { + "input_value": {"display_name": "Input"}, + "max_tokens": { + "display_name": "Max Tokens", + "advanced": True, + }, + "model_kwargs": { + "display_name": "Model Kwargs", + "advanced": True, + }, + "model_name": { + "display_name": "Model Name", + "advanced": False, + "options": [ + "open-mistral-7b", + "open-mixtral-8x7b", + "open-mixtral-8x22b", + "mistral-small-latest", + "mistral-medium-latest", + "mistral-large-latest" + ], + "value": "open-mistral-7b", + }, + "mistral_api_base": { + "display_name": "Mistral API Base", + "advanced": True, + "info": ( + "The base URL of the Mistral API. Defaults to https://api.mistral.ai.\n\n" + "You can change this to use other APIs like JinaChat, LocalAI and Prem." + ), + }, + "mistral_api_key": { + "display_name": "Mistral API Key", + "info": "The Mistral API Key to use for the Mistral model.", + "advanced": False, + "password": True, + }, + "temperature": { + "display_name": "Temperature", + "advanced": False, + "value": 0.1, + }, + "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, + mistral_api_key: str, + temperature: float, + model_name: str, + max_tokens: Optional[int] = 256, + model_kwargs: NestedDict = {}, + mistral_api_base: Optional[str] = None, + stream: bool = False, + system_message: Optional[str] = None, + ) -> Text: + if not mistral_api_base: + mistral_api_base = "https://api.mistral.ai" + if mistral_api_key: + api_key = SecretStr(mistral_api_key) + else: + api_key = None + + chat_model = ChatMistralAI( + max_tokens=max_tokens, + model_kwargs=model_kwargs, + model=model_name, + base_url=mistral_api_base, + api_key=api_key, + temperature=temperature, + ) + + return self.get_chat_result(chat_model, stream, input_value, system_message) From 919db5d928cec9250555daa705c1594820b719a9 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Fri, 10 May 2024 11:23:37 -0300 Subject: [PATCH 12/55] =?UTF-8?q?=E2=9C=A8=20(raw-component):=20create=20a?= =?UTF-8?q?=20new=20raw=20component=20called=20RawComponent=20=F0=9F=93=9D?= =?UTF-8?q?=20(raw-component):=20add=20a=20basic=20implementation=20of=20t?= =?UTF-8?q?he=20RawComponent=20with=20a=20simple=20div=20element=20inside?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/boilerplate/raw-component/index.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/frontend/src/boilerplate/raw-component/index.tsx diff --git a/src/frontend/src/boilerplate/raw-component/index.tsx b/src/frontend/src/boilerplate/raw-component/index.tsx new file mode 100644 index 000000000..0595c1808 --- /dev/null +++ b/src/frontend/src/boilerplate/raw-component/index.tsx @@ -0,0 +1,9 @@ +type RawComponentProps = {}; +const RawComponent = ({}: RawComponentProps) => { + return ( + <> +
RawComponent
+ + ); +}; +export default RawComponent; From 5ca1c228930b4ab8ca86ea81b87d40ebb9a734c2 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 10 May 2024 12:25:34 -0300 Subject: [PATCH 13/55] Add support for Python 3.12 (#1873) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for Python 3.12 * chore: Update Python version to 3.11 and DuckDB dependency to 0.10.2 * chore: fix mistral components lint * Update SQLAgent and SQLExecutor imports to use langchain_community utilities * Update langchain import to langchain_community * Update langchain import to langchain_community * 📝 (langflow/__main__.py): Import warnings module to suppress warnings during app execution 📝 (langflow/api/v1/schemas.py): Update timestamp field default value to use datetime.now with timezone.utc 📝 (auth/utils.py): Ignore warnings related to datetime.utcnow when decoding JWT tokens and creating refresh tokens 📝 (models/flow/model.py): Update updated_at field default value to use lambda function with timezone.utc 📝 (models/user/model.py): Update create_at and updated_at field default values to use lambda function with timezone.utc --- .github/workflows/lint.yml | 3 +- .github/workflows/python_test.yml | 3 +- .github/workflows/typescript_test.yml | 2 +- poetry.lock | 869 ++++++------------ pyproject.toml | 6 +- src/backend/base/langflow/__main__.py | 5 +- src/backend/base/langflow/api/v1/flows.py | 6 +- src/backend/base/langflow/api/v1/schemas.py | 4 +- src/backend/base/langflow/base/data/utils.py | 58 +- .../langflow/components/agents/SQLAgent.py | 2 +- .../components/experimental/SQLExecutor.py | 2 +- .../BaiduQianfanLLMEndpointsSpecs.py | 2 +- .../model_specs/ChatMistralSpecs.py | 8 +- .../model_specs/HuggingFaceEndpointsSpecs.py | 2 +- .../components/models/MistralModel.py | 52 +- src/backend/base/langflow/config.yaml | 5 - .../base/langflow/graph/graph/constants.py | 2 - .../base/langflow/graph/vertex/types.py | 5 - .../base/langflow/interface/agents/custom.py | 2 +- .../base/langflow/interface/custom_lists.py | 4 +- .../langflow/interface/importing/utils.py | 6 - .../langflow/interface/initialize/loading.py | 21 - .../interface/output_parsers/__init__.py | 0 .../langflow/interface/output_parsers/base.py | 63 -- src/backend/base/langflow/interface/types.py | 2 - src/backend/base/langflow/interface/utils.py | 2 +- .../base/langflow/services/auth/utils.py | 37 +- .../services/database/models/flow/model.py | 4 +- .../services/database/models/user/model.py | 6 +- .../base/langflow/services/settings/base.py | 2 - src/backend/base/langflow/settings.py | 2 - .../base/langflow/template/field/prompt.py | 2 +- .../frontend_node/custom_components.py | 1 - .../template/frontend_node/output_parsers.py | 12 - src/backend/base/poetry.lock | 136 +-- src/backend/base/pyproject.toml | 4 +- 36 files changed, 468 insertions(+), 874 deletions(-) delete mode 100644 src/backend/base/langflow/interface/output_parsers/__init__.py delete mode 100644 src/backend/base/langflow/interface/output_parsers/base.py delete mode 100644 src/backend/base/langflow/template/frontend_node/output_parsers.py diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e1b427322..3c5898369 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,8 +22,9 @@ jobs: strategy: matrix: python-version: - - "3.10" + - "3.12" - "3.11" + - "3.10" steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }} diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml index b0cfee04e..dac1d4f6a 100644 --- a/.github/workflows/python_test.yml +++ b/.github/workflows/python_test.yml @@ -23,8 +23,9 @@ jobs: strategy: matrix: python-version: - - "3.10" + - "3.12" - "3.11" + - "3.10" env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} steps: diff --git a/.github/workflows/typescript_test.yml b/.github/workflows/typescript_test.yml index 71ea535da..dc5bc061e 100644 --- a/.github/workflows/typescript_test.yml +++ b/.github/workflows/typescript_test.yml @@ -8,7 +8,7 @@ on: env: POETRY_VERSION: "1.8.2" NODE_VERSION: "21" - PYTHON_VERSION: "3.10" + PYTHON_VERSION: "3.12" # Define the directory where Playwright browsers will be installed. # Adjust if your project uses a different path. PLAYWRIGHT_BROWSERS_PATH: "ms-playwright" diff --git a/poetry.lock b/poetry.lock index 57995055b..3c20644f0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiohttp" @@ -469,17 +469,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.100" +version = "1.34.102" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.100-py3-none-any.whl", hash = "sha256:bbe2bb0dfcd92380da2a2fa2c2f586ba06c118b796380b2d0f3d0ebd103ec28d"}, - {file = "boto3-1.34.100.tar.gz", hash = "sha256:016f6d66900bb1a835dea2063f1e91fc7057dbf7fb7df8add0706f0da9492631"}, + {file = "boto3-1.34.102-py3-none-any.whl", hash = "sha256:1c1fb2884f85c0ec6b62e6e7ed5a2a6635e1188f3ab5d2b700f7db1cf8464484"}, + {file = "boto3-1.34.102.tar.gz", hash = "sha256:65e4b9fb9ceefe19976e8822ac0cd68d28946d4697e538741d2bbdb5b45ae42f"}, ] [package.dependencies] -botocore = ">=1.34.100,<1.35.0" +botocore = ">=1.34.102,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -488,13 +488,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.100" +version = "1.34.102" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.100-py3-none-any.whl", hash = "sha256:ee516fb9e9e906d311f2a9921afaf79c594db239a5b4b626e89e6960401aad0b"}, - {file = "botocore-1.34.100.tar.gz", hash = "sha256:513bea60c6531af8e1ae1fdb2947e3ef99712f39c58f4656b5efef9cb6f75a13"}, + {file = "botocore-1.34.102-py3-none-any.whl", hash = "sha256:79ac7fc2729294395c70eff9c23510f00785ad2acd78d6130cb4379e9f27da86"}, + {file = "botocore-1.34.102.tar.gz", hash = "sha256:e2f8a9f4bac6f7b568e6e981ac2a2500bc992329c85dde8546f0cae8605dd009"}, ] [package.dependencies] @@ -1421,13 +1421,13 @@ tests = ["pytest"] [[package]] name = "dataclasses-json" -version = "0.6.5" +version = "0.6.6" description = "Easily serialize dataclasses to and from JSON." optional = false python-versions = "<4.0,>=3.7" files = [ - {file = "dataclasses_json-0.6.5-py3-none-any.whl", hash = "sha256:f49c77aa3a85cac5bf5b7f65f4790ca0d2be8ef4d92c75e91ba0103072788a39"}, - {file = "dataclasses_json-0.6.5.tar.gz", hash = "sha256:1c287594d9fcea72dc42d6d3836cf14848c2dc5ce88f65ed61b36b57f515fe26"}, + {file = "dataclasses_json-0.6.6-py3-none-any.whl", hash = "sha256:e54c5c87497741ad454070ba0ed411523d46beb5da102e221efb873801b0ba85"}, + {file = "dataclasses_json-0.6.6.tar.gz", hash = "sha256:0c09827d26fffda27f1be2fed7a7a01a29c5ddcd2eb6393ad5ebf9d77e9deae8"}, ] [package.dependencies] @@ -1519,24 +1519,6 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] -[[package]] -name = "deepdiff" -version = "7.0.1" -description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other." -optional = false -python-versions = ">=3.8" -files = [ - {file = "deepdiff-7.0.1-py3-none-any.whl", hash = "sha256:447760081918216aa4fd4ca78a4b6a848b81307b2ea94c810255334b759e1dc3"}, - {file = "deepdiff-7.0.1.tar.gz", hash = "sha256:260c16f052d4badbf60351b4f77e8390bee03a0b516246f6839bc813fb429ddf"}, -] - -[package.dependencies] -ordered-set = ">=4.1.0,<4.2.0" - -[package.extras] -cli = ["click (==8.1.7)", "pyyaml (==6.0.1)"] -optimize = ["orjson"] - [[package]] name = "defusedxml" version = "0.7.1" @@ -1731,50 +1713,58 @@ weaviate = ["weaviate-client (>=3.26.1,<3.27.0)", "weaviate-client (>=4.5.4,<4.6 [[package]] name = "duckdb" -version = "0.9.2" -description = "DuckDB embedded database" +version = "0.10.2" +description = "DuckDB in-process database" optional = false python-versions = ">=3.7.0" files = [ - {file = "duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:aadcea5160c586704c03a8a796c06a8afffbefefb1986601104a60cb0bfdb5ab"}, - {file = "duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:08215f17147ed83cbec972175d9882387366de2ed36c21cbe4add04b39a5bcb4"}, - {file = "duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee6c2a8aba6850abef5e1be9dbc04b8e72a5b2c2b67f77892317a21fae868fe7"}, - {file = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff49f3da9399900fd58b5acd0bb8bfad22c5147584ad2427a78d937e11ec9d0"}, - {file = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5ac5baf8597efd2bfa75f984654afcabcd698342d59b0e265a0bc6f267b3f0"}, - {file = "duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:81c6df905589a1023a27e9712edb5b724566587ef280a0c66a7ec07c8083623b"}, - {file = "duckdb-0.9.2-cp310-cp310-win32.whl", hash = "sha256:a298cd1d821c81d0dec8a60878c4b38c1adea04a9675fb6306c8f9083bbf314d"}, - {file = "duckdb-0.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:492a69cd60b6cb4f671b51893884cdc5efc4c3b2eb76057a007d2a2295427173"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:061a9ea809811d6e3025c5de31bc40e0302cfb08c08feefa574a6491e882e7e8"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a43f93be768af39f604b7b9b48891f9177c9282a408051209101ff80f7450d8f"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac29c8c8f56fff5a681f7bf61711ccb9325c5329e64f23cb7ff31781d7b50773"}, - {file = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b14d98d26bab139114f62ade81350a5342f60a168d94b27ed2c706838f949eda"}, - {file = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:796a995299878913e765b28cc2b14c8e44fae2f54ab41a9ee668c18449f5f833"}, - {file = "duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6cb64ccfb72c11ec9c41b3cb6181b6fd33deccceda530e94e1c362af5f810ba1"}, - {file = "duckdb-0.9.2-cp311-cp311-win32.whl", hash = "sha256:930740cb7b2cd9e79946e1d3a8f66e15dc5849d4eaeff75c8788d0983b9256a5"}, - {file = "duckdb-0.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:c28f13c45006fd525001b2011cdf91fa216530e9751779651e66edc0e446be50"}, - {file = "duckdb-0.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fbce7bbcb4ba7d99fcec84cec08db40bc0dd9342c6c11930ce708817741faeeb"}, - {file = "duckdb-0.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15a82109a9e69b1891f0999749f9e3265f550032470f51432f944a37cfdc908b"}, - {file = "duckdb-0.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9490fb9a35eb74af40db5569d90df8a04a6f09ed9a8c9caa024998c40e2506aa"}, - {file = "duckdb-0.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:696d5c6dee86c1a491ea15b74aafe34ad2b62dcd46ad7e03b1d00111ca1a8c68"}, - {file = "duckdb-0.9.2-cp37-cp37m-win32.whl", hash = "sha256:4f0935300bdf8b7631ddfc838f36a858c1323696d8c8a2cecbd416bddf6b0631"}, - {file = "duckdb-0.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:0aab900f7510e4d2613263865570203ddfa2631858c7eb8cbed091af6ceb597f"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d8130ed6a0c9421b135d0743705ea95b9a745852977717504e45722c112bf7a"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:974e5de0294f88a1a837378f1f83330395801e9246f4e88ed3bfc8ada65dcbee"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4fbc297b602ef17e579bb3190c94d19c5002422b55814421a0fc11299c0c1100"}, - {file = "duckdb-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1dd58a0d84a424924a35b3772419f8cd78a01c626be3147e4934d7a035a8ad68"}, - {file = "duckdb-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11a1194a582c80dfb57565daa06141727e415ff5d17e022dc5f31888a5423d33"}, - {file = "duckdb-0.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:be45d08541002a9338e568dca67ab4f20c0277f8f58a73dfc1435c5b4297c996"}, - {file = "duckdb-0.9.2-cp38-cp38-win32.whl", hash = "sha256:dd6f88aeb7fc0bfecaca633629ff5c986ac966fe3b7dcec0b2c48632fd550ba2"}, - {file = "duckdb-0.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:28100c4a6a04e69aa0f4a6670a6d3d67a65f0337246a0c1a429f3f28f3c40b9a"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ae5bf0b6ad4278e46e933e51473b86b4b932dbc54ff097610e5b482dd125552"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e5d0bb845a80aa48ed1fd1d2d285dd352e96dc97f8efced2a7429437ccd1fe1f"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ce262d74a52500d10888110dfd6715989926ec936918c232dcbaddb78fc55b4"}, - {file = "duckdb-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6935240da090a7f7d2666f6d0a5e45ff85715244171ca4e6576060a7f4a1200e"}, - {file = "duckdb-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5cfb93e73911696a98b9479299d19cfbc21dd05bb7ab11a923a903f86b4d06e"}, - {file = "duckdb-0.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:64e3bc01751f31e7572d2716c3e8da8fe785f1cdc5be329100818d223002213f"}, - {file = "duckdb-0.9.2-cp39-cp39-win32.whl", hash = "sha256:6e5b80f46487636368e31b61461940e3999986359a78660a50dfdd17dd72017c"}, - {file = "duckdb-0.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:e6142a220180dbeea4f341708bd5f9501c5c962ce7ef47c1cadf5e8810b4cb13"}, - {file = "duckdb-0.9.2.tar.gz", hash = "sha256:3843afeab7c3fc4a4c0b53686a4cc1d9cdbdadcbb468d60fef910355ecafd447"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3891d3ac03e12a3e5c43afa3020fe701f64060f52d25f429a1ed7b5d914368d3"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f63877651f1fb940e049dc53038eb763856616319acf4f892b1c3ed074f5ab0"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:06e3a36f04f4d98d2c0bbdd63e517cfbe114a795306e26ec855e62e076af5043"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf5f95ad5b75c8e65c6508b4df02043dd0b9d97712b9a33236ad77c388ce7861"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ff62bc98278c98fecbd6eecec5d698ad41ebd654110feaadbf8ac8bb59b1ecf"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cceede13fde095c23cf9a53adf7c414c7bfb21b9a7aa6a4836014fdbecbfca70"}, + {file = "duckdb-0.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:acdfff60b7efccd7f731213a9795851256249dfacf80367074b2b2e144f716dd"}, + {file = "duckdb-0.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:4a5d5655cf0bdaf664a6f332afe465e02b08cef715548a0983bb7aef48da06a6"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a9d15842876d18763e085648656cccc7660a215d16254906db5c4471be2c7732"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c88cdcdc8452c910e4298223e7d9fca291534ff5aa36090aa49c9e6557550b13"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:364cd6f5dc8a1010d144d08c410ba9a74c521336ee5bda84fabc6616216a6d6a"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c57c11d1060296f5e9ebfb5bb7e5521e0d77912e8f9ff43c90240c3311e9de9"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:186d86b8dda8e1076170eb770bb2bb73ea88ca907d92885c9695d6515207b205"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f65b62f31c6bff21afc0261cfe28d238b8f34ec78f339546b12f4740c39552a"}, + {file = "duckdb-0.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a860d7466a5c93714cdd94559ce9e1db2ab91914f0941c25e5e93d4ebe36a5fa"}, + {file = "duckdb-0.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:33308190e9c7f05a3a0a2d46008a043effd4eae77011869d7c18fb37acdd9215"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3a8b2f1229b4aecb79cd28ffdb99032b1497f0a805d0da1136a9b6115e1afc70"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d23a6dea61963733a0f45a0d0bbb1361fb2a47410ed5ff308b4a1f869d4eeb6f"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:20ee0aa27e688aa52a40b434ec41a50431d0b06edeab88edc2feaca18d82c62c"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80a6d43d9044f0997a15a92e0c0ff3afd21151a1e572a92f439cc4f56b7090e1"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6934758cacd06029a5c9f54556a43bd277a86757e22bf8d0dd11ca15c1813d1c"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a11e2d68bd79044eea5486b1cddb5b915115f537e5c74eeb94c768ce30f9f4b"}, + {file = "duckdb-0.10.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0bf58385c43b8e448a2fea7e8729054934bf73ea616d1d7ef8184eda07f975e2"}, + {file = "duckdb-0.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:eae75c7014597ded6e7f6dc51e32d48362a31608acd73e9f795748ee94335a54"}, + {file = "duckdb-0.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62e89deff778a7a86f651802b947a3466425f6cce41e9d7d412d39e492932943"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f87e555fd36ec6da316b727a39fb24c53124a797dfa9b451bdea87b2f20a351f"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41e8b34b1a944590ebcf82f8cc59d67b084fe99479f048892d60da6c1402c386"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c68c6dde2773774cf2371522a3959ea2716fc2b3a4891d4066f0e426455fe19"}, + {file = "duckdb-0.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ff6a8a0980d0f9398fa461deffa59465dac190d707468478011ea8a5fe1f2c81"}, + {file = "duckdb-0.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:728dd4ff0efda387a424754e5508d4f8c72a272c2d3ccb036a83286f60b46002"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c461d6b4619e80170044a9eb999bbf4097e330d3a4974ced0a7eaeb79c7c39f6"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:909351ff72eb3b50b89761251148d8a186594d8a438e12dcf5494794caff6693"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d9eeb8393d69abafd355b869669957eb85b89e4df677e420b9ef0693b7aa6cb4"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3102bcf5011e8f82ea3c2bde43108774fe5a283a410d292c0843610ea13e2237"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d64d443613e5f16caf7d67102733538c90f7715867c1a98597efd3babca068e3"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb31398826d1b7473344e5ee8e0f826370c9752549469ba1327042ace9041f80"}, + {file = "duckdb-0.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d09dcec467cd6127d5cc1fb0ce4efbd77e761882d9d772b0f64fc2f79a2a1cde"}, + {file = "duckdb-0.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:82fab1a24faf7c33d8a7afed08b57ee36e8821a3a68a2f1574cd238ea440bba0"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38607e6e6618e8ea28c8d9b67aa9e22cfd6d6d673f2e8ab328bd6e867b697f69"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb0c23bc8c09615bff38aebcf8e92e6ae74959c67b3c9e5b00edddc730bf22be"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:00576c11c78c83830ab483bad968e07cd9b5f730e7ffaf5aa5fadee5ac4f71e9"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:077db692cdda50c4684ef87dc2a68507665804caa90e539dbe819116bda722ad"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca25984ad9f9a04e46e8359f852668c11569534e3bb8424b80be711303ad2314"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a72cc40982c7b92cf555e574618fc711033b013bf258b611ba18d7654c89d8c"}, + {file = "duckdb-0.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27b9efd6e788eb561535fdc0cbc7c74aca1ff39f748b7cfc27aa49b00e22da1"}, + {file = "duckdb-0.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:4800469489bc262dda61a7f1d40acedf67cf2454874e9d8bbf07920dc2b147e6"}, + {file = "duckdb-0.10.2.tar.gz", hash = "sha256:0f609c9d5f941f1ecde810f010dd9321cd406a552c1df20318a13fa64247f67f"}, ] [[package]] @@ -2067,17 +2057,6 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] -[[package]] -name = "filetype" -version = "1.2.0" -description = "Infer file type and MIME type of any file/buffer. No external dependencies." -optional = false -python-versions = "*" -files = [ - {file = "filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"}, - {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"}, -] - [[package]] name = "flaml" version = "2.1.2" @@ -2601,13 +2580,13 @@ httplib2 = ">=0.19.0" [[package]] name = "google-cloud-aiplatform" -version = "1.50.0" +version = "1.51.0" description = "Vertex AI API client library" optional = false python-versions = ">=3.8" files = [ - {file = "google-cloud-aiplatform-1.50.0.tar.gz", hash = "sha256:f9f7cc76dbaad3905408fd07d6322caa6c4cd60a0330e4b15de66033c6598cc6"}, - {file = "google_cloud_aiplatform-1.50.0-py2.py3-none-any.whl", hash = "sha256:6aa8246086252fe01d3438cd6566561147405a09611cf03f082be197c77b8197"}, + {file = "google-cloud-aiplatform-1.51.0.tar.gz", hash = "sha256:901993b4d14392452699c14cf23d72c01c5488ee36a7e00b23195e64d7d2f5ec"}, + {file = "google_cloud_aiplatform-1.51.0-py2.py3-none-any.whl", hash = "sha256:f2d3ff231454fe397f02fce1358680dea76ed7c74fc42e6c7e1aa1acb1648df3"}, ] [package.dependencies] @@ -2629,8 +2608,8 @@ cloud-profiler = ["tensorboard-plugin-profile (>=2.4.0,<3.0.0dev)", "tensorflow datasets = ["pyarrow (>=10.0.1)", "pyarrow (>=14.0.0)", "pyarrow (>=3.0.0,<8.0dev)"] endpoint = ["requests (>=2.28.1)"] full = ["cloudpickle (<3.0)", "docker (>=5.0.3)", "explainable-ai-sdk (>=1.0.0)", "fastapi (>=0.71.0,<=0.109.1)", "google-cloud-bigquery", "google-cloud-bigquery-storage", "google-cloud-logging (<4.0)", "google-vizier (>=0.1.6)", "httpx (>=0.23.0,<0.25.0)", "immutabledict", "lit-nlp (==0.4.0)", "mlflow (>=1.27.0,<=2.1.1)", "nest-asyncio (>=1.0.0,<1.6.0)", "numpy (>=1.15.0)", "pandas (>=1.0.0)", "pandas (>=1.0.0,<2.2.0)", "pyarrow (>=10.0.1)", "pyarrow (>=14.0.0)", "pyarrow (>=3.0.0,<8.0dev)", "pyarrow (>=6.0.1)", "pydantic (<2)", "pyyaml (>=5.3.1,<7)", "ray[default] (>=2.4,<2.5.dev0 || >2.9.0,!=2.9.1,!=2.9.2,<=2.9.3)", "ray[default] (>=2.5,<=2.9.3)", "requests (>=2.28.1)", "starlette (>=0.17.1)", "tensorflow (>=2.3.0,<3.0.0dev)", "tensorflow (>=2.3.0,<3.0.0dev)", "urllib3 (>=1.21.1,<1.27)", "uvicorn[standard] (>=0.16.0)"] -langchain = ["langchain (>=0.1.13,<0.2)", "langchain-core (<0.2)", "langchain-google-vertexai (<0.2)"] -langchain-testing = ["absl-py", "cloudpickle (>=2.2.1,<3.0)", "langchain (>=0.1.13,<0.2)", "langchain-core (<0.2)", "langchain-google-vertexai (<0.2)", "pydantic (>=2.6.3,<3)", "pytest-xdist"] +langchain = ["langchain (>=0.1.16,<0.2)", "langchain-core (<0.2)", "langchain-google-vertexai (<2)"] +langchain-testing = ["absl-py", "cloudpickle (>=2.2.1,<3.0)", "langchain (>=0.1.16,<0.2)", "langchain-core (<0.2)", "langchain-google-vertexai (<2)", "pydantic (>=2.6.3,<3)", "pytest-xdist"] lit = ["explainable-ai-sdk (>=1.0.0)", "lit-nlp (==0.4.0)", "pandas (>=1.0.0)", "tensorflow (>=2.3.0,<3.0.0dev)"] metadata = ["numpy (>=1.15.0)", "pandas (>=1.0.0)"] pipelines = ["pyyaml (>=5.3.1,<7)"] @@ -3854,17 +3833,6 @@ files = [ [package.dependencies] jsonpointer = ">=1.9" -[[package]] -name = "jsonpath-python" -version = "1.0.6" -description = "A more powerful JSONPath implementation in modern python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, - {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, -] - [[package]] name = "jsonpointer" version = "2.4" @@ -3978,22 +3946,21 @@ adal = ["adal (>=1.0.2)"] [[package]] name = "langchain" -version = "0.1.17" +version = "0.1.19" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain-0.1.17-py3-none-any.whl", hash = "sha256:f6c5b5fdb529545e6cafbb4ba099031508e621ba1ed7985cf078a597ade3458b"}, - {file = "langchain-0.1.17.tar.gz", hash = "sha256:709b80afa00ae634dfc7042f3e4c20309267b21ffeacc7d7494d58bcae1862f7"}, + {file = "langchain-0.1.19-py3-none-any.whl", hash = "sha256:a1270b70139344a09f91c8a1b117c4300d9920d6d88aaaaf5ba729625ac68801"}, + {file = "langchain-0.1.19.tar.gz", hash = "sha256:7d2ffb66944a84dcac99901c4fd33f6d92aa7f794d17b5ba9a29c55a7306e32c"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} dataclasses-json = ">=0.5.7,<0.7" -jsonpatch = ">=1.33,<2.0" -langchain-community = ">=0.0.36,<0.1" -langchain-core = ">=0.1.48,<0.2.0" +langchain-community = ">=0.0.38,<0.1" +langchain-core = ">=0.1.52,<0.2.0" langchain-text-splitters = ">=0.0.1,<0.1" langsmith = ">=0.1.17,<0.2.0" numpy = ">=1,<2" @@ -4066,19 +4033,19 @@ langchain-core = ">=0.1.42,<0.2.0" [[package]] name = "langchain-community" -version = "0.0.37" +version = "0.0.38" description = "Community contributed LangChain integrations." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_community-0.0.37-py3-none-any.whl", hash = "sha256:52e8557602dc099c2e236ec8a0599a956e2f08cfeb61e501815f5ec2d8545747"}, - {file = "langchain_community-0.0.37.tar.gz", hash = "sha256:db2b5829bb20bc5b04c126b69143dbc31a880e949e94110c236b2c176906889f"}, + {file = "langchain_community-0.0.38-py3-none-any.whl", hash = "sha256:ecb48660a70a08c90229be46b0cc5f6bc9f38f2833ee44c57dfab9bf3a2c121a"}, + {file = "langchain_community-0.0.38.tar.gz", hash = "sha256:127fc4b75bc67b62fe827c66c02e715a730fef8fe69bd2023d466bab06b5810d"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" dataclasses-json = ">=0.5.7,<0.7" -langchain-core = ">=0.1.51,<0.2.0" +langchain-core = ">=0.1.52,<0.2.0" langsmith = ">=0.1.0,<0.2.0" numpy = ">=1,<2" PyYAML = ">=5.3" @@ -4265,26 +4232,12 @@ files = [ requests = ">=2,<3" types-requests = ">=2.31.0.2,<3.0.0.0" -[[package]] -name = "langdetect" -version = "1.0.9" -description = "Language detection library ported from Google's language-detection." -optional = false -python-versions = "*" -files = [ - {file = "langdetect-1.0.9-py2-none-any.whl", hash = "sha256:7cbc0746252f19e76f77c0b1690aadf01963be835ef0cd4b56dddf2a8f1dfc2a"}, - {file = "langdetect-1.0.9.tar.gz", hash = "sha256:cbc1fef89f8d062739774bd51eda3da3274006b3661d199c2655f6b3f6d605a0"}, -] - -[package.dependencies] -six = "*" - [[package]] name = "langflow-base" version = "0.0.41" description = "A Python package with a built-in web application" optional = false -python-versions = ">=3.10,<3.12" +python-versions = ">=3.10,<3.13" files = [] develop = true @@ -4295,7 +4248,7 @@ bcrypt = "4.0.1" cachetools = "^5.3.1" cryptography = "^42.0.5" docstring-parser = "^0.15" -duckdb = "^0.9.2" +duckdb = "^0.10.2" emoji = "^2.11.0" fastapi = "^0.110.1" gunicorn = "^22.0.0" @@ -4336,13 +4289,13 @@ url = "src/backend/base" [[package]] name = "langfuse" -version = "2.29.2" +version = "2.29.3" description = "A client library for accessing langfuse" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langfuse-2.29.2-py3-none-any.whl", hash = "sha256:2c289b291124cfb486ae4a2234276ecdf453111b3affc0ad0e639cd688e1e9cb"}, - {file = "langfuse-2.29.2.tar.gz", hash = "sha256:734783fa21f28f4bd171d4c837ee1c108f191d643ccd1f001704a5491f8f52fb"}, + {file = "langfuse-2.29.3-py3-none-any.whl", hash = "sha256:7471365dc19677eecbc82319c7785f6b8c41437eabe5716c9f262e2f0a2fc43c"}, + {file = "langfuse-2.29.3.tar.gz", hash = "sha256:408873adc3e77725b94e2105be8e1c395f7b8a604f43aa28a772df02e49be088"}, ] [package.dependencies] @@ -4360,13 +4313,13 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.55" +version = "0.1.56" 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.55-py3-none-any.whl", hash = "sha256:c198b4019d0e0948fa2c94efcafa0312bd5e7ce36aae8d62a38af2d6b16584fc"}, - {file = "langsmith-0.1.55.tar.gz", hash = "sha256:08b75046471e3c32cb6b526e48ca4570bfe3911d6b0a3f8575ee062da940324c"}, + {file = "langsmith-0.1.56-py3-none-any.whl", hash = "sha256:2f930e054ea8eccd8ff99f0f129ae7d2513973b2e706d5483f44ea9951a1dca0"}, + {file = "langsmith-0.1.56.tar.gz", hash = "sha256:ff645b5bf16e2566740218ed6c048a1f8edbbedb4480a0d305a837ec71303fbf"}, ] [package.dependencies] @@ -4393,13 +4346,13 @@ regex = ["regex"] [[package]] name = "litellm" -version = "1.36.2" +version = "1.37.0" 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.36.2-py3-none-any.whl", hash = "sha256:541b954e070b0ecb7406a57127d52661e54b0d9394a0a8d85f8cfd86256e5d36"}, - {file = "litellm-1.36.2.tar.gz", hash = "sha256:6554d298473efc9d80b127c0ded4cd47cf23e16aaef21004fd16420f84d91975"}, + {file = "litellm-1.37.0-py3-none-any.whl", hash = "sha256:74f7ccf8c10491aa393cd1a77aff4db9fd61bbffe52a7326c96811db823e1005"}, + {file = "litellm-1.37.0.tar.gz", hash = "sha256:441fbdc119f3336f1693d2022c1887d6d98453dbab32920318c823ad8ddf0d66"}, ] [package.dependencies] @@ -4419,12 +4372,12 @@ proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", " [[package]] name = "llama-cpp-python" -version = "0.2.70" +version = "0.2.72" description = "Python bindings for the llama.cpp library" optional = true python-versions = ">=3.8" files = [ - {file = "llama_cpp_python-0.2.70.tar.gz", hash = "sha256:12d046bed7900f46c0b6b3df37f20aa24049477e0cd93c6b69b97754cb0ed842"}, + {file = "llama_cpp_python-0.2.72.tar.gz", hash = "sha256:7da4957043927f73d4425c919c843581e5a3ceb5e65cafbc29bfb45703814a56"}, ] [package.dependencies] @@ -4441,13 +4394,13 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)", "scipy (>=1.10)"] [[package]] name = "llama-index" -version = "0.10.35" +version = "0.10.36" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index-0.10.35-py3-none-any.whl", hash = "sha256:1e30f7dceff5e05cb9bfe8727b767487dfe4f97dc2c71a4ca8276aa983dc6e9e"}, - {file = "llama_index-0.10.35.tar.gz", hash = "sha256:cf1b9ac3b65cc4fd035bfeb0010353a65403aa202d830e21dc7beda7e6284e62"}, + {file = "llama_index-0.10.36-py3-none-any.whl", hash = "sha256:e57779f332323b00576cf9e8fee0ab5b978aaf35902288691da01a7839b99e58"}, + {file = "llama_index-0.10.36.tar.gz", hash = "sha256:275309a2317e9279b296e552c334e566c4f011223f6ed39e342f5264a05c4d9a"}, ] [package.dependencies] @@ -4498,13 +4451,13 @@ llama-index-llms-openai = ">=0.1.1,<0.2.0" [[package]] name = "llama-index-core" -version = "0.10.35.post1" +version = "0.10.36" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_core-0.10.35.post1-py3-none-any.whl", hash = "sha256:1c5993946202a9aec86bd6f0943991d1fe443556bd3e6c7b345cb360a46dc6c2"}, - {file = "llama_index_core-0.10.35.post1.tar.gz", hash = "sha256:f62013217bf7c04b6adf9dc2c1b168ff957f924519f19af2f383a0f0c34308e4"}, + {file = "llama_index_core-0.10.36-py3-none-any.whl", hash = "sha256:a6e8ea790e5b3656a254d9b47f8c00044dd46aae1cd43004c5d1303a7502b3e6"}, + {file = "llama_index_core-0.10.36.tar.gz", hash = "sha256:02f06bdefb5c6fd11dee1f65007a98decf3b266ad76136b7cfd3bec44efc5493"}, ] [package.dependencies] @@ -4610,13 +4563,13 @@ query-tools = ["guidance (>=0.0.64,<0.0.65)", "jsonpath-ng (>=1.6.0,<2.0.0)", "l [[package]] name = "llama-index-llms-openai" -version = "0.1.17" +version = "0.1.18" description = "llama-index llms openai integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_llms_openai-0.1.17-py3-none-any.whl", hash = "sha256:04d1906ca1fbd34f8322acb5565fbfd605c5ea0e000bfba4fd0b1f512c7e0ca0"}, - {file = "llama_index_llms_openai-0.1.17.tar.gz", hash = "sha256:66d3af761dc232388b54a017b0cb8401ebd74c02d69cae7d604d8288ec1b683d"}, + {file = "llama_index_llms_openai-0.1.18-py3-none-any.whl", hash = "sha256:934cf72d10385f1c76c0183b0e94ce1850fab1026287e01b7db0a14c946dfd79"}, + {file = "llama_index_llms_openai-0.1.18.tar.gz", hash = "sha256:8cb7546a1885ba558ff580b114d638569a0aed81a264961114e719bc42b37100"}, ] [package.dependencies] @@ -4671,13 +4624,13 @@ llama-index-program-openai = ">=0.1.1,<0.2.0" [[package]] name = "llama-index-readers-file" -version = "0.1.21" +version = "0.1.22" description = "llama-index readers file integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_readers_file-0.1.21-py3-none-any.whl", hash = "sha256:5740cf6d8bf18c1f27455e178005d839530fdae664c13503f14de92d4cee0d39"}, - {file = "llama_index_readers_file-0.1.21.tar.gz", hash = "sha256:f219c252579a3872a51ad369447820984e5702cda1117aa9ea84a8d8283476da"}, + {file = "llama_index_readers_file-0.1.22-py3-none-any.whl", hash = "sha256:a8d4a69a9ea659c14ebb22ca9a5560b9c7ec6f501e7f68f6c52f591374165376"}, + {file = "llama_index_readers_file-0.1.22.tar.gz", hash = "sha256:37de54ad0cfbdc607c195532b9a292417a4714f57773570b87027b8dc381f0e2"}, ] [package.dependencies] @@ -4851,7 +4804,6 @@ files = [ {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-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f"}, {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"}, @@ -4876,6 +4828,7 @@ files = [ {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"}, @@ -4966,21 +4919,6 @@ babel = ["Babel"] lingua = ["lingua"] testing = ["pytest"] -[[package]] -name = "markdown" -version = "3.6" -description = "Python implementation of John Gruber's Markdown." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, - {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, -] - -[package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] -testing = ["coverage", "pyyaml"] - [[package]] name = "markdown-it-py" version = "3.0.0" @@ -5942,13 +5880,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.26.0" +version = "1.28.0" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.26.0-py3-none-any.whl", hash = "sha256:884ced523fb0225780f8b0e0ed6f7e014049c32d049a41ad0ac962869f1055d1"}, - {file = "openai-1.26.0.tar.gz", hash = "sha256:642e857b60855702ee6ff665e8fa80946164f77b92e58fd24e01b545685b8405"}, + {file = "openai-1.28.0-py3-none-any.whl", hash = "sha256:94b5a99f5121e1747dda1bb8fff31820d5ab4b49056a9cf2e3605f5c90011955"}, + {file = "openai-1.28.0.tar.gz", hash = "sha256:ac43b8b48aec70de4b76cfc96ae906bf8d5814427475b9dabb662f84f655f0e1"}, ] [package.dependencies] @@ -6152,20 +6090,6 @@ document = ["ase", "cmaes (>=0.10.0)", "fvcore", "lightgbm", "matplotlib (!=3.6. optional = ["boto3", "cmaes (>=0.10.0)", "google-cloud-storage", "matplotlib (!=3.6.0)", "pandas", "plotly (>=4.9.0)", "redis", "scikit-learn (>=0.24.2)", "scipy", "torch"] test = ["coverage", "fakeredis[lua]", "kaleido", "moto", "pytest", "scipy (>=1.9.2)", "torch"] -[[package]] -name = "ordered-set" -version = "4.1.0" -description = "An OrderedSet is a custom MutableSet that remembers its order, so that every" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"}, - {file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"}, -] - -[package.extras] -dev = ["black", "mypy", "pytest"] - [[package]] name = "orjson" version = "3.10.0" @@ -6290,6 +6214,7 @@ files = [ numpy = [ {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -6509,7 +6434,10 @@ files = [ certifi = ">=2019.11.17" tqdm = ">=4.64.1" typing-extensions = ">=3.7.4" -urllib3 = {version = ">=1.26.0", markers = "python_version >= \"3.8\" and python_version < \"3.12\""} +urllib3 = [ + {version = ">=1.26.0", markers = "python_version >= \"3.8\" and python_version < \"3.12\""}, + {version = ">=1.26.5", markers = "python_version >= \"3.12\" and python_version < \"4.0\""}, +] [package.extras] grpc = ["googleapis-common-protos (>=1.53.0)", "grpc-gateway-protoc-gen-openapiv2 (==0.1.0)", "grpcio (>=1.44.0)", "grpcio (>=1.59.0)", "lz4 (>=3.1.3)", "protobuf (>=3.20.0,<3.21.0)"] @@ -6717,13 +6645,12 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] [[package]] name = "psycopg" -version = "3.1.18" +version = "3.1.19" description = "PostgreSQL database adapter for Python" optional = false python-versions = ">=3.7" files = [ - {file = "psycopg-3.1.18-py3-none-any.whl", hash = "sha256:4d5a0a5a8590906daa58ebd5f3cfc34091377354a1acced269dd10faf55da60e"}, - {file = "psycopg-3.1.18.tar.gz", hash = "sha256:31144d3fb4c17d78094d9e579826f047d4af1da6a10427d91dfcfb6ecdf6f12b"}, + {file = "psycopg-3.1.19-py3-none-any.whl", hash = "sha256:dca5e5521c859f6606686432ae1c94e8766d29cc91f2ee595378c510cc5b0731"}, ] [package.dependencies] @@ -6731,8 +6658,8 @@ typing-extensions = ">=4.1" tzdata = {version = "*", markers = "sys_platform == \"win32\""} [package.extras] -binary = ["psycopg-binary (==3.1.18)"] -c = ["psycopg-c (==3.1.18)"] +binary = ["psycopg-binary (==3.1.19)"] +c = ["psycopg-c (==3.1.19)"] dev = ["black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.4.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"] docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"] pool = ["psycopg-pool"] @@ -6740,76 +6667,74 @@ test = ["anyio (>=3.6.2,<4.0)", "mypy (>=1.4.1)", "pproxy (>=2.7)", "pytest (>=6 [[package]] name = "psycopg-binary" -version = "3.1.18" +version = "3.1.19" description = "PostgreSQL database adapter for Python -- C optimisation distribution" optional = false python-versions = ">=3.7" files = [ - {file = "psycopg_binary-3.1.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c323103dfa663b88204cf5f028e83c77d7a715f9b6f51d2bbc8184b99ddd90a"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:887f8d856c91510148be942c7acd702ccf761a05f59f8abc123c22ab77b5a16c"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d322ba72cde4ca2eefc2196dad9ad7e52451acd2f04e3688d590290625d0c970"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:489aa4fe5a0b653b68341e9e44af247dedbbc655326854aa34c163ef1bcb3143"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ff0948457bfa8c0d35c46e3a75193906d1c275538877ba65907fd67aa059ad"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b15e3653c82384b043d820fc637199b5c6a36b37fa4a4943e0652785bb2bad5d"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f8ff3bc08b43f36fdc24fedb86d42749298a458c4724fb588c4d76823ac39f54"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1729d0e3dfe2546d823841eb7a3d003144189d6f5e138ee63e5227f8b75276a5"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:13bcd3742112446037d15e360b27a03af4b5afcf767f5ee374ef8f5dd7571b31"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:320047e3d3554b857e16c2b6b615a85e0db6a02426f4d203a4594a2f125dfe57"}, - {file = "psycopg_binary-3.1.18-cp310-cp310-win_amd64.whl", hash = "sha256:888a72c2aca4316ca6d4a619291b805677bae99bba2f6e31a3c18424a48c7e4d"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e4de16a637ec190cbee82e0c2dc4860fed17a23a35f7a1e6dc479a5c6876722"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6432047b8b24ef97e3fbee1d1593a0faaa9544c7a41a2c67d1f10e7621374c83"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d684227ef8212e27da5f2aff9d4d303cc30b27ac1702d4f6881935549486dd5"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67284e2e450dc7a9e4d76e78c0bd357dc946334a3d410defaeb2635607f632cd"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c9b6bd7fb5c6638cb32469674707649b526acfe786ba6d5a78ca4293d87bae4"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7121acc783c4e86d2d320a7fb803460fab158a7f0a04c5e8c5d49065118c1e73"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e28ff8f3de7b56588c2a398dc135fd9f157d12c612bd3daa7e6ba9872337f6f5"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c84a0174109f329eeda169004c7b7ca2e884a6305acab4a39600be67f915ed38"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:531381f6647fc267383dca88dbe8a70d0feff433a8e3d0c4939201fea7ae1b82"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b293e01057e63c3ac0002aa132a1071ce0fdb13b9ee2b6b45d3abdb3525c597d"}, - {file = "psycopg_binary-3.1.18-cp311-cp311-win_amd64.whl", hash = "sha256:780a90bcb69bf27a8b08bc35b958e974cb6ea7a04cdec69e737f66378a344d68"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:87dd9154b757a5fbf6d590f6f6ea75f4ad7b764a813ae04b1d91a70713f414a1"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f876ebbf92db70125f6375f91ab4bc6b27648aa68f90d661b1fc5affb4c9731c"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d2f0cb45e4574f8b2fe7c6d0a0e2eb58903a4fd1fbaf60954fba82d595ab7"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd27f713f2e5ef3fd6796e66c1a5203a27a30ecb847be27a78e1df8a9a5ae68c"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c38a4796abf7380f83b1653c2711cb2449dd0b2e5aca1caa75447d6fa5179c69"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2f7f95746efd1be2dc240248cc157f4315db3fd09fef2adfcc2a76e24aa5741"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4085f56a8d4fc8b455e8f44380705c7795be5317419aa5f8214f315e4205d804"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2e2484ae835dedc80cdc7f1b1a939377dc967fed862262cfd097aa9f50cade46"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3c2b039ae0c45eee4cd85300ef802c0f97d0afc78350946a5d0ec77dd2d7e834"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f54978c4b646dec77fefd8485fa82ec1a87807f334004372af1aaa6de9539a5"}, - {file = "psycopg_binary-3.1.18-cp312-cp312-win_amd64.whl", hash = "sha256:9ffcbbd389e486d3fd83d30107bbf8b27845a295051ccabde240f235d04ed921"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c76659ae29a84f2c14f56aad305dd00eb685bd88f8c0a3281a9a4bc6bd7d2aa7"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7afcd6f1d55992f26d9ff7b0bd4ee6b475eb43aa3f054d67d32e09f18b0065"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:639dd78ac09b144b0119076783cb64e1128cc8612243e9701d1503c816750b2e"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1cf59e0bb12e031a48bb628aae32df3d0c98fd6c759cb89f464b1047f0ca9c8"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e262398e5d51563093edf30612cd1e20fedd932ad0994697d7781ca4880cdc3d"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:59701118c7d8842e451f1e562d08e8708b3f5d14974eefbce9374badd723c4ae"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:dea4a59da7850192fdead9da888e6b96166e90608cf39e17b503f45826b16f84"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4575da95fc441244a0e2ebaf33a2b2f74164603341d2046b5cde0a9aa86aa7e2"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:812726266ab96de681f2c7dbd6b734d327f493a78357fcc16b2ac86ff4f4e080"}, - {file = "psycopg_binary-3.1.18-cp37-cp37m-win_amd64.whl", hash = "sha256:3e7ce4d988112ca6c75765c7f24c83bdc476a6a5ce00878df6c140ca32c3e16d"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:02bd4da45d5ee9941432e2e9bf36fa71a3ac21c6536fe7366d1bd3dd70d6b1e7"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:39242546383f6b97032de7af30edb483d237a0616f6050512eee7b218a2aa8ee"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d46ae44d66bf6058a812467f6ae84e4e157dee281bfb1cfaeca07dee07452e85"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad35ac7fd989184bf4d38a87decfb5a262b419e8ba8dcaeec97848817412c64a"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:247474af262bdd5559ee6e669926c4f23e9cf53dae2d34c4d991723c72196404"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ebecbf2406cd6875bdd2453e31067d1bd8efe96705a9489ef37e93b50dc6f09"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1859aeb2133f5ecdd9cbcee155f5e38699afc06a365f903b1512c765fd8d457e"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:da917f6df8c6b2002043193cb0d74cc173b3af7eb5800ad69c4e1fbac2a71c30"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9e24e7b6a68a51cc3b162d0339ae4e1263b253e887987d5c759652f5692b5efe"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e252d66276c992319ed6cd69a3ffa17538943954075051e992143ccbf6dc3d3e"}, - {file = "psycopg_binary-3.1.18-cp38-cp38-win_amd64.whl", hash = "sha256:5d6e860edf877d4413e4a807e837d55e3a7c7df701e9d6943c06e460fa6c058f"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eea5f14933177ffe5c40b200f04f814258cc14b14a71024ad109f308e8bad414"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:824a1bfd0db96cc6bef2d1e52d9e0963f5bf653dd5bc3ab519a38f5e6f21c299"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a87e9eeb80ce8ec8c2783f29bce9a50bbcd2e2342a340f159c3326bf4697afa1"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91074f78a9f890af5f2c786691575b6b93a4967ad6b8c5a90101f7b8c1a91d9c"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e05f6825f8db4428782135e6986fec79b139210398f3710ed4aa6ef41473c008"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f68ac2364a50d4cf9bb803b4341e83678668f1881a253e1224574921c69868c"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7ac1785d67241d5074f8086705fa68e046becea27964267ab3abd392481d7773"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:cd2a9f7f0d4dacc5b9ce7f0e767ae6cc64153264151f50698898c42cabffec0c"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:3e4b0bb91da6f2238dbd4fbb4afc40dfb4f045bb611b92fce4d381b26413c686"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:74e498586b72fb819ca8ea82107747d0cb6e00ae685ea6d1ab3f929318a8ce2d"}, - {file = "psycopg_binary-3.1.18-cp39-cp39-win_amd64.whl", hash = "sha256:d4422af5232699f14b7266a754da49dc9bcd45eba244cf3812307934cd5d6679"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7204818f05151dd08f8f851defb01972ec9d2cc925608eb0de232563f203f354"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4e67fd86758dbeac85641419a54f84d74495a8683b58ad5dfad08b7fc37a8f"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12173e34b176e93ad2da913de30f774d5119c2d4d4640c6858d2d77dfa6c9bf"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052f5193304066318853b4b2e248f523c8f52b371fc4e95d4ef63baee3f30955"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29008f3f8977f600b8a7fb07c2e041b01645b08121760609cc45e861a0364dc9"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c6a9a651a08d876303ed059c9553df18b3c13c3406584a70a8f37f1a1fe2709"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:91a645e6468c4f064b7f4f3b81074bdd68fe5aa2b8c5107de15dcd85ba6141be"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5c6956808fd5cf0576de5a602243af8e04594b25b9a28675feddc71c5526410a"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:1622ca27d5a7a98f7d8f35e8b146dc7efda4a4b6241d2edf7e076bd6bcecbeb4"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a100482950a55228f648bd382bb71bfaff520002f29845274fccbbf02e28bd52"}, + {file = "psycopg_binary-3.1.19-cp310-cp310-win_amd64.whl", hash = "sha256:955ca8905c0251fc4af7ce0a20999e824a25652f53a558ab548b60969f1f368e"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cf49e91dcf699b8a449944ed898ef1466b39b92720613838791a551bc8f587a"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:964c307e400c5f33fa762ba1e19853e048814fcfbd9679cc923431adb7a2ead2"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3433924e1b14074798331dc2bfae2af452ed7888067f2fc145835704d8981b15"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00879d4c6be4b3afc510073f48a5e960f797200e261ab3d9bd9b7746a08c669d"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a6997c80f86d3dd80a4f078bb3b200079c47eeda4fd409d8899b883c90d2ac"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0106e42b481677c41caa69474fe530f786dcef88b11b70000f0e45a03534bc8f"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81efe09ba27533e35709905c3061db4dc9fb814f637360578d065e2061fbb116"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d312d6dddc18d9c164e1893706269c293cba1923118349d375962b1188dafb01"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:bfd2c734da9950f7afaad5f132088e0e1478f32f042881fca6651bb0c8d14206"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8a732610a5a6b4f06dadcf9288688a8ff202fd556d971436a123b7adb85596e2"}, + {file = "psycopg_binary-3.1.19-cp311-cp311-win_amd64.whl", hash = "sha256:321814a9a3ad785855a821b842aba08ca1b7de7dfb2979a2f0492dca9ec4ae70"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4aa0ca13bb8a725bb6d12c13999217fd5bc8b86a12589f28a74b93e076fbb959"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:469424e354ebcec949aa6aa30e5a9edc352a899d9a68ad7a48f97df83cc914cf"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b04f5349313529ae1f1c42fe1aa0443faaf50fdf12d13866c2cc49683bfa53d0"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:959feabddc7fffac89b054d6f23f3b3c62d7d3c90cd414a02e3747495597f150"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e9da624a6ca4bc5f7fa1f03f8485446b5b81d5787b6beea2b4f8d9dbef878ad7"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1823221a6b96e38b15686170d4fc5b36073efcb87cce7d3da660440b50077f6"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:866db42f986298f0cf15d805225eb8df2228bf19f7997d7f1cb5f388cbfc6a0f"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:738c34657305b5973af6dbb6711b07b179dfdd21196d60039ca30a74bafe9648"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb9758473200384a04374d0e0cac6f451218ff6945a024f65a1526802c34e56e"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0e991632777e217953ac960726158987da684086dd813ac85038c595e7382c91"}, + {file = "psycopg_binary-3.1.19-cp312-cp312-win_amd64.whl", hash = "sha256:1d87484dd42c8783c44a30400949efb3d81ef2487eaa7d64d1c54df90cf8b97a"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d1d1723d7449c12bb61aca7eb6e0c6ab2863cd8dc0019273cc4d4a1982f84bdb"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e538a8671005641fa195eab962f85cf0504defbd3b548c4c8fc27102a59f687b"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c50592bc8517092f40979e4a5d934f96a1737a77724bb1d121eb78b614b30fc8"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95f16ae82bc242b76cd3c3e5156441e2bd85ff9ec3a9869d750aad443e46073c"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aebd1e98e865e9a28ce0cb2c25b7dfd752f0d1f0a423165b55cd32a431dcc0f4"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:49cd7af7d49e438a39593d1dd8cab106a1912536c2b78a4d814ebdff2786094e"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:affebd61aa3b7a8880fd4ac3ee94722940125ff83ff485e1a7c76be9adaabb38"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:d1bac282f140fa092f2bbb6c36ed82270b4a21a6fc55d4b16748ed9f55e50fdb"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1285aa54449e362b1d30d92b2dc042ad3ee80f479cc4e323448d0a0a8a1641fa"}, + {file = "psycopg_binary-3.1.19-cp37-cp37m-win_amd64.whl", hash = "sha256:6cff31af8155dc9ee364098a328bab688c887c732c66b8d027e5b03818ca0287"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d9b689c4a17dd3130791dcbb8c30dbf05602f7c2d56c792e193fb49adc7bf5f8"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:017518bd2de4851adc826a224fb105411e148ad845e11355edd6786ba3dfedf5"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c35fd811f339a3cbe7f9b54b2d9a5e592e57426c6cc1051632a62c59c4810208"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38ed45ec9673709bfa5bc17f140e71dd4cca56d4e58ef7fd50d5a5043a4f55c6"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:433f1c256108f9e26f480a8cd6ddb0fb37dbc87d7f5a97e4540a9da9b881f23f"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ed61e43bf5dc8d0936daf03a19fef3168d64191dbe66483f7ad08c4cea0bc36b"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ae8109ff9fdf1fa0cb87ab6645298693fdd2666a7f5f85660df88f6965e0bb7"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a53809ee02e3952fae7977c19b30fd828bd117b8f5edf17a3a94212feb57faaf"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9d39d5ffc151fb33bcd55b99b0e8957299c0b1b3e5a1a5f4399c1287ef0051a9"}, + {file = "psycopg_binary-3.1.19-cp38-cp38-win_amd64.whl", hash = "sha256:e14bc8250000921fcccd53722f86b3b3d1b57db901e206e49e2ab2afc5919c2d"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd88c5cea4efe614d5004fb5f5dcdea3d7d59422be796689e779e03363102d24"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:621a814e60825162d38760c66351b4df679fd422c848b7c2f86ad399bff27145"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46e50c05952b59a214e27d3606f6d510aaa429daed898e16b8a37bfbacc81acc"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03354a9db667c27946e70162cb0042c3929154167f3678a30d23cebfe0ad55b5"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:703c2f3b79037581afec7baa2bdbcb0a1787f1758744a7662099b0eca2d721cb"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6469ebd9e93327e9f5f36dcf8692fb1e7aeaf70087c1c15d4f2c020e0be3a891"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:85bca9765c04b6be90cb46e7566ffe0faa2d7480ff5c8d5e055ac427f039fd24"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:a836610d5c75e9cff98b9fdb3559c007c785c09eaa84a60d5d10ef6f85f671e8"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef8de7a1d9fb3518cc6b58e3c80b75a824209ad52b90c542686c912db8553dad"}, + {file = "psycopg_binary-3.1.19-cp39-cp39-win_amd64.whl", hash = "sha256:76fcd33342f38e35cd6b5408f1bc117d55ab8b16e5019d99b6d3ce0356c51717"}, ] [[package]] @@ -7663,20 +7588,6 @@ asyncio-client = ["aiohttp (>=3.4)"] client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] docs = ["sphinx"] -[[package]] -name = "python-iso639" -version = "2024.4.27" -description = "ISO 639 language codes, names, and other associated information" -optional = false -python-versions = ">=3.8" -files = [ - {file = "python_iso639-2024.4.27-py3-none-any.whl", hash = "sha256:27526a84cebc4c4d53fea9d1ebbc7209c8d279bebaa343e6765a1fc8780565ab"}, - {file = "python_iso639-2024.4.27.tar.gz", hash = "sha256:97e63b5603e085c6a56a12a95740010e75d9134e0aab767e0978b53fd8824f13"}, -] - -[package.extras] -dev = ["black (==24.4.2)", "build (==1.2.1)", "flake8 (==7.0.0)", "pytest (==8.1.2)", "requests (==2.31.0)", "twine (==5.0.0)"] - [[package]] name = "python-jose" version = "3.3.0" @@ -7698,17 +7609,6 @@ cryptography = ["cryptography (>=3.4.0)"] pycrypto = ["pyasn1", "pycrypto (>=2.6.0,<2.7.0)"] pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"] -[[package]] -name = "python-magic" -version = "0.4.27" -description = "File type identification using libmagic" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, - {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, -] - [[package]] name = "python-multipart" version = "0.0.7" @@ -7963,7 +7863,10 @@ files = [ grpcio = ">=1.41.0" grpcio-tools = ">=1.41.0" httpx = {version = ">=0.20.0", extras = ["http2"]} -numpy = {version = ">=1.21", markers = "python_version >= \"3.8\" and python_version < \"3.12\""} +numpy = [ + {version = ">=1.21", markers = "python_version >= \"3.8\" and python_version < \"3.12\""}, + {version = ">=1.26", markers = "python_version >= \"3.12\""}, +] portalocker = ">=2.7.0,<3.0.0" pydantic = ">=1.10.8" urllib3 = ">=1.26.14,<3" @@ -8007,108 +7910,6 @@ all = ["emoji", "langchain (>=0.0.321)", "ltp", "sentencepiece", "torch", "torch data-clean = ["emoji", "ltp", "sentencepiece", "torch", "torch (<=1.13.1)"] langchain = ["langchain (>=0.0.321)"] -[[package]] -name = "rapidfuzz" -version = "3.9.0" -description = "rapid fuzzy string matching" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bd375c4830fee11d502dd93ecadef63c137ae88e1aaa29cc15031fa66d1e0abb"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:55e2c5076f38fc1dbaacb95fa026a3e409eee6ea5ac4016d44fb30e4cad42b20"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:488f74126904db6b1bea545c2f3567ea882099f4c13f46012fe8f4b990c683df"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3f2d1ea7cd57dfcd34821e38b4924c80a31bcf8067201b1ab07386996a9faee"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b11e602987bcb4ea22b44178851f27406fca59b0836298d0beb009b504dba266"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3083512e9bf6ed2bb3d25883922974f55e21ae7f8e9f4e298634691ae1aee583"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b33c6d4b3a1190bc0b6c158c3981535f9434e8ed9ffa40cf5586d66c1819fb4b"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcb95fde22f98e6d0480db8d6038c45fe2d18a338690e6f9bba9b82323f3469"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:08d8b49b3a4fb8572e480e73fcddc750da9cbb8696752ee12cca4bf8c8220d52"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e721842e6b601ebbeb8cc5e12c75bbdd1d9e9561ea932f2f844c418c31256e82"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7988363b3a415c5194ce1a68d380629247f8713e669ad81db7548eb156c4f365"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2d267d4c982ab7d177e994ab1f31b98ff3814f6791b90d35dda38307b9e7c989"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0bb28ab5300cf974c7eb68ea21125c493e74b35b1129e629533468b2064ae0a2"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-win32.whl", hash = "sha256:1b1f74997b6d94d66375479fa55f70b1c18e4d865d7afcd13f0785bfd40a9d3c"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:c56d2efdfaa1c642029f3a7a5bb76085c5531f7a530777be98232d2ce142553c"}, - {file = "rapidfuzz-3.9.0-cp310-cp310-win_arm64.whl", hash = "sha256:6a83128d505cac76ea560bb9afcb3f6986e14e50a6f467db9a31faef4bd9b347"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e2218d62ab63f3c5ad48eced898854d0c2c327a48f0fb02e2288d7e5332a22c8"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:36bf35df2d6c7d5820da20a6720aee34f67c15cd2daf8cf92e8141995c640c25"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:905b01a9b633394ff6bb5ebb1c5fd660e0e180c03fcf9d90199cc6ed74b87cf7"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33cfabcb7fd994938a6a08e641613ce5fe46757832edc789c6a5602e7933d6fa"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1179dcd3d150a67b8a678cd9c84f3baff7413ff13c9e8fe85e52a16c97e24c9b"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47d97e28c42f1efb7781993b67c749223f198f6653ef177a0c8f2b1c516efcaf"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28da953eb2ef9ad527e536022da7afff6ace7126cdd6f3e21ac20f8762e76d2c"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:182b4e11de928fb4834e8f8b5ecd971b5b10a86fabe8636ab65d3a9b7e0e9ca7"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c74f2da334ce597f31670db574766ddeaee5d9430c2c00e28d0fbb7f76172036"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:014ac55b03f4074f903248ded181f3000f4cdbd134e6155cbf643f0eceb4f70f"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c4ef34b2ddbf448f1d644b4ec6475df8bbe5b9d0fee173ff2e87322a151663bd"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fc02157f521af15143fae88f92ef3ddcc4e0cff05c40153a9549dc0fbdb9adb3"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ff08081c49b18ba253a99e6a47f492e6ee8019e19bbb6ddc3ed360cd3ecb2f62"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-win32.whl", hash = "sha256:b9bf90b3d96925cbf8ef44e5ee3cf39ef0c422f12d40f7a497e91febec546650"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5d5684f54d82d9b0cf0b2701e55a630527a9c3dd5ddcf7a2e726a475ac238f2"}, - {file = "rapidfuzz-3.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:a2de844e0e971d7bd8aa41284627dbeacc90e750b90acfb016836553c7a63192"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f81fe99a69ac8ee3fd905e70c62f3af033901aeb60b69317d1d43d547b46e510"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:633b9d03fc04abc585c197104b1d0af04b1f1db1abc99f674d871224cd15557a"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab872cb57ae97c54ba7c71a9e3c9552beb57cb907c789b726895576d1ea9af6f"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdd8c15c3a14e409507fdf0c0434ec481d85c6cbeec8bdcd342a8cd1eda03825"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2444d8155d9846f206e2079bb355b85f365d9457480b0d71677a112d0a7f7128"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83bd3d01f04061c3660742dc85143a89d49fd23eb31eccbf60ad56c4b955617"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ca799f882364e69d0872619afb19efa3652b7133c18352e4a3d86a324fb2bb1"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6993d361f28b9ef5f0fa4e79b8541c2f3507be7471b9f9cb403a255e123b31e1"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:170822a1b1719f02b58e3dce194c8ad7d4c5b39be38c0fdec603bd19c6f9cf81"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e86e39c1c1a0816ceda836e6f7bd3743b930cbc51a43a81bb433b552f203f25"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:731269812ea837e0b93d913648e404736407408e33a00b75741e8f27c590caa2"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8e5ff882d3a3d081157ceba7e0ebc7fac775f95b08cbb143accd4cece6043819"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2003071aa633477a01509890c895f9ef56cf3f2eaa72c7ec0b567f743c1abcba"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-win32.whl", hash = "sha256:13857f9070600ea1f940749f123b02d0b027afbaa45e72186df0f278915761d0"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:134b7098ac109834eeea81424b6822f33c4c52bf80b81508295611e7a21be12a"}, - {file = "rapidfuzz-3.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:2a96209f046fe328be30fc43f06e3d4b91f0d5b74e9dcd627dbfd65890fa4a5e"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:544b0bf9d17170720809918e9ccd0d482d4a3a6eca35630d8e1459f737f71755"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d536f8beb8dd82d6efb20fe9f82c2cfab9ffa0384b5d184327e393a4edde91d"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:30f7609da871510583f87484a10820b26555a473a90ab356cdda2f3b4456256c"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f4a2468432a1db491af6f547fad8f6d55fa03e57265c2f20e5eaceb68c7907e"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a7ec4676242c8a430509cff42ce98bca2fbe30188a63d0f60fdcbfd7e84970"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dcb523243e988c849cf81220164ec3bbed378a699e595a8914fffe80596dc49f"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4eea3bf72c4fe68e957526ffd6bcbb403a21baa6b3344aaae2d3252313df6199"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4514980a5d204c076dd5b756960f6b1b7598f030009456e6109d76c4c331d03c"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9a06a99f1335fe43464d7121bc6540de7cd9c9475ac2025babb373fe7f27846b"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6c1ed63345d1581c39d4446b1a8c8f550709656ce2a3c88c47850b258167f3c2"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cd2e6e97daf17ebb3254285cf8dd86c60d56d6cf35c67f0f9a557ef26bd66290"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:9bc0f7e6256a9c668482c41c8a3de5d0aa12e8ca346dcc427b97c7edb82cba48"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c09f4e87e82a164c9db769474bc61f8c8b677f2aeb0234b8abac73d2ecf9799"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-win32.whl", hash = "sha256:e65b8f7921bf60cbb207c132842a6b45eefef48c4c3b510eb16087d6c08c70af"}, - {file = "rapidfuzz-3.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9d6478957fb35c7844ad08f2442b62ba76c1857a56370781a707eefa4f4981e1"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:65d9250a4b0bf86320097306084bc3ca479c8f5491927c170d018787793ebe95"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47b7c0840afa724db3b1a070bc6ed5beab73b4e659b1d395023617fc51bf68a2"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a16c48c6df8fb633efbbdea744361025d01d79bca988f884a620e63e782fe5b"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48105991ff6e4a51c7f754df500baa070270ed3d41784ee0d097549bc9fcb16d"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a7f273906b3c7cc6d63a76e088200805947aa0bc1ada42c6a0e582e19c390d7"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c396562d304e974b4b0d5cd3afc4f92c113ea46a36e6bc62e45333d6aa8837e"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68da1b70458fea5290ec9a169fcffe0c17ff7e5bb3c3257e63d7021a50601a8e"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c5b8f9a7b177af6ce7c6ad5b95588b4b73e37917711aafa33b2e79ee80fe709"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3c42a238bf9dd48f4ccec4c6934ac718225b00bb3a438a008c219e7ccb3894c7"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a365886c42177b2beab475a50ba311b59b04f233ceaebc4c341f6f91a86a78e2"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ce897b5dafb7fb7587a95fe4d449c1ea0b6d9ac4462fbafefdbbeef6eee4cf6a"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:413ac49bae291d7e226a5c9be65c71b2630b3346bce39268d02cb3290232e4b7"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8982fc3bd49d55a91569fc8a3feba0de4cef0b391ff9091be546e9df075b81"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-win32.whl", hash = "sha256:3904d0084ab51f82e9f353031554965524f535522a48ec75c30b223eb5a0a488"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:3733aede16ea112728ffeafeb29ccc62e095ed8ec816822fa2a82e92e2c08696"}, - {file = "rapidfuzz-3.9.0-cp39-cp39-win_arm64.whl", hash = "sha256:fc4e26f592b51f97acf0a3f8dfed95e4d830c6a8fbf359361035df836381ab81"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e33362e98c7899b5f60dcb06ada00acd8673ce0d59aefe9a542701251fd00423"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb67cf43ad83cb886cbbbff4df7dcaad7aedf94d64fca31aea0da7d26684283c"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2e106cc66453bb80d2ad9c0044f8287415676df5c8036d737d05d4b9cdbf8e"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1256915f7e7a5cf2c151c9ac44834b37f9bd1c97e8dec6f936884f01b9dfc7d"}, - {file = "rapidfuzz-3.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ae643220584518cbff8bf2974a0494d3e250763af816b73326a512c86ae782ce"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:491274080742110427f38a6085bb12dffcaff1eef12dccf9e8758398c7e3957e"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bc5559b9b94326922c096b30ae2d8e5b40b2e9c2c100c2cc396ad91bcb84d30"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:849160dc0f128acb343af514ca827278005c1d00148d025e4035e034fc2d8c7f"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:623883fb78e692d54ed7c43b09beec52c6685f10a45a7518128e25746667403b"}, - {file = "rapidfuzz-3.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d20ab9abc7e19767f1951772a6ab14cb4eddd886493c2da5ee12014596ad253f"}, - {file = "rapidfuzz-3.9.0.tar.gz", hash = "sha256:b182f0fb61f6ac435e416eb7ab330d62efdbf9b63cf0c7fa12d1f57c2eaaf6f3"}, -] - -[package.extras] -full = ["numpy"] - [[package]] name = "realtime" version = "1.0.4" @@ -8155,90 +7956,90 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "regex" -version = "2024.4.28" +version = "2024.5.10" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd196d056b40af073d95a2879678585f0b74ad35190fac04ca67954c582c6b61"}, - {file = "regex-2024.4.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8bb381f777351bd534462f63e1c6afb10a7caa9fa2a421ae22c26e796fe31b1f"}, - {file = "regex-2024.4.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:47af45b6153522733aa6e92543938e97a70ce0900649ba626cf5aad290b737b6"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99d6a550425cc51c656331af0e2b1651e90eaaa23fb4acde577cf15068e2e20f"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf29304a8011feb58913c382902fde3395957a47645bf848eea695839aa101b7"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:92da587eee39a52c91aebea8b850e4e4f095fe5928d415cb7ed656b3460ae79a"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6277d426e2f31bdbacb377d17a7475e32b2d7d1f02faaecc48d8e370c6a3ff31"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28e1f28d07220c0f3da0e8fcd5a115bbb53f8b55cecf9bec0c946eb9a059a94c"}, - {file = "regex-2024.4.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:aaa179975a64790c1f2701ac562b5eeb733946eeb036b5bcca05c8d928a62f10"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6f435946b7bf7a1b438b4e6b149b947c837cb23c704e780c19ba3e6855dbbdd3"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:19d6c11bf35a6ad077eb23852827f91c804eeb71ecb85db4ee1386825b9dc4db"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:fdae0120cddc839eb8e3c15faa8ad541cc6d906d3eb24d82fb041cfe2807bc1e"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e672cf9caaf669053121f1766d659a8813bd547edef6e009205378faf45c67b8"}, - {file = "regex-2024.4.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f57515750d07e14743db55d59759893fdb21d2668f39e549a7d6cad5d70f9fea"}, - {file = "regex-2024.4.28-cp310-cp310-win32.whl", hash = "sha256:a1409c4eccb6981c7baabc8888d3550df518add6e06fe74fa1d9312c1838652d"}, - {file = "regex-2024.4.28-cp310-cp310-win_amd64.whl", hash = "sha256:1f687a28640f763f23f8a9801fe9e1b37338bb1ca5d564ddd41619458f1f22d1"}, - {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84077821c85f222362b72fdc44f7a3a13587a013a45cf14534df1cbbdc9a6796"}, - {file = "regex-2024.4.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45d4503de8f4f3dc02f1d28a9b039e5504a02cc18906cfe744c11def942e9eb"}, - {file = "regex-2024.4.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:457c2cd5a646dd4ed536c92b535d73548fb8e216ebee602aa9f48e068fc393f3"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b51739ddfd013c6f657b55a508de8b9ea78b56d22b236052c3a85a675102dc6"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:459226445c7d7454981c4c0ce0ad1a72e1e751c3e417f305722bbcee6697e06a"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:670fa596984b08a4a769491cbdf22350431970d0112e03d7e4eeaecaafcd0fec"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe00f4fe11c8a521b173e6324d862ee7ee3412bf7107570c9b564fe1119b56fb"}, - {file = "regex-2024.4.28-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36f392dc7763fe7924575475736bddf9ab9f7a66b920932d0ea50c2ded2f5636"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:23a412b7b1a7063f81a742463f38821097b6a37ce1e5b89dd8e871d14dbfd86b"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f1d6e4b7b2ae3a6a9df53efbf199e4bfcff0959dbdb5fd9ced34d4407348e39a"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:499334ad139557de97cbc4347ee921c0e2b5e9c0f009859e74f3f77918339257"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:0940038bec2fe9e26b203d636c44d31dd8766abc1fe66262da6484bd82461ccf"}, - {file = "regex-2024.4.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:66372c2a01782c5fe8e04bff4a2a0121a9897e19223d9eab30c54c50b2ebeb7f"}, - {file = "regex-2024.4.28-cp311-cp311-win32.whl", hash = "sha256:c77d10ec3c1cf328b2f501ca32583625987ea0f23a0c2a49b37a39ee5c4c4630"}, - {file = "regex-2024.4.28-cp311-cp311-win_amd64.whl", hash = "sha256:fc0916c4295c64d6890a46e02d4482bb5ccf33bf1a824c0eaa9e83b148291f90"}, - {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:08a1749f04fee2811c7617fdd46d2e46d09106fa8f475c884b65c01326eb15c5"}, - {file = "regex-2024.4.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b8eb28995771c087a73338f695a08c9abfdf723d185e57b97f6175c5051ff1ae"}, - {file = "regex-2024.4.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd7ef715ccb8040954d44cfeff17e6b8e9f79c8019daae2fd30a8806ef5435c0"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb0315a2b26fde4005a7c401707c5352df274460f2f85b209cf6024271373013"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2fc053228a6bd3a17a9b0a3f15c3ab3cf95727b00557e92e1cfe094b88cc662"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fe9739a686dc44733d52d6e4f7b9c77b285e49edf8570754b322bca6b85b4cc"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74fcf77d979364f9b69fcf8200849ca29a374973dc193a7317698aa37d8b01c"}, - {file = "regex-2024.4.28-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:965fd0cf4694d76f6564896b422724ec7b959ef927a7cb187fc6b3f4e4f59833"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2fef0b38c34ae675fcbb1b5db760d40c3fc3612cfa186e9e50df5782cac02bcd"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bc365ce25f6c7c5ed70e4bc674f9137f52b7dd6a125037f9132a7be52b8a252f"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ac69b394764bb857429b031d29d9604842bc4cbfd964d764b1af1868eeebc4f0"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:144a1fc54765f5c5c36d6d4b073299832aa1ec6a746a6452c3ee7b46b3d3b11d"}, - {file = "regex-2024.4.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2630ca4e152c221072fd4a56d4622b5ada876f668ecd24d5ab62544ae6793ed6"}, - {file = "regex-2024.4.28-cp312-cp312-win32.whl", hash = "sha256:7f3502f03b4da52bbe8ba962621daa846f38489cae5c4a7b5d738f15f6443d17"}, - {file = "regex-2024.4.28-cp312-cp312-win_amd64.whl", hash = "sha256:0dd3f69098511e71880fb00f5815db9ed0ef62c05775395968299cb400aeab82"}, - {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:374f690e1dd0dbdcddea4a5c9bdd97632cf656c69113f7cd6a361f2a67221cb6"}, - {file = "regex-2024.4.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f87ae6b96374db20f180eab083aafe419b194e96e4f282c40191e71980c666"}, - {file = "regex-2024.4.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5dbc1bcc7413eebe5f18196e22804a3be1bfdfc7e2afd415e12c068624d48247"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f85151ec5a232335f1be022b09fbbe459042ea1951d8a48fef251223fc67eee1"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57ba112e5530530fd175ed550373eb263db4ca98b5f00694d73b18b9a02e7185"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:224803b74aab56aa7be313f92a8d9911dcade37e5f167db62a738d0c85fdac4b"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54a047b607fd2d2d52a05e6ad294602f1e0dec2291152b745870afc47c1397"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a2a512d623f1f2d01d881513af9fc6a7c46e5cfffb7dc50c38ce959f9246c94"}, - {file = "regex-2024.4.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c06bf3f38f0707592898428636cbb75d0a846651b053a1cf748763e3063a6925"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1031a5e7b048ee371ab3653aad3030ecfad6ee9ecdc85f0242c57751a05b0ac4"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7a353ebfa7154c871a35caca7bfd8f9e18666829a1dc187115b80e35a29393e"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7e76b9cfbf5ced1aca15a0e5b6f229344d9b3123439ffce552b11faab0114a02"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5ce479ecc068bc2a74cb98dd8dba99e070d1b2f4a8371a7dfe631f85db70fe6e"}, - {file = "regex-2024.4.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d77b6f63f806578c604dca209280e4c54f0fa9a8128bb8d2cc5fb6f99da4150"}, - {file = "regex-2024.4.28-cp38-cp38-win32.whl", hash = "sha256:d84308f097d7a513359757c69707ad339da799e53b7393819ec2ea36bc4beb58"}, - {file = "regex-2024.4.28-cp38-cp38-win_amd64.whl", hash = "sha256:2cc1b87bba1dd1a898e664a31012725e48af826bf3971e786c53e32e02adae6c"}, - {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7413167c507a768eafb5424413c5b2f515c606be5bb4ef8c5dee43925aa5718b"}, - {file = "regex-2024.4.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:108e2dcf0b53a7c4ab8986842a8edcb8ab2e59919a74ff51c296772e8e74d0ae"}, - {file = "regex-2024.4.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f1c5742c31ba7d72f2dedf7968998730664b45e38827637e0f04a2ac7de2f5f1"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecc6148228c9ae25ce403eade13a0961de1cb016bdb35c6eafd8e7b87ad028b1"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7d893c8cf0e2429b823ef1a1d360a25950ed11f0e2a9df2b5198821832e1947"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4290035b169578ffbbfa50d904d26bec16a94526071ebec3dadbebf67a26b25e"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44a22ae1cfd82e4ffa2066eb3390777dc79468f866f0625261a93e44cdf6482b"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd24fd140b69f0b0bcc9165c397e9b2e89ecbeda83303abf2a072609f60239e2"}, - {file = "regex-2024.4.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:39fb166d2196413bead229cd64a2ffd6ec78ebab83fff7d2701103cf9f4dfd26"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9301cc6db4d83d2c0719f7fcda37229691745168bf6ae849bea2e85fc769175d"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7c3d389e8d76a49923683123730c33e9553063d9041658f23897f0b396b2386f"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:99ef6289b62042500d581170d06e17f5353b111a15aa6b25b05b91c6886df8fc"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b91d529b47798c016d4b4c1d06cc826ac40d196da54f0de3c519f5a297c5076a"}, - {file = "regex-2024.4.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:43548ad74ea50456e1c68d3c67fff3de64c6edb85bcd511d1136f9b5376fc9d1"}, - {file = "regex-2024.4.28-cp39-cp39-win32.whl", hash = "sha256:05d9b6578a22db7dedb4df81451f360395828b04f4513980b6bd7a1412c679cc"}, - {file = "regex-2024.4.28-cp39-cp39-win_amd64.whl", hash = "sha256:3986217ec830c2109875be740531feb8ddafe0dfa49767cdcd072ed7e8927962"}, - {file = "regex-2024.4.28.tar.gz", hash = "sha256:83ab366777ea45d58f72593adf35d36ca911ea8bd838483c1823b883a121b0e4"}, + {file = "regex-2024.5.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eda3dd46df535da787ffb9036b5140f941ecb91701717df91c9daf64cabef953"}, + {file = "regex-2024.5.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1d5bd666466c8f00a06886ce1397ba8b12371c1f1c6d1bef11013e9e0a1464a8"}, + {file = "regex-2024.5.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32e5f3b8e32918bfbdd12eca62e49ab3031125c454b507127ad6ecbd86e62fca"}, + {file = "regex-2024.5.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:534efd2653ebc4f26fc0e47234e53bf0cb4715bb61f98c64d2774a278b58c846"}, + {file = "regex-2024.5.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:193b7c6834a06f722f0ce1ba685efe80881de7c3de31415513862f601097648c"}, + {file = "regex-2024.5.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:160ba087232c5c6e2a1e7ad08bd3a3f49b58c815be0504d8c8aacfb064491cd8"}, + {file = "regex-2024.5.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:951be1eae7b47660412dc4938777a975ebc41936d64e28081bf2e584b47ec246"}, + {file = "regex-2024.5.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8a0f0ab5453e409586b11ebe91c672040bc804ca98d03a656825f7890cbdf88"}, + {file = "regex-2024.5.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9e6d4d6ae1827b2f8c7200aaf7501c37cf3f3896c86a6aaf2566448397c823dd"}, + {file = "regex-2024.5.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:161a206c8f3511e2f5fafc9142a2cc25d7fe9a1ec5ad9b4ad2496a7c33e1c5d2"}, + {file = "regex-2024.5.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:44b3267cea873684af022822195298501568ed44d542f9a2d9bebc0212e99069"}, + {file = "regex-2024.5.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:560278c9975694e1f0bc50da187abf2cdc1e4890739ea33df2bc4a85eeef143e"}, + {file = "regex-2024.5.10-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:70364a097437dd0a90b31cd77f09f7387ad9ac60ef57590971f43b7fca3082a5"}, + {file = "regex-2024.5.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:42be5de7cc8c1edac55db92d82b68dc8e683b204d6f5414c5a51997a323d7081"}, + {file = "regex-2024.5.10-cp310-cp310-win32.whl", hash = "sha256:9a8625849387b9d558d528e263ecc9c0fbde86cfa5c2f0eef43fff480ae24d71"}, + {file = "regex-2024.5.10-cp310-cp310-win_amd64.whl", hash = "sha256:903350bf44d7e4116b4d5898b30b15755d61dcd3161e3413a49c7db76f0bee5a"}, + {file = "regex-2024.5.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bf9596cba92ce7b1fd32c7b07c6e3212c7eed0edc271757e48bfcd2b54646452"}, + {file = "regex-2024.5.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:45cc13d398b6359a7708986386f72bd156ae781c3e83a68a6d4cee5af04b1ce9"}, + {file = "regex-2024.5.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ad45f3bccfcb00868f2871dce02a755529838d2b86163ab8a246115e80cfb7d6"}, + {file = "regex-2024.5.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33d19f0cde6838c81acffff25c7708e4adc7dd02896c9ec25c3939b1500a1778"}, + {file = "regex-2024.5.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a9f89d7db5ef6bdf53e5cc8e6199a493d0f1374b3171796b464a74ebe8e508a"}, + {file = "regex-2024.5.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c6c71cf92b09e5faa72ea2c68aa1f61c9ce11cb66fdc5069d712f4392ddfd00"}, + {file = "regex-2024.5.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7467ad8b0eac0b28e52679e972b9b234b3de0ea5cee12eb50091d2b68145fe36"}, + {file = "regex-2024.5.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc0db93ad039fc2fe32ccd3dd0e0e70c4f3d6e37ae83f0a487e1aba939bd2fbd"}, + {file = "regex-2024.5.10-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fa9335674d7c819674467c7b46154196c51efbaf5f5715187fd366814ba3fa39"}, + {file = "regex-2024.5.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7dda3091838206969c2b286f9832dff41e2da545b99d1cfaea9ebd8584d02708"}, + {file = "regex-2024.5.10-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:504b5116e2bd1821efd815941edff7535e93372a098e156bb9dffde30264e798"}, + {file = "regex-2024.5.10-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:91b53dea84415e8115506cc62e441a2b54537359c63d856d73cb1abe05af4c9a"}, + {file = "regex-2024.5.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1a3903128f9e17a500618e80c68165c78c741ebb17dd1a0b44575f92c3c68b02"}, + {file = "regex-2024.5.10-cp311-cp311-win32.whl", hash = "sha256:236cace6c1903effd647ed46ce6dd5d76d54985fc36dafc5256032886736c85d"}, + {file = "regex-2024.5.10-cp311-cp311-win_amd64.whl", hash = "sha256:12446827f43c7881decf2c126762e11425de5eb93b3b0d8b581344c16db7047a"}, + {file = "regex-2024.5.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:14905ed75c7a6edf423eb46c213ed3f4507c38115f1ed3c00f4ec9eafba50e58"}, + {file = "regex-2024.5.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4fad420b14ae1970a1f322e8ae84a1d9d89375eb71e1b504060ab2d1bfe68f3c"}, + {file = "regex-2024.5.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c46a76a599fcbf95f98755275c5527304cc4f1bb69919434c1e15544d7052910"}, + {file = "regex-2024.5.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0faecb6d5779753a6066a3c7a0471a8d29fe25d9981ca9e552d6d1b8f8b6a594"}, + {file = "regex-2024.5.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aab65121229c2ecdf4a31b793d99a6a0501225bd39b616e653c87b219ed34a49"}, + {file = "regex-2024.5.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50e7e96a527488334379e05755b210b7da4a60fc5d6481938c1fa053e0c92184"}, + {file = "regex-2024.5.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba034c8db4b264ef1601eb33cd23d87c5013b8fb48b8161debe2e5d3bd9156b0"}, + {file = "regex-2024.5.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:031219782d97550c2098d9a68ce9e9eaefe67d2d81d8ff84c8354f9c009e720c"}, + {file = "regex-2024.5.10-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62b5f7910b639f3c1d122d408421317c351e213ca39c964ad4121f27916631c6"}, + {file = "regex-2024.5.10-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cd832bd9b6120d6074f39bdfbb3c80e416848b07ac72910f1c7f03131a6debc3"}, + {file = "regex-2024.5.10-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:e91b1976358e17197157b405cab408a5f4e33310cda211c49fc6da7cffd0b2f0"}, + {file = "regex-2024.5.10-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:571452362d552de508c37191b6abbbb660028b8b418e2d68c20779e0bc8eaaa8"}, + {file = "regex-2024.5.10-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5253dcb0bfda7214523de58b002eb0090cb530d7c55993ce5f6d17faf953ece7"}, + {file = "regex-2024.5.10-cp312-cp312-win32.whl", hash = "sha256:2f30a5ab8902f93930dc6f627c4dd5da2703333287081c85cace0fc6e21c25af"}, + {file = "regex-2024.5.10-cp312-cp312-win_amd64.whl", hash = "sha256:3799e36d60a35162bb35b2246d8bb012192b7437dff807ef79c14e7352706306"}, + {file = "regex-2024.5.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bbdc5db2c98ac2bf1971ffa1410c87ca7a15800415f788971e8ba8520fc0fda9"}, + {file = "regex-2024.5.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6ccdeef4584450b6f0bddd5135354908dacad95425fcb629fe36d13e48b60f32"}, + {file = "regex-2024.5.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:29d839829209f3c53f004e1de8c3113efce6d98029f044fa5cfee666253ee7e6"}, + {file = "regex-2024.5.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0709ba544cf50bd5cb843df4b8bb6701bae2b70a8e88da9add8386cbca5c1385"}, + {file = "regex-2024.5.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:972b49f2fe1047b9249c958ec4fa1bdd2cf8ce305dc19d27546d5a38e57732d8"}, + {file = "regex-2024.5.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cdbb1998da94607d5eec02566b9586f0e70d6438abf1b690261aac0edda7ab6"}, + {file = "regex-2024.5.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf7c8ee4861d9ef5b1120abb75846828c811f932d63311596ad25fa168053e00"}, + {file = "regex-2024.5.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d35d4cc9270944e95f9c88af757b0c9fc43f396917e143a5756608462c5223b"}, + {file = "regex-2024.5.10-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8722f72068b3e1156a4b2e1afde6810f1fc67155a9fa30a4b9d5b4bc46f18fb0"}, + {file = "regex-2024.5.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:696639a73ca78a380acfaa0a1f6dd8220616a99074c05bba9ba8bb916914b224"}, + {file = "regex-2024.5.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea057306ab469130167014b662643cfaed84651c792948891d003cf0039223a5"}, + {file = "regex-2024.5.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b43b78f9386d3d932a6ce5af4b45f393d2e93693ee18dc4800d30a8909df700e"}, + {file = "regex-2024.5.10-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c43395a3b7cc9862801a65c6994678484f186ce13c929abab44fb8a9e473a55a"}, + {file = "regex-2024.5.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0bc94873ba11e34837bffd7e5006703abeffc4514e2f482022f46ce05bd25e67"}, + {file = "regex-2024.5.10-cp38-cp38-win32.whl", hash = "sha256:1118ba9def608250250f4b3e3f48c62f4562ba16ca58ede491b6e7554bfa09ff"}, + {file = "regex-2024.5.10-cp38-cp38-win_amd64.whl", hash = "sha256:458d68d34fb74b906709735c927c029e62f7d06437a98af1b5b6258025223210"}, + {file = "regex-2024.5.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:15e593386ec6331e0ab4ac0795b7593f02ab2f4b30a698beb89fbdc34f92386a"}, + {file = "regex-2024.5.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ca23b41355ba95929e9505ee04e55495726aa2282003ed9b012d86f857d3e49b"}, + {file = "regex-2024.5.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c8982ee19ccecabbaeac1ba687bfef085a6352a8c64f821ce2f43e6d76a9298"}, + {file = "regex-2024.5.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7117cb7d6ac7f2e985f3d18aa8a1728864097da1a677ffa69e970ca215baebf1"}, + {file = "regex-2024.5.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b66421f8878a0c82fc0c272a43e2121c8d4c67cb37429b764f0d5ad70b82993b"}, + {file = "regex-2024.5.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:224a9269f133564109ce668213ef3cb32bc72ccf040b0b51c72a50e569e9dc9e"}, + {file = "regex-2024.5.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab98016541543692a37905871a5ffca59b16e08aacc3d7d10a27297b443f572d"}, + {file = "regex-2024.5.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51d27844763c273a122e08a3e86e7aefa54ee09fb672d96a645ece0454d8425e"}, + {file = "regex-2024.5.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:853cc36e756ff673bf984e9044ccc8fad60b95a748915dddeab9488aea974c73"}, + {file = "regex-2024.5.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4e7eaf9df15423d07b6050fb91f86c66307171b95ea53e2d87a7993b6d02c7f7"}, + {file = "regex-2024.5.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:169fd0acd7a259f58f417e492e93d0e15fc87592cd1e971c8c533ad5703b5830"}, + {file = "regex-2024.5.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:334b79ce9c08f26b4659a53f42892793948a613c46f1b583e985fd5a6bf1c149"}, + {file = "regex-2024.5.10-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f03b1dbd4d9596dd84955bb40f7d885204d6aac0d56a919bb1e0ff2fb7e1735a"}, + {file = "regex-2024.5.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfa6d61a76c77610ba9274c1a90a453062bdf6887858afbe214d18ad41cf6bde"}, + {file = "regex-2024.5.10-cp39-cp39-win32.whl", hash = "sha256:249fbcee0a277c32a3ce36d8e36d50c27c968fdf969e0fbe342658d4e010fbc8"}, + {file = "regex-2024.5.10-cp39-cp39-win_amd64.whl", hash = "sha256:0ce56a923f4c01d7568811bfdffe156268c0a7aae8a94c902b92fe34c4bde785"}, + {file = "regex-2024.5.10.tar.gz", hash = "sha256:304e7e2418146ae4d0ef0e9ffa28f881f7874b45b4994cc2279b21b6e7ae50c8"}, ] [[package]] @@ -8811,7 +8612,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", optional = true, markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\" or extra == \"asyncio\""} +greenlet = {version = "!=0.4.17", optional = true, markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\" or extra == \"asyncio\""} typing-extensions = ">=4.6.0" [package.extras] @@ -8997,20 +8798,6 @@ files = [ [package.dependencies] mpmath = ">=0.19" -[[package]] -name = "tabulate" -version = "0.9.0" -description = "Pretty-print tabular data" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, - {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, -] - -[package.extras] -widechars = ["wcwidth"] - [[package]] name = "tbb" version = "2021.12.0" @@ -9792,130 +9579,6 @@ files = [ {file = "ujson-5.9.0.tar.gz", hash = "sha256:89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532"}, ] -[[package]] -name = "unstructured" -version = "0.12.5" -description = "A library that prepares raw documents for downstream ML tasks." -optional = false -python-versions = ">=3.9.0,<3.12" -files = [ - {file = "unstructured-0.12.5-py3-none-any.whl", hash = "sha256:cce7de36964f556810adb8728d0639d8e9b3ef4567443877609f3c66a54e24d1"}, - {file = "unstructured-0.12.5.tar.gz", hash = "sha256:5ea6c881049e7d98a88c07192bcb6ab750de41b4e3b594972ed1034bda99dbae"}, -] - -[package.dependencies] -backoff = "*" -beautifulsoup4 = "*" -chardet = "*" -dataclasses-json = "*" -emoji = "*" -filetype = "*" -langdetect = "*" -lxml = "*" -markdown = {version = "*", optional = true, markers = "extra == \"md\""} -nltk = "*" -numpy = "*" -python-iso639 = "*" -python-magic = "*" -rapidfuzz = "*" -requests = "*" -tabulate = "*" -typing-extensions = "*" -unstructured-client = ">=0.15.1" -wrapt = "*" - -[package.extras] -airtable = ["pyairtable"] -all-docs = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "python-docx", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.23)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -astra = ["astrapy"] -azure = ["adlfs", "fsspec"] -azure-cognitive-search = ["azure-search-documents"] -bedrock = ["boto3", "langchain-community"] -biomed = ["bs4"] -box = ["boxfs", "fsspec"] -chroma = ["chromadb"] -confluence = ["atlassian-python-api"] -csv = ["pandas"] -databricks-volumes = ["databricks-sdk"] -delta-table = ["deltalake", "fsspec"] -discord = ["discord-py"] -doc = ["python-docx"] -docx = ["python-docx"] -dropbox = ["dropboxdrivefs", "fsspec"] -elasticsearch = ["elasticsearch"] -embed-huggingface = ["huggingface", "langchain-community", "sentence-transformers"] -epub = ["pypandoc"] -gcs = ["bs4", "fsspec", "gcsfs"] -github = ["pygithub (>1.58.0)"] -gitlab = ["python-gitlab"] -google-drive = ["google-api-python-client"] -hubspot = ["hubspot-api-client", "urllib3"] -huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"] -image = ["onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "unstructured-inference (==0.7.23)", "unstructured.pytesseract (>=0.3.12)"] -jira = ["atlassian-python-api"] -local-inference = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "python-docx", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.23)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -md = ["markdown"] -mongodb = ["pymongo"] -msg = ["msg-parser"] -notion = ["htmlBuilder", "notion-client"] -odt = ["pypandoc", "python-docx"] -onedrive = ["Office365-REST-Python-Client", "bs4", "msal"] -openai = ["langchain-community", "openai", "tiktoken"] -opensearch = ["opensearch-py"] -org = ["pypandoc"] -outlook = ["Office365-REST-Python-Client", "msal"] -paddleocr = ["unstructured.paddleocr (==2.6.1.3)"] -pdf = ["onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "unstructured-inference (==0.7.23)", "unstructured.pytesseract (>=0.3.12)"] -pinecone = ["pinecone-client (==2.2.4)"] -postgres = ["psycopg2-binary"] -ppt = ["python-pptx (<=0.6.23)"] -pptx = ["python-pptx (<=0.6.23)"] -qdrant = ["qdrant-client"] -reddit = ["praw"] -rst = ["pypandoc"] -rtf = ["pypandoc"] -s3 = ["fsspec", "s3fs"] -salesforce = ["simple-salesforce"] -sftp = ["fsspec", "paramiko"] -sharepoint = ["Office365-REST-Python-Client", "msal"] -slack = ["slack-sdk"] -tsv = ["pandas"] -weaviate = ["weaviate-client"] -wikipedia = ["wikipedia"] -xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] - -[[package]] -name = "unstructured-client" -version = "0.22.0" -description = "Python Client SDK for Unstructured API" -optional = false -python-versions = ">=3.8" -files = [ - {file = "unstructured-client-0.22.0.tar.gz", hash = "sha256:d76351c456fcf4067f59135c09a35008a120103621a1ac94cf9448db28ef2e1e"}, - {file = "unstructured_client-0.22.0-py3-none-any.whl", hash = "sha256:140f7dd8515cc9be3276f66d6fb08d235ea35a50d4eb38a6ef82b60fc3d2fea0"}, -] - -[package.dependencies] -certifi = ">=2023.7.22" -charset-normalizer = ">=3.2.0" -dataclasses-json = ">=0.6.4" -deepdiff = ">=6.0" -idna = ">=3.4" -jsonpath-python = ">=1.0.6" -marshmallow = ">=3.19.0" -mypy-extensions = ">=1.0.0" -packaging = ">=23.1" -pypdf = ">=4.0" -python-dateutil = ">=2.8.2" -requests = ">=2.31.0" -six = ">=1.16.0" -typing-extensions = ">=4.7.1" -typing-inspect = ">=0.9.0" -urllib3 = ">=1.26.18" - -[package.extras] -dev = ["pylint (==2.16.2)"] - [[package]] name = "uritemplate" version = "4.1.1" @@ -10156,13 +9819,13 @@ files = [ [[package]] name = "weaviate-client" -version = "4.5.7" +version = "4.6.0" description = "A python native Weaviate client" optional = false python-versions = ">=3.8" files = [ - {file = "weaviate_client-4.5.7-py3-none-any.whl", hash = "sha256:97958050d215ab64d702e5dd29206c4b855a3372d3ae22f784287a2d0ed085dc"}, - {file = "weaviate_client-4.5.7.tar.gz", hash = "sha256:130f7371c4af31949e6f3537683813f0e5adb7ec94a5536e2278768c5fe057bf"}, + {file = "weaviate_client-4.6.0-py3-none-any.whl", hash = "sha256:4c9608ba5d495d1fe28e451aca057086cb55242bb8432bfb0008f433eef7a6ab"}, + {file = "weaviate_client-4.6.0.tar.gz", hash = "sha256:5cc6c8b2a6f9122b34ffa688070e5060ab044fe72a4a9233eb9938c6067866b8"}, ] [package.dependencies] @@ -10747,5 +10410,5 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" -python-versions = ">=3.10,<3.12" -content-hash = "d3ac1c13a79e0c368642bacb2907061361b7865b5136fdc969f5f5a28c7d2322" +python-versions = ">=3.10,<3.13" +content-hash = "1e59b887d9cef40cd980e2cb698c48e135911400176d8bef1012ddc8853e420a" diff --git a/pyproject.toml b/pyproject.toml index dbfcee43b..282980cbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ langflow = "langflow.__main__:main" [tool.poetry.dependencies] -python = ">=3.10,<3.12" +python = ">=3.10,<3.13" langflow-base = { path = "./src/backend/base", develop = true } beautifulsoup4 = "^4.12.2" google-search-results = "^2.4.1" @@ -72,7 +72,7 @@ langchain-cohere = "^0.1.0rc1" elasticsearch = "^8.12.0" pytube = "^15.0.0" llama-index = "^0.10.13" -unstructured = { extras = ["md"], version = "^0.12.4" } +# unstructured = { extras = ["md"], version = "^0.12.4" } dspy-ai = "^2.4.0" html2text = "^2024.2.26" assemblyai = "^0.23.1" @@ -85,7 +85,7 @@ zep-python = { version = "^2.0.0rc5", allow-prereleases = true } langchain-google-vertexai = "^1.0.3" langchain-groq = "^0.1.3" langchain-pinecone = "^0.1.0" -langchain-mistralai ="^0.1.6" +langchain-mistralai = "^0.1.6" [tool.poetry.group.dev.dependencies] diff --git a/src/backend/base/langflow/__main__.py b/src/backend/base/langflow/__main__.py index 925e6a7a1..4e09b8ee5 100644 --- a/src/backend/base/langflow/__main__.py +++ b/src/backend/base/langflow/__main__.py @@ -4,6 +4,7 @@ import sys import time from pathlib import Path from typing import Optional +import warnings import click import httpx @@ -468,7 +469,9 @@ def migration( def main(): - app() + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + app() if __name__ == "__main__": diff --git a/src/backend/base/langflow/api/v1/flows.py b/src/backend/base/langflow/api/v1/flows.py index bd055f120..bafd1c08b 100644 --- a/src/backend/base/langflow/api/v1/flows.py +++ b/src/backend/base/langflow/api/v1/flows.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from typing import List from uuid import UUID @@ -33,7 +33,7 @@ def create_flow( flow.user_id = current_user.id db_flow = Flow.model_validate(flow, from_attributes=True) - db_flow.updated_at = datetime.utcnow() + db_flow.updated_at = datetime.now(timezone.utc) session.add(db_flow) session.commit() @@ -128,7 +128,7 @@ def update_flow( for key, value in flow_data.items(): if value is not None: setattr(db_flow, key, value) - db_flow.updated_at = datetime.utcnow() + db_flow.updated_at = datetime.now(timezone.utc) session.add(db_flow) session.commit() session.refresh(db_flow) diff --git a/src/backend/base/langflow/api/v1/schemas.py b/src/backend/base/langflow/api/v1/schemas.py index 1a68dcc8f..9558ac8c5 100644 --- a/src/backend/base/langflow/api/v1/schemas.py +++ b/src/backend/base/langflow/api/v1/schemas.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from enum import Enum from pathlib import Path from typing import Any, Dict, List, Optional, Union @@ -250,7 +250,7 @@ class VertexBuildResponse(BaseModel): """JSON string of the params.""" data: ResultDataResponse """Mapping of vertex ids to result dict containing the param name and result value.""" - timestamp: Optional[datetime] = Field(default_factory=datetime.utcnow) + timestamp: Optional[datetime] = Field(default_factory=lambda: datetime.now(timezone.utc)) """Timestamp of the build.""" diff --git a/src/backend/base/langflow/base/data/utils.py b/src/backend/base/langflow/base/data/utils.py index 09169393b..7026d4968 100644 --- a/src/backend/base/langflow/base/data/utils.py +++ b/src/backend/base/langflow/base/data/utils.py @@ -67,23 +67,25 @@ def retrieve_file_paths( return file_paths -def partition_file_to_record(file_path: str, silent_errors: bool) -> Optional[Record]: - # Use the partition function to load the file - from unstructured.partition.auto import partition # type: ignore +# ! Removing unstructured dependency until +# ! 3.12 is supported +# def partition_file_to_record(file_path: str, silent_errors: bool) -> Optional[Record]: +# # Use the partition function to load the file +# from unstructured.partition.auto import partition # type: ignore - try: - elements = partition(file_path) - except Exception as e: - if not silent_errors: - raise ValueError(f"Error loading file {file_path}: {e}") from e - return None +# try: +# elements = partition(file_path) +# except Exception as e: +# if not silent_errors: +# raise ValueError(f"Error loading file {file_path}: {e}") from e +# return None - # Create a Record - text = "\n\n".join([Text(el) for el in elements]) - metadata = elements.metadata if hasattr(elements, "metadata") else {} - metadata["file_path"] = file_path - record = Record(text=text, data=metadata) - return record +# # Create a Record +# text = "\n\n".join([Text(el) for el in elements]) +# metadata = elements.metadata if hasattr(elements, "metadata") else {} +# metadata["file_path"] = file_path +# record = Record(text=text, data=metadata) +# return record def read_text_file(file_path: str) -> str: @@ -131,18 +133,20 @@ def parse_text_file_to_record(file_path: str, silent_errors: bool) -> Optional[R return record -def get_elements( - file_paths: List[str], - silent_errors: bool, - max_concurrency: int, - use_multithreading: bool, -) -> List[Optional[Record]]: - if use_multithreading: - records = parallel_load_records(file_paths, silent_errors, max_concurrency) - else: - records = [partition_file_to_record(file_path, silent_errors) for file_path in file_paths] - records = list(filter(None, records)) - return records +# ! Removing unstructured dependency until +# ! 3.12 is supported +# def get_elements( +# file_paths: List[str], +# silent_errors: bool, +# max_concurrency: int, +# use_multithreading: bool, +# ) -> List[Optional[Record]]: +# if use_multithreading: +# records = parallel_load_records(file_paths, silent_errors, max_concurrency) +# else: +# records = [partition_file_to_record(file_path, silent_errors) for file_path in file_paths] +# records = list(filter(None, records)) +# return records def parallel_load_records( diff --git a/src/backend/base/langflow/components/agents/SQLAgent.py b/src/backend/base/langflow/components/agents/SQLAgent.py index 68f65d18f..abde4ab94 100644 --- a/src/backend/base/langflow/components/agents/SQLAgent.py +++ b/src/backend/base/langflow/components/agents/SQLAgent.py @@ -1,7 +1,7 @@ from typing import Callable, Union from langchain.agents import AgentExecutor -from langchain.sql_database import SQLDatabase +from langchain_community.utilities import SQLDatabase from langchain_community.agent_toolkits import SQLDatabaseToolkit from langchain_community.agent_toolkits.sql.base import create_sql_agent diff --git a/src/backend/base/langflow/components/experimental/SQLExecutor.py b/src/backend/base/langflow/components/experimental/SQLExecutor.py index 2289514a6..a62ac187b 100644 --- a/src/backend/base/langflow/components/experimental/SQLExecutor.py +++ b/src/backend/base/langflow/components/experimental/SQLExecutor.py @@ -1,5 +1,5 @@ from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool -from langchain_experimental.sql.base import SQLDatabase +from langchain_community.utilities import SQLDatabase from langflow.field_typing import Text from langflow.interface.custom.custom_component import CustomComponent diff --git a/src/backend/base/langflow/components/model_specs/BaiduQianfanLLMEndpointsSpecs.py b/src/backend/base/langflow/components/model_specs/BaiduQianfanLLMEndpointsSpecs.py index 21ed13e70..cc4ba3b9f 100644 --- a/src/backend/base/langflow/components/model_specs/BaiduQianfanLLMEndpointsSpecs.py +++ b/src/backend/base/langflow/components/model_specs/BaiduQianfanLLMEndpointsSpecs.py @@ -1,6 +1,6 @@ from typing import Optional -from langchain.llms.baidu_qianfan_endpoint import QianfanLLMEndpoint +from langchain_community.llms.baidu_qianfan_endpoint import QianfanLLMEndpoint from langflow.interface.custom.custom_component import CustomComponent from langflow.field_typing import BaseLanguageModel diff --git a/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py b/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py index 2bfab4f6a..90f94aacd 100644 --- a/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py +++ b/src/backend/base/langflow/components/model_specs/ChatMistralSpecs.py @@ -30,7 +30,7 @@ class MistralAIModelComponent(CustomComponent): "open-mixtral-8x22b", "mistral-small-latest", "mistral-medium-latest", - "mistral-large-latest" + "mistral-large-latest", ], "info": "Name of the model to use.", "required": True, @@ -64,9 +64,9 @@ class MistralAIModelComponent(CustomComponent): def build( self, model: str, + temperature: float = 0.1, mistral_api_key: Optional[str] = None, max_tokens: Optional[int] = None, - temperature: Optional[float] = None, mistral_api_base: Optional[str] = None, ) -> BaseLanguageModel: # Set default API endpoint if not provided @@ -75,11 +75,11 @@ class MistralAIModelComponent(CustomComponent): try: output = ChatMistralAI( - model=model, + model_name=model, api_key=(SecretStr(mistral_api_key) if mistral_api_key else None), max_tokens=max_tokens, temperature=temperature, - base_url=mistral_api_base, + endpoint=mistral_api_base, ) except Exception as e: raise ValueError("Could not connect to Mistral API.") from e diff --git a/src/backend/base/langflow/components/model_specs/HuggingFaceEndpointsSpecs.py b/src/backend/base/langflow/components/model_specs/HuggingFaceEndpointsSpecs.py index c16fb2c2c..c145105ea 100644 --- a/src/backend/base/langflow/components/model_specs/HuggingFaceEndpointsSpecs.py +++ b/src/backend/base/langflow/components/model_specs/HuggingFaceEndpointsSpecs.py @@ -1,7 +1,7 @@ from typing import Optional from langflow.field_typing import BaseLanguageModel -from langchain.llms.huggingface_endpoint import HuggingFaceEndpoint +from langchain_community.llms.huggingface_endpoint import HuggingFaceEndpoint from langflow.interface.custom.custom_component import CustomComponent diff --git a/src/backend/base/langflow/components/models/MistralModel.py b/src/backend/base/langflow/components/models/MistralModel.py index d6e3a27f0..b8834b314 100644 --- a/src/backend/base/langflow/components/models/MistralModel.py +++ b/src/backend/base/langflow/components/models/MistralModel.py @@ -5,7 +5,7 @@ from pydantic.v1 import SecretStr from langflow.base.constants import STREAM_INFO_TEXT from langflow.base.models.model import LCModelComponent -from langflow.field_typing import NestedDict, Text +from langflow.field_typing import Text class MistralAIModelComponent(LCModelComponent): @@ -32,10 +32,6 @@ class MistralAIModelComponent(LCModelComponent): "display_name": "Max Tokens", "advanced": True, }, - "model_kwargs": { - "display_name": "Model Kwargs", - "advanced": True, - }, "model_name": { "display_name": "Model Name", "advanced": False, @@ -45,7 +41,7 @@ class MistralAIModelComponent(LCModelComponent): "open-mixtral-8x22b", "mistral-small-latest", "mistral-medium-latest", - "mistral-large-latest" + "mistral-large-latest", ], "value": "open-mistral-7b", }, @@ -78,19 +74,48 @@ class MistralAIModelComponent(LCModelComponent): "info": "System message to pass to the model.", "advanced": True, }, + "max_retries": { + "display_name": "Max Retries", + "advanced": True, + }, + "timeout": { + "display_name": "Timeout", + "advanced": True, + }, + "max_concurrent_requests": { + "display_name": "Max Concurrent Requests", + "advanced": True, + }, + "top_p": { + "display_name": "Top P", + "advanced": True, + }, + "random_seed": { + "display_name": "Random Seed", + "advanced": True, + }, + "safe_mode": { + "display_name": "Safe Mode", + "advanced": True, + }, } def build( self, input_value: Text, mistral_api_key: str, - temperature: float, model_name: str, + temperature: float = 0.1, max_tokens: Optional[int] = 256, - model_kwargs: NestedDict = {}, mistral_api_base: Optional[str] = None, stream: bool = False, system_message: Optional[str] = None, + max_retries: int = 5, + timeout: int = 120, + max_concurrent_requests: int = 64, + top_p: float = 1, + random_seed: Optional[int] = None, + safe_mode: bool = False, ) -> Text: if not mistral_api_base: mistral_api_base = "https://api.mistral.ai" @@ -101,11 +126,16 @@ class MistralAIModelComponent(LCModelComponent): chat_model = ChatMistralAI( max_tokens=max_tokens, - model_kwargs=model_kwargs, - model=model_name, - base_url=mistral_api_base, + model_name=model_name, + endpoint=mistral_api_base, api_key=api_key, temperature=temperature, + max_retries=max_retries, + timeout=timeout, + max_concurrent_requests=max_concurrent_requests, + top_p=top_p, + random_seed=random_seed, + safe_mode=safe_mode, ) return self.get_chat_result(chat_model, stream, input_value, system_message) diff --git a/src/backend/base/langflow/config.yaml b/src/backend/base/langflow/config.yaml index ac9a7456b..561fac48d 100644 --- a/src/backend/base/langflow/config.yaml +++ b/src/backend/base/langflow/config.yaml @@ -224,11 +224,6 @@ wrappers: documentation: "" SQLDatabase: documentation: "" -output_parsers: - StructuredOutputParser: - documentation: "https://python.langchain.com/docs/modules/model_io/output_parsers/structured" - ResponseSchema: - documentation: "https://python.langchain.com/docs/modules/model_io/output_parsers/structured" custom_components: CustomComponent: documentation: "https://docs.langflow.org/guidelines/custom-component" diff --git a/src/backend/base/langflow/graph/graph/constants.py b/src/backend/base/langflow/graph/graph/constants.py index f948a0753..193159c13 100644 --- a/src/backend/base/langflow/graph/graph/constants.py +++ b/src/backend/base/langflow/graph/graph/constants.py @@ -5,7 +5,6 @@ from langflow.interface.document_loaders.base import documentloader_creator from langflow.interface.embeddings.base import embedding_creator from langflow.interface.llms.base import llm_creator from langflow.interface.memories.base import memory_creator -from langflow.interface.output_parsers.base import output_parser_creator from langflow.interface.prompts.base import prompt_creator from langflow.interface.retrievers.base import retriever_creator from langflow.interface.text_splitters.base import textsplitter_creator @@ -46,7 +45,6 @@ class VertexTypesDict(LazyLoadDictBase): # **{t: types.VectorStoreVertex for t in vectorstore_creator.to_list()}, **{t: types.DocumentLoaderVertex for t in documentloader_creator.to_list()}, **{t: types.TextSplitterVertex for t in textsplitter_creator.to_list()}, - **{t: types.OutputParserVertex for t in output_parser_creator.to_list()}, **{t: types.CustomComponentVertex for t in custom_component_creator.to_list()}, **{t: types.RetrieverVertex for t in retriever_creator.to_list()}, **{t: types.ChatVertex for t in CHAT_COMPONENTS}, diff --git a/src/backend/base/langflow/graph/vertex/types.py b/src/backend/base/langflow/graph/vertex/types.py index 87f4856b2..5faeeaa8b 100644 --- a/src/backend/base/langflow/graph/vertex/types.py +++ b/src/backend/base/langflow/graph/vertex/types.py @@ -300,11 +300,6 @@ class PromptVertex(Vertex): return str(self._built_object) -class OutputParserVertex(Vertex): - def __init__(self, data: Dict, graph): - super().__init__(data, graph=graph, base_type="output_parsers") - - class CustomComponentVertex(Vertex): def __init__(self, data: Dict, graph): super().__init__(data, graph=graph, base_type="custom_components") diff --git a/src/backend/base/langflow/interface/agents/custom.py b/src/backend/base/langflow/interface/agents/custom.py index 142b77139..680bc9bf8 100644 --- a/src/backend/base/langflow/interface/agents/custom.py +++ b/src/backend/base/langflow/interface/agents/custom.py @@ -7,7 +7,7 @@ from langchain.agents.agent_toolkits.vectorstore.prompt import ROUTER_PREFIX as from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS from langchain.base_language import BaseLanguageModel from langchain.chains.llm import LLMChain -from langchain.sql_database import SQLDatabase +from langchain_community.utilities import SQLDatabase from langchain.tools.sql_database.prompt import QUERY_CHECKER from langchain_community.agent_toolkits import SQLDatabaseToolkit from langchain_community.agent_toolkits.json.prompt import JSON_PREFIX, JSON_SUFFIX diff --git a/src/backend/base/langflow/interface/custom_lists.py b/src/backend/base/langflow/interface/custom_lists.py index 8f428ee11..9b494e450 100644 --- a/src/backend/base/langflow/interface/custom_lists.py +++ b/src/backend/base/langflow/interface/custom_lists.py @@ -1,7 +1,7 @@ import inspect from typing import Any -from langchain import llms, memory, requests, text_splitter +from langchain import llms, memory, text_splitter from langchain_community import agent_toolkits, document_loaders, embeddings from langchain_community.chat_models import AzureChatOpenAI, ChatAnthropic, ChatOpenAI, ChatVertexAI @@ -43,8 +43,6 @@ memory_type_to_cls_dict: dict[str, Any] = { memory_name: import_class(f"langchain.memory.{memory_name}") for memory_name in memory.__all__ } -# Wrappers -wrapper_type_to_cls_dict: dict[str, Any] = {wrapper.__name__: wrapper for wrapper in [requests.RequestsWrapper]} # Embeddings embedding_type_to_cls_dict: dict[str, Any] = { diff --git a/src/backend/base/langflow/interface/importing/utils.py b/src/backend/base/langflow/interface/importing/utils.py index 24612df3c..1b921d87b 100644 --- a/src/backend/base/langflow/interface/importing/utils.py +++ b/src/backend/base/langflow/interface/importing/utils.py @@ -45,7 +45,6 @@ def import_by_type(_type: str, name: str) -> Any: "documentloaders": import_documentloader, "textsplitters": import_textsplitter, "utilities": import_utility, - "output_parsers": import_output_parser, "retrievers": import_retriever, } if _type == "models": @@ -57,11 +56,6 @@ def import_by_type(_type: str, name: str) -> Any: return loaded_func(name) -def import_output_parser(output_parser: str) -> Any: - """Import output parser from output parser name""" - return import_module(f"from langchain.output_parsers import {output_parser}") - - def import_chat_llm(llm: str) -> BaseChatModel: """Import chat llm from llm name""" return import_class(f"langchain_community.chat_models.{llm}") diff --git a/src/backend/base/langflow/interface/initialize/loading.py b/src/backend/base/langflow/interface/initialize/loading.py index fcec59cae..c1014ef90 100644 --- a/src/backend/base/langflow/interface/initialize/loading.py +++ b/src/backend/base/langflow/interface/initialize/loading.py @@ -20,7 +20,6 @@ from langflow.interface.importing.utils import import_by_type from langflow.interface.initialize.llm import initialize_vertexai from langflow.interface.initialize.utils import handle_format_kwargs, handle_node_type, handle_partial_variables from langflow.interface.initialize.vector_store import vecstore_initializer -from langflow.interface.output_parsers.base import output_parser_creator from langflow.interface.retrievers.base import retriever_creator from langflow.interface.toolkits.base import toolkits_creator from langflow.interface.utils import load_file_into_dict @@ -126,8 +125,6 @@ async def instantiate_based_on_type( return instantiate_utility(node_type, class_object, params) elif base_type == "chains": return instantiate_chains(node_type, class_object, params) - elif base_type == "output_parsers": - return instantiate_output_parser(node_type, class_object, params) elif base_type == "models": return instantiate_llm(node_type, class_object, params) elif base_type == "retrievers": @@ -201,15 +198,6 @@ def instantiate_wrapper(node_type, class_object, params): return class_object(**params) -def instantiate_output_parser(node_type, class_object, params): - if node_type in output_parser_creator.from_method_nodes: - method = output_parser_creator.from_method_nodes[node_type] - if class_method := getattr(class_object, method, None): - return class_method(**params) - raise ValueError(f"Method {method} not found in {class_object}") - return class_object(**params) - - def instantiate_llm(node_type, class_object, params: Dict): # This is a workaround so JinaChat works until streaming is implemented # if "openai_api_base" in params and "jina" in params["openai_api_base"]: @@ -514,15 +502,6 @@ def build_prompt_template(prompt, tools): "show": False, "multiline": False, }, - "output_parser": { - "type": "BaseOutputParser", - "required": False, - "placeholder": "", - "list": False, - "show": False, - "multline": False, - "value": None, - }, "template": { "type": "str", "required": True, diff --git a/src/backend/base/langflow/interface/output_parsers/__init__.py b/src/backend/base/langflow/interface/output_parsers/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/backend/base/langflow/interface/output_parsers/base.py b/src/backend/base/langflow/interface/output_parsers/base.py deleted file mode 100644 index b38bba87e..000000000 --- a/src/backend/base/langflow/interface/output_parsers/base.py +++ /dev/null @@ -1,63 +0,0 @@ -from typing import ClassVar, Dict, List, Optional, Type - -from langchain import output_parsers -from langflow.interface.base import LangChainTypeCreator -from langflow.interface.importing.utils import import_class -from langflow.interface.utils import build_template_from_class -from langflow.services.deps import get_settings_service -from langflow.template.frontend_node.output_parsers import OutputParserFrontendNode -from langflow.utils.util import build_template_from_method -from loguru import logger - - -class OutputParserCreator(LangChainTypeCreator): - type_name: str = "output_parsers" - from_method_nodes: ClassVar[Dict] = { - "StructuredOutputParser": "from_response_schemas", - } - - @property - def frontend_node_class(self) -> Type[OutputParserFrontendNode]: - return OutputParserFrontendNode - - @property - def type_to_loader_dict(self) -> Dict: - if self.type_dict is None: - settings_service = get_settings_service() - self.type_dict = { - output_parser_name: import_class(f"langchain.output_parsers.{output_parser_name}") - # if output_parser_name is not lower case it is a class - for output_parser_name in output_parsers.__all__ - } - self.type_dict = { - name: output_parser - for name, output_parser in self.type_dict.items() - if name in settings_service.settings.OUTPUT_PARSERS or settings_service.settings.DEV - } - return self.type_dict - - def get_signature(self, name: str) -> Optional[Dict]: - try: - if name in self.from_method_nodes: - return build_template_from_method( - name, - type_to_cls_dict=self.type_to_loader_dict, - method_name=self.from_method_nodes[name], - ) - else: - return build_template_from_class( - name, - type_to_cls_dict=self.type_to_loader_dict, - ) - except ValueError as exc: - # raise ValueError("OutputParser not found") from exc - logger.error(f"OutputParser {name} not found: {exc}") - except AttributeError as exc: - logger.error(f"OutputParser {name} not loaded: {exc}") - return None - - def to_list(self) -> List[str]: - return list(self.type_to_loader_dict.keys()) - - -output_parser_creator = OutputParserCreator() diff --git a/src/backend/base/langflow/interface/types.py b/src/backend/base/langflow/interface/types.py index 32ab7ff95..46fa44a37 100644 --- a/src/backend/base/langflow/interface/types.py +++ b/src/backend/base/langflow/interface/types.py @@ -8,7 +8,6 @@ from langflow.interface.document_loaders.base import documentloader_creator from langflow.interface.embeddings.base import embedding_creator from langflow.interface.llms.base import llm_creator from langflow.interface.memories.base import memory_creator -from langflow.interface.output_parsers.base import output_parser_creator from langflow.interface.retrievers.base import retriever_creator from langflow.interface.text_splitters.base import textsplitter_creator from langflow.interface.toolkits.base import toolkits_creator @@ -48,7 +47,6 @@ def build_langchain_types_dict(): # sourcery skip: dict-assign-update-to-union documentloader_creator, textsplitter_creator, # utility_creator, - output_parser_creator, retriever_creator, ] diff --git a/src/backend/base/langflow/interface/utils.py b/src/backend/base/langflow/interface/utils.py index aa4e3f7e1..d4271eabf 100644 --- a/src/backend/base/langflow/interface/utils.py +++ b/src/backend/base/langflow/interface/utils.py @@ -106,7 +106,7 @@ def set_langchain_cache(settings): if cache_type := os.getenv("LANGFLOW_LANGCHAIN_CACHE"): try: - cache_class = import_class(f"langchain.cache.{cache_type or settings.LANGCHAIN_CACHE}") + cache_class = import_class(f"langchain_community.cache.{cache_type or settings.LANGCHAIN_CACHE}") logger.debug(f"Setting up LLM caching with {cache_class.__name__}") set_llm_cache(cache_class()) diff --git a/src/backend/base/langflow/services/auth/utils.py b/src/backend/base/langflow/services/auth/utils.py index d2290036e..f8396077c 100644 --- a/src/backend/base/langflow/services/auth/utils.py +++ b/src/backend/base/langflow/services/auth/utils.py @@ -1,21 +1,20 @@ from datetime import datetime, timedelta, timezone from typing import Annotated, Coroutine, Optional, Union from uuid import UUID +import warnings from cryptography.fernet import Fernet from fastapi import Depends, HTTPException, Security, status from fastapi.security import APIKeyHeader, APIKeyQuery, OAuth2PasswordBearer + + from jose import JWTError, jwt from sqlmodel import Session from starlette.websockets import WebSocket from langflow.services.database.models.api_key.crud import check_key from langflow.services.database.models.api_key.model import ApiKey -from langflow.services.database.models.user.crud import ( - get_user_by_id, - get_user_by_username, - update_user_last_login_at, -) +from langflow.services.database.models.user.crud import get_user_by_id, get_user_by_username, update_user_last_login_at from langflow.services.database.models.user.model import User from langflow.services.deps import get_session, get_settings_service @@ -111,11 +110,15 @@ async def get_current_user_by_jwt( raise credentials_exception try: - payload = jwt.decode( - token, - settings_service.auth_settings.SECRET_KEY.get_secret_value(), - algorithms=[settings_service.auth_settings.ALGORITHM], - ) + # Ignore warning about datetime.utcnow + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + + payload = jwt.decode( + token, + settings_service.auth_settings.SECRET_KEY.get_secret_value(), + algorithms=[settings_service.auth_settings.ALGORITHM], + ) user_id: UUID = payload.get("sub") # type: ignore token_type: str = payload.get("type") # type: ignore if expires := payload.get("exp", None): @@ -285,11 +288,14 @@ def create_refresh_token(refresh_token: str, db: Session = Depends(get_session)) settings_service = get_settings_service() try: - payload = jwt.decode( - refresh_token, - settings_service.auth_settings.SECRET_KEY.get_secret_value(), - algorithms=[settings_service.auth_settings.ALGORITHM], - ) + # Ignore warning about datetime.utcnow + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + payload = jwt.decode( + refresh_token, + settings_service.auth_settings.SECRET_KEY.get_secret_value(), + algorithms=[settings_service.auth_settings.ALGORITHM], + ) user_id: UUID = payload.get("sub") # type: ignore token_type: str = payload.get("type") # type: ignore @@ -349,3 +355,4 @@ def decrypt_api_key(encrypted_api_key: str, settings_service=Depends(get_setting encoded_bytes = encrypted_api_key decrypted_key = fernet.decrypt(encoded_bytes).decode() return decrypted_key + return decrypted_key diff --git a/src/backend/base/langflow/services/database/models/flow/model.py b/src/backend/base/langflow/services/database/models/flow/model.py index e814d1f3a..42cd9277d 100644 --- a/src/backend/base/langflow/services/database/models/flow/model.py +++ b/src/backend/base/langflow/services/database/models/flow/model.py @@ -1,7 +1,7 @@ # Path: src/backend/langflow/services/database/models/flow/model.py import warnings -from datetime import datetime +from datetime import datetime, timezone from typing import TYPE_CHECKING, Dict, Optional from uuid import UUID, uuid4 @@ -23,7 +23,7 @@ class FlowBase(SQLModel): icon_bg_color: Optional[str] = Field(default=None, nullable=True) data: Optional[Dict] = Field(default=None, nullable=True) is_component: Optional[bool] = Field(default=False, nullable=True) - updated_at: Optional[datetime] = Field(default_factory=datetime.utcnow, nullable=True) + updated_at: Optional[datetime] = Field(default_factory=lambda: datetime.now(timezone.utc), nullable=True) folder: Optional[str] = Field(default=None, nullable=True) @field_validator("icon_bg_color") diff --git a/src/backend/base/langflow/services/database/models/user/model.py b/src/backend/base/langflow/services/database/models/user/model.py index fa229b4b3..491ae4efc 100644 --- a/src/backend/base/langflow/services/database/models/user/model.py +++ b/src/backend/base/langflow/services/database/models/user/model.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from typing import TYPE_CHECKING, Optional from uuid import UUID, uuid4 @@ -17,8 +17,8 @@ class User(SQLModel, table=True): profile_image: Optional[str] = Field(default=None, nullable=True) is_active: bool = Field(default=False) is_superuser: bool = Field(default=False) - create_at: datetime = Field(default_factory=datetime.utcnow) - updated_at: datetime = Field(default_factory=datetime.utcnow) + create_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) + updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) last_login_at: Optional[datetime] = Field(default=None, nullable=True) api_keys: list["ApiKey"] = Relationship( back_populates="user", diff --git a/src/backend/base/langflow/services/settings/base.py b/src/backend/base/langflow/services/settings/base.py index db6ba1022..300bafd1d 100644 --- a/src/backend/base/langflow/services/settings/base.py +++ b/src/backend/base/langflow/services/settings/base.py @@ -72,7 +72,6 @@ class Settings(BaseSettings): TOOLKITS: dict = {} TEXTSPLITTERS: dict = {} UTILITIES: dict = {} - OUTPUT_PARSERS: dict = {} CUSTOM_COMPONENTS: dict = {} # Define the default LANGFLOW_DIR @@ -241,7 +240,6 @@ class Settings(BaseSettings): self.VECTORSTORES = new_settings.VECTORSTORES or {} self.DOCUMENTLOADERS = new_settings.DOCUMENTLOADERS or {} self.RETRIEVERS = new_settings.RETRIEVERS or {} - self.OUTPUT_PARSERS = new_settings.OUTPUT_PARSERS or {} self.CUSTOM_COMPONENTS = new_settings.CUSTOM_COMPONENTS or {} self.COMPONENTS_PATH = new_settings.COMPONENTS_PATH or [] self.DEV = dev diff --git a/src/backend/base/langflow/settings.py b/src/backend/base/langflow/settings.py index 9cc761b68..3f340df95 100644 --- a/src/backend/base/langflow/settings.py +++ b/src/backend/base/langflow/settings.py @@ -28,7 +28,6 @@ class Settings(BaseSettings): TOOLKITS: dict = {} TEXTSPLITTERS: dict = {} UTILITIES: dict = {} - OUTPUT_PARSERS: dict = {} CUSTOM_COMPONENTS: dict = {} DEV: bool = False @@ -102,7 +101,6 @@ class Settings(BaseSettings): self.VECTORSTORES = new_settings.VECTORSTORES or {} self.DOCUMENTLOADERS = new_settings.DOCUMENTLOADERS or {} self.RETRIEVERS = new_settings.RETRIEVERS or {} - self.OUTPUT_PARSERS = new_settings.OUTPUT_PARSERS or {} self.CUSTOM_COMPONENTS = new_settings.CUSTOM_COMPONENTS or {} self.COMPONENTS_PATH = new_settings.COMPONENTS_PATH or [] self.DEV = dev diff --git a/src/backend/base/langflow/template/field/prompt.py b/src/backend/base/langflow/template/field/prompt.py index 72c57c5db..ccc5d01a0 100644 --- a/src/backend/base/langflow/template/field/prompt.py +++ b/src/backend/base/langflow/template/field/prompt.py @@ -10,5 +10,5 @@ class DefaultPromptField(TemplateField): advanced: bool = False multiline: bool = True - input_types: list[str] = ["Document", "BaseOutputParser", "Record", "Text"] + input_types: list[str] = ["Document", "Record", "Text"] value: str = "" # Set the value to empty string diff --git a/src/backend/base/langflow/template/frontend_node/custom_components.py b/src/backend/base/langflow/template/frontend_node/custom_components.py index 456aa7466..577c89684 100644 --- a/src/backend/base/langflow/template/frontend_node/custom_components.py +++ b/src/backend/base/langflow/template/frontend_node/custom_components.py @@ -14,7 +14,6 @@ from langflow.field_typing import ( BaseLLM, BaseLoader, BaseMemory, - BaseOutputParser, BasePromptTemplate, BaseRetriever, Callable, diff --git a/src/backend/base/langflow/template/frontend_node/output_parsers.py b/src/backend/base/langflow/template/frontend_node/output_parsers.py deleted file mode 100644 index 6b33ee680..000000000 --- a/src/backend/base/langflow/template/frontend_node/output_parsers.py +++ /dev/null @@ -1,12 +0,0 @@ -from typing import Optional - - -from langflow.template.field.base import TemplateField -from langflow.template.frontend_node.base import FrontendNode - - -class OutputParserFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - field.show = True diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 1b9cf758c..381ecd598 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -517,13 +517,13 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "dataclasses-json" -version = "0.6.5" +version = "0.6.6" description = "Easily serialize dataclasses to and from JSON." optional = false python-versions = "<4.0,>=3.7" files = [ - {file = "dataclasses_json-0.6.5-py3-none-any.whl", hash = "sha256:f49c77aa3a85cac5bf5b7f65f4790ca0d2be8ef4d92c75e91ba0103072788a39"}, - {file = "dataclasses_json-0.6.5.tar.gz", hash = "sha256:1c287594d9fcea72dc42d6d3836cf14848c2dc5ce88f65ed61b36b57f515fe26"}, + {file = "dataclasses_json-0.6.6-py3-none-any.whl", hash = "sha256:e54c5c87497741ad454070ba0ed411523d46beb5da102e221efb873801b0ba85"}, + {file = "dataclasses_json-0.6.6.tar.gz", hash = "sha256:0c09827d26fffda27f1be2fed7a7a01a29c5ddcd2eb6393ad5ebf9d77e9deae8"}, ] [package.dependencies] @@ -558,50 +558,58 @@ files = [ [[package]] name = "duckdb" -version = "0.9.2" -description = "DuckDB embedded database" +version = "0.10.2" +description = "DuckDB in-process database" optional = false python-versions = ">=3.7.0" files = [ - {file = "duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:aadcea5160c586704c03a8a796c06a8afffbefefb1986601104a60cb0bfdb5ab"}, - {file = "duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:08215f17147ed83cbec972175d9882387366de2ed36c21cbe4add04b39a5bcb4"}, - {file = "duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee6c2a8aba6850abef5e1be9dbc04b8e72a5b2c2b67f77892317a21fae868fe7"}, - {file = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff49f3da9399900fd58b5acd0bb8bfad22c5147584ad2427a78d937e11ec9d0"}, - {file = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5ac5baf8597efd2bfa75f984654afcabcd698342d59b0e265a0bc6f267b3f0"}, - {file = "duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:81c6df905589a1023a27e9712edb5b724566587ef280a0c66a7ec07c8083623b"}, - {file = "duckdb-0.9.2-cp310-cp310-win32.whl", hash = "sha256:a298cd1d821c81d0dec8a60878c4b38c1adea04a9675fb6306c8f9083bbf314d"}, - {file = "duckdb-0.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:492a69cd60b6cb4f671b51893884cdc5efc4c3b2eb76057a007d2a2295427173"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:061a9ea809811d6e3025c5de31bc40e0302cfb08c08feefa574a6491e882e7e8"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a43f93be768af39f604b7b9b48891f9177c9282a408051209101ff80f7450d8f"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac29c8c8f56fff5a681f7bf61711ccb9325c5329e64f23cb7ff31781d7b50773"}, - {file = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b14d98d26bab139114f62ade81350a5342f60a168d94b27ed2c706838f949eda"}, - {file = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:796a995299878913e765b28cc2b14c8e44fae2f54ab41a9ee668c18449f5f833"}, - {file = "duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6cb64ccfb72c11ec9c41b3cb6181b6fd33deccceda530e94e1c362af5f810ba1"}, - {file = "duckdb-0.9.2-cp311-cp311-win32.whl", hash = "sha256:930740cb7b2cd9e79946e1d3a8f66e15dc5849d4eaeff75c8788d0983b9256a5"}, - {file = "duckdb-0.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:c28f13c45006fd525001b2011cdf91fa216530e9751779651e66edc0e446be50"}, - {file = "duckdb-0.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fbce7bbcb4ba7d99fcec84cec08db40bc0dd9342c6c11930ce708817741faeeb"}, - {file = "duckdb-0.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15a82109a9e69b1891f0999749f9e3265f550032470f51432f944a37cfdc908b"}, - {file = "duckdb-0.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9490fb9a35eb74af40db5569d90df8a04a6f09ed9a8c9caa024998c40e2506aa"}, - {file = "duckdb-0.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:696d5c6dee86c1a491ea15b74aafe34ad2b62dcd46ad7e03b1d00111ca1a8c68"}, - {file = "duckdb-0.9.2-cp37-cp37m-win32.whl", hash = "sha256:4f0935300bdf8b7631ddfc838f36a858c1323696d8c8a2cecbd416bddf6b0631"}, - {file = "duckdb-0.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:0aab900f7510e4d2613263865570203ddfa2631858c7eb8cbed091af6ceb597f"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d8130ed6a0c9421b135d0743705ea95b9a745852977717504e45722c112bf7a"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:974e5de0294f88a1a837378f1f83330395801e9246f4e88ed3bfc8ada65dcbee"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4fbc297b602ef17e579bb3190c94d19c5002422b55814421a0fc11299c0c1100"}, - {file = "duckdb-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1dd58a0d84a424924a35b3772419f8cd78a01c626be3147e4934d7a035a8ad68"}, - {file = "duckdb-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11a1194a582c80dfb57565daa06141727e415ff5d17e022dc5f31888a5423d33"}, - {file = "duckdb-0.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:be45d08541002a9338e568dca67ab4f20c0277f8f58a73dfc1435c5b4297c996"}, - {file = "duckdb-0.9.2-cp38-cp38-win32.whl", hash = "sha256:dd6f88aeb7fc0bfecaca633629ff5c986ac966fe3b7dcec0b2c48632fd550ba2"}, - {file = "duckdb-0.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:28100c4a6a04e69aa0f4a6670a6d3d67a65f0337246a0c1a429f3f28f3c40b9a"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ae5bf0b6ad4278e46e933e51473b86b4b932dbc54ff097610e5b482dd125552"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e5d0bb845a80aa48ed1fd1d2d285dd352e96dc97f8efced2a7429437ccd1fe1f"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ce262d74a52500d10888110dfd6715989926ec936918c232dcbaddb78fc55b4"}, - {file = "duckdb-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6935240da090a7f7d2666f6d0a5e45ff85715244171ca4e6576060a7f4a1200e"}, - {file = "duckdb-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5cfb93e73911696a98b9479299d19cfbc21dd05bb7ab11a923a903f86b4d06e"}, - {file = "duckdb-0.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:64e3bc01751f31e7572d2716c3e8da8fe785f1cdc5be329100818d223002213f"}, - {file = "duckdb-0.9.2-cp39-cp39-win32.whl", hash = "sha256:6e5b80f46487636368e31b61461940e3999986359a78660a50dfdd17dd72017c"}, - {file = "duckdb-0.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:e6142a220180dbeea4f341708bd5f9501c5c962ce7ef47c1cadf5e8810b4cb13"}, - {file = "duckdb-0.9.2.tar.gz", hash = "sha256:3843afeab7c3fc4a4c0b53686a4cc1d9cdbdadcbb468d60fef910355ecafd447"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3891d3ac03e12a3e5c43afa3020fe701f64060f52d25f429a1ed7b5d914368d3"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f63877651f1fb940e049dc53038eb763856616319acf4f892b1c3ed074f5ab0"}, + {file = "duckdb-0.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:06e3a36f04f4d98d2c0bbdd63e517cfbe114a795306e26ec855e62e076af5043"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf5f95ad5b75c8e65c6508b4df02043dd0b9d97712b9a33236ad77c388ce7861"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ff62bc98278c98fecbd6eecec5d698ad41ebd654110feaadbf8ac8bb59b1ecf"}, + {file = "duckdb-0.10.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cceede13fde095c23cf9a53adf7c414c7bfb21b9a7aa6a4836014fdbecbfca70"}, + {file = "duckdb-0.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:acdfff60b7efccd7f731213a9795851256249dfacf80367074b2b2e144f716dd"}, + {file = "duckdb-0.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:4a5d5655cf0bdaf664a6f332afe465e02b08cef715548a0983bb7aef48da06a6"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a9d15842876d18763e085648656cccc7660a215d16254906db5c4471be2c7732"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c88cdcdc8452c910e4298223e7d9fca291534ff5aa36090aa49c9e6557550b13"}, + {file = "duckdb-0.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:364cd6f5dc8a1010d144d08c410ba9a74c521336ee5bda84fabc6616216a6d6a"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c57c11d1060296f5e9ebfb5bb7e5521e0d77912e8f9ff43c90240c3311e9de9"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:186d86b8dda8e1076170eb770bb2bb73ea88ca907d92885c9695d6515207b205"}, + {file = "duckdb-0.10.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f65b62f31c6bff21afc0261cfe28d238b8f34ec78f339546b12f4740c39552a"}, + {file = "duckdb-0.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a860d7466a5c93714cdd94559ce9e1db2ab91914f0941c25e5e93d4ebe36a5fa"}, + {file = "duckdb-0.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:33308190e9c7f05a3a0a2d46008a043effd4eae77011869d7c18fb37acdd9215"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3a8b2f1229b4aecb79cd28ffdb99032b1497f0a805d0da1136a9b6115e1afc70"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d23a6dea61963733a0f45a0d0bbb1361fb2a47410ed5ff308b4a1f869d4eeb6f"}, + {file = "duckdb-0.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:20ee0aa27e688aa52a40b434ec41a50431d0b06edeab88edc2feaca18d82c62c"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80a6d43d9044f0997a15a92e0c0ff3afd21151a1e572a92f439cc4f56b7090e1"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6934758cacd06029a5c9f54556a43bd277a86757e22bf8d0dd11ca15c1813d1c"}, + {file = "duckdb-0.10.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a11e2d68bd79044eea5486b1cddb5b915115f537e5c74eeb94c768ce30f9f4b"}, + {file = "duckdb-0.10.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0bf58385c43b8e448a2fea7e8729054934bf73ea616d1d7ef8184eda07f975e2"}, + {file = "duckdb-0.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:eae75c7014597ded6e7f6dc51e32d48362a31608acd73e9f795748ee94335a54"}, + {file = "duckdb-0.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62e89deff778a7a86f651802b947a3466425f6cce41e9d7d412d39e492932943"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f87e555fd36ec6da316b727a39fb24c53124a797dfa9b451bdea87b2f20a351f"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41e8b34b1a944590ebcf82f8cc59d67b084fe99479f048892d60da6c1402c386"}, + {file = "duckdb-0.10.2-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c68c6dde2773774cf2371522a3959ea2716fc2b3a4891d4066f0e426455fe19"}, + {file = "duckdb-0.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ff6a8a0980d0f9398fa461deffa59465dac190d707468478011ea8a5fe1f2c81"}, + {file = "duckdb-0.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:728dd4ff0efda387a424754e5508d4f8c72a272c2d3ccb036a83286f60b46002"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c461d6b4619e80170044a9eb999bbf4097e330d3a4974ced0a7eaeb79c7c39f6"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:909351ff72eb3b50b89761251148d8a186594d8a438e12dcf5494794caff6693"}, + {file = "duckdb-0.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d9eeb8393d69abafd355b869669957eb85b89e4df677e420b9ef0693b7aa6cb4"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3102bcf5011e8f82ea3c2bde43108774fe5a283a410d292c0843610ea13e2237"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d64d443613e5f16caf7d67102733538c90f7715867c1a98597efd3babca068e3"}, + {file = "duckdb-0.10.2-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb31398826d1b7473344e5ee8e0f826370c9752549469ba1327042ace9041f80"}, + {file = "duckdb-0.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d09dcec467cd6127d5cc1fb0ce4efbd77e761882d9d772b0f64fc2f79a2a1cde"}, + {file = "duckdb-0.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:82fab1a24faf7c33d8a7afed08b57ee36e8821a3a68a2f1574cd238ea440bba0"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38607e6e6618e8ea28c8d9b67aa9e22cfd6d6d673f2e8ab328bd6e867b697f69"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb0c23bc8c09615bff38aebcf8e92e6ae74959c67b3c9e5b00edddc730bf22be"}, + {file = "duckdb-0.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:00576c11c78c83830ab483bad968e07cd9b5f730e7ffaf5aa5fadee5ac4f71e9"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:077db692cdda50c4684ef87dc2a68507665804caa90e539dbe819116bda722ad"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca25984ad9f9a04e46e8359f852668c11569534e3bb8424b80be711303ad2314"}, + {file = "duckdb-0.10.2-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a72cc40982c7b92cf555e574618fc711033b013bf258b611ba18d7654c89d8c"}, + {file = "duckdb-0.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27b9efd6e788eb561535fdc0cbc7c74aca1ff39f748b7cfc27aa49b00e22da1"}, + {file = "duckdb-0.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:4800469489bc262dda61a7f1d40acedf67cf2454874e9d8bbf07920dc2b147e6"}, + {file = "duckdb-0.10.2.tar.gz", hash = "sha256:0f609c9d5f941f1ecde810f010dd9321cd406a552c1df20318a13fa64247f67f"}, ] [[package]] @@ -1023,22 +1031,21 @@ files = [ [[package]] name = "langchain" -version = "0.1.17" +version = "0.1.19" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain-0.1.17-py3-none-any.whl", hash = "sha256:f6c5b5fdb529545e6cafbb4ba099031508e621ba1ed7985cf078a597ade3458b"}, - {file = "langchain-0.1.17.tar.gz", hash = "sha256:709b80afa00ae634dfc7042f3e4c20309267b21ffeacc7d7494d58bcae1862f7"}, + {file = "langchain-0.1.19-py3-none-any.whl", hash = "sha256:a1270b70139344a09f91c8a1b117c4300d9920d6d88aaaaf5ba729625ac68801"}, + {file = "langchain-0.1.19.tar.gz", hash = "sha256:7d2ffb66944a84dcac99901c4fd33f6d92aa7f794d17b5ba9a29c55a7306e32c"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} dataclasses-json = ">=0.5.7,<0.7" -jsonpatch = ">=1.33,<2.0" -langchain-community = ">=0.0.36,<0.1" -langchain-core = ">=0.1.48,<0.2.0" +langchain-community = ">=0.0.38,<0.1" +langchain-core = ">=0.1.52,<0.2.0" langchain-text-splitters = ">=0.0.1,<0.1" langsmith = ">=0.1.17,<0.2.0" numpy = ">=1,<2" @@ -1064,19 +1071,19 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"] [[package]] name = "langchain-community" -version = "0.0.37" +version = "0.0.38" description = "Community contributed LangChain integrations." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_community-0.0.37-py3-none-any.whl", hash = "sha256:52e8557602dc099c2e236ec8a0599a956e2f08cfeb61e501815f5ec2d8545747"}, - {file = "langchain_community-0.0.37.tar.gz", hash = "sha256:db2b5829bb20bc5b04c126b69143dbc31a880e949e94110c236b2c176906889f"}, + {file = "langchain_community-0.0.38-py3-none-any.whl", hash = "sha256:ecb48660a70a08c90229be46b0cc5f6bc9f38f2833ee44c57dfab9bf3a2c121a"}, + {file = "langchain_community-0.0.38.tar.gz", hash = "sha256:127fc4b75bc67b62fe827c66c02e715a730fef8fe69bd2023d466bab06b5810d"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" dataclasses-json = ">=0.5.7,<0.7" -langchain-core = ">=0.1.51,<0.2.0" +langchain-core = ">=0.1.52,<0.2.0" langsmith = ">=0.1.0,<0.2.0" numpy = ">=1,<2" PyYAML = ">=5.3" @@ -1112,18 +1119,18 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langchain-experimental" -version = "0.0.57" +version = "0.0.58" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_experimental-0.0.57-py3-none-any.whl", hash = "sha256:96479a2d45a35722cf2fe49655639e91d3fff5ccaba498cda32b088d5b184325"}, - {file = "langchain_experimental-0.0.57.tar.gz", hash = "sha256:d1fb452aa1f04f32f0e08b83b083f35552f4ece1077c5bdcf86327f56f1758b5"}, + {file = "langchain_experimental-0.0.58-py3-none-any.whl", hash = "sha256:106d3bc7df3dd20687378db7534c2fc21e2589201d43de42f832a1e3913dd55b"}, + {file = "langchain_experimental-0.0.58.tar.gz", hash = "sha256:8ef10ff6b39f44ef468f8f21beb3749957d2262ec64d05db2719934936ca0285"}, ] [package.dependencies] -langchain = ">=0.1.15,<0.2.0" -langchain-core = ">=0.1.41,<0.2.0" +langchain = ">=0.1.17,<0.2.0" +langchain-core = ">=0.1.52,<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)"] @@ -1162,13 +1169,13 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langsmith" -version = "0.1.54" +version = "0.1.56" 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.54-py3-none-any.whl", hash = "sha256:e8ba2758dbdff0fccb35337c28a5ab641dd980b22e178d390b72a15c9ae9caff"}, - {file = "langsmith-0.1.54.tar.gz", hash = "sha256:86f5a90e48303de897f37a893f8bb635eabdaf23e674099e8bc0f2e9ca2f8faf"}, + {file = "langsmith-0.1.56-py3-none-any.whl", hash = "sha256:2f930e054ea8eccd8ff99f0f129ae7d2513973b2e706d5483f44ea9951a1dca0"}, + {file = "langsmith-0.1.56.tar.gz", hash = "sha256:ff645b5bf16e2566740218ed6c048a1f8edbbedb4480a0d305a837ec71303fbf"}, ] [package.dependencies] @@ -1809,6 +1816,7 @@ files = [ numpy = [ {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -2891,5 +2899,5 @@ local = [] [metadata] lock-version = "2.0" -python-versions = ">=3.10,<3.12" -content-hash = "cd3479e6f463fcdce1bef948ca71952b0650d1d7f4891ba1bc873368cd4b095d" +python-versions = ">=3.10,<3.13" +content-hash = "200c17e119f7ba7fdb64de320bdf464c65daf06f62bcc41258b32247a99e3dc1" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 1b2bc9c1c..44f32601c 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -25,7 +25,7 @@ documentation = "https://docs.langflow.org" langflow-base = "langflow.__main__:main" [tool.poetry.dependencies] -python = ">=3.10,<3.12" +python = ">=3.10,<3.13" fastapi = "^0.110.1" httpx = "*" uvicorn = "^0.29.0" @@ -52,7 +52,7 @@ docstring-parser = "^0.15" python-jose = "^3.3.0" pandas = "2.2.0" multiprocess = "^0.70.14" -duckdb = "^0.9.2" +duckdb = "^0.10.2" python-socketio = "^5.11.0" python-docx = "^1.1.0" jq = { version = "^1.7.0", markers = "sys_platform != 'win32'" } From 08c0732cfd69b5a29843ca49fcc2347f90df7601 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 12:26:44 -0300 Subject: [PATCH 14/55] Bump werkzeug from 3.0.2 to 3.0.3 (#1841) Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: werkzeug dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 3c20644f0..daae4b59c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4804,6 +4804,7 @@ files = [ {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-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f"}, {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"}, @@ -4828,7 +4829,6 @@ files = [ {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"}, From 71324440a28212e53cddfcb4bccdc9cfada5859e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 12:26:58 -0300 Subject: [PATCH 15/55] Bump jinja2 from 3.1.3 to 3.1.4 (#1840) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4) --- updated-dependencies: - dependency-name: jinja2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From c69f950cbab1afe8c0f0e898cc71458028d5afd3 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com> Date: Fri, 10 May 2024 12:30:45 -0300 Subject: [PATCH 16/55] Migrate Tweaks Module to Zustand Library and Add All Flows (#1847) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ (codeTabsComponent/index.tsx): refactor code to remove unnecessary code and improve readability 📝 (codeTabsComponent/index.tsx): update comments in source code to provide better understanding of the code logic ♻️ (apiModal/index.tsx): refactor code to remove unnecessary code and improve readability 📝 (apiModal/index.tsx): update comments in source code to provide better understanding of the code logic 🔧 (tweaksStore.ts): add new store for managing tweaks data 📝 (components/index.ts): update codeTabsPropsType to use array syntax for tweak and tweaksList properties for better readability and consistency ♻️ (utils/utils.ts): refactor toTitleCase function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor groupByFamily function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getPythonApiCode function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getCurlCode function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getPythonCode function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getWidgetCode function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getFieldTitle function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor IncrementObjectKey function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getSetFromObject function to remove unnecessary comma and improve code readability ♻️ (utils/utils.ts): refactor getRandomName function to remove unnecessary comma and improve code readability * 📝 (codeTabsComponent/index.tsx): remove unnecessary whitespace in className ♻️ (codeTabsComponent/index.tsx): refactor code to improve readability and remove unnecessary code ♻️ (apiModal/index.tsx): refactor code to improve readability and remove unnecessary code ♻️ (tweaksStore.ts): refactor code to improve readability and remove unnecessary code ✨ (zustand/tweaks/index.ts): add types for tweaks store * ✨ (codeTabsComponent/index.tsx): refactor code to improve readability and remove unnecessary code ♻️ (codeTabsComponent/index.tsx): refactor code to improve readability and remove unnecessary code ♻️ (utils/utils.ts): refactor code to improve readability and remove unnecessary code ✅ (tweaks_test.spec.ts): add end-to-end test to check if tweaks are updating when something on the flow changes * 🐛 (accordionComponent/index.tsx): fix variable name from 'trigger' to 'keyValue' for better clarity and readability ♻️ (accordionComponent/index.tsx): refactor code to use 'defaultValue' prop instead of manually setting the value in the AccordionItem component 🐛 (codeTabsComponent/index.tsx): remove unused 'openAccordions' function ♻️ (codeTabsComponent/index.tsx): refactor code to remove unnecessary condition for opening accordions in the onValueChange event handler ♻️ (codeTabsComponent/index.tsx): refactor code to remove unused 'open' prop in AccordionItem component ♻️ (codeTabsComponent/index.tsx): refactor code to remove unused 'openAccordion' state variable ♻️ (codeTabsComponent/index.tsx): refactor code to remove unused 'openAccordions' function call in the onValueChange event handler * 🐛 (apiModal/index.tsx): remove unnecessary comma after ref parameter in ApiModal component ♻️ (apiModal/index.tsx): refactor code to improve readability and remove unnecessary commas in function parameters ✨ (apiModal/index.tsx): add conditional check before assigning values to tabs array to prevent errors when tabs is undefined or empty * 🐛 (index.tsx): remove unnecessary defaultValue prop from Accordion component ♻️ (index.tsx): refactor AccordionItem component to remove defaultValue prop and simplify code * 🐛 (apiModal/index.tsx): remove unnecessary comma after ref parameter in function signature ♻️ (apiModal/index.tsx): refactor code to improve readability and remove unnecessary comma after ref parameter in function signature * refactor tweaks * ✨ (codeTabsComponent/index.tsx): add autoFocus prop to the tweaks switch to prevent it from automatically gaining focus when rendered ♻️ (codeTabsComponent/index.tsx): refactor classNames in the api-modal-according-display div to remove unnecessary whitespace ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api-modal-according-display div to improve readability and remove unnecessary parentheses ♻️ (codeTabsComponent/index.tsx): refactor mapping of templateFields in the api * fix tests on tweaks --- .../components/accordionComponent/index.tsx | 7 +- .../src/components/chatComponent/index.tsx | 2 +- .../components/codeTabsComponent/index.tsx | 161 ++++++------ src/frontend/src/modals/apiModal/index.tsx | 245 ------------------ .../modals/apiModal/utils/build-content.tsx | 10 + .../src/modals/apiModal/utils/build-tweaks.ts | 8 + .../utils/check-can-build-tweak-object.ts | 13 + .../apiModal/utils/get-changes-types.ts | 26 ++ .../utils/get-nodes-with-default-value.ts | 28 ++ .../src/modals/apiModal/utils/get-value.ts | 29 +++ .../src/modals/apiModal/views/index.tsx | 211 +++++++++++++++ src/frontend/src/stores/tweaksStore.ts | 9 + src/frontend/src/types/components/index.ts | 17 +- .../src/types/zustand/tweaks/index.ts | 8 + src/frontend/src/utils/reactflowUtils.ts | 111 ++++---- src/frontend/src/utils/utils.ts | 53 +--- .../tests/end-to-end/tweaks_test.spec.ts | 72 ++++- 17 files changed, 575 insertions(+), 435 deletions(-) delete mode 100644 src/frontend/src/modals/apiModal/index.tsx create mode 100644 src/frontend/src/modals/apiModal/utils/build-content.tsx create mode 100644 src/frontend/src/modals/apiModal/utils/build-tweaks.ts create mode 100644 src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts create mode 100644 src/frontend/src/modals/apiModal/utils/get-changes-types.ts create mode 100644 src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts create mode 100644 src/frontend/src/modals/apiModal/utils/get-value.ts create mode 100644 src/frontend/src/modals/apiModal/views/index.tsx create mode 100644 src/frontend/src/stores/tweaksStore.ts create mode 100644 src/frontend/src/types/zustand/tweaks/index.ts diff --git a/src/frontend/src/components/accordionComponent/index.tsx b/src/frontend/src/components/accordionComponent/index.tsx index fd9e42580..fdcf8b96c 100644 --- a/src/frontend/src/components/accordionComponent/index.tsx +++ b/src/frontend/src/components/accordionComponent/index.tsx @@ -15,17 +15,16 @@ export default function AccordionComponent({ sideBar, }: AccordionComponentType): JSX.Element { const [value, setValue] = useState( - open.length === 0 ? "" : getOpenAccordion() + open.length === 0 ? "" : getOpenAccordion(), ); function getOpenAccordion(): string { let value = ""; open.forEach((el) => { - if (el == trigger) { - value = trigger; + if (el == keyValue) { + value = keyValue; } }); - return value; } diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index 7d55f9229..5de2198a0 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -1,7 +1,7 @@ import { Transition } from "@headlessui/react"; import { useEffect, useMemo, useRef, useState } from "react"; import IOModal from "../../modals/IOModal"; -import ApiModal from "../../modals/apiModal"; +import ApiModal from "../../modals/apiModal/views"; import ShareModal from "../../modals/shareModal"; import useFlowStore from "../../stores/flowStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index 355ddb1ec..c40c11439 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -41,6 +41,8 @@ import IconComponent from "../genericIconComponent"; import InputComponent from "../inputComponent"; import KeypairListComponent from "../keypairListComponent"; import ShadTooltip from "../shadTooltipComponent"; +import { Label } from "../ui/label"; +import { Switch } from "../ui/switch"; export default function CodeTabsComponent({ flow, @@ -49,14 +51,13 @@ export default function CodeTabsComponent({ setActiveTab, isMessage, tweaks, + setActiveTweaks, + activeTweaks, }: codeTabsPropsType) { const [isCopied, setIsCopied] = useState(false); const [data, setData] = useState(flow ? flow["data"]!["nodes"] : null); - const [openAccordion, setOpenAccordion] = useState([]); const dark = useDarkStore((state) => state.dark); const unselectAll = useFlowStore((state) => state.unselectAll); - const setNode = useFlowStore((state) => state.setNode); - const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); useEffect(() => { @@ -107,21 +108,6 @@ export default function CodeTabsComponent({ URL.revokeObjectURL(url); }; - function openAccordions() { - let accordionsToOpen: string[] = []; - tweaks?.tweak!.current.forEach((el) => { - Object.keys(el).forEach((key) => { - if (Object.keys(el[key]).length > 0) { - accordionsToOpen.push(key); - setOpenAccordion(accordionsToOpen); - } - }); - }); - - if (accordionsToOpen.length == 0) { - setOpenAccordion([]); - } - } return ( { setActiveTab(value); - if (value === "3") { - openAccordions(); - } }} >
@@ -155,27 +138,58 @@ export default function CodeTabsComponent({ ) : (
)} - {Number(activeTab) < 4 && ( -
- - + Tweaks +
- )} + + {Number(activeTab) < 4 && ( + <> + + + + )} +
{tabs.map((tab, idx) => ( @@ -205,14 +219,12 @@ export default function CodeTabsComponent({
{data?.map((node: any, i) => (
- {tweaks?.tweaksList!.current.includes( - node["data"]["id"] - ) && ( + {tweaks?.tweaksList!.includes(node["data"]["id"]) && ( {node["data"]["node"]["display_name"]}
} - open={openAccordion} keyValue={node["data"]["id"]} >
@@ -247,8 +258,8 @@ export default function CodeTabsComponent({ .show && LANGFLOW_SUPPORTED_TYPES.has( node.data.node.template[templateField] - .type - ) + .type, + ), ) .map((templateField, indx) => { return ( @@ -298,12 +309,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -339,13 +350,13 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node .template[ templateField - ] + ], ); }} /> @@ -383,12 +394,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -416,12 +427,12 @@ export default function CodeTabsComponent({ ].value = e; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], e, node.data.node.template[ templateField - ] + ], ); }} size="small" @@ -447,7 +458,7 @@ export default function CodeTabsComponent({ ].fileTypes } onFileChange={( - value: any + value: any, ) => { node.data.node.template[ templateField @@ -490,12 +501,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -525,12 +536,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} value={ @@ -582,12 +593,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -623,12 +634,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -664,12 +675,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -693,7 +704,7 @@ export default function CodeTabsComponent({ node.data.node! .template[ templateField - ].value + ].value, ) } duplicateKey={ @@ -702,15 +713,15 @@ export default function CodeTabsComponent({ onChange={(target) => { const valueToNumbers = convertValuesToNumbers( - target + target, ); node.data.node!.template[ templateField ].value = valueToNumbers; setErrorDuplicateKey( hasDuplicateKeys( - valueToNumbers - ) + valueToNumbers, + ), ); setData((old) => { let newInputList = @@ -722,12 +733,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} isList={ @@ -767,12 +778,12 @@ export default function CodeTabsComponent({ ].value = target; return newInputList; }); - tweaks.buildTweakObject!( + tweaks?.buildTweakObject!( node["data"]["id"], target, node.data.node.template[ templateField - ] + ], ); }} /> @@ -795,7 +806,7 @@ export default function CodeTabsComponent({ )} - {tweaks?.tweaksList!.current.length === 0 && ( + {tweaks?.tweaksList!.length === 0 && ( <>
No tweaks are available for this flow. diff --git a/src/frontend/src/modals/apiModal/index.tsx b/src/frontend/src/modals/apiModal/index.tsx deleted file mode 100644 index 9e847aae5..000000000 --- a/src/frontend/src/modals/apiModal/index.tsx +++ /dev/null @@ -1,245 +0,0 @@ -import "ace-builds/src-noconflict/ext-language_tools"; -import "ace-builds/src-noconflict/mode-python"; -import "ace-builds/src-noconflict/theme-github"; -import "ace-builds/src-noconflict/theme-twilight"; -import { - ReactNode, - forwardRef, - useContext, - useEffect, - useRef, - useState, -} from "react"; -// import "ace-builds/webpack-resolver"; -import CodeTabsComponent from "../../components/codeTabsComponent"; -import IconComponent from "../../components/genericIconComponent"; -import { - EXPORT_CODE_DIALOG, - LANGFLOW_SUPPORTED_TYPES, -} from "../../constants/constants"; -import { AuthContext } from "../../contexts/authContext"; -import useFlowStore from "../../stores/flowStore"; -import { TemplateVariableType } from "../../types/api"; -import { tweakType, uniqueTweakType } from "../../types/components"; -import { FlowType, NodeType } from "../../types/flow/index"; -import { buildTweaks, convertArrayToObj } from "../../utils/reactflowUtils"; -import { - getCurlCode, - getPythonApiCode, - getPythonCode, - getWidgetCode, - tabsArray, -} from "../../utils/utils"; -import BaseModal from "../baseModal"; - -const ApiModal = forwardRef( - ( - { - flow, - children, - }: { - flow: FlowType; - children: ReactNode; - }, - ref - ) => { - const { autoLogin } = useContext(AuthContext); - const [open, setOpen] = useState(false); - const [activeTab, setActiveTab] = useState("0"); - const tweak = useRef([]); - const tweaksList = useRef([]); - const [getTweak, setTweak] = useState([]); - const flowState = useFlowStore((state) => state.flowState); - const pythonApiCode = getPythonApiCode(flow, autoLogin, tweak.current); - const curl_code = getCurlCode(flow, autoLogin, tweak.current); - const pythonCode = getPythonCode(flow, tweak.current); - const widgetCode = getWidgetCode(flow, autoLogin, flowState); - const tweaksCode = buildTweaks(flow); - const codesArray = [ - curl_code, - pythonApiCode, - pythonCode, - widgetCode, - pythonCode, - ]; - const [tabs, setTabs] = useState(tabsArray(codesArray, 0)); - - function startState() { - tweak.current = []; - setTweak([]); - tweaksList.current = []; - } - - useEffect(() => { - if (flow["data"]!["nodes"].length == 0) { - startState(); - } else { - tweak.current = []; - const t = buildTweaks(flow); - tweak.current.push(t); - } - - filterNodes(); - - if (Object.keys(tweaksCode).length > 0) { - setActiveTab("0"); - setTabs(tabsArray(codesArray, 1)); - } else { - setTabs(tabsArray(codesArray, 1)); - } - }, [flow["data"]!["nodes"], open]); - - function filterNodes() { - let arrNodesWithValues: string[] = []; - - flow["data"]!["nodes"].forEach((node) => { - if (!node["data"]["node"]["template"]) { - return; - } - Object.keys(node["data"]["node"]["template"]) - .filter( - (templateField) => - templateField.charAt(0) !== "_" && - node.data.node.template[templateField].show && - LANGFLOW_SUPPORTED_TYPES.has( - node.data.node.template[templateField].type - ) - ) - .map((n, i) => { - arrNodesWithValues.push(node["id"]); - }); - }); - - tweaksList.current = arrNodesWithValues.filter((value, index, self) => { - return self.indexOf(value) === index; - }); - } - function buildTweakObject( - tw: string, - changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType - ) { - if (typeof changes === "string" && template.type === "float") { - changes = parseFloat(changes); - } - if (typeof changes === "string" && template.type === "int") { - changes = parseInt(changes); - } - if (template.list === true && Array.isArray(changes)) { - changes = changes?.filter((x) => x !== ""); - } - - if (template.type === "dict" && Array.isArray(changes)) { - changes = convertArrayToObj(changes); - } - - if (template.type === "NestedDict") { - changes = JSON.stringify(changes); - } - - const existingTweak = tweak.current.find((element) => - element.hasOwnProperty(tw) - ); - - if (existingTweak) { - existingTweak[tw][template["name"]!] = changes as string; - - if (existingTweak[tw][template["name"]!] == template.value) { - tweak.current.forEach((element) => { - if (element[tw] && Object.keys(element[tw])?.length === 0) { - tweak.current = tweak.current.filter((obj) => { - const prop = obj[Object.keys(obj)[0]].prop; - return prop !== undefined && prop !== null && prop !== ""; - }); - } - }); - } - } else { - const newTweak = { - [tw]: { - [template["name"]!]: changes, - }, - } as uniqueTweakType; - tweak.current.push(newTweak); - } - - const pythonApiCode = getPythonApiCode(flow, autoLogin, tweak.current); - const curl_code = getCurlCode(flow, autoLogin, tweak.current); - const pythonCode = getPythonCode(flow, tweak.current); - const widgetCode = getWidgetCode(flow, autoLogin, flowState); - - tabs![0].code = curl_code; - tabs![1].code = pythonApiCode; - tabs![2].code = pythonCode; - tabs![3].code = widgetCode; - - setTweak(tweak.current); - } - - function buildContent(value: string) { - const htmlContent = ( -
- {value != null && value != "" ? value : "None"} -
- ); - return htmlContent; - } - - function getValue( - value: string, - node: NodeType, - template: TemplateVariableType - ) { - let returnValue = value ?? ""; - - if (getTweak.length > 0) { - for (const obj of getTweak) { - Object.keys(obj).forEach((key) => { - const value = obj[key]; - if (key == node["id"]) { - Object.keys(value).forEach((key) => { - if (key == template["name"]) { - returnValue = value[key]; - } - }); - } - }); - } - } else { - return value ?? ""; - } - return returnValue; - } - - return ( - - {children} - - API - - - - - - ); - } -); - -export default ApiModal; diff --git a/src/frontend/src/modals/apiModal/utils/build-content.tsx b/src/frontend/src/modals/apiModal/utils/build-content.tsx new file mode 100644 index 000000000..80468fe71 --- /dev/null +++ b/src/frontend/src/modals/apiModal/utils/build-content.tsx @@ -0,0 +1,10 @@ +export function buildContent(value: string) { + const htmlContent = ( +
+ {value != null && value != "" ? value : "None"} +
+ ); + return htmlContent; +} + +export default buildContent; diff --git a/src/frontend/src/modals/apiModal/utils/build-tweaks.ts b/src/frontend/src/modals/apiModal/utils/build-tweaks.ts new file mode 100644 index 000000000..82d35302a --- /dev/null +++ b/src/frontend/src/modals/apiModal/utils/build-tweaks.ts @@ -0,0 +1,8 @@ +import { FlowType } from "../../../types/flow"; + +export function buildTweaks(flow: FlowType) { + return flow.data!.nodes.reduce((acc, node) => { + acc[node.data.id] = {}; + return acc; + }, {}); +} diff --git a/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts b/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts new file mode 100644 index 000000000..5a859cae8 --- /dev/null +++ b/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts @@ -0,0 +1,13 @@ +import { LANGFLOW_SUPPORTED_TYPES } from "../../../constants/constants"; + +export const checkCanBuildTweakObject = (element, templateField) => { + return ( + element.data.node.template[templateField] && + templateField.charAt(0) !== "_" && + element.data.node.template[templateField].show && + LANGFLOW_SUPPORTED_TYPES.has( + element.data.node.template[templateField].type, + ) && + templateField !== "code" + ); +}; diff --git a/src/frontend/src/modals/apiModal/utils/get-changes-types.ts b/src/frontend/src/modals/apiModal/utils/get-changes-types.ts new file mode 100644 index 000000000..e8e912ff3 --- /dev/null +++ b/src/frontend/src/modals/apiModal/utils/get-changes-types.ts @@ -0,0 +1,26 @@ +import { TemplateVariableType } from "../../../types/api"; +import { convertArrayToObj } from "../../../utils/reactflowUtils"; + +export const getChangesType = ( + changes: string | string[] | boolean | number | Object[] | Object, + template: TemplateVariableType, +) => { + if (typeof changes === "string" && template.type === "float") { + changes = parseFloat(changes); + } + if (typeof changes === "string" && template.type === "int") { + changes = parseInt(changes); + } + if (template.list === true && Array.isArray(changes)) { + changes = changes?.filter((x) => x !== ""); + } + + if (template.type === "dict" && Array.isArray(changes)) { + changes = convertArrayToObj(changes); + } + + if (template.type === "NestedDict") { + changes = JSON.stringify(changes); + } + return changes; +}; diff --git a/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts b/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts new file mode 100644 index 000000000..fb30a57a1 --- /dev/null +++ b/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts @@ -0,0 +1,28 @@ +import { LANGFLOW_SUPPORTED_TYPES } from "../../../constants/constants"; + +export const getNodesWithDefaultValue = (flow) => { + let arrNodesWithValues: string[] = []; + + flow["data"]!["nodes"].forEach((node) => { + if (!node["data"]["node"]["template"]) { + return; + } + Object.keys(node["data"]["node"]["template"]) + .filter( + (templateField) => + templateField.charAt(0) !== "_" && + node.data.node.template[templateField].show && + LANGFLOW_SUPPORTED_TYPES.has( + node.data.node.template[templateField].type, + ), + ) + .map((n, i) => { + arrNodesWithValues.push(node["id"]); + }); + }); + + const tweaksListFiltered = arrNodesWithValues.filter((value, index, self) => { + return self.indexOf(value) === index; + }); + return tweaksListFiltered; +}; diff --git a/src/frontend/src/modals/apiModal/utils/get-value.ts b/src/frontend/src/modals/apiModal/utils/get-value.ts new file mode 100644 index 000000000..df8e5bdde --- /dev/null +++ b/src/frontend/src/modals/apiModal/utils/get-value.ts @@ -0,0 +1,29 @@ +import { TemplateVariableType } from "../../../types/api"; +import { NodeType } from "../../../types/flow"; + +export const getValue = ( + value: string, + node: NodeType, + template: TemplateVariableType, + tweak: Object[], +) => { + let returnValue = value ?? ""; + + if (tweak.length > 0) { + for (const obj of tweak) { + Object.keys(obj).forEach((key) => { + const value = obj[key]; + if (key == node["id"]) { + Object.keys(value).forEach((key) => { + if (key == template["name"]) { + returnValue = value[key]; + } + }); + } + }); + } + } else { + return value ?? ""; + } + return returnValue; +}; diff --git a/src/frontend/src/modals/apiModal/views/index.tsx b/src/frontend/src/modals/apiModal/views/index.tsx new file mode 100644 index 000000000..6aebb7618 --- /dev/null +++ b/src/frontend/src/modals/apiModal/views/index.tsx @@ -0,0 +1,211 @@ +import "ace-builds/src-noconflict/ext-language_tools"; +import "ace-builds/src-noconflict/mode-python"; +import "ace-builds/src-noconflict/theme-github"; +import "ace-builds/src-noconflict/theme-twilight"; +import { ReactNode, forwardRef, useContext, useEffect, useState } from "react"; +// import "ace-builds/webpack-resolver"; +import { cloneDeep } from "lodash"; +import CodeTabsComponent from "../../../components/codeTabsComponent"; +import IconComponent from "../../../components/genericIconComponent"; +import { EXPORT_CODE_DIALOG } from "../../../constants/constants"; +import { AuthContext } from "../../../contexts/authContext"; +import { useTweaksStore } from "../../../stores/tweaksStore"; +import { TemplateVariableType } from "../../../types/api"; +import { uniqueTweakType } from "../../../types/components"; +import { FlowType } from "../../../types/flow/index"; +import { + getCurlCode, + getPythonApiCode, + getPythonCode, + getWidgetCode, + tabsArray, +} from "../../../utils/utils"; +import BaseModal from "../../baseModal"; +import { buildContent } from "../utils/build-content"; +import { buildTweaks } from "../utils/build-tweaks"; +import { checkCanBuildTweakObject } from "../utils/check-can-build-tweak-object"; +import { getChangesType } from "../utils/get-changes-types"; +import { getNodesWithDefaultValue } from "../utils/get-nodes-with-default-value"; +import { getValue } from "../utils/get-value"; + +const ApiModal = forwardRef( + ( + { + flow, + children, + }: { + flow: FlowType; + children: ReactNode; + }, + ref, + ) => { + const tweak = useTweaksStore((state) => state.tweak); + const addTweaks = useTweaksStore((state) => state.setTweak); + const setTweaksList = useTweaksStore((state) => state.setTweaksList); + const tweaksList = useTweaksStore((state) => state.tweaksList); + + const [activeTweaks, setActiveTweaks] = useState(false); + const { autoLogin } = useContext(AuthContext); + const [open, setOpen] = useState(false); + const [activeTab, setActiveTab] = useState("0"); + const pythonApiCode = getPythonApiCode(flow?.id, autoLogin, tweak); + const curl_code = getCurlCode(flow?.id, autoLogin, tweak); + const pythonCode = getPythonCode(flow?.name, tweak); + const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); + const tweaksCode = buildTweaks(flow); + const codesArray = [ + curl_code, + pythonApiCode, + pythonCode, + widgetCode, + pythonCode, + ]; + const [tabs, setTabs] = useState(tabsArray(codesArray, 0)); + + const canShowTweaks = + flow && + flow["data"] && + flow["data"]!["nodes"] && + tweak && + tweak?.length > 0 && + activeTweaks === true; + + const buildTweaksInitialState = () => { + const newTweak: any = []; + const t = buildTweaks(flow); + newTweak.push(t); + addTweaks(newTweak); + addCodes(newTweak); + }; + + useEffect(() => { + if (flow["data"]!["nodes"].length == 0) { + addTweaks([]); + setTweaksList([]); + } else { + buildTweaksInitialState(); + } + + filterNodes(); + + if (Object.keys(tweaksCode).length > 0) { + setActiveTab("0"); + setTabs(tabsArray(codesArray, 1)); + } else { + setTabs(tabsArray(codesArray, 1)); + } + }, [flow["data"]!["nodes"], open]); + + useEffect(() => { + if (canShowTweaks) { + const nodes = flow["data"]!["nodes"]; + nodes.forEach((element) => { + const nodeId = element["id"]; + const template = element["data"]["node"]["template"]; + + Object.keys(template).forEach((templateField) => { + if (checkCanBuildTweakObject(element, templateField)) { + buildTweakObject( + nodeId, + element.data.node.template[templateField].value, + element.data.node.template[templateField], + ); + } + }); + }); + } else { + buildTweaksInitialState(); + } + }, [activeTweaks]); + + const filterNodes = () => { + setTweaksList(getNodesWithDefaultValue(flow)); + }; + + async function buildTweakObject( + tw: string, + changes: string | string[] | boolean | number | Object[] | Object, + template: TemplateVariableType, + ) { + changes = getChangesType(changes, template); + + const existingTweak = tweak.find((element) => element.hasOwnProperty(tw)); + + if (existingTweak) { + existingTweak[tw][template["name"]!] = changes as string; + + if (existingTweak[tw][template["name"]!] == template.value) { + tweak.forEach((element) => { + if (element[tw] && Object.keys(element[tw])?.length === 0) { + const filteredTweaks = tweak.filter((obj) => { + const prop = obj[Object.keys(obj)[0]].prop; + return prop !== undefined && prop !== null && prop !== ""; + }); + addTweaks(filteredTweaks); + } + }); + } + } else { + const newTweak = { + [tw]: { + [template["name"]!]: changes, + }, + } as uniqueTweakType; + tweak.push(newTweak); + } + + if (tweak && tweak.length > 0) { + const cloneTweak = cloneDeep(tweak); + addCodes(cloneTweak); + addTweaks(cloneTweak); + } + } + + const addCodes = (cloneTweak) => { + const pythonApiCode = getPythonApiCode(flow?.id, autoLogin, cloneTweak); + const curl_code = getCurlCode(flow?.id, autoLogin, cloneTweak); + const pythonCode = getPythonCode(flow?.name, cloneTweak); + const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); + + if (tabs && tabs?.length > 0) { + tabs![0].code = curl_code; + tabs![1].code = pythonApiCode; + tabs![2].code = pythonCode; + tabs![3].code = widgetCode; + } + }; + + return ( + + {children} + + API + + + + + + ); + }, +); + +export default ApiModal; diff --git a/src/frontend/src/stores/tweaksStore.ts b/src/frontend/src/stores/tweaksStore.ts new file mode 100644 index 000000000..cbf035b6f --- /dev/null +++ b/src/frontend/src/stores/tweaksStore.ts @@ -0,0 +1,9 @@ +import { create } from "zustand"; +import { TweaksStoreType } from "../types/zustand/tweaks"; + +export const useTweaksStore = create((set, get) => ({ + tweak: [], + setTweak: (tweak) => set({ tweak }), + tweaksList: [], + setTweaksList: (tweaksList) => set({ tweaksList }), +})); diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 2a3ee29b7..d883b7014 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -511,7 +511,7 @@ export type nodeToolbarPropsType = { updateNodeCode?: ( newNodeClass: APIClassType, code: string, - name: string + name: string, ) => void; setShowState: (show: boolean | SetStateAction) => void; isOutdated?: boolean; @@ -561,7 +561,7 @@ export type chatMessagePropsType = { updateChat: ( chat: ChatMessageType, message: string, - stream_url?: string + stream_url?: string, ) => void; }; @@ -646,20 +646,23 @@ export type codeTabsPropsType = { setActiveTab: (value: string) => void; isMessage?: boolean; tweaks?: { - tweak?: { current: tweakType }; - tweaksList?: { current: Array }; + tweak?: tweakType; + tweaksList?: Array; buildContent?: (value: string) => ReactNode; getValue?: ( value: string, node: NodeType, - template: TemplateVariableType + template: TemplateVariableType, + tweak: tweakType, ) => string; buildTweakObject?: ( tw: string, changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType - ) => string | void; + template: TemplateVariableType, + ) => Promise; }; + activeTweaks?: boolean; + setActiveTweaks?: (value: boolean) => void; }; export type crashComponentPropsType = { diff --git a/src/frontend/src/types/zustand/tweaks/index.ts b/src/frontend/src/types/zustand/tweaks/index.ts new file mode 100644 index 000000000..3eb0a5f73 --- /dev/null +++ b/src/frontend/src/types/zustand/tweaks/index.ts @@ -0,0 +1,8 @@ +import { tweakType } from "../../components"; + +export type TweaksStoreType = { + tweak: tweakType; + setTweak: (tweak: tweakType) => void; + tweaksList: string[]; + setTweaksList: (tweaksList: string[]) => void; +}; diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index deb470f80..83772ee0d 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -102,18 +102,18 @@ export function unselectAllNodes({ updateNodes, data }: unselectAllNodesType) { export function isValidConnection( { source, target, sourceHandle, targetHandle }: Connection, nodes: Node[], - edges: Edge[] + edges: Edge[], ) { const targetHandleObject: targetHandleType = scapeJSONParse(targetHandle!); const sourceHandleObject: sourceHandleType = scapeJSONParse(sourceHandle!); if ( targetHandleObject.inputTypes?.some( - (n) => n === sourceHandleObject.dataType + (n) => n === sourceHandleObject.dataType, ) || sourceHandleObject.baseClasses.some( (t) => targetHandleObject.inputTypes?.some((n) => n === t) || - t === targetHandleObject.type + t === targetHandleObject.type, ) ) { let targetNode = nodes.find((node) => node.id === target!)?.data?.node; @@ -146,7 +146,7 @@ export function removeApiKeys(flow: FlowType): FlowType { export function updateTemplate( reference: APITemplateType, - objectToUpdate: APITemplateType + objectToUpdate: APITemplateType, ): APITemplateType { let clonedObject: APITemplateType = cloneDeep(reference); @@ -206,7 +206,7 @@ export const processDataFromFlow = (flow: FlowType, refreshIds = true) => { export function updateIds( { edges, nodes }: { edges: Edge[]; nodes: Node[] }, - selection?: { edges: Edge[]; nodes: Node[] } + selection?: { edges: Edge[]; nodes: Node[] }, ) { let idsMap = {}; const selectionIds = selection?.nodes.map((n) => n.id); @@ -234,7 +234,7 @@ export function updateIds( edge.source = idsMap[edge.source]; edge.target = idsMap[edge.target]; const sourceHandleObject: sourceHandleType = scapeJSONParse( - edge.sourceHandle! + edge.sourceHandle!, ); edge.sourceHandle = scapedJSONStringfy({ ...sourceHandleObject, @@ -244,7 +244,7 @@ export function updateIds( edge.data.sourceHandle.id = edge.source; } const targetHandleObject: targetHandleType = scapeJSONParse( - edge.targetHandle! + edge.targetHandle!, ); edge.targetHandle = scapedJSONStringfy({ ...targetHandleObject, @@ -264,13 +264,6 @@ export function updateIds( return idsMap; } -export function buildTweaks(flow: FlowType) { - return flow.data!.nodes.reduce((acc, node) => { - acc[node.data.id] = {}; - return acc; - }, {}); -} - export function validateNode(node: NodeType, edges: Edge[]): Array { if (!node.data?.node?.template || !Object.keys(node.data.node.template)) { return [ @@ -297,11 +290,11 @@ export function validateNode(node: NodeType, edges: Edge[]): Array { (scapeJSONParse(edge.targetHandle!) as targetHandleType).fieldName === t && (scapeJSONParse(edge.targetHandle!) as targetHandleType).id === - node.id + node.id, ) ) { errors.push( - `${displayName || type} is missing ${getFieldTitle(template, t)}.` + `${displayName || type} is missing ${getFieldTitle(template, t)}.`, ); } else if ( template[t].type === "dict" && @@ -315,15 +308,15 @@ export function validateNode(node: NodeType, edges: Edge[]): Array { errors.push( `${displayName || type} (${getFieldTitle( template, - t - )}) contains duplicate keys with the same values.` + t, + )}) contains duplicate keys with the same values.`, ); if (hasEmptyKey(template[t].value)) errors.push( `${displayName || type} (${getFieldTitle( template, - t - )}) field must not be empty.` + t, + )}) field must not be empty.`, ); } return errors; @@ -332,7 +325,7 @@ export function validateNode(node: NodeType, edges: Edge[]): Array { export function validateNodes( nodes: Node[], - edges: Edge[] + edges: Edge[], ): // this returns an array of tuples with the node id and the errors Array<{ id: string; errors: Array }> { if (nodes.length === 0) { @@ -353,7 +346,7 @@ export function updateEdges(edges: Edge[]) { if (edges) edges.forEach((edge) => { const targetHandleObject: targetHandleType = scapeJSONParse( - edge.targetHandle! + edge.targetHandle!, ); edge.className = "stroke-gray-900 stroke-connection"; }); @@ -420,7 +413,7 @@ export function handleKeyDown( | React.KeyboardEvent | React.KeyboardEvent, inputValue: string | string[] | null, - block: string + block: string, ) { //condition to fix bug control+backspace on Windows/Linux if ( @@ -445,7 +438,7 @@ export function handleKeyDown( } export function handleOnlyIntegerInput( - event: React.KeyboardEvent + event: React.KeyboardEvent, ) { if ( event.key === "." || @@ -461,7 +454,7 @@ export function handleOnlyIntegerInput( export function getConnectedNodes( edge: Edge, - nodes: Array + nodes: Array, ): Array { const sourceId = edge.source; const targetId = edge.target; @@ -561,7 +554,7 @@ export function checkOldEdgesHandles(edges: Edge[]): boolean { !edge.sourceHandle || !edge.targetHandle || !edge.sourceHandle.includes("{") || - !edge.targetHandle.includes("{") + !edge.targetHandle.includes("{"), ); } @@ -584,7 +577,7 @@ export function customStringify(obj: any): string { const keys = Object.keys(obj).sort(); const keyValuePairs = keys.map( - (key) => `"${key}":${customStringify(obj[key])}` + (key) => `"${key}":${customStringify(obj[key])}`, ); return `{${keyValuePairs.join(",")}}`; } @@ -613,7 +606,7 @@ export function getHandleId( source: string, sourceHandle: string, target: string, - targetHandle: string + targetHandle: string, ) { return ( "reactflow__edge-" + source + sourceHandle + "-" + target + targetHandle @@ -624,7 +617,7 @@ export function generateFlow( selection: OnSelectionChangeParams, nodes: Node[], edges: Edge[], - name: string + name: string, ): generateFlowType { const newFlowData = { nodes, edges, viewport: { zoom: 1, x: 0, y: 0 } }; const uid = new ShortUniqueId({ length: 5 }); @@ -633,7 +626,7 @@ export function generateFlow( newFlowData.edges = selection.edges.filter( (edge) => selection.nodes.some((node) => node.id === edge.target) && - selection.nodes.some((node) => node.id === edge.source) + selection.nodes.some((node) => node.id === edge.source), ); newFlowData.nodes = selection.nodes; @@ -654,7 +647,7 @@ export function generateFlow( (edge) => (selection.nodes.some((node) => node.id === edge.target) || selection.nodes.some((node) => node.id === edge.source)) && - newFlowData.edges.every((e) => e.id !== edge.id) + newFlowData.edges.every((e) => e.id !== edge.id), ), }; } @@ -665,13 +658,13 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) { const { nodes, edges } = groupNode.data.node!.flow!.data!; const lastNode = findLastNode(groupNode.data.node!.flow!.data!); newEdges = newEdges.filter( - (e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id) + (e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id), ); newEdges.forEach((edge) => { if (lastNode && edge.source === lastNode.id) { edge.source = groupNode.id; let newSourceHandle: sourceHandleType = scapeJSONParse( - edge.sourceHandle! + edge.sourceHandle!, ); newSourceHandle.id = groupNode.id; edge.sourceHandle = scapedJSONStringfy(newSourceHandle); @@ -698,7 +691,7 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) { export function filterFlow( selection: OnSelectionChangeParams, setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void, - setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void + setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void, ) { setNodes((nodes) => nodes.filter((node) => !selection.nodes.includes(node))); setEdges((edges) => edges.filter((edge) => !selection.edges.includes(edge))); @@ -736,7 +729,7 @@ export function updateFlowPosition(NewPosition: XYPosition, flow: FlowType) { export function concatFlows( flow: FlowType, setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void, - setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void + setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void, ) { const { nodes, edges } = flow.data!; setNodes((old) => [...old, ...nodes]); @@ -745,7 +738,7 @@ export function concatFlows( export function validateSelection( selection: OnSelectionChangeParams, - edges: Edge[] + edges: Edge[], ): Array { //add edges to selection if selection mode selected only nodes if (selection.edges.length === 0) { @@ -757,7 +750,7 @@ export function validateSelection( let nodesSet = new Set(selection.nodes.map((n) => n.id)); // then filter the edges that are connected to the nodes in the set let connectedEdges = selection.edges.filter( - (e) => nodesSet.has(e.source) && nodesSet.has(e.target) + (e) => nodesSet.has(e.source) && nodesSet.has(e.target), ); // add the edges to the selection selection.edges = connectedEdges; @@ -771,17 +764,17 @@ export function validateSelection( selection.nodes.some( (node) => isInputNode(node.data as NodeDataType) || - isOutputNode(node.data as NodeDataType) + isOutputNode(node.data as NodeDataType), ) ) { errorsArray.push( - "Please select only nodes that are not input or output nodes" + "Please select only nodes that are not input or output nodes", ); } //check if there are two or more nodes with free outputs if ( selection.nodes.filter( - (n) => !selection.edges.some((e) => e.source === n.id) + (n) => !selection.edges.some((e) => e.source === n.id), ).length > 1 ) { errorsArray.push("Please select only one node with free outputs"); @@ -792,7 +785,7 @@ export function validateSelection( selection.nodes.some( (node) => !selection.edges.some((edge) => edge.target === node.id) && - !selection.edges.some((edge) => edge.source === node.id) + !selection.edges.some((edge) => edge.source === node.id), ) ) { errorsArray.push("Please select only nodes that are connected"); @@ -849,8 +842,8 @@ export function mergeNodeTemplates({ nodeTemplate[key].display_name ? nodeTemplate[key].display_name : nodeTemplate[key].name - ? toTitleCase(nodeTemplate[key].name) - : toTitleCase(key); + ? toTitleCase(nodeTemplate[key].name) + : toTitleCase(key); } } }); @@ -861,7 +854,7 @@ function isHandleConnected( edges: Edge[], key: string, field: TemplateVariableType, - nodeId: string + nodeId: string, ) { /* this function receives a flow and a handleId and check if there is a connection with this handle @@ -877,7 +870,7 @@ function isHandleConnected( id: nodeId, proxy: { id: field.proxy!.id, field: field.proxy!.field }, inputTypes: field.input_types, - } as targetHandleType) + } as targetHandleType), ) ) { return true; @@ -892,7 +885,7 @@ function isHandleConnected( fieldName: key, id: nodeId, inputTypes: field.input_types, - } as targetHandleType) + } as targetHandleType), ) ) { return true; @@ -915,7 +908,7 @@ export function generateNodeTemplate(Flow: FlowType) { export function generateNodeFromFlow( flow: FlowType, - getNodeId: (type: string) => string + getNodeId: (type: string) => string, ): NodeType { const { nodes } = flow.data!; const outputNode = cloneDeep(findLastNode(flow.data!)); @@ -946,7 +939,7 @@ export function generateNodeFromFlow( export function connectedInputNodesOnHandle( nodeId: string, handleId: string, - { nodes, edges }: { nodes: NodeType[]; edges: Edge[] } + { nodes, edges }: { nodes: NodeType[]; edges: Edge[] }, ) { const connectedNodes: Array<{ name: string; id: string; isGroup: boolean }> = []; @@ -983,7 +976,7 @@ export function connectedInputNodesOnHandle( export function updateProxyIdsOnTemplate( template: APITemplateType, - idsMap: { [key: string]: string } + idsMap: { [key: string]: string }, ) { Object.keys(template).forEach((key) => { if (template[key].proxy && idsMap[template[key].proxy!.id]) { @@ -994,7 +987,7 @@ export function updateProxyIdsOnTemplate( export function updateEdgesIds( edges: Edge[], - idsMap: { [key: string]: string } + idsMap: { [key: string]: string }, ) { edges.forEach((edge) => { let targetHandle: targetHandleType = edge.data.targetHandle; @@ -1027,7 +1020,7 @@ export function expandGroupNode( nodes: Node[], edges: Edge[], setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void, - setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void + setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void, ) { const idsMap = updateIds(flow!.data!); updateProxyIdsOnTemplate(template, idsMap); @@ -1070,7 +1063,7 @@ export function expandGroupNode( const lastNode = cloneDeep(findLastNode(flow!.data!)); newEdge.source = lastNode!.id; let newSourceHandle: sourceHandleType = scapeJSONParse( - newEdge.sourceHandle! + newEdge.sourceHandle!, ); newSourceHandle.id = lastNode!.id; newEdge.data.sourceHandle = newSourceHandle; @@ -1124,7 +1117,7 @@ export function expandGroupNode( export function getGroupStatus( flow: FlowType, - ssData: { [key: string]: { valid: boolean; params: string } } + ssData: { [key: string]: { valid: boolean; params: string } }, ) { let status = { valid: true, params: SUCCESS_BUILD }; const { nodes } = flow.data!; @@ -1143,7 +1136,7 @@ export function getGroupStatus( export function createFlowComponent( nodeData: NodeDataType, - version: string + version: string, ): FlowType { const flowNode: FlowType = { data: { @@ -1179,7 +1172,7 @@ export function downloadNode(NodeFLow: FlowType) { export function updateComponentNameAndType( data: any, - component: NodeDataType + component: NodeDataType, ) {} export function removeFileNameFromComponents(flow: FlowType) { @@ -1253,7 +1246,7 @@ export function extractFieldsFromComponenents(data: APIObjectType) { export function downloadFlow( flow: FlowType, flowName: string, - flowDescription?: string + flowDescription?: string, ) { let clonedFlow = cloneDeep(flow); removeFileNameFromComponents(clonedFlow); @@ -1263,7 +1256,7 @@ export function downloadFlow( ...clonedFlow, name: flowName, description: flowDescription, - }) + }), )}`; // create a link element and set its properties @@ -1278,7 +1271,7 @@ export function downloadFlow( export function downloadFlows() { downloadFlowsFromDatabase().then((flows) => { const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent( - JSON.stringify(flows) + JSON.stringify(flows), )}`; // create a link element and set its properties @@ -1293,7 +1286,7 @@ export function downloadFlows() { export const createNewFlow = ( flowData: ReactFlowJsonObject, - flow: FlowType + flow: FlowType, ) => { return { description: flow?.description ?? getRandomDescription(), diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index 7c269d8e4..5e1786404 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -13,9 +13,8 @@ import { nodeGroupedObjType, tweakType, } from "../types/components"; -import { FlowType, NodeType } from "../types/flow"; +import { NodeType } from "../types/flow"; import { FlowState } from "../types/tabs"; -import { buildTweaks } from "./reactflowUtils"; export function classNames(...classes: Array): string { return classes.filter(Boolean).join(" "); @@ -323,17 +322,10 @@ export function getChatInputField(flowState?: FlowState) { * @returns {string} - The python code */ export function getPythonApiCode( - flow: FlowType, + flowId: string, isAuth: boolean, - tweak?: any[], + tweaksBuildedObject, ): string { - const flowId = flow.id; - - // create a dictionary of node ids and the values is an empty dictionary - // flow.data.nodes.forEach((node) => { - // node.data.id - // } - const tweaks = buildTweaks(flow); return `import requests from typing import Optional @@ -341,11 +333,7 @@ BASE_API_URL = "${window.location.protocol}//${window.location.host}/api/v1/run" FLOW_ID = "${flowId}" # You can tweak the flow by adding a tweaks dictionary # e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}} -TWEAKS = ${ - tweak && tweak.length > 0 - ? buildTweakObject(tweak) - : JSON.stringify(tweaks, null, 2) - } +TWEAKS = ${JSON.stringify(tweaksBuildedObject, null, 2)} def run_flow(message: str, flow_id: str, @@ -391,13 +379,10 @@ print(run_flow(message=message, flow_id=FLOW_ID, tweaks=TWEAKS${ * @returns {string} - The curl code */ export function getCurlCode( - flow: FlowType, + flowId: string, isAuth: boolean, - tweak?: any[], + tweaksBuildedObject, ): string { - const flowId = flow.id; - const tweaks = buildTweaks(flow); - return `curl -X POST \\ ${window.location.protocol}//${ window.location.host @@ -408,11 +393,7 @@ export function getCurlCode( -d '{"input_value": "message", "output_type": "chat", "input_type": "chat", - "tweaks": ${ - tweak && tweak.length > 0 - ? buildTweakObject(tweak) - : JSON.stringify(tweaks, null, 2) - }}' + "tweaks": ${JSON.stringify(tweaksBuildedObject, null, 2)}' `; } @@ -439,16 +420,9 @@ export function getOutputIds(flow) { * @param {any[]} tweak - The tweaks * @returns {string} - The python code */ -export function getPythonCode(flow: FlowType, tweak?: any[]): string { - const flowName = flow.name; - const tweaks = buildTweaks(flow); - +export function getPythonCode(flowName: string, tweaksBuildedObject): string { return `from langflow.load import run_flow_from_json -TWEAKS = ${ - tweak && tweak.length > 0 - ? buildTweakObject(tweak) - : JSON.stringify(tweaks, null, 2) - } +TWEAKS = ${JSON.stringify(tweaksBuildedObject, null, 2)} result = run_flow_from_json(flow="${flowName}.json", input_value="message", @@ -461,15 +435,10 @@ result = run_flow_from_json(flow="${flowName}.json", * @returns {string} - The widget code */ export function getWidgetCode( - flow: FlowType, + flowId: string, + flowName: string, isAuth: boolean, - flowState?: FlowState, ): string { - const flowId = flow.id; - const flowName = flow.name; - const inputs = buildInputs(); - let chat_input_field = getChatInputField(flowState); - return ` { await page.getByRole("tab", { name: "cURL" }).click(); await page.getByRole("button", { name: "Copy Code" }).click(); const handle = await page.evaluateHandle(() => - navigator.clipboard.readText() + navigator.clipboard.readText(), ); const clipboardContent = await handle.jsonValue(); const oldValue = clipboardContent; @@ -50,10 +50,78 @@ test("curl_api_generation", async ({ page, context }) => { await page.getByRole("tab", { name: "cURL" }).click(); await page.getByRole("button", { name: "Copy Code" }).click(); const handle2 = await page.evaluateHandle(() => - navigator.clipboard.readText() + navigator.clipboard.readText(), ); const clipboardContent2 = await handle2.jsonValue(); const newValue = clipboardContent2; expect(oldValue).not.toBe(newValue); expect(clipboardContent2.length).toBeGreaterThan(clipboardContent.length); }); + +test("check if tweaks are updating when someothing on the flow changes", async ({ + page, +}) => { + await page.goto("/"); + await page.waitForTimeout(2000); + + let modalCount = 0; + try { + const modalTitleElement = await page?.getByTestId("modal-title"); + if (modalTitleElement) { + modalCount = await modalTitleElement.count(); + } + } catch (error) { + modalCount = 0; + } + + while (modalCount === 0) { + await page.locator('//*[@id="new-project-btn"]').click(); + await page.waitForTimeout(5000); + modalCount = await page.getByTestId("modal-title")?.count(); + } + await page.waitForTimeout(1000); + + await page.getByTestId("blank-flow").click(); + await page.waitForTimeout(1000); + await page.getByTestId("extended-disclosure").click(); + await page.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("Chroma"); + + await page.waitForTimeout(1000); + + await page + .getByTestId("vectorstoresChroma") + .dragTo(page.locator('//*[@id="react-flow-id"]')); + await page.mouse.up(); + await page.mouse.down(); + await page.getByTitle("fit view").click(); + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + await page.getByTestId("input-collection_name").click(); + await page + .getByTestId("input-collection_name") + .fill("collection_name_test_123123123!@#$&*(&%$@"); + + await page.getByTestId("input-index_directory").click(); + await page + .getByTestId("input-index_directory") + .fill("index_directory_123123123!@#$&*(&%$@"); + + await page.getByText("API", { exact: true }).first().click(); + + await page.getByText("Tweaks").nth(1).click(); + + await page.getByText("collection_name_test_123123123!@#$&*(&%$@").isVisible(); + await page.getByText("index_directory_123123123!@#$&*(&%$@").isVisible(); + + await page.getByText("Python API", { exact: true }).click(); + + await page.getByText("collection_name_test_123123123!@#$&*(&%$@").isVisible(); + await page.getByText("index_directory_123123123!@#$&*(&%$@").isVisible(); + + await page.getByText("Python Code", { exact: true }).click(); + + await page.getByText("collection_name_test_123123123!@#$&*(&%$@").isVisible(); + await page.getByText("index_directory_123123123!@#$&*(&%$@").isVisible(); +}); From e36901bb343aaee6080c36c7171ae6bbcd1da371 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 10 May 2024 12:33:05 -0300 Subject: [PATCH 17/55] =?UTF-8?q?=E2=9C=85=20(pyproject.toml):=20update=20?= =?UTF-8?q?package=20versions=20to=201.0.0a31=20and=200.0.42=20for=20'lang?= =?UTF-8?q?flow'=20and=20'langflow-base'=20respectively?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 14 +++++++------- pyproject.toml | 2 +- src/backend/base/pyproject.toml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index daae4b59c..1fefc4bc1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4234,7 +4234,7 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langflow-base" -version = "0.0.41" +version = "0.0.42" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -4289,13 +4289,13 @@ url = "src/backend/base" [[package]] name = "langfuse" -version = "2.29.3" +version = "2.30.0" description = "A client library for accessing langfuse" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langfuse-2.29.3-py3-none-any.whl", hash = "sha256:7471365dc19677eecbc82319c7785f6b8c41437eabe5716c9f262e2f0a2fc43c"}, - {file = "langfuse-2.29.3.tar.gz", hash = "sha256:408873adc3e77725b94e2105be8e1c395f7b8a604f43aa28a772df02e49be088"}, + {file = "langfuse-2.30.0-py3-none-any.whl", hash = "sha256:f5bb91f6fc8f16d99a0f685e57e2d2b2c00edc51c4238f499916a2e7f6810fb5"}, + {file = "langfuse-2.30.0.tar.gz", hash = "sha256:22b2612ba1a78f6bbf173a287e7d77ba9ad9a640d440949a3a7f9c249a777278"}, ] [package.dependencies] @@ -4372,12 +4372,12 @@ proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", " [[package]] name = "llama-cpp-python" -version = "0.2.72" +version = "0.2.73" description = "Python bindings for the llama.cpp library" optional = true python-versions = ">=3.8" files = [ - {file = "llama_cpp_python-0.2.72.tar.gz", hash = "sha256:7da4957043927f73d4425c919c843581e5a3ceb5e65cafbc29bfb45703814a56"}, + {file = "llama_cpp_python-0.2.73.tar.gz", hash = "sha256:78ac8d5f7fa06090255f0b64bf6acf2bc864c32447a1e9fbdf553f7b199fea07"}, ] [package.dependencies] @@ -4804,7 +4804,6 @@ files = [ {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-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f"}, {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"}, @@ -4829,6 +4828,7 @@ files = [ {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"}, diff --git a/pyproject.toml b/pyproject.toml index 282980cbc..e73ca8ec6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a30" +version = "1.0.0a31" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 44f32601c..8be699508 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.41" +version = "0.0.42" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From da256785d0c49bf95dfb98cd09ee7b0b7be933f9 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 10 May 2024 12:34:24 -0300 Subject: [PATCH 18/55] refactor: Improve variable creation logic in VariableService (#1875) * refactor: Improve variable creation logic in VariableService --- .../langflow/services/variable/service.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/backend/base/langflow/services/variable/service.py b/src/backend/base/langflow/services/variable/service.py index ea5126d79..0c9208121 100644 --- a/src/backend/base/langflow/services/variable/service.py +++ b/src/backend/base/langflow/services/variable/service.py @@ -29,17 +29,20 @@ class VariableService(Service): for var in self.settings_service.settings.variables_to_get_from_environment: if var in os.environ: logger.debug(f"Creating {var} variable from environment.") - try: - self.create_variable( - user_id=user_id, - name=var, - value=os.environ[var], - default_fields=[], - _type="Credential", - session=session, - ) - except Exception as e: - logger.error(f"Error creating {var} variable: {e}") + if not session.exec( + select(Variable).where(Variable.user_id == user_id, Variable.name == var) + ).first(): + try: + self.create_variable( + user_id=user_id, + name=var, + value=os.environ[var], + default_fields=[], + _type="Credential", + session=session, + ) + except Exception as e: + logger.error(f"Error creating {var} variable: {e}") else: logger.info("Skipping environment variable storage.") From 8b873b78c953c2e3b3d9db7ae002b46bdbe8aae7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 13 May 2024 11:07:28 -0700 Subject: [PATCH 19/55] Add gpt-4o model --- .../base/langflow/base/models/openai_constants.py | 2 +- .../langflow/components/model_specs/ChatOpenAISpecs.py | 2 +- .../base/langflow/components/models/OpenAIModel.py | 3 +-- .../Basic Prompting (Hello, world!).json | 5 +++-- .../starter_projects/Langflow Blog Writter.json | 5 +++-- .../starter_projects/Langflow Document QA.json | 5 +++-- .../starter_projects/Langflow Memory Conversation.json | 5 +++-- .../starter_projects/Langflow Prompt Chaining.json | 10 ++++++---- .../starter_projects/VectorStore-RAG-Flows.json | 5 +++-- src/backend/base/langflow/utils/constants.py | 1 + 10 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/backend/base/langflow/base/models/openai_constants.py b/src/backend/base/langflow/base/models/openai_constants.py index 89ad8425e..e846229cc 100644 --- a/src/backend/base/langflow/base/models/openai_constants.py +++ b/src/backend/base/langflow/base/models/openai_constants.py @@ -1 +1 @@ -MODEL_NAMES = ["gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", "gpt-3.5-turbo-0125"] +MODEL_NAMES = ["gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", "gpt-3.5-turbo-0125"] diff --git a/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py b/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py index e37eacc77..5a7d47f04 100644 --- a/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py +++ b/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py @@ -52,7 +52,7 @@ class ChatOpenAIComponent(CustomComponent): self, max_tokens: Optional[int] = 256, model_kwargs: NestedDict = {}, - model_name: str = "gpt-4-1106-preview", + model_name: str = "gpt-4o", openai_api_base: Optional[str] = None, openai_api_key: Optional[str] = None, temperature: float = 0.7, diff --git a/src/backend/base/langflow/components/models/OpenAIModel.py b/src/backend/base/langflow/components/models/OpenAIModel.py index a37caefc3..149c93ad3 100644 --- a/src/backend/base/langflow/components/models/OpenAIModel.py +++ b/src/backend/base/langflow/components/models/OpenAIModel.py @@ -41,7 +41,6 @@ class OpenAIModelComponent(LCModelComponent): "display_name": "Model Name", "advanced": False, "options": MODEL_NAMES, - "value": "gpt-4-turbo-preview", }, "openai_api_base": { "display_name": "OpenAI API Base", @@ -79,7 +78,7 @@ class OpenAIModelComponent(LCModelComponent): input_value: Text, openai_api_key: str, temperature: float, - model_name: str, + model_name: str = "gpt-4o", max_tokens: Optional[int] = 256, model_kwargs: NestedDict = {}, openai_api_base: Optional[str] = None, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json index 445f38db9..b8693e13f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json @@ -149,7 +149,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -200,7 +200,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -210,6 +210,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json index 3161b6937..d2e4986ab 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json @@ -453,7 +453,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -504,7 +504,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -514,6 +514,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json index 94156919a..cde05c847 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json @@ -598,7 +598,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -649,7 +649,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -659,6 +659,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index c477eb0e8..a20f7bc19 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -679,7 +679,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -730,7 +730,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -740,6 +740,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json index 7f56faaf0..38dda79d5 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json @@ -798,7 +798,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -849,7 +849,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -859,6 +859,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", @@ -1154,7 +1155,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -1205,7 +1206,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -1215,6 +1216,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", 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 b0f1ad3b1..e13a206c9 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 @@ -793,7 +793,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\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\": MODEL_NAMES,\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 = \"gpt-4o\",\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 if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\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=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, @@ -844,7 +844,7 @@ }, "model_name": { "type": "str", - "required": true, + "required": false, "placeholder": "", "list": true, "show": true, @@ -854,6 +854,7 @@ "file_path": "", "password": false, "options": [ + "gpt-4o", "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-3.5-turbo", diff --git a/src/backend/base/langflow/utils/constants.py b/src/backend/base/langflow/utils/constants.py index ac0a03fdf..99ac950d3 100644 --- a/src/backend/base/langflow/utils/constants.py +++ b/src/backend/base/langflow/utils/constants.py @@ -8,6 +8,7 @@ OPENAI_MODELS = [ "text-ada-001", ] CHAT_OPENAI_MODELS = [ + "gpt-4o", "gpt-4-turbo-preview", "gpt-4-0125-preview", "gpt-4-1106-preview", From 1ea9fcde25e6e774eee2d59337acd019eb17a272 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 13 May 2024 11:10:49 -0700 Subject: [PATCH 20/55] chore: Update package versions to 1.0.0a32 and 0.0.43 for 'langflow' and 'langflow-base' respectively --- poetry.lock | 454 +++++++++++++++----------------- pyproject.toml | 2 +- src/backend/base/poetry.lock | 306 ++++++++++----------- src/backend/base/pyproject.toml | 2 +- 4 files changed, 366 insertions(+), 398 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1fefc4bc1..909af7a6e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -365,13 +365,13 @@ files = [ [[package]] name = "bce-python-sdk" -version = "0.9.7" +version = "0.9.9" description = "BCE SDK for python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,<4,>=2.7" files = [ - {file = "bce_python_sdk-0.9.7-py3-none-any.whl", hash = "sha256:6c8d07118de9491803c0cef6f5486ebe2f562f850c14552442d7c448b6a5d35a"}, - {file = "bce_python_sdk-0.9.7.tar.gz", hash = "sha256:4a27f6723af9fc39f58b48d2d6dce82f88cf19ab9507e20bd2f0b7bca64bd17d"}, + {file = "bce_python_sdk-0.9.9-py3-none-any.whl", hash = "sha256:cf8886667fdb7c2bc9b40f30fc99a6fbc201f336025cc7cefa294a232973419b"}, + {file = "bce_python_sdk-0.9.9.tar.gz", hash = "sha256:574baf5a6907892ad030f32b018a2455de16cc268eccf05984026a0d8eb2c7be"}, ] [package.dependencies] @@ -469,17 +469,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.102" +version = "1.34.103" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.102-py3-none-any.whl", hash = "sha256:1c1fb2884f85c0ec6b62e6e7ed5a2a6635e1188f3ab5d2b700f7db1cf8464484"}, - {file = "boto3-1.34.102.tar.gz", hash = "sha256:65e4b9fb9ceefe19976e8822ac0cd68d28946d4697e538741d2bbdb5b45ae42f"}, + {file = "boto3-1.34.103-py3-none-any.whl", hash = "sha256:59b6499f1bb423dd99de6566a20d0a7cf1a5476824be3a792290fd86600e8365"}, + {file = "boto3-1.34.103.tar.gz", hash = "sha256:58d097241f3895c4a4c80c9e606689c6e06d77f55f9f53a4cc02dee7e03938b9"}, ] [package.dependencies] -botocore = ">=1.34.102,<1.35.0" +botocore = ">=1.34.103,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -488,13 +488,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.102" +version = "1.34.103" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.102-py3-none-any.whl", hash = "sha256:79ac7fc2729294395c70eff9c23510f00785ad2acd78d6130cb4379e9f27da86"}, - {file = "botocore-1.34.102.tar.gz", hash = "sha256:e2f8a9f4bac6f7b568e6e981ac2a2500bc992329c85dde8546f0cae8605dd009"}, + {file = "botocore-1.34.103-py3-none-any.whl", hash = "sha256:0330d139f18f78d38127e65361859e24ebd6a8bcba184f903c01bb999a3fa431"}, + {file = "botocore-1.34.103.tar.gz", hash = "sha256:5f07e2c7302c0a9f469dcd08b4ddac152e9f5888b12220242c20056255010939"}, ] [package.dependencies] @@ -2524,13 +2524,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-api-python-client" -version = "2.128.0" +version = "2.129.0" description = "Google API Client Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-python-client-2.128.0.tar.gz", hash = "sha256:908af182dfc1cd79412a489b37fe45e4f3cc99c74e80c7c477ca5babaa54eea5"}, - {file = "google_api_python_client-2.128.0-py2.py3-none-any.whl", hash = "sha256:99da6acb0acc648e309102b0e0262d7fef30f07f6bf56c6eeaa0504ceca113e3"}, + {file = "google-api-python-client-2.129.0.tar.gz", hash = "sha256:984cc8cc8eb4923468b1926d2b8effc5b459a4dda3c845896eb87c153b28ef84"}, + {file = "google_api_python_client-2.129.0-py2.py3-none-any.whl", hash = "sha256:d50f7e2dfdbb7fc2732f6a0cba1c54d7bb676390679526c6bb628c901e43ec86"}, ] [package.dependencies] @@ -3946,13 +3946,13 @@ adal = ["adal (>=1.0.2)"] [[package]] name = "langchain" -version = "0.1.19" +version = "0.1.20" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain-0.1.19-py3-none-any.whl", hash = "sha256:a1270b70139344a09f91c8a1b117c4300d9920d6d88aaaaf5ba729625ac68801"}, - {file = "langchain-0.1.19.tar.gz", hash = "sha256:7d2ffb66944a84dcac99901c4fd33f6d92aa7f794d17b5ba9a29c55a7306e32c"}, + {file = "langchain-0.1.20-py3-none-any.whl", hash = "sha256:09991999fbd6c3421a12db3c7d1f52d55601fc41d9b2a3ef51aab2e0e9c38da9"}, + {file = "langchain-0.1.20.tar.gz", hash = "sha256:f35c95eed8c8375e02dce95a34f2fd4856a4c98269d6dc34547a23dba5beab7e"}, ] [package.dependencies] @@ -4234,7 +4234,7 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langflow-base" -version = "0.0.42" +version = "0.0.43" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -4313,13 +4313,13 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.56" +version = "0.1.57" 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.56-py3-none-any.whl", hash = "sha256:2f930e054ea8eccd8ff99f0f129ae7d2513973b2e706d5483f44ea9951a1dca0"}, - {file = "langsmith-0.1.56.tar.gz", hash = "sha256:ff645b5bf16e2566740218ed6c048a1f8edbbedb4480a0d305a837ec71303fbf"}, + {file = "langsmith-0.1.57-py3-none-any.whl", hash = "sha256:dbd83b0944a2fbea4151f0aa053530d93fcf6784a580621bc60633cb890b57dc"}, + {file = "langsmith-0.1.57.tar.gz", hash = "sha256:4682204de19f0218029c2b8445ce2cc3485c8d0df9796b31e2ce4c9051fce365"}, ] [package.dependencies] @@ -4346,13 +4346,13 @@ regex = ["regex"] [[package]] name = "litellm" -version = "1.37.0" +version = "1.37.5" 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.37.0-py3-none-any.whl", hash = "sha256:74f7ccf8c10491aa393cd1a77aff4db9fd61bbffe52a7326c96811db823e1005"}, - {file = "litellm-1.37.0.tar.gz", hash = "sha256:441fbdc119f3336f1693d2022c1887d6d98453dbab32920318c823ad8ddf0d66"}, + {file = "litellm-1.37.5-py3-none-any.whl", hash = "sha256:a444dad4079d3d4c49037fe37581cd04b2135e674e9e9d1cfdbda32facd546ec"}, + {file = "litellm-1.37.5.tar.gz", hash = "sha256:22d7292d2952d82992ebebc3b7dfa1a97393f603ce652f3223f2742123ba7f2b"}, ] [package.dependencies] @@ -4372,12 +4372,12 @@ proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", " [[package]] name = "llama-cpp-python" -version = "0.2.73" +version = "0.2.74" description = "Python bindings for the llama.cpp library" optional = true python-versions = ">=3.8" files = [ - {file = "llama_cpp_python-0.2.73.tar.gz", hash = "sha256:78ac8d5f7fa06090255f0b64bf6acf2bc864c32447a1e9fbdf553f7b199fea07"}, + {file = "llama_cpp_python-0.2.74.tar.gz", hash = "sha256:2da38f4e58cfd1d742da2d944d1e3cc0256a8c466698920230497d7e361287c8"}, ] [package.dependencies] @@ -4563,13 +4563,13 @@ query-tools = ["guidance (>=0.0.64,<0.0.65)", "jsonpath-ng (>=1.6.0,<2.0.0)", "l [[package]] name = "llama-index-llms-openai" -version = "0.1.18" +version = "0.1.19" description = "llama-index llms openai integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_llms_openai-0.1.18-py3-none-any.whl", hash = "sha256:934cf72d10385f1c76c0183b0e94ce1850fab1026287e01b7db0a14c946dfd79"}, - {file = "llama_index_llms_openai-0.1.18.tar.gz", hash = "sha256:8cb7546a1885ba558ff580b114d638569a0aed81a264961114e719bc42b37100"}, + {file = "llama_index_llms_openai-0.1.19-py3-none-any.whl", hash = "sha256:2bd98ff3abbb4aa0daed1fbe01d8b69f8270ab86c53f8da51fc9f148a672264c"}, + {file = "llama_index_llms_openai-0.1.19.tar.gz", hash = "sha256:f61b64a997892e424fb3cd547090d279c5b210ef15b614fc39de854d3ccaa7e7"}, ] [package.dependencies] @@ -4577,13 +4577,13 @@ llama-index-core = ">=0.10.24,<0.11.0" [[package]] name = "llama-index-multi-modal-llms-openai" -version = "0.1.5" +version = "0.1.6" description = "llama-index multi-modal-llms openai integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_multi_modal_llms_openai-0.1.5-py3-none-any.whl", hash = "sha256:bb332580e7e4b5f2f87488b3649d2ceb53ee82c848e59694578a982c3982ce0b"}, - {file = "llama_index_multi_modal_llms_openai-0.1.5.tar.gz", hash = "sha256:9a237f4f886d1e20c27e9493e80b3e1f8753859481ff1b58fe25b7aa39b198a2"}, + {file = "llama_index_multi_modal_llms_openai-0.1.6-py3-none-any.whl", hash = "sha256:0b6950a6cf98d16ade7d3b9dd0821ecfe457ca103819ae6c3e66cfc9634ca646"}, + {file = "llama_index_multi_modal_llms_openai-0.1.6.tar.gz", hash = "sha256:10de75a877a444af35306385faad9b9f0624391e55309970564114a080a0578c"}, ] [package.dependencies] @@ -4732,165 +4732,149 @@ dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptio [[package]] name = "lxml" -version = "5.2.1" +version = "5.2.2" 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.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"}, + {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632"}, + {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526"}, + {file = "lxml-5.2.2-cp310-cp310-win32.whl", hash = "sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30"}, + {file = "lxml-5.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7"}, + {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545"}, + {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b"}, + {file = "lxml-5.2.2-cp311-cp311-win32.whl", hash = "sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438"}, + {file = "lxml-5.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be"}, + {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391"}, + {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836"}, + {file = "lxml-5.2.2-cp312-cp312-win32.whl", hash = "sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a"}, + {file = "lxml-5.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48"}, + {file = "lxml-5.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56"}, + {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9"}, + {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264"}, + {file = "lxml-5.2.2-cp36-cp36m-win32.whl", hash = "sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3"}, + {file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"}, + {file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"}, + {file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"}, + {file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"}, + {file = "lxml-5.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1"}, + {file = "lxml-5.2.2-cp38-cp38-win32.whl", hash = "sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30"}, + {file = "lxml-5.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6"}, + {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30"}, + {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9"}, + {file = "lxml-5.2.2-cp39-cp39-win32.whl", hash = "sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf"}, + {file = "lxml-5.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324"}, + {file = "lxml-5.2.2.tar.gz", hash = "sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87"}, ] [package.extras] @@ -5880,13 +5864,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.28.0" +version = "1.28.2" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.28.0-py3-none-any.whl", hash = "sha256:94b5a99f5121e1747dda1bb8fff31820d5ab4b49056a9cf2e3605f5c90011955"}, - {file = "openai-1.28.0.tar.gz", hash = "sha256:ac43b8b48aec70de4b76cfc96ae906bf8d5814427475b9dabb662f84f655f0e1"}, + {file = "openai-1.28.2-py3-none-any.whl", hash = "sha256:2b2ebe032080b53f0a91ebe5f45462d3a5b504d82a6bc5146c750653a47be587"}, + {file = "openai-1.28.2.tar.gz", hash = "sha256:a0cae5785e2d1e9ae0732970fc0555da13a5a7e08d0a339fb670525d3b5e0e1a"}, ] [package.dependencies] @@ -6534,13 +6518,13 @@ test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint" [[package]] name = "pre-commit" -version = "3.7.0" +version = "3.7.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" files = [ - {file = "pre_commit-3.7.0-py2.py3-none-any.whl", hash = "sha256:5eae9e10c2b5ac51577c3452ec0a490455c45a0533f7960f993a0d01e59decab"}, - {file = "pre_commit-3.7.0.tar.gz", hash = "sha256:e209d61b8acdcf742404408531f0c37d49d2c734fd7cff2d6076083d191cb060"}, + {file = "pre_commit-3.7.1-py2.py3-none-any.whl", hash = "sha256:fae36fd1d7ad7d6a5a1c0b0d5adb2ed1a3bda5a21bf6c3e5372073d7a11cd4c5"}, + {file = "pre_commit-3.7.1.tar.gz", hash = "sha256:8ca3ad567bc78a4972a3f1a477e94a79d4597e8140a6e0b651c5e33899c3654a"}, ] [package.dependencies] @@ -8853,47 +8837,47 @@ files = [ [[package]] name = "tiktoken" -version = "0.6.0" +version = "0.7.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"}, + {file = "tiktoken-0.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485f3cc6aba7c6b6ce388ba634fbba656d9ee27f766216f45146beb4ac18b25f"}, + {file = "tiktoken-0.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e54be9a2cd2f6d6ffa3517b064983fb695c9a9d8aa7d574d1ef3c3f931a99225"}, + {file = "tiktoken-0.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79383a6e2c654c6040e5f8506f3750db9ddd71b550c724e673203b4f6b4b4590"}, + {file = "tiktoken-0.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d4511c52caacf3c4981d1ae2df85908bd31853f33d30b345c8b6830763f769c"}, + {file = "tiktoken-0.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13c94efacdd3de9aff824a788353aa5749c0faee1fbe3816df365ea450b82311"}, + {file = "tiktoken-0.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8e58c7eb29d2ab35a7a8929cbeea60216a4ccdf42efa8974d8e176d50c9a3df5"}, + {file = "tiktoken-0.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:21a20c3bd1dd3e55b91c1331bf25f4af522c525e771691adbc9a69336fa7f702"}, + {file = "tiktoken-0.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:10c7674f81e6e350fcbed7c09a65bca9356eaab27fb2dac65a1e440f2bcfe30f"}, + {file = "tiktoken-0.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:084cec29713bc9d4189a937f8a35dbdfa785bd1235a34c1124fe2323821ee93f"}, + {file = "tiktoken-0.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:811229fde1652fedcca7c6dfe76724d0908775b353556d8a71ed74d866f73f7b"}, + {file = "tiktoken-0.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86b6e7dc2e7ad1b3757e8a24597415bafcfb454cebf9a33a01f2e6ba2e663992"}, + {file = "tiktoken-0.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1063c5748be36344c7e18c7913c53e2cca116764c2080177e57d62c7ad4576d1"}, + {file = "tiktoken-0.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:20295d21419bfcca092644f7e2f2138ff947a6eb8cfc732c09cc7d76988d4a89"}, + {file = "tiktoken-0.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:959d993749b083acc57a317cbc643fb85c014d055b2119b739487288f4e5d1cb"}, + {file = "tiktoken-0.7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:71c55d066388c55a9c00f61d2c456a6086673ab7dec22dd739c23f77195b1908"}, + {file = "tiktoken-0.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09ed925bccaa8043e34c519fbb2f99110bd07c6fd67714793c21ac298e449410"}, + {file = "tiktoken-0.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03c6c40ff1db0f48a7b4d2dafeae73a5607aacb472fa11f125e7baf9dce73704"}, + {file = "tiktoken-0.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d20b5c6af30e621b4aca094ee61777a44118f52d886dbe4f02b70dfe05c15350"}, + {file = "tiktoken-0.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d427614c3e074004efa2f2411e16c826f9df427d3c70a54725cae860f09e4bf4"}, + {file = "tiktoken-0.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8c46d7af7b8c6987fac9b9f61041b452afe92eb087d29c9ce54951280f899a97"}, + {file = "tiktoken-0.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0bc603c30b9e371e7c4c7935aba02af5994a909fc3c0fe66e7004070858d3f8f"}, + {file = "tiktoken-0.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2398fecd38c921bcd68418675a6d155fad5f5e14c2e92fcf5fe566fa5485a858"}, + {file = "tiktoken-0.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f5f6afb52fb8a7ea1c811e435e4188f2bef81b5e0f7a8635cc79b0eef0193d6"}, + {file = "tiktoken-0.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:861f9ee616766d736be4147abac500732b505bf7013cfaf019b85892637f235e"}, + {file = "tiktoken-0.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54031f95c6939f6b78122c0aa03a93273a96365103793a22e1793ee86da31685"}, + {file = "tiktoken-0.7.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fffdcb319b614cf14f04d02a52e26b1d1ae14a570f90e9b55461a72672f7b13d"}, + {file = "tiktoken-0.7.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c72baaeaefa03ff9ba9688624143c858d1f6b755bb85d456d59e529e17234769"}, + {file = "tiktoken-0.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:131b8aeb043a8f112aad9f46011dced25d62629091e51d9dc1adbf4a1cc6aa98"}, + {file = "tiktoken-0.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cabc6dc77460df44ec5b879e68692c63551ae4fae7460dd4ff17181df75f1db7"}, + {file = "tiktoken-0.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8d57f29171255f74c0aeacd0651e29aa47dff6f070cb9f35ebc14c82278f3b25"}, + {file = "tiktoken-0.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ee92776fdbb3efa02a83f968c19d4997a55c8e9ce7be821ceee04a1d1ee149c"}, + {file = "tiktoken-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e215292e99cb41fbc96988ef62ea63bb0ce1e15f2c147a61acc319f8b4cbe5bf"}, + {file = "tiktoken-0.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8a81bac94769cab437dd3ab0b8a4bc4e0f9cf6835bcaa88de71f39af1791727a"}, + {file = "tiktoken-0.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d6d73ea93e91d5ca771256dfc9d1d29f5a554b83821a1dc0891987636e0ae226"}, + {file = "tiktoken-0.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:2bcb28ddf79ffa424f171dfeef9a4daff61a94c631ca6813f43967cb263b83b9"}, + {file = "tiktoken-0.7.0.tar.gz", hash = "sha256:1077266e949c24e0291f6c350433c6f0971365ece2b173a23bc3b9f9defef6b6"}, ] [package.dependencies] @@ -9318,13 +9302,13 @@ files = [ [[package]] name = "types-pillow" -version = "10.2.0.20240423" +version = "10.2.0.20240511" description = "Typing stubs for Pillow" optional = false python-versions = ">=3.8" files = [ - {file = "types-Pillow-10.2.0.20240423.tar.gz", hash = "sha256:696e68b9b6a58548fc307a8669830469237c5b11809ddf978ac77fafa79251cd"}, - {file = "types_Pillow-10.2.0.20240423-py3-none-any.whl", hash = "sha256:bd12923093b96c91d523efcdb66967a307f1a843bcfaf2d5a529146c10a9ced3"}, + {file = "types-Pillow-10.2.0.20240511.tar.gz", hash = "sha256:b2fcc27b8e15ae3741941e43b4f39eba6fce6bcb152af90bbb07b387d2585783"}, + {file = "types_Pillow-10.2.0.20240511-py3-none-any.whl", hash = "sha256:ef87a19ea0a02a89c784cbc1b99dfff6c00dd0d5796a8ac868cf7ec69c5f88ff"}, ] [[package]] @@ -9442,13 +9426,13 @@ urllib3 = ">=2" [[package]] name = "types-setuptools" -version = "69.5.0.20240423" +version = "69.5.0.20240513" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" files = [ - {file = "types-setuptools-69.5.0.20240423.tar.gz", hash = "sha256:a7ba908f1746c4337d13f027fa0f4a5bcad6d1d92048219ba792b3295c58586d"}, - {file = "types_setuptools-69.5.0.20240423-py3-none-any.whl", hash = "sha256:a4381e041510755a6c9210e26ad55b1629bc10237aeb9cb8b6bd24996b73db48"}, + {file = "types-setuptools-69.5.0.20240513.tar.gz", hash = "sha256:3a8ccea3e3f1f639856a1dd622be282f74e94e00fdc364630240f999cc9594fc"}, + {file = "types_setuptools-69.5.0.20240513-py3-none-any.whl", hash = "sha256:bd3964c08cffd5a057d9cabe61641c86a41a1b5dd2b652b8d371eed64d89d726"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index e73ca8ec6..62544c31e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a31" +version = "1.0.0a32" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 381ecd598..a36ad1a2b 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -1031,13 +1031,13 @@ files = [ [[package]] name = "langchain" -version = "0.1.19" +version = "0.1.20" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain-0.1.19-py3-none-any.whl", hash = "sha256:a1270b70139344a09f91c8a1b117c4300d9920d6d88aaaaf5ba729625ac68801"}, - {file = "langchain-0.1.19.tar.gz", hash = "sha256:7d2ffb66944a84dcac99901c4fd33f6d92aa7f794d17b5ba9a29c55a7306e32c"}, + {file = "langchain-0.1.20-py3-none-any.whl", hash = "sha256:09991999fbd6c3421a12db3c7d1f52d55601fc41d9b2a3ef51aab2e0e9c38da9"}, + {file = "langchain-0.1.20.tar.gz", hash = "sha256:f35c95eed8c8375e02dce95a34f2fd4856a4c98269d6dc34547a23dba5beab7e"}, ] [package.dependencies] @@ -1169,13 +1169,13 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langsmith" -version = "0.1.56" +version = "0.1.57" 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.56-py3-none-any.whl", hash = "sha256:2f930e054ea8eccd8ff99f0f129ae7d2513973b2e706d5483f44ea9951a1dca0"}, - {file = "langsmith-0.1.56.tar.gz", hash = "sha256:ff645b5bf16e2566740218ed6c048a1f8edbbedb4480a0d305a837ec71303fbf"}, + {file = "langsmith-0.1.57-py3-none-any.whl", hash = "sha256:dbd83b0944a2fbea4151f0aa053530d93fcf6784a580621bc60633cb890b57dc"}, + {file = "langsmith-0.1.57.tar.gz", hash = "sha256:4682204de19f0218029c2b8445ce2cc3485c8d0df9796b31e2ce4c9051fce365"}, ] [package.dependencies] @@ -1203,165 +1203,149 @@ dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptio [[package]] name = "lxml" -version = "5.2.1" +version = "5.2.2" 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.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"}, + {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632"}, + {file = "lxml-5.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f"}, + {file = "lxml-5.2.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393"}, + {file = "lxml-5.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526"}, + {file = "lxml-5.2.2-cp310-cp310-win32.whl", hash = "sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30"}, + {file = "lxml-5.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7"}, + {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545"}, + {file = "lxml-5.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d"}, + {file = "lxml-5.2.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa"}, + {file = "lxml-5.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b"}, + {file = "lxml-5.2.2-cp311-cp311-win32.whl", hash = "sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438"}, + {file = "lxml-5.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be"}, + {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391"}, + {file = "lxml-5.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466"}, + {file = "lxml-5.2.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c"}, + {file = "lxml-5.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836"}, + {file = "lxml-5.2.2-cp312-cp312-win32.whl", hash = "sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a"}, + {file = "lxml-5.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48"}, + {file = "lxml-5.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce"}, + {file = "lxml-5.2.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56"}, + {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9"}, + {file = "lxml-5.2.2-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264"}, + {file = "lxml-5.2.2-cp36-cp36m-win32.whl", hash = "sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3"}, + {file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"}, + {file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"}, + {file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"}, + {file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"}, + {file = "lxml-5.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5"}, + {file = "lxml-5.2.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b"}, + {file = "lxml-5.2.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1"}, + {file = "lxml-5.2.2-cp38-cp38-win32.whl", hash = "sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30"}, + {file = "lxml-5.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6"}, + {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30"}, + {file = "lxml-5.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a"}, + {file = "lxml-5.2.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472"}, + {file = "lxml-5.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9"}, + {file = "lxml-5.2.2-cp39-cp39-win32.whl", hash = "sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf"}, + {file = "lxml-5.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2"}, + {file = "lxml-5.2.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8"}, + {file = "lxml-5.2.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db"}, + {file = "lxml-5.2.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a"}, + {file = "lxml-5.2.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324"}, + {file = "lxml-5.2.2.tar.gz", hash = "sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87"}, ] [package.extras] diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 8be699508..b71200be7 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.42" +version = "0.0.43" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From d8c8f4db7a6cba4e3201e1cc401ee6fd02725ddd Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Mon, 13 May 2024 15:06:26 -0400 Subject: [PATCH 21/55] initial-content --- docs/docs/administration/global-env.mdx | 43 ++++++++++++++++++++++++ docs/sidebars.js | 1 + docs/static/img/global-env.png | Bin 0 -> 87279 bytes 3 files changed, 44 insertions(+) create mode 100644 docs/docs/administration/global-env.mdx create mode 100644 docs/static/img/global-env.png diff --git a/docs/docs/administration/global-env.mdx b/docs/docs/administration/global-env.mdx new file mode 100644 index 000000000..4525707ae --- /dev/null +++ b/docs/docs/administration/global-env.mdx @@ -0,0 +1,43 @@ +import ZoomableImage from "/src/theme/ZoomableImage.js"; +import Admonition from "@theme/Admonition"; + +# Global environment variables + +Langflow 1.0 alpha includes the option to add **Global Environment Variables** for your application. + +## Example + +In this example, you'll add the `openai_api_key` credential as a global environment variable to the **Basic Prompting** starter project. + +For more information on the starter flow, see [Basic prompting ](../starter-projects/basic-prompting.mdx). + +1. From the Langflow dashboard, click **New Project**. +2. Select **Basic Prompting**. +3. The **Basic Prompting** flow is created. +4. To create an environment variable for the **OpenAI** component, in the **OpenAI API Key** field, click the **Globe** button, and then click **Add New Variable**. + + + You can also create global variables in **Settings** > **Variables and Secrets**. + + + 1. In the **Variable Name** field, enter `openai_api_key`. + 2. In the **Value** field, paste your OpenAI API Key (`sk-...`). + 3. For the variable **Type**, select **Credential**. + 4. In the **Apply to Fields** field, select **OpenAI API Key** to apply this variable to all fields named **OpenAI API Key**. + 5. Click **Save Variable**. + + + +You now have a `openai_api_key` global environment variable for your Langflow project. + +5. To view and manage your project's global environment variables, visit **Settings** > **Variables and Secrets**. + +For more on variables in HuggingFace Spaces, see [Managing Secrets](https://huggingface.co/docs/hub/spaces-overview#managing-secrets). + diff --git a/docs/sidebars.js b/docs/sidebars.js index 848400d18..cf66f270f 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -40,6 +40,7 @@ module.exports = { "administration/login", "administration/api", "administration/cli", + "administration/global-env", "administration/components", "administration/collection", "administration/prompt-customization", diff --git a/docs/static/img/global-env.png b/docs/static/img/global-env.png new file mode 100644 index 0000000000000000000000000000000000000000..763444dc4528fc68c817f9879162cb7b7407503b GIT binary patch literal 87279 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
$=H`@6M8ir+0$RBG*;;;P4&9Rs|;7vF^a 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 literal 0 HcmV?d00001 From 3af526734c4383b61e15ee4b74aa27b7b568adef Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Mon, 13 May 2024 15:07:13 -0400 Subject: [PATCH 22/55] title --- docs/docs/administration/global-env.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/administration/global-env.mdx b/docs/docs/administration/global-env.mdx index 4525707ae..28dbff22f 100644 --- a/docs/docs/administration/global-env.mdx +++ b/docs/docs/administration/global-env.mdx @@ -5,7 +5,7 @@ import Admonition from "@theme/Admonition"; Langflow 1.0 alpha includes the option to add **Global Environment Variables** for your application. -## Example +## Add a global variable to a project In this example, you'll add the `openai_api_key` credential as a global environment variable to the **Basic Prompting** starter project. From f6a6241b66d69317ffa884ceb364a48db6773f43 Mon Sep 17 00:00:00 2001 From: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Date: Mon, 13 May 2024 18:37:39 -0400 Subject: [PATCH 23/55] initial-content --- docs/docs/administration/playground.mdx | 28 ++++++++++++++++++++++++ docs/sidebars.js | 1 + docs/static/img/playground-chat.png | Bin 0 -> 134800 bytes 3 files changed, 29 insertions(+) create mode 100644 docs/docs/administration/playground.mdx create mode 100644 docs/static/img/playground-chat.png diff --git a/docs/docs/administration/playground.mdx b/docs/docs/administration/playground.mdx new file mode 100644 index 000000000..6fe14e73f --- /dev/null +++ b/docs/docs/administration/playground.mdx @@ -0,0 +1,28 @@ +import ThemedImage from "@theme/ThemedImage"; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import ZoomableImage from "/src/theme/ZoomableImage.js"; +import ReactPlayer from "react-player"; +import Admonition from "@theme/Admonition"; + +# Playground + +In Langflow 1.0 alpha, the **Playground** replaces the **Integration Window**. + +The **Playground** offers an interface for interacting with chat flows. + +1. To use the **Playground**, from your **Collections** page, click **Playground** in one of your flows. +The **Playground** window opens. + + + +2. Chat with your bot as you normally would. + +The Playground allows you to run flows without opening them in the flow editor. +This applies to the Langflow store, too - as long as you have your global environment variables set, you can run flows by clicking the **Playground** button. diff --git a/docs/sidebars.js b/docs/sidebars.js index 848400d18..a0e2af3f1 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -40,6 +40,7 @@ module.exports = { "administration/login", "administration/api", "administration/cli", + "administration/playground", "administration/components", "administration/collection", "administration/prompt-customization", diff --git a/docs/static/img/playground-chat.png b/docs/static/img/playground-chat.png new file mode 100644 index 0000000000000000000000000000000000000000..d2625c28fe4e09afbae23ce7cfacb190cf2c30f2 GIT binary patch literal 134800 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

v%$fJD0heQo@Z%V6vz>|ZCYtbS+ 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 Date: Tue, 14 May 2024 10:50:11 -0400 Subject: [PATCH 24/55] cleanup --- docs/docs/administration/playground.mdx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/docs/administration/playground.mdx b/docs/docs/administration/playground.mdx index 6fe14e73f..a990ef2af 100644 --- a/docs/docs/administration/playground.mdx +++ b/docs/docs/administration/playground.mdx @@ -8,9 +8,13 @@ import Admonition from "@theme/Admonition"; In Langflow 1.0 alpha, the **Playground** replaces the **Integration Window**. -The **Playground** offers an interface for interacting with chat flows. +The **Playground** provides an interface for interacting with flows without opening them in the flow editor. -1. To use the **Playground**, from your **Collections** page, click **Playground** in one of your flows. +It even works for flows hosted on the Langflow store! + +As long as you have a flow's environment variables set, you can run it by clicking the **Playground** button. + +1. From your **Collections** page, click **Playground** in one of your flows. The **Playground** window opens. -2. Chat with your bot as you normally would. - -The Playground allows you to run flows without opening them in the flow editor. -This applies to the Langflow store, too - as long as you have your global environment variables set, you can run flows by clicking the **Playground** button. +2. Chat with your bot as you normally would, all without having to open the editor. From 3abc7eedc3bf919dfa26f139a7965ea032e09b0b Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 14 May 2024 14:46:44 -0300 Subject: [PATCH 25/55] Fix duplicate group bug (#1859) * fix duplicate group bug * remove commented console.log --- .../components/PageComponent/index.tsx | 41 ++++++------- src/frontend/src/stores/flowStore.ts | 59 +++++++++---------- src/frontend/src/utils/reactflowUtils.ts | 1 - 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index cb1a6e553..1c6951726 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -51,19 +51,19 @@ export default function Page({ }): JSX.Element { const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const autoSaveCurrentFlow = useFlowsManagerStore( - (state) => state.autoSaveCurrentFlow + (state) => state.autoSaveCurrentFlow, ); const types = useTypesStore((state) => state.types); const templates = useTypesStore((state) => state.templates); const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const reactFlowWrapper = useRef(null); const [showCanvas, setSHowCanvas] = useState( - Object.keys(templates).length > 0 && Object.keys(types).length > 0 + Object.keys(templates).length > 0 && Object.keys(types).length > 0, ); const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const setReactFlowInstance = useFlowStore( - (state) => state.setReactFlowInstance + (state) => state.setReactFlowInstance, ); const nodes = useFlowStore((state) => state.nodes); const edges = useFlowStore((state) => state.edges); @@ -80,10 +80,10 @@ export default function Page({ const paste = useFlowStore((state) => state.paste); const resetFlow = useFlowStore((state) => state.resetFlow); const lastCopiedSelection = useFlowStore( - (state) => state.lastCopiedSelection + (state) => state.lastCopiedSelection, ); const setLastCopiedSelection = useFlowStore( - (state) => state.setLastCopiedSelection + (state) => state.setLastCopiedSelection, ); const onConnect = useFlowStore((state) => state.onConnect); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); @@ -106,7 +106,7 @@ export default function Page({ clonedSelection!, clonedNodes, clonedEdges, - getRandomName() + getRandomName(), ); const newGroupNode = generateNodeFromFlow(newFlow, getNodeId); const newEdges = reconnectEdges(newGroupNode, removedEdges); @@ -114,8 +114,8 @@ export default function Page({ ...clonedNodes.filter( (oldNodes) => !clonedSelection?.nodes.some( - (selectionNode) => selectionNode.id === oldNodes.id - ) + (selectionNode) => selectionNode.id === oldNodes.id, + ), ), newGroupNode, ]); @@ -125,8 +125,8 @@ export default function Page({ !clonedSelection!.nodes.some( (selectionNode) => selectionNode.id === oldEdge.target || - selectionNode.id === oldEdge.source - ) + selectionNode.id === oldEdge.source, + ), ), ...newEdges, ]); @@ -141,7 +141,8 @@ export default function Page({ const setNode = useFlowStore((state) => state.setNode); useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { - const selectedNode = nodes.filter((obj) => obj.selected); + const selectedNode = lastSelection?.nodes ?? []; + const selectedEdges = lastSelection?.edges ?? []; if ( selectionMenuVisible && (event.ctrlKey || event.metaKey) && @@ -174,11 +175,11 @@ export default function Page({ ) { event.preventDefault(); paste( - { nodes: selectedNode, edges: [] }, + { nodes: selectedNode, edges: selectedEdges }, { x: position.current.x, y: position.current.y, - } + }, ); } if (!isWrappedWithClass(event, "noundo")) { @@ -274,7 +275,7 @@ export default function Page({ useEffect(() => { setSHowCanvas( - Object.keys(templates).length > 0 && Object.keys(types).length > 0 + Object.keys(templates).length > 0 && Object.keys(types).length > 0, ); }, [templates, types]); @@ -283,7 +284,7 @@ export default function Page({ takeSnapshot(); onConnect(params); }, - [takeSnapshot, onConnect] + [takeSnapshot, onConnect], ); const onNodeDragStart: NodeDragHandler = useCallback(() => { @@ -324,7 +325,7 @@ export default function Page({ // Extract the data from the drag event and parse it as a JSON object const data: { type: string; node?: APIClassType } = JSON.parse( - event.dataTransfer.getData("nodedata") + event.dataTransfer.getData("nodedata"), ); const newId = getNodeId(data.type); @@ -340,7 +341,7 @@ export default function Page({ }; paste( { nodes: [newNode], edges: [] }, - { x: event.clientX, y: event.clientY } + { x: event.clientX, y: event.clientY }, ); } else if (event.dataTransfer.types.some((types) => types === "Files")) { takeSnapshot(); @@ -369,7 +370,7 @@ export default function Page({ } }, // Specify dependencies for useCallback - [getNodeId, setNodes, takeSnapshot, paste] + [getNodeId, setNodes, takeSnapshot, paste], ); const onEdgeUpdateStart = useCallback(() => { @@ -385,7 +386,7 @@ export default function Page({ setEdges((els) => updateEdge(oldEdge, newConnection, els)); } }, - [setEdges] + [setEdges], ); const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => { @@ -418,7 +419,7 @@ export default function Page({ (flow: OnSelectionChangeParams): void => { setLastSelection(flow); }, - [] + [], ); const onPaneClick = useCallback((flow) => { diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 0c3328add..44879aba8 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -49,7 +49,7 @@ import FlowPage from "../pages/FlowPage"; // this is our useStore hook that we can use in our components to get parts of the store and call actions const useFlowStore = create((set, get) => ({ onFlowPage: false, - setOnFlowPage:(FlowPage=>set({onFlowPage:FlowPage})), + setOnFlowPage: (FlowPage) => set({ onFlowPage: FlowPage }), flowState: undefined, flowBuildStatus: {}, nodes: [], @@ -80,7 +80,7 @@ const useFlowStore = create((set, get) => ({ updateFlowPool: ( nodeId: string, data: FlowPoolObjectType | ChatOutputType | chatInputType, - buildId?: string + buildId?: string, ) => { let newFlowPool = cloneDeep({ ...get().flowPool }); if (!newFlowPool[nodeId]) { @@ -152,7 +152,7 @@ const useFlowStore = create((set, get) => ({ edges: applyEdgeChanges(changes, get().edges), }); }, - setNodes: (change,skipSave=false) => { + setNodes: (change, skipSave = false) => { let newChange = typeof change === "function" ? change(get().nodes) : change; let newEdges = cleanEdges(newChange, get().edges); const { inputs, outputs } = getInputsAndOutputs(newChange); @@ -171,11 +171,11 @@ const useFlowStore = create((set, get) => ({ flowsManager.autoSaveCurrentFlow( newChange, newEdges, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, ); } }, - setEdges: (change,skipSave=false) => { + setEdges: (change, skipSave = false) => { let newChange = typeof change === "function" ? change(get().edges) : change; set({ edges: newChange, @@ -187,7 +187,7 @@ const useFlowStore = create((set, get) => ({ flowsManager.autoSaveCurrentFlow( get().nodes, newChange, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, ); } }, @@ -205,7 +205,7 @@ const useFlowStore = create((set, get) => ({ return newChange; } return node; - }) + }), ); }, getNode: (id: string) => { @@ -216,8 +216,8 @@ const useFlowStore = create((set, get) => ({ get().nodes.filter((node) => typeof nodeId === "string" ? node.id !== nodeId - : !nodeId.includes(node.id) - ) + : !nodeId.includes(node.id), + ), ); }, deleteEdge: (edgeId) => { @@ -225,13 +225,11 @@ const useFlowStore = create((set, get) => ({ get().edges.filter((edge) => typeof edgeId === "string" ? edge.id !== edgeId - : !edgeId.includes(edge.id) - ) + : !edgeId.includes(edge.id), + ), ); }, paste: (selection, position) => { - function updateGroup() {} - if ( selection.nodes.some((node) => node.data.type === "ChatInput") && checkChatInput(get().nodes) @@ -268,8 +266,6 @@ const useFlowStore = create((set, get) => ({ let newId = getNodeId(node.data.type); idsMap[node.id] = newId; - updateGroupRecursion(node, selection.edges); - // Create a new node object const newNode: NodeType = { id: newId, @@ -283,6 +279,7 @@ const useFlowStore = create((set, get) => ({ id: newId, }, }; + updateGroupRecursion(newNode, selection.edges); // Add the new node to the list of nodes in state newNodes = newNodes @@ -295,7 +292,7 @@ const useFlowStore = create((set, get) => ({ let source = idsMap[edge.source]; let target = idsMap[edge.target]; const sourceHandleObject: sourceHandleType = scapeJSONParse( - edge.sourceHandle! + edge.sourceHandle!, ); let sourceHandle = scapedJSONStringfy({ ...sourceHandleObject, @@ -305,7 +302,7 @@ const useFlowStore = create((set, get) => ({ edge.data.sourceHandle = sourceHandleObject; const targetHandleObject: targetHandleType = scapeJSONParse( - edge.targetHandle! + edge.targetHandle!, ); let targetHandle = scapedJSONStringfy({ ...targetHandleObject, @@ -326,7 +323,7 @@ const useFlowStore = create((set, get) => ({ className: "stroke-gray-900 ", selected: false, }, - newEdges.map((edge) => ({ ...edge, selected: false })) + newEdges.map((edge) => ({ ...edge, selected: false })), ); }); get().setEdges(newEdges); @@ -345,10 +342,10 @@ const useFlowStore = create((set, get) => ({ }); const newNodes = get().nodes.filter( - (node) => !nodesIdsSelected.includes(node.id) + (node) => !nodesIdsSelected.includes(node.id), ); const newEdges = get().edges.filter( - (edge) => !edgesIdsSelected.includes(edge.id) + (edge) => !edgesIdsSelected.includes(edge.id), ); set({ nodes: newNodes, edges: newEdges }); @@ -406,7 +403,7 @@ const useFlowStore = create((set, get) => ({ style: { stroke: "#555" }, className: "stroke-foreground stroke-connection", }, - oldEdges + oldEdges, ); return newEdges; @@ -416,7 +413,7 @@ const useFlowStore = create((set, get) => ({ .autoSaveCurrentFlow( get().nodes, newEdges, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, ); }, unselectAll: () => { @@ -447,7 +444,7 @@ const useFlowStore = create((set, get) => ({ function validateSubgraph(nodes: string[]) { const errorsObjs = validateNodes( get().nodes.filter((node) => nodes.includes(node.id)), - get().edges + get().edges, ); const errors = errorsObjs.map((obj) => obj.errors).flat(); @@ -466,7 +463,7 @@ const useFlowStore = create((set, get) => ({ function handleBuildUpdate( vertexBuildData: VertexBuildTypeAPI, status: BuildStatus, - runId: string + runId: string, ) { if (vertexBuildData && vertexBuildData.inactivated_vertices) { get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices); @@ -484,11 +481,11 @@ const useFlowStore = create((set, get) => ({ // next_vertices_ids should be next_vertices_ids without the inactivated vertices const next_vertices_ids = vertexBuildData.next_vertices_ids.filter( - (id) => !vertexBuildData.inactivated_vertices?.includes(id) + (id) => !vertexBuildData.inactivated_vertices?.includes(id), ); const nextVertices: VertexLayerElementType[] = zip( next_vertices_ids, - vertexBuildData.top_level_vertices + vertexBuildData.top_level_vertices, ).map(([id, reference]) => ({ id: id!, reference })); const newLayers = [ @@ -507,13 +504,13 @@ const useFlowStore = create((set, get) => ({ }); get().updateBuildStatus( vertexBuildData.top_level_vertices, - BuildStatus.TO_BUILD + BuildStatus.TO_BUILD, ); } get().addDataToFlowPool( { ...vertexBuildData, buildId: runId }, - vertexBuildData.id + vertexBuildData.id, ); useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status); @@ -522,7 +519,7 @@ const useFlowStore = create((set, get) => ({ const newFlowBuildStatus = { ...get().flowBuildStatus }; // filter out the vertices that are not status const verticesToUpdate = verticesIds?.filter( - (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT + (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT, ); if (verticesToUpdate) { @@ -587,7 +584,7 @@ const useFlowStore = create((set, get) => ({ verticesLayers: VertexLayerElementType[][]; runId: string; verticesToRun: string[]; - } | null + } | null, ) => { set({ verticesBuild: vertices }); }, @@ -612,7 +609,7 @@ const useFlowStore = create((set, get) => ({ // that are going to be built verticesIds: get().verticesBuild!.verticesIds.filter( // keep the vertices that are not in the list of vertices to remove - (vertex) => !vertices.includes(vertex) + (vertex) => !vertices.includes(vertex), ), }, }); diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 83772ee0d..64f876f95 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -994,7 +994,6 @@ export function updateEdgesIds( if (targetHandle.proxy && idsMap[targetHandle.proxy!.id]) { targetHandle.proxy!.id = idsMap[targetHandle.proxy!.id]; } - console.log("edge", edge); edge.data.targetHandle = targetHandle; edge.targetHandle = scapedJSONStringfy(targetHandle); }); From c464e16d283da4dc3af7b9818c2fcc839c53c8db Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 14 May 2024 14:47:20 -0300 Subject: [PATCH 26/55] refactor: Update expandGroupNode function to handle template proxy values --- src/frontend/package-lock.json | 668 ++++++++++------------- src/frontend/src/utils/reactflowUtils.ts | 55 +- 2 files changed, 321 insertions(+), 402 deletions(-) diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index d4d59c3a2..bfa0919ba 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -107,15 +107,6 @@ "vite": "^4.5.2" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@adobe/css-tools": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", @@ -180,20 +171,20 @@ } }, "node_modules/@babel/core": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", - "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", + "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.4", + "@babel/generator": "^7.24.5", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.4", - "@babel/parser": "^7.24.4", + "@babel/helper-module-transforms": "^7.24.5", + "@babel/helpers": "^7.24.5", + "@babel/parser": "^7.24.5", "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/traverse": "^7.24.5", + "@babel/types": "^7.24.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -209,11 +200,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", - "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", + "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -280,15 +271,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", + "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.24.3", + "@babel/helper-simple-access": "^7.24.5", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/helper-validator-identifier": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -298,22 +289,22 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", + "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", + "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -328,9 +319,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "engines": { "node": ">=6.9.0" } @@ -344,24 +335,24 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", - "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz", + "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==", "dependencies": { "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.24.5", + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", + "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -371,9 +362,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -382,9 +373,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -406,18 +397,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", + "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/parser": "^7.24.5", + "@babel/types": "^7.24.5", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -426,12 +417,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", + "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.1", + "@babel/helper-validator-identifier": "^7.24.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -877,28 +868,28 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", - "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.1.tgz", + "integrity": "sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==", "dependencies": { - "@floating-ui/utils": "^0.2.1" + "@floating-ui/utils": "^0.2.0" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", - "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", + "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", "dependencies": { "@floating-ui/core": "^1.0.0", "@floating-ui/utils": "^0.2.0" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", - "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.9.tgz", + "integrity": "sha512-q0umO0+LQK4+p6aGyvzASqKbKOJcAHJ7ycE9CuUvfx3s9zTHWmGJTPOIlM/hmSBfUfg/XfY5YhLBLR/LHwShQQ==", "dependencies": { - "@floating-ui/dom": "^1.6.1" + "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -906,9 +897,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", - "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", + "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" }, "node_modules/@headlessui/react": { "version": "1.7.19", @@ -1106,26 +1097,11 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -1133,12 +1109,6 @@ "node": ">=10" } }, - "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "optional": true - }, "node_modules/@million/lint": { "version": "0.0.73", "resolved": "https://registry.npmjs.org/@million/lint/-/lint-0.0.73.tgz", @@ -1839,12 +1809,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.43.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.43.1.tgz", - "integrity": "sha512-HgtQzFgNEEo4TE22K/X7sYTYNqEMMTZmFS8kTq6m8hXj+m1D8TgwgIbumHddJa9h4yl4GkKb8/bgAl2+g7eDgA==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.0.tgz", + "integrity": "sha512-rNX5lbNidamSUorBhB4XZ9SQTjAqfe5M+p37Z8ic0jPFBMo5iCtQz1kRWkEMg+rYOKSlVycpQmpqjSFq7LXOfg==", "dev": true, "dependencies": { - "playwright": "1.43.1" + "playwright": "1.44.0" }, "bin": { "playwright": "cli.js" @@ -2869,11 +2839,11 @@ } }, "node_modules/@reactflow/background": { - "version": "11.3.12", - "resolved": "https://registry.npmjs.org/@reactflow/background/-/background-11.3.12.tgz", - "integrity": "sha512-jBuWVb43JQy5h4WOS7G0PU8voGTEJNA+qDmx8/jyBtrjbasTesLNfQvboTGjnQYYiJco6mw5vrtQItAJDNoIqw==", + "version": "11.3.13", + "resolved": "https://registry.npmjs.org/@reactflow/background/-/background-11.3.13.tgz", + "integrity": "sha512-hkvpVEhgvfTDyCvdlitw4ioKCYLaaiRXnuEG+1QM3Np+7N1DiWF1XOv5I8AFyNoJL07yXEkbECUTsHvkBvcG5A==", "dependencies": { - "@reactflow/core": "11.11.2", + "@reactflow/core": "11.11.3", "classcat": "^5.0.3", "zustand": "^4.4.1" }, @@ -2883,11 +2853,11 @@ } }, "node_modules/@reactflow/controls": { - "version": "11.2.12", - "resolved": "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.12.tgz", - "integrity": "sha512-L9F3+avFRShoprdT+5oOijm5gVsz2rqWCXBzOAgD923L1XFGIspdiHLLf8IlPGsT+mfl0GxbptZhaEeEzl1e3g==", + "version": "11.2.13", + "resolved": "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.13.tgz", + "integrity": "sha512-3xgEg6ALIVkAQCS4NiBjb7ad8Cb3D8CtA7Vvl4Hf5Ar2PIVs6FOaeft9s2iDZGtsWP35ECDYId1rIFVhQL8r+A==", "dependencies": { - "@reactflow/core": "11.11.2", + "@reactflow/core": "11.11.3", "classcat": "^5.0.3", "zustand": "^4.4.1" }, @@ -2897,9 +2867,9 @@ } }, "node_modules/@reactflow/core": { - "version": "11.11.2", - "resolved": "https://registry.npmjs.org/@reactflow/core/-/core-11.11.2.tgz", - "integrity": "sha512-+GfgyskweL1PsgRSguUwfrT2eDotlFgaKfDLm7x0brdzzPJY2qbCzVetaxedaiJmIli3817iYbILvE9qLKwbRA==", + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/@reactflow/core/-/core-11.11.3.tgz", + "integrity": "sha512-+adHdUa7fJSEM93fWfjQwyWXeI92a1eLKwWbIstoCakHpL8UjzwhEh6sn+mN2h/59MlVI7Ehr1iGTt3MsfcIFA==", "dependencies": { "@types/d3": "^7.4.0", "@types/d3-drag": "^3.0.1", @@ -2917,11 +2887,11 @@ } }, "node_modules/@reactflow/minimap": { - "version": "11.7.12", - "resolved": "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.12.tgz", - "integrity": "sha512-SRDU77c2PCF54PV/MQfkz7VOW46q7V1LZNOQlXAp7dkNyAOI6R+tb9qBUtUJOvILB+TCN6pRfD9fQ+2T99bW3Q==", + "version": "11.7.13", + "resolved": "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.13.tgz", + "integrity": "sha512-m2MvdiGSyOu44LEcERDEl1Aj6x//UQRWo3HEAejNU4HQTlJnYrSN8tgrYF8TxC1+c/9UdyzQY5VYgrTwW4QWdg==", "dependencies": { - "@reactflow/core": "11.11.2", + "@reactflow/core": "11.11.3", "@types/d3-selection": "^3.0.3", "@types/d3-zoom": "^3.0.1", "classcat": "^5.0.3", @@ -2935,11 +2905,11 @@ } }, "node_modules/@reactflow/node-resizer": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.12.tgz", - "integrity": "sha512-6LHJGuI1zHyRrZHw5gGlVLIWnvVxid9WIqw8FMFSg+oF2DuS3pAPwSoZwypy7W22/gDNl9eD1Dcl/OtFtDFQ+w==", + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.13.tgz", + "integrity": "sha512-X7ceQ2s3jFLgbkg03n2RYr4hm3jTVrzkW2W/8ANv/SZfuVmF8XJxlERuD8Eka5voKqLda0ywIZGAbw9GoHLfUQ==", "dependencies": { - "@reactflow/core": "11.11.2", + "@reactflow/core": "11.11.3", "classcat": "^5.0.4", "d3-drag": "^3.0.0", "d3-selection": "^3.0.0", @@ -2951,11 +2921,11 @@ } }, "node_modules/@reactflow/node-toolbar": { - "version": "1.3.12", - "resolved": "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.12.tgz", - "integrity": "sha512-4kJRvNna/E3y2MZW9/80wTKwkhw4pLJiz3D5eQrD13XcmojSb1rArO9CiwyrI+rMvs5gn6NlCFB4iN1F+Q+lxQ==", + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.13.tgz", + "integrity": "sha512-aknvNICO10uWdthFSpgD6ctY/CTBeJUMV9co8T9Ilugr08Nb89IQ4uD0dPmr031ewMQxixtYIkw+sSDDzd2aaQ==", "dependencies": { - "@reactflow/core": "11.11.2", + "@reactflow/core": "11.11.3", "classcat": "^5.0.3", "zustand": "^4.4.1" }, @@ -2965,9 +2935,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", - "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz", + "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==", "engines": { "node": ">=14.0.0" } @@ -3249,26 +3219,11 @@ } } }, - "node_modules/@swc/cli/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/cli/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -3276,16 +3231,10 @@ "node": ">=10" } }, - "node_modules/@swc/cli/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@swc/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.0.tgz", - "integrity": "sha512-fjADAC5gOOX54Rpcr1lF9DHLD+nPD5H/zXLtEgK2Ez3esmogT+LfHzCZtUxqetjvaMChKhQ0Pp0ZB6Hpz/tCbw==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.6.tgz", + "integrity": "sha512-0UC0NkgWoqd9fkHPn1NTkTsQucW8iaA1fujK2OLGp40Zg5Vr7nrwBlqruX9expVMggS4rv/3vZSAGzRm80VQ/g==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3300,16 +3249,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.5.0", - "@swc/core-darwin-x64": "1.5.0", - "@swc/core-linux-arm-gnueabihf": "1.5.0", - "@swc/core-linux-arm64-gnu": "1.5.0", - "@swc/core-linux-arm64-musl": "1.5.0", - "@swc/core-linux-x64-gnu": "1.5.0", - "@swc/core-linux-x64-musl": "1.5.0", - "@swc/core-win32-arm64-msvc": "1.5.0", - "@swc/core-win32-ia32-msvc": "1.5.0", - "@swc/core-win32-x64-msvc": "1.5.0" + "@swc/core-darwin-arm64": "1.5.6", + "@swc/core-darwin-x64": "1.5.6", + "@swc/core-linux-arm-gnueabihf": "1.5.6", + "@swc/core-linux-arm64-gnu": "1.5.6", + "@swc/core-linux-arm64-musl": "1.5.6", + "@swc/core-linux-x64-gnu": "1.5.6", + "@swc/core-linux-x64-musl": "1.5.6", + "@swc/core-win32-arm64-msvc": "1.5.6", + "@swc/core-win32-ia32-msvc": "1.5.6", + "@swc/core-win32-x64-msvc": "1.5.6" }, "peerDependencies": { "@swc/helpers": "^0.5.0" @@ -3321,9 +3270,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.0.tgz", - "integrity": "sha512-dyA25zQjm3xmMFsRPFgBpSqWSW9TITnkndZkZAiPYLjBxH9oTNMa0l09BePsaqEeXySY++tUgAeYu/9onsHLbg==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.6.tgz", + "integrity": "sha512-U4szqU03cvZOTXug5o+HQbbg16ZGwANtr7LELjw4hmWBqSTcbBVXgocyBMm1L4ngFIsqJc33D+urnnaae/NfMg==", "cpu": [ "arm64" ], @@ -3337,9 +3286,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.0.tgz", - "integrity": "sha512-cO7kZMMA/fcQIBT31LBzcVNSk3AZGVYLqvEPnJhFImjPm3mGKUd6kWpARUEGR68MyRU2VsWhE6eCjMcM+G7bxw==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.6.tgz", + "integrity": "sha512-k4jymBHYkbfGw8DT4bLtVsAckpp2dblyImQHRPScpvDyS4jUo4174mgy/dEnFmZVLTbuZAY876zBQyH+eJ3p4A==", "cpu": [ "x64" ], @@ -3353,9 +3302,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.0.tgz", - "integrity": "sha512-BXaXytS4y9lBFRO6vwA6ovvy1d2ZIzS02i2R1oegoZzzNu89CJDpkYXYS9bId0GvK2m9Q9y2ofoZzKE2Rp3PqQ==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.6.tgz", + "integrity": "sha512-ijwGEdP18vS8YmvHUIfKYDFQ5mQ1GtCxhJp+IcJlrBJE+/eSJVvEVF5WwXFQ+Hzj6tr/OOub8UcRNUaQokjh3A==", "cpu": [ "arm" ], @@ -3369,9 +3318,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.0.tgz", - "integrity": "sha512-Bu4/41pGadXKnRsUbox0ig63xImATVH704oPCXcoOvNGkDyMjWgIAhzIi111vrwFNpj9utabgUE4AtlUa2tAOQ==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.6.tgz", + "integrity": "sha512-6YD942jsDm64wgGNew4Q1Yh8CRI4QKWTqjzCkvlZCGV6aOw5B663WDSnUEKIoN4egeLcvSiqYYGlKMfbkkfNMw==", "cpu": [ "arm64" ], @@ -3385,9 +3334,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.0.tgz", - "integrity": "sha512-lUFFvC8tsepNcTnKEHNrePWanVVef6PQ82Rv9wIeebgGHRUqDh6+CyCqodXez+aKz6NyE/PBIfp0r+jPx4hoJA==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.6.tgz", + "integrity": "sha512-Jntdd/HQAgRSQFUpmXjiU00BG08Yl5G1pgYDBXG2mPfkndGGgapRT8JPsnzfQujh9nOdWMIQDnCGU+mB4NY2Dg==", "cpu": [ "arm64" ], @@ -3401,9 +3350,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.0.tgz", - "integrity": "sha512-c6LegFU1qdyMfk+GzNIOvrX61+mksm21Q01FBnXSy1nf1ACj/a86jmr3zkPl0zpNVHfPOw3Ry1QIuLQKD+67YA==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.6.tgz", + "integrity": "sha512-cdaAyAZJvYCx0u9uadUVe4VVJOEC6GeVO5uTGo/vybCsKFn2Z8WVjGVTeHbxdp7pH2II9MRTySIv1eCCq70SOQ==", "cpu": [ "x64" ], @@ -3417,9 +3366,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.0.tgz", - "integrity": "sha512-I/V8aWBmfDWwjtM1bS8ASG+6PcO/pVFYyPP5g2ok46Vz1o1MnAUd18mHnWX43nqVJokaW+BD/G4ZMZ+gXRl4zQ==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.6.tgz", + "integrity": "sha512-mGIs4d6/Hv/5EbP2d+2YNmIj9U5U/6CiPZsTyahQcEl+vJjNsmwDJoLex36LhxoGIUmVbbgk6cHj5DoHWNl0bQ==", "cpu": [ "x64" ], @@ -3433,9 +3382,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.0.tgz", - "integrity": "sha512-nN685BvI7iM58xabrSOSQHUvIY10pcXh5H9DmS8LeYqG6Dkq7QZ8AwYqqonOitIS5C35MUfhSMLpOTzKoLdUqA==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.6.tgz", + "integrity": "sha512-ViiS2pUXy/J9RZWJXQJMuDKid0lqH9fu2piFi3IHnMWyyWPla5qHYijkeODwrdBsjc30NAHjV6jfka5SZduqiw==", "cpu": [ "arm64" ], @@ -3449,9 +3398,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.0.tgz", - "integrity": "sha512-3YjltmEHljI+TvuDOC4lspUzjBUoB3X5BhftRBprSTJx/czuMl0vdoZKs2Snzb5Eqqesp0Rl8q+iQ1E1oJ6dEA==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.6.tgz", + "integrity": "sha512-Ju5z65Nda8oYjt2Z4CGbuBLxM+98TcewLogutI69rBo5S70xunadp4ANIHcr9fZlTu/IX9mxZmUpOaHtb+/TfA==", "cpu": [ "ia32" ], @@ -3465,9 +3414,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.0.tgz", - "integrity": "sha512-ZairtCwJsaxnUH85DcYCyGpNb9bUoIm9QXYW+VaEoXwbcB95dTIiJwN0aRxPT8B0B2MNw/CXLqjoPo6sDwz5iw==", + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.6.tgz", + "integrity": "sha512-pkqJsdrgxyFYJA+g9a3zbl+AoxYoBtv+Rji1Fw4+Sq7CsSMWboayWNN5fKRiyi3u3nG8kxqyGi51PsKy2G4Vpg==", "cpu": [ "x64" ], @@ -3567,11 +3516,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.4.0.tgz", - "integrity": "sha512-GZN4xn/Tg5w7gvYeVcMVCeL4pEyUhvg+Cp6KX2Z01C4FRNxIWMgIQ9ibgMarNQfo+gt0PVLcEER4A9sNv/jlow==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz", + "integrity": "sha512-rtvo7KwuIvqK9zb0VZ5IL7fiJAEnG+0EiFZz8FUOs+2mhGqdGmjKIaT1XU7Zq0eFqL0jonLlhbayJI/J2SA/Bw==", "dependencies": { - "@tanstack/virtual-core": "3.4.0" + "@tanstack/virtual-core": "3.5.0" }, "funding": { "type": "github", @@ -3583,18 +3532,18 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.4.0.tgz", - "integrity": "sha512-75jXqXxqq5M5Veb9KP1STi8kA5u408uOOAefk2ftHDGCpUk3RP6zX++QqfbmHJTBiU72NQ+ghgCZVts/Wocz8Q==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.5.0.tgz", + "integrity": "sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@testing-library/dom": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.0.0.tgz", - "integrity": "sha512-PmJPnogldqoVFf+EwbHvbBJ98MmqASV8kLrBYgsDNxQcFMeIS7JFL48sfyXvuMtgmWO/wMhh25odr+8VhDmn4g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", + "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", "dev": true, "peer": true, "dependencies": { @@ -4281,9 +4230,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz", + "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==", "dev": true }, "node_modules/@types/mathjax": { @@ -4305,9 +4254,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "16.18.96", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.96.tgz", - "integrity": "sha512-84iSqGXoO+Ha16j8pRZ/L90vDMKX04QTYMTfYeE1WrjWaZXuchBehGUZEpNgx7JnmlrIHdnABmpjrQjhCnNldQ==", + "version": "16.18.97", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.97.tgz", + "integrity": "sha512-4muilE1Lbfn57unR+/nT9AFjWk0MtWi5muwCEJqnOvfRQDbSfLCUdN7vCIg8TYuaANfhLOV85ve+FNpiUsbSRg==", "devOptional": true }, "node_modules/@types/prop-types": { @@ -4316,9 +4265,9 @@ "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.0.tgz", - "integrity": "sha512-DiUcKjzE6soLyln8NNZmyhcQjVv+WsUIFSqetMN0p8927OztKT4VTfFTqsbAi5oAGIcgOmOajlfBqyptDDjZRw==", + "version": "18.3.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.2.tgz", + "integrity": "sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4393,9 +4342,9 @@ "optional": true }, "node_modules/ace-builds": { - "version": "1.33.1", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.33.1.tgz", - "integrity": "sha512-pj5mcXV1n3s86UI4SWUt8X0ltN8cTaYcvF76cSmvy5i2ZDtXX9KkjVcYTGkCV7ox6VUrzqHByeqH0xRsMjXi4g==" + "version": "1.33.2", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.33.2.tgz", + "integrity": "sha512-uDqCe+XDIdnADaDrA8o+x+qAfbM6uqyDQ43QcE6qC7zBPTvQSMOSPcXW+HvjZhEc2YbVYSaxXJX1qQKPgYqi5w==" }, "node_modules/acorn": { "version": "8.11.3", @@ -4435,16 +4384,16 @@ } }, "node_modules/ag-grid-community": { - "version": "31.2.1", - "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-31.2.1.tgz", - "integrity": "sha512-D+gnUQ4dHZ/EQJmupQnDqcEKiCEeuK5ZxlsIpdPKgHg/23dmW+aEdivtB9nLpSc2IEK0RUpchcSxeUT37Boo5A==" + "version": "31.3.1", + "resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-31.3.1.tgz", + "integrity": "sha512-kKnNxY8UaVoF0aUSdtzK7oGr48Wj+VrdDY5l2p9+HdF0cAo/jBEasuUYR85QbkumNyilI6UbFpO6IyCrjNQ6Iw==" }, "node_modules/ag-grid-react": { - "version": "31.2.1", - "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-31.2.1.tgz", - "integrity": "sha512-9UH3xxXRwZfW97oz58KboyCJl4t+zdetopieeHVcttsXX1DvGFDUIEz7A1sQaG8e1DAXLMf3IxoIPrfWheH4XA==", + "version": "31.3.1", + "resolved": "https://registry.npmjs.org/ag-grid-react/-/ag-grid-react-31.3.1.tgz", + "integrity": "sha512-MP5PhFeRhe1gWNx866Sr1C+IrJcrJ0yj8pM/ls+Be/GNmSyIcmGb0Gwbl19bOSdfL5btTkNmGY/RbwnIO4GoMQ==", "dependencies": { - "ag-grid-community": "31.2.1", + "ag-grid-community": "31.3.1", "prop-types": "^15.8.1" }, "peerDependencies": { @@ -4760,26 +4709,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bin-version-check/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/bin-version-check/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -4787,12 +4721,6 @@ "node": ">=10" } }, - "node_modules/bin-version-check/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/bin-version/node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -5035,9 +4963,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001612", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", - "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "version": "1.0.30001618", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001618.tgz", + "integrity": "sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==", "funding": [ { "type": "opencollective", @@ -5537,9 +5465,9 @@ } }, "node_modules/daisyui": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.10.2.tgz", - "integrity": "sha512-eCWS1W/JPyxW9IvlgW5m0R6rp9ZhRsBTW37rvEUthckkjsV04u8XipV519OoccSA46ixhSJa3q7XLI1WUFtRCA==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.11.1.tgz", + "integrity": "sha512-obT9CUbQdW6eoHwSeT5VwaRrWlwrM4OT5qlfdJ0oQlSIEYhwnEl2+L2fwu5PioLbitwuMdYC2X8I1cyy8Pf6LQ==", "dev": true, "dependencies": { "css-selector-tokenizer": "^0.8", @@ -5859,9 +5787,9 @@ } }, "node_modules/dompurify": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.1.tgz", - "integrity": "sha512-tVP8C/GJwnABOn/7cx/ymx/hXpmBfWIPihC1aOEvS8GbMqy3pgeYtJk1HXN3CO7tu+8bpY18f6isjR5Cymj0TQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.3.tgz", + "integrity": "sha512-5sOWYSNPaxz6o2MUPvtyxTTqR4D3L77pr5rUQoWgD5ROQtVIZQgJkXbo1DLlK3vj11YGw5+LnF4SYti4gZmwng==" }, "node_modules/dot-case": { "version": "3.0.4", @@ -5889,9 +5817,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.4.750", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz", - "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==" + "version": "1.4.767", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.767.tgz", + "integrity": "sha512-nzzHfmQqBss7CE3apQHkHjXW77+8w3ubGCIoEijKCJebPufREaFETgGXWTkh32t259F3Kcq+R8MZdFdOJROgYw==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -6851,9 +6779,9 @@ } }, "node_modules/framer-motion": { - "version": "11.1.7", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.1.7.tgz", - "integrity": "sha512-cW11Pu53eDAXUEhv5hEiWuIXWhfkbV32PlgVISn7jRdcAiVrJ1S03YQQ0/DzoswGYYwKi4qYmHHjCzAH52eSdQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.2.0.tgz", + "integrity": "sha512-LRfLVPEwtO9IXJCAsWvtj3XZxrdZDcTxNNkZEq30aQ8p7/wimfUkDy67TDWdtzPiyKDkqOHDhaQC6XVrQ4Fh7A==", "dependencies": { "tslib": "^2.4.0" }, @@ -8794,14 +8722,14 @@ } }, "node_modules/merge-refs": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.2.2.tgz", - "integrity": "sha512-RwcT7GsQR3KbuLw1rRuodq4Nt547BKEBkliZ0qqsrpyNne9bGTFtsFIsIpx82huWhcl3kOlOlH4H0xkPk/DqVw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.3.0.tgz", + "integrity": "sha512-nqXPXbso+1dcKDpPCXvwZyJILz+vSLqGGOnDrYHQYE+B8n9JTCekVLC65AfCpR4ggVyA/45Y0iR9LDyS2iI+zA==", "funding": { "url": "https://github.com/wojtekmaj/merge-refs?sponsor=1" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -9731,9 +9659,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", - "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", + "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -9835,17 +9763,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -10082,24 +10010,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.1.tgz", - "integrity": "sha512-tS24spDe/zXhWbNPErCHs/AGOzbKGHT+ybSBqmdLm8WZ1xXLWvH8Qn71QPAlqVhd0qUTWjy+Kl9JmISgDdEjsA==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "engines": { "node": "14 || >=16.14" } @@ -10147,9 +10075,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -10179,11 +10107,11 @@ } }, "node_modules/playwright": { - "version": "1.43.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz", - "integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0.tgz", + "integrity": "sha512-F9b3GUCLQ3Nffrfb6dunPOkE5Mh68tR7zN32L4jCk4FjQamgesGay7/dAAe1WaMEGV04DkdJfcJzjoCKygUaRQ==", "dependencies": { - "playwright-core": "1.43.1" + "playwright-core": "1.44.0" }, "bin": { "playwright": "cli.js" @@ -10196,9 +10124,9 @@ } }, "node_modules/playwright-core": { - "version": "1.43.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz", - "integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0.tgz", + "integrity": "sha512-ZTbkNpFfYcGWohvTTl+xewITm7EOuqIqex0c7dNZ+aXsbrLj0qI8XlGKfPpipjm0Wny/4Lt4CJsWJk1stVS5qQ==", "bin": { "playwright-core": "cli.js" }, @@ -10883,9 +10811,9 @@ } }, "node_modules/react-icons": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.1.0.tgz", - "integrity": "sha512-D3zug1270S4hbSlIRJ0CUS97QE1yNNKDjzQe3HqY0aefp2CBn9VgzgES27sRR2gOvFK+0CNx/BW0ggOESp6fqQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", "peerDependencies": { "react": "*" } @@ -10944,9 +10872,9 @@ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/react-pdf": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.7.1.tgz", - "integrity": "sha512-cbbf/PuRtGcPPw+HLhMI1f6NSka8OJgg+j/yPWTe95Owf0fK6gmVY7OXpTxMeh92O3T3K3EzfE0ML0eXPGwR5g==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.7.3.tgz", + "integrity": "sha512-a2VfDl8hiGjugpqezBTUzJHYLNB7IS7a2t7GD52xMI9xHg8LdVaTMsnM9ZlNmKadnStT/tvX5IfV0yLn+JvYmw==", "dependencies": { "clsx": "^2.0.0", "dequal": "^2.0.3", @@ -11041,11 +10969,11 @@ } }, "node_modules/react-router": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", - "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", + "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==", "dependencies": { - "@remix-run/router": "1.16.0" + "@remix-run/router": "1.16.1" }, "engines": { "node": ">=14.0.0" @@ -11055,12 +10983,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", - "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz", + "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==", "dependencies": { - "@remix-run/router": "1.16.0", - "react-router": "6.23.0" + "@remix-run/router": "1.16.1", + "react-router": "6.23.1" }, "engines": { "node": ">=14.0.0" @@ -11116,16 +11044,16 @@ } }, "node_modules/reactflow": { - "version": "11.11.2", - "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.2.tgz", - "integrity": "sha512-o1fT3stSdhzW+SedCGNSmEvZvULZygZIMLyW67NcWNZrgwx1wuJfzLg5fuQ0Nzf389wItumZX/zP3zdaPX7lEw==", + "version": "11.11.3", + "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.3.tgz", + "integrity": "sha512-wusd1Xpn1wgsSEv7UIa4NNraCwH9syBtubBy4xVNXg3b+CDKM+sFaF3hnMx0tr0et4km9urIDdNvwm34QiZong==", "dependencies": { - "@reactflow/background": "11.3.12", - "@reactflow/controls": "11.2.12", - "@reactflow/core": "11.11.2", - "@reactflow/minimap": "11.7.12", - "@reactflow/node-resizer": "2.2.12", - "@reactflow/node-toolbar": "1.3.12" + "@reactflow/background": "11.3.13", + "@reactflow/controls": "11.2.13", + "@reactflow/core": "11.11.3", + "@reactflow/minimap": "11.7.13", + "@reactflow/node-resizer": "2.2.13", + "@reactflow/node-toolbar": "1.3.13" }, "peerDependencies": { "react": ">=17", @@ -11545,26 +11473,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semver-truncate/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/semver-truncate/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -11572,12 +11485,6 @@ "node": ">=10" } }, - "node_modules/semver-truncate/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -12223,30 +12130,30 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "10.3.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz", + "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.6", "minimatch": "^9.0.1", "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "path-scurry": "^1.11.0" }, "bin": { "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/sucrase/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -12452,9 +12359,9 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -12613,9 +12520,9 @@ } }, "node_modules/undici": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.14.1.tgz", - "integrity": "sha512-mAel3i4BsYhkeVPXeIPXVGPJKeBzqCieZYoFsbWfUzd68JmHByhc1Plit5WlylxXFaGpgkZB8mExlxnt+Q1p7A==", + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.16.1.tgz", + "integrity": "sha512-NeNiTT7ixpeiL1qOIU/xTVpHpVP0svmI6PwoCKaMGaI5AsHOaRdwqU/f7Fi9eyU4u03nd5U/BC8wmRMnS9nqoA==", "engines": { "node": ">=18.17" } @@ -12766,9 +12673,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "funding": [ { "type": "opencollective", @@ -12784,8 +12691,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -13545,6 +13452,15 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -13672,9 +13588,9 @@ "devOptional": true }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", "engines": { "node": ">=10.0.0" }, @@ -13726,9 +13642,9 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", "bin": { "yaml": "bin.mjs" }, @@ -13749,9 +13665,9 @@ } }, "node_modules/zod": { - "version": "3.23.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.4.tgz", - "integrity": "sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw==", + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 83772ee0d..b85782b09 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -1075,32 +1075,35 @@ export function expandGroupNode( }); //update template values Object.keys(template).forEach((key) => { - let { field, id } = template[key].proxy!; - let nodeIndex = gNodes.findIndex((n) => n.id === id); - if (nodeIndex !== -1) { - let proxy: { id: string; field: string } | undefined; - let display_name: string | undefined; - let show = gNodes[nodeIndex].data.node!.template[field].show; - let advanced = gNodes[nodeIndex].data.node!.template[field].advanced; - if (gNodes[nodeIndex].data.node!.template[field].display_name) { - display_name = - gNodes[nodeIndex].data.node!.template[field].display_name; - } else { - display_name = gNodes[nodeIndex].data.node!.template[field].name; - } - if (gNodes[nodeIndex].data.node!.template[field].proxy) { - proxy = gNodes[nodeIndex].data.node!.template[field].proxy; - } - gNodes[nodeIndex].data.node!.template[field] = template[key]; - gNodes[nodeIndex].data.node!.template[field].show = show; - gNodes[nodeIndex].data.node!.template[field].advanced = advanced; - gNodes[nodeIndex].data.node!.template[field].display_name = display_name; - // keep the nodes selected after ungrouping - // gNodes[nodeIndex].selected = false; - if (proxy) { - gNodes[nodeIndex].data.node!.template[field].proxy = proxy; - } else { - delete gNodes[nodeIndex].data.node!.template[field].proxy; + if (template[key].proxy) { + let { field, id } = template[key].proxy!; + let nodeIndex = gNodes.findIndex((n) => n.id === id); + if (nodeIndex !== -1) { + let proxy: { id: string; field: string } | undefined; + let display_name: string | undefined; + let show = gNodes[nodeIndex].data.node!.template[field].show; + let advanced = gNodes[nodeIndex].data.node!.template[field].advanced; + if (gNodes[nodeIndex].data.node!.template[field].display_name) { + display_name = + gNodes[nodeIndex].data.node!.template[field].display_name; + } else { + display_name = gNodes[nodeIndex].data.node!.template[field].name; + } + if (gNodes[nodeIndex].data.node!.template[field].proxy) { + proxy = gNodes[nodeIndex].data.node!.template[field].proxy; + } + gNodes[nodeIndex].data.node!.template[field] = template[key]; + gNodes[nodeIndex].data.node!.template[field].show = show; + gNodes[nodeIndex].data.node!.template[field].advanced = advanced; + gNodes[nodeIndex].data.node!.template[field].display_name = + display_name; + // keep the nodes selected after ungrouping + // gNodes[nodeIndex].selected = false; + if (proxy) { + gNodes[nodeIndex].data.node!.template[field].proxy = proxy; + } else { + delete gNodes[nodeIndex].data.node!.template[field].proxy; + } } } }); From 14ff98213da4c777d3e851bedf0ec4c3dc106414 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 14 May 2024 19:23:36 -0300 Subject: [PATCH 27/55] add export flow on API modal and fix .env bug (#1896) * feat(codeTabsComponent): add ExportModal component to enable exporting flow data in CodeTabsComponent * refactor(service.py): update VariableService to handle environment variables with whitespace by stripping the value before creating the variable * chore: Update package versions to 1.0.0a33 and 0.0.44 for 'langflow' and 'langflow-base' respectively * make lock --- poetry.lock | 230 ++++++++++-------- pyproject.toml | 2 +- .../langflow/services/variable/service.py | 5 +- src/backend/base/poetry.lock | 6 +- src/backend/base/pyproject.toml | 2 +- .../components/codeTabsComponent/index.tsx | 7 + 6 files changed, 138 insertions(+), 114 deletions(-) diff --git a/poetry.lock b/poetry.lock index 909af7a6e..8c06db1c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -469,17 +469,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.103" +version = "1.34.105" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.103-py3-none-any.whl", hash = "sha256:59b6499f1bb423dd99de6566a20d0a7cf1a5476824be3a792290fd86600e8365"}, - {file = "boto3-1.34.103.tar.gz", hash = "sha256:58d097241f3895c4a4c80c9e606689c6e06d77f55f9f53a4cc02dee7e03938b9"}, + {file = "boto3-1.34.105-py3-none-any.whl", hash = "sha256:b633e8fbf7145bdb995ce68a27d096bb89fd393185b0e773418d81cd78db5a03"}, + {file = "boto3-1.34.105.tar.gz", hash = "sha256:f2c11635be0de7b7c06eb606ece1add125e02d6ed521592294a0a21af09af135"}, ] [package.dependencies] -botocore = ">=1.34.103,<1.35.0" +botocore = ">=1.34.105,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -488,13 +488,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.103" +version = "1.34.105" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.103-py3-none-any.whl", hash = "sha256:0330d139f18f78d38127e65361859e24ebd6a8bcba184f903c01bb999a3fa431"}, - {file = "botocore-1.34.103.tar.gz", hash = "sha256:5f07e2c7302c0a9f469dcd08b4ddac152e9f5888b12220242c20056255010939"}, + {file = "botocore-1.34.105-py3-none-any.whl", hash = "sha256:a459d060b541beecb50681e6e8a39313cca981e146a59ba7c5229d62f631a016"}, + {file = "botocore-1.34.105.tar.gz", hash = "sha256:727d5d3e800ac8b705fca6e19b6fefa1e728a81d62a712df9bd32ed0117c740b"}, ] [package.dependencies] @@ -2476,13 +2476,13 @@ examples = ["oauth2"] [[package]] name = "google-ai-generativelanguage" -version = "0.6.2" +version = "0.6.3" description = "Google Ai Generativelanguage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-ai-generativelanguage-0.6.2.tar.gz", hash = "sha256:308791ac3b9dad015b359172970739aa3753dd542142a416d07f9fa047e22386"}, - {file = "google_ai_generativelanguage-0.6.2-py3-none-any.whl", hash = "sha256:bf84c34c641570d7e8a1f2e6901e6771af1438f2ee8307d1801fd43585f9b1c6"}, + {file = "google-ai-generativelanguage-0.6.3.tar.gz", hash = "sha256:10a11f1e1bb8470ff50030c1acd729b3aba7a29ade2c30cf1d1c917291366c67"}, + {file = "google_ai_generativelanguage-0.6.3-py3-none-any.whl", hash = "sha256:55a6698f6c9cbbfde5f9cd288073b6941dd9e3e6dc2176dfa3197f9a4c489895"}, ] [package.dependencies] @@ -2796,16 +2796,16 @@ testing = ["pytest"] [[package]] name = "google-generativeai" -version = "0.5.2" +version = "0.5.3" description = "Google Generative AI High level API client library and tools." optional = false python-versions = ">=3.9" files = [ - {file = "google_generativeai-0.5.2-py3-none-any.whl", hash = "sha256:56f39485a0a673c93c21ec31c17809cc6a964193fb77b7ce809ad15d0dd72d7b"}, + {file = "google_generativeai-0.5.3-py3-none-any.whl", hash = "sha256:a74509ee219601c74c0561eb4e1c9af6a88594c7dd098d30a18c6592afe62bd9"}, ] [package.dependencies] -google-ai-generativelanguage = "0.6.2" +google-ai-generativelanguage = "0.6.3" google-api-core = "*" google-api-python-client = "*" google-auth = ">=2.15.0" @@ -4234,7 +4234,7 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langflow-base" -version = "0.0.43" +version = "0.0.44" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -4346,13 +4346,13 @@ regex = ["regex"] [[package]] name = "litellm" -version = "1.37.5" +version = "1.37.9" 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.37.5-py3-none-any.whl", hash = "sha256:a444dad4079d3d4c49037fe37581cd04b2135e674e9e9d1cfdbda32facd546ec"}, - {file = "litellm-1.37.5.tar.gz", hash = "sha256:22d7292d2952d82992ebebc3b7dfa1a97393f603ce652f3223f2742123ba7f2b"}, + {file = "litellm-1.37.9-py3-none-any.whl", hash = "sha256:f5e96df4e28e302a5df4e8f5599ac35ffbeebbacf4d68f4c609155e24ba8fa03"}, + {file = "litellm-1.37.9.tar.gz", hash = "sha256:2a2fecacde1e3a414b3865c99e5be3b5cffd21433e2648f660116f1ac9333294"}, ] [package.dependencies] @@ -4368,7 +4368,7 @@ 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 (>=22.0.0,<23.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)"] +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.111.0,<0.112.0)", "fastapi-sso (>=0.10.0,<0.11.0)", "gunicorn (>=22.0.0,<23.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" @@ -4394,13 +4394,13 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)", "scipy (>=1.10)"] [[package]] name = "llama-index" -version = "0.10.36" +version = "0.10.37" description = "Interface between LLMs and your data" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index-0.10.36-py3-none-any.whl", hash = "sha256:e57779f332323b00576cf9e8fee0ab5b978aaf35902288691da01a7839b99e58"}, - {file = "llama_index-0.10.36.tar.gz", hash = "sha256:275309a2317e9279b296e552c334e566c4f011223f6ed39e342f5264a05c4d9a"}, + {file = "llama_index-0.10.37-py3-none-any.whl", hash = "sha256:da8871c5c8e5d038e56c0e5cb8c18a81ddc4117bf403bace95b4cec212f88fb9"}, + {file = "llama_index-0.10.37.tar.gz", hash = "sha256:d5057fd609e2423e75a4695242ab030d1647e4f07cb46faf9476ab504005f033"}, ] [package.dependencies] @@ -4419,13 +4419,13 @@ llama-index-readers-llama-parse = ">=0.1.2,<0.2.0" [[package]] name = "llama-index-agent-openai" -version = "0.2.4" +version = "0.2.5" description = "llama-index agent openai integration" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_index_agent_openai-0.2.4-py3-none-any.whl", hash = "sha256:b05eb7f0331d40a7a2bcaabaa84c9c7ebe6837a72038d03cbb71c083a4301a81"}, - {file = "llama_index_agent_openai-0.2.4.tar.gz", hash = "sha256:cd4a58f8bf233728ceda554cbb34de56a2b6bbbbff6ce801c3f8ff0c8280bf55"}, + {file = "llama_index_agent_openai-0.2.5-py3-none-any.whl", hash = "sha256:67536bb104b24734f79324207034d948a2ca7e4cc20dd60cf05d6eeb4b12a586"}, + {file = "llama_index_agent_openai-0.2.5.tar.gz", hash = "sha256:45f4cc670d037a8a67f541d3a4d095f7f61caff6ed2c25702441eb1116d4b495"}, ] [package.dependencies] @@ -4659,13 +4659,13 @@ llama-parse = ">=0.4.0,<0.5.0" [[package]] name = "llama-parse" -version = "0.4.2" +version = "0.4.3" description = "Parse files into RAG-Optimized formats." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "llama_parse-0.4.2-py3-none-any.whl", hash = "sha256:5ce0390141f216dcd88c1123fea7f2a4f561d177f791a97217a3db3509dec4ff"}, - {file = "llama_parse-0.4.2.tar.gz", hash = "sha256:fa04c09730b102155f6505de9cf91998c86d334581f0f12597c5eb47ca5db859"}, + {file = "llama_parse-0.4.3-py3-none-any.whl", hash = "sha256:c48c53a3080daeede293df620dddb1f381e084c31ee2dd44dce3f8615df723e8"}, + {file = "llama_parse-0.4.3.tar.gz", hash = "sha256:01836147b5238873b24a7dd41c5ab942b01b09b92d75570f30cf2861c084a0eb"}, ] [package.dependencies] @@ -4886,13 +4886,13 @@ source = ["Cython (>=3.0.10)"] [[package]] name = "mako" -version = "1.3.3" +version = "1.3.5" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" files = [ - {file = "Mako-1.3.3-py3-none-any.whl", hash = "sha256:5324b88089a8978bf76d1629774fcc2f1c07b82acdf00f4c5dd8ceadfffc4b40"}, - {file = "Mako-1.3.3.tar.gz", hash = "sha256:e16c01d9ab9c11f7290eef1cfefc093fb5a45ee4a3da09e2fec2e4d1bae54e73"}, + {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, + {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, ] [package.dependencies] @@ -5864,13 +5864,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.28.2" +version = "1.30.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.28.2-py3-none-any.whl", hash = "sha256:2b2ebe032080b53f0a91ebe5f45462d3a5b504d82a6bc5146c750653a47be587"}, - {file = "openai-1.28.2.tar.gz", hash = "sha256:a0cae5785e2d1e9ae0732970fc0555da13a5a7e08d0a339fb670525d3b5e0e1a"}, + {file = "openai-1.30.1-py3-none-any.whl", hash = "sha256:c9fb3c3545c118bbce8deb824397b9433a66d0d0ede6a96f7009c95b76de4a46"}, + {file = "openai-1.30.1.tar.gz", hash = "sha256:4f85190e577cba0b066e1950b8eb9b11d25bc7ebcc43a86b326ce1bfa564ec74"}, ] [package.dependencies] @@ -6230,13 +6230,13 @@ xml = ["lxml (>=4.9.2)"] [[package]] name = "pandas-stubs" -version = "2.2.1.240316" +version = "2.2.2.240514" description = "Type annotations for pandas" optional = false python-versions = ">=3.9" files = [ - {file = "pandas_stubs-2.2.1.240316-py3-none-any.whl", hash = "sha256:0126a26451a37cb893ea62357ca87ba3d181bd999ec8ba2ca5602e20207d6682"}, - {file = "pandas_stubs-2.2.1.240316.tar.gz", hash = "sha256:236a4f812fb6b1922e9607ff09e427f6d8540c421c9e5a40e3e4ddf7adac7f05"}, + {file = "pandas_stubs-2.2.2.240514-py3-none-any.whl", hash = "sha256:5d6f64d45a98bc94152a0f76fa648e598cd2b9ba72302fd34602479f0c391a53"}, + {file = "pandas_stubs-2.2.2.240514.tar.gz", hash = "sha256:85b20da44a62c80eb8389bcf4cbfe31cce1cafa8cca4bf1fc75ec45892e72ce8"}, ] [package.dependencies] @@ -6635,6 +6635,7 @@ optional = false python-versions = ">=3.7" files = [ {file = "psycopg-3.1.19-py3-none-any.whl", hash = "sha256:dca5e5521c859f6606686432ae1c94e8766d29cc91f2ee595378c510cc5b0731"}, + {file = "psycopg-3.1.19.tar.gz", hash = "sha256:92d7b78ad82426cdcf1a0440678209faa890c6e1721361c2f8901f0dccd62961"}, ] [package.dependencies] @@ -9491,76 +9492,89 @@ devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3) [[package]] name = "ujson" -version = "5.9.0" +version = "5.10.0" description = "Ultra fast JSON encoder and decoder for Python" optional = false python-versions = ">=3.8" files = [ - {file = "ujson-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ab71bf27b002eaf7d047c54a68e60230fbd5cd9da60de7ca0aa87d0bccead8fa"}, - {file = "ujson-5.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a365eac66f5aa7a7fdf57e5066ada6226700884fc7dce2ba5483538bc16c8c5"}, - {file = "ujson-5.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e015122b337858dba5a3dc3533af2a8fc0410ee9e2374092f6a5b88b182e9fcc"}, - {file = "ujson-5.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:779a2a88c53039bebfbccca934430dabb5c62cc179e09a9c27a322023f363e0d"}, - {file = "ujson-5.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10ca3c41e80509fd9805f7c149068fa8dbee18872bbdc03d7cca928926a358d5"}, - {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a566e465cb2fcfdf040c2447b7dd9718799d0d90134b37a20dff1e27c0e9096"}, - {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f833c529e922577226a05bc25b6a8b3eb6c4fb155b72dd88d33de99d53113124"}, - {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b68a0caab33f359b4cbbc10065c88e3758c9f73a11a65a91f024b2e7a1257106"}, - {file = "ujson-5.9.0-cp310-cp310-win32.whl", hash = "sha256:7cc7e605d2aa6ae6b7321c3ae250d2e050f06082e71ab1a4200b4ae64d25863c"}, - {file = "ujson-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6d3f10eb8ccba4316a6b5465b705ed70a06011c6f82418b59278fbc919bef6f"}, - {file = "ujson-5.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b23bbb46334ce51ddb5dded60c662fbf7bb74a37b8f87221c5b0fec1ec6454b"}, - {file = "ujson-5.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6974b3a7c17bbf829e6c3bfdc5823c67922e44ff169851a755eab79a3dd31ec0"}, - {file = "ujson-5.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5964ea916edfe24af1f4cc68488448fbb1ec27a3ddcddc2b236da575c12c8ae"}, - {file = "ujson-5.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ba7cac47dd65ff88571eceeff48bf30ed5eb9c67b34b88cb22869b7aa19600d"}, - {file = "ujson-5.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bbd91a151a8f3358c29355a491e915eb203f607267a25e6ab10531b3b157c5e"}, - {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:829a69d451a49c0de14a9fecb2a2d544a9b2c884c2b542adb243b683a6f15908"}, - {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a807ae73c46ad5db161a7e883eec0fbe1bebc6a54890152ccc63072c4884823b"}, - {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8fc2aa18b13d97b3c8ccecdf1a3c405f411a6e96adeee94233058c44ff92617d"}, - {file = "ujson-5.9.0-cp311-cp311-win32.whl", hash = "sha256:70e06849dfeb2548be48fdd3ceb53300640bc8100c379d6e19d78045e9c26120"}, - {file = "ujson-5.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:7309d063cd392811acc49b5016728a5e1b46ab9907d321ebbe1c2156bc3c0b99"}, - {file = "ujson-5.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:20509a8c9f775b3a511e308bbe0b72897ba6b800767a7c90c5cca59d20d7c42c"}, - {file = "ujson-5.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b28407cfe315bd1b34f1ebe65d3bd735d6b36d409b334100be8cdffae2177b2f"}, - {file = "ujson-5.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d302bd17989b6bd90d49bade66943c78f9e3670407dbc53ebcf61271cadc399"}, - {file = "ujson-5.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f21315f51e0db8ee245e33a649dd2d9dce0594522de6f278d62f15f998e050e"}, - {file = "ujson-5.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5635b78b636a54a86fdbf6f027e461aa6c6b948363bdf8d4fbb56a42b7388320"}, - {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82b5a56609f1235d72835ee109163c7041b30920d70fe7dac9176c64df87c164"}, - {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5ca35f484622fd208f55041b042d9d94f3b2c9c5add4e9af5ee9946d2d30db01"}, - {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:829b824953ebad76d46e4ae709e940bb229e8999e40881338b3cc94c771b876c"}, - {file = "ujson-5.9.0-cp312-cp312-win32.whl", hash = "sha256:25fa46e4ff0a2deecbcf7100af3a5d70090b461906f2299506485ff31d9ec437"}, - {file = "ujson-5.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:60718f1720a61560618eff3b56fd517d107518d3c0160ca7a5a66ac949c6cf1c"}, - {file = "ujson-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d581db9db9e41d8ea0b2705c90518ba623cbdc74f8d644d7eb0d107be0d85d9c"}, - {file = "ujson-5.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ff741a5b4be2d08fceaab681c9d4bc89abf3c9db600ab435e20b9b6d4dfef12e"}, - {file = "ujson-5.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdcb02cabcb1e44381221840a7af04433c1dc3297af76fde924a50c3054c708c"}, - {file = "ujson-5.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e208d3bf02c6963e6ef7324dadf1d73239fb7008491fdf523208f60be6437402"}, - {file = "ujson-5.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4b3917296630a075e04d3d07601ce2a176479c23af838b6cf90a2d6b39b0d95"}, - {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0c4d6adb2c7bb9eb7c71ad6f6f612e13b264942e841f8cc3314a21a289a76c4e"}, - {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0b159efece9ab5c01f70b9d10bbb77241ce111a45bc8d21a44c219a2aec8ddfd"}, - {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0cb4a7814940ddd6619bdce6be637a4b37a8c4760de9373bac54bb7b229698b"}, - {file = "ujson-5.9.0-cp38-cp38-win32.whl", hash = "sha256:dc80f0f5abf33bd7099f7ac94ab1206730a3c0a2d17549911ed2cb6b7aa36d2d"}, - {file = "ujson-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:506a45e5fcbb2d46f1a51fead991c39529fc3737c0f5d47c9b4a1d762578fc30"}, - {file = "ujson-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0fd2eba664a22447102062814bd13e63c6130540222c0aa620701dd01f4be81"}, - {file = "ujson-5.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bdf7fc21a03bafe4ba208dafa84ae38e04e5d36c0e1c746726edf5392e9f9f36"}, - {file = "ujson-5.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2f909bc08ce01f122fd9c24bc6f9876aa087188dfaf3c4116fe6e4daf7e194f"}, - {file = "ujson-5.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd4ea86c2afd41429751d22a3ccd03311c067bd6aeee2d054f83f97e41e11d8f"}, - {file = "ujson-5.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:63fb2e6599d96fdffdb553af0ed3f76b85fda63281063f1cb5b1141a6fcd0617"}, - {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:32bba5870c8fa2a97f4a68f6401038d3f1922e66c34280d710af00b14a3ca562"}, - {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:37ef92e42535a81bf72179d0e252c9af42a4ed966dc6be6967ebfb929a87bc60"}, - {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f69f16b8f1c69da00e38dc5f2d08a86b0e781d0ad3e4cc6a13ea033a439c4844"}, - {file = "ujson-5.9.0-cp39-cp39-win32.whl", hash = "sha256:3382a3ce0ccc0558b1c1668950008cece9bf463ebb17463ebf6a8bfc060dae34"}, - {file = "ujson-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:6adef377ed583477cf005b58c3025051b5faa6b8cc25876e594afbb772578f21"}, - {file = "ujson-5.9.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ffdfebd819f492e48e4f31c97cb593b9c1a8251933d8f8972e81697f00326ff1"}, - {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4eec2ddc046360d087cf35659c7ba0cbd101f32035e19047013162274e71fcf"}, - {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbb90aa5c23cb3d4b803c12aa220d26778c31b6e4b7a13a1f49971f6c7d088e"}, - {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0823cb70866f0d6a4ad48d998dd338dce7314598721bc1b7986d054d782dfd"}, - {file = "ujson-5.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4e35d7885ed612feb6b3dd1b7de28e89baaba4011ecdf995e88be9ac614765e9"}, - {file = "ujson-5.9.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b048aa93eace8571eedbd67b3766623e7f0acbf08ee291bef7d8106210432427"}, - {file = "ujson-5.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:323279e68c195110ef85cbe5edce885219e3d4a48705448720ad925d88c9f851"}, - {file = "ujson-5.9.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ac92d86ff34296f881e12aa955f7014d276895e0e4e868ba7fddebbde38e378"}, - {file = "ujson-5.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6eecbd09b316cea1fd929b1e25f70382917542ab11b692cb46ec9b0a26c7427f"}, - {file = "ujson-5.9.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:473fb8dff1d58f49912323d7cb0859df5585cfc932e4b9c053bf8cf7f2d7c5c4"}, - {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f91719c6abafe429c1a144cfe27883eace9fb1c09a9c5ef1bcb3ae80a3076a4e"}, - {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1c0991c4fe256f5fdb19758f7eac7f47caac29a6c57d0de16a19048eb86bad"}, - {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a8ea0f55a1396708e564595aaa6696c0d8af532340f477162ff6927ecc46e21"}, - {file = "ujson-5.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:07e0cfdde5fd91f54cd2d7ffb3482c8ff1bf558abf32a8b953a5d169575ae1cd"}, - {file = "ujson-5.9.0.tar.gz", hash = "sha256:89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532"}, + {file = "ujson-5.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd"}, + {file = "ujson-5.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22cffecf73391e8abd65ef5f4e4dd523162a3399d5e84faa6aebbf9583df86d6"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26b0e2d2366543c1bb4fbd457446f00b0187a2bddf93148ac2da07a53fe51569"}, + {file = "ujson-5.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:caf270c6dba1be7a41125cd1e4fc7ba384bf564650beef0df2dd21a00b7f5770"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a245d59f2ffe750446292b0094244df163c3dc96b3ce152a2c837a44e7cda9d1"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:94a87f6e151c5f483d7d54ceef83b45d3a9cca7a9cb453dbdbb3f5a6f64033f5"}, + {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:29b443c4c0a113bcbb792c88bea67b675c7ca3ca80c3474784e08bba01c18d51"}, + {file = "ujson-5.10.0-cp310-cp310-win32.whl", hash = "sha256:c18610b9ccd2874950faf474692deee4223a994251bc0a083c114671b64e6518"}, + {file = "ujson-5.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:924f7318c31874d6bb44d9ee1900167ca32aa9b69389b98ecbde34c1698a250f"}, + {file = "ujson-5.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a5b366812c90e69d0f379a53648be10a5db38f9d4ad212b60af00bd4048d0f00"}, + {file = "ujson-5.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:502bf475781e8167f0f9d0e41cd32879d120a524b22358e7f205294224c71126"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b91b5d0d9d283e085e821651184a647699430705b15bf274c7896f23fe9c9d8"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:129e39af3a6d85b9c26d5577169c21d53821d8cf68e079060602e861c6e5da1b"}, + {file = "ujson-5.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f77b74475c462cb8b88680471193064d3e715c7c6074b1c8c412cb526466efe9"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ec0ca8c415e81aa4123501fee7f761abf4b7f386aad348501a26940beb1860f"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab13a2a9e0b2865a6c6db9271f4b46af1c7476bfd51af1f64585e919b7c07fd4"}, + {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:57aaf98b92d72fc70886b5a0e1a1ca52c2320377360341715dd3933a18e827b1"}, + {file = "ujson-5.10.0-cp311-cp311-win32.whl", hash = "sha256:2987713a490ceb27edff77fb184ed09acdc565db700ee852823c3dc3cffe455f"}, + {file = "ujson-5.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f00ea7e00447918ee0eff2422c4add4c5752b1b60e88fcb3c067d4a21049a720"}, + {file = "ujson-5.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98ba15d8cbc481ce55695beee9f063189dce91a4b08bc1d03e7f0152cd4bbdd5"}, + {file = "ujson-5.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9d2edbf1556e4f56e50fab7d8ff993dbad7f54bac68eacdd27a8f55f433578e"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6627029ae4f52d0e1a2451768c2c37c0c814ffc04f796eb36244cf16b8e57043"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ccb77b3e40b151e20519c6ae6d89bfe3f4c14e8e210d910287f778368bb3d1"}, + {file = "ujson-5.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3caf9cd64abfeb11a3b661329085c5e167abbe15256b3b68cb5d914ba7396f3"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6e32abdce572e3a8c3d02c886c704a38a1b015a1fb858004e03d20ca7cecbb21"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a65b6af4d903103ee7b6f4f5b85f1bfd0c90ba4eeac6421aae436c9988aa64a2"}, + {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:604a046d966457b6cdcacc5aa2ec5314f0e8c42bae52842c1e6fa02ea4bda42e"}, + {file = "ujson-5.10.0-cp312-cp312-win32.whl", hash = "sha256:6dea1c8b4fc921bf78a8ff00bbd2bfe166345f5536c510671bccececb187c80e"}, + {file = "ujson-5.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:38665e7d8290188b1e0d57d584eb8110951a9591363316dd41cf8686ab1d0abc"}, + {file = "ujson-5.10.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:618efd84dc1acbd6bff8eaa736bb6c074bfa8b8a98f55b61c38d4ca2c1f7f287"}, + {file = "ujson-5.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38d5d36b4aedfe81dfe251f76c0467399d575d1395a1755de391e58985ab1c2e"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67079b1f9fb29ed9a2914acf4ef6c02844b3153913eb735d4bf287ee1db6e557"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7d0e0ceeb8fe2468c70ec0c37b439dd554e2aa539a8a56365fd761edb418988"}, + {file = "ujson-5.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59e02cd37bc7c44d587a0ba45347cc815fb7a5fe48de16bf05caa5f7d0d2e816"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a890b706b64e0065f02577bf6d8ca3b66c11a5e81fb75d757233a38c07a1f20"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:621e34b4632c740ecb491efc7f1fcb4f74b48ddb55e65221995e74e2d00bbff0"}, + {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9500e61fce0cfc86168b248104e954fead61f9be213087153d272e817ec7b4f"}, + {file = "ujson-5.10.0-cp313-cp313-win32.whl", hash = "sha256:4c4fc16f11ac1612f05b6f5781b384716719547e142cfd67b65d035bd85af165"}, + {file = "ujson-5.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:4573fd1695932d4f619928fd09d5d03d917274381649ade4328091ceca175539"}, + {file = "ujson-5.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a984a3131da7f07563057db1c3020b1350a3e27a8ec46ccbfbf21e5928a43050"}, + {file = "ujson-5.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73814cd1b9db6fc3270e9d8fe3b19f9f89e78ee9d71e8bd6c9a626aeaeaf16bd"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61e1591ed9376e5eddda202ec229eddc56c612b61ac6ad07f96b91460bb6c2fb"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2c75269f8205b2690db4572a4a36fe47cd1338e4368bc73a7a0e48789e2e35a"}, + {file = "ujson-5.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7223f41e5bf1f919cd8d073e35b229295aa8e0f7b5de07ed1c8fddac63a6bc5d"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc2fd6b3067c0782e7002ac3b38cf48608ee6366ff176bbd02cf969c9c20fe"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:232cc85f8ee3c454c115455195a205074a56ff42608fd6b942aa4c378ac14dd7"}, + {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cc6139531f13148055d691e442e4bc6601f6dba1e6d521b1585d4788ab0bfad4"}, + {file = "ujson-5.10.0-cp38-cp38-win32.whl", hash = "sha256:e7ce306a42b6b93ca47ac4a3b96683ca554f6d35dd8adc5acfcd55096c8dfcb8"}, + {file = "ujson-5.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:e82d4bb2138ab05e18f089a83b6564fee28048771eb63cdecf4b9b549de8a2cc"}, + {file = "ujson-5.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dfef2814c6b3291c3c5f10065f745a1307d86019dbd7ea50e83504950136ed5b"}, + {file = "ujson-5.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4734ee0745d5928d0ba3a213647f1c4a74a2a28edc6d27b2d6d5bd9fa4319e27"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47ebb01bd865fdea43da56254a3930a413f0c5590372a1241514abae8aa7c76"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee5e97c2496874acbf1d3e37b521dd1f307349ed955e62d1d2f05382bc36dd5"}, + {file = "ujson-5.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7490655a2272a2d0b072ef16b0b58ee462f4973a8f6bbe64917ce5e0a256f9c0"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba17799fcddaddf5c1f75a4ba3fd6441f6a4f1e9173f8a786b42450851bd74f1"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2aff2985cef314f21d0fecc56027505804bc78802c0121343874741650a4d3d1"}, + {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ad88ac75c432674d05b61184178635d44901eb749786c8eb08c102330e6e8996"}, + {file = "ujson-5.10.0-cp39-cp39-win32.whl", hash = "sha256:2544912a71da4ff8c4f7ab5606f947d7299971bdd25a45e008e467ca638d13c9"}, + {file = "ujson-5.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:3ff201d62b1b177a46f113bb43ad300b424b7847f9c5d38b1b4ad8f75d4a282a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5b6fee72fa77dc172a28f21693f64d93166534c263adb3f96c413ccc85ef6e64"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:61d0af13a9af01d9f26d2331ce49bb5ac1fb9c814964018ac8df605b5422dcb3"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecb24f0bdd899d368b715c9e6664166cf694d1e57be73f17759573a6986dd95a"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbd8fd427f57a03cff3ad6574b5e299131585d9727c8c366da4624a9069ed746"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beeaf1c48e32f07d8820c705ff8e645f8afa690cca1544adba4ebfa067efdc88"}, + {file = "ujson-5.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:baed37ea46d756aca2955e99525cc02d9181de67f25515c468856c38d52b5f3b"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7663960f08cd5a2bb152f5ee3992e1af7690a64c0e26d31ba7b3ff5b2ee66337"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8640fb4072d36b08e95a3a380ba65779d356b2fee8696afeb7794cf0902d0a1"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78778a3aa7aafb11e7ddca4e29f46bc5139131037ad628cc10936764282d6753"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0111b27f2d5c820e7f2dbad7d48e3338c824e7ac4d2a12da3dc6061cc39c8e6"}, + {file = "ujson-5.10.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c66962ca7565605b355a9ed478292da628b8f18c0f2793021ca4425abf8b01e5"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ba43cc34cce49cf2d4bc76401a754a81202d8aa926d0e2b79f0ee258cb15d3a4"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac56eb983edce27e7f51d05bc8dd820586c6e6be1c5216a6809b0c668bb312b8"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44bd4b23a0e723bf8b10628288c2c7c335161d6840013d4d5de20e48551773b"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c10f4654e5326ec14a46bcdeb2b685d4ada6911050aa8baaf3501e57024b804"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0de4971a89a762398006e844ae394bd46991f7c385d7a6a3b93ba229e6dac17e"}, + {file = "ujson-5.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e1402f0564a97d2a52310ae10a64d25bcef94f8dd643fcf5d310219d915484f7"}, + {file = "ujson-5.10.0.tar.gz", hash = "sha256:b3cd8f3c5d8c7738257f1018880444f7b7d9b66232c64649f562d7ba86ad4bc1"}, ] [[package]] @@ -9685,13 +9699,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.26.1" +version = "20.26.2" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.26.1-py3-none-any.whl", hash = "sha256:7aa9982a728ae5892558bff6a2839c00b9ed145523ece2274fad6f414690ae75"}, - {file = "virtualenv-20.26.1.tar.gz", hash = "sha256:604bfdceaeece392802e6ae48e69cec49168b9c5f4a44e483963f9242eb0e78b"}, + {file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"}, + {file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"}, ] [package.dependencies] @@ -9803,13 +9817,13 @@ files = [ [[package]] name = "weaviate-client" -version = "4.6.0" +version = "4.6.1" description = "A python native Weaviate client" optional = false python-versions = ">=3.8" files = [ - {file = "weaviate_client-4.6.0-py3-none-any.whl", hash = "sha256:4c9608ba5d495d1fe28e451aca057086cb55242bb8432bfb0008f433eef7a6ab"}, - {file = "weaviate_client-4.6.0.tar.gz", hash = "sha256:5cc6c8b2a6f9122b34ffa688070e5060ab044fe72a4a9233eb9938c6067866b8"}, + {file = "weaviate_client-4.6.1-py3-none-any.whl", hash = "sha256:0db94e5c87f92c9490d90f6de6637baa55dc0d92a3750dd782667b7e5d718ca3"}, + {file = "weaviate_client-4.6.1.tar.gz", hash = "sha256:6d3351f20dd98e3936351473c305ff7660c5ec4bd8b5ad1f11593ef60e8058f6"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 62544c31e..55edcab69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a32" +version = "1.0.0a33" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/langflow/services/variable/service.py b/src/backend/base/langflow/services/variable/service.py index 0c9208121..84671e0f9 100644 --- a/src/backend/base/langflow/services/variable/service.py +++ b/src/backend/base/langflow/services/variable/service.py @@ -33,10 +33,13 @@ class VariableService(Service): select(Variable).where(Variable.user_id == user_id, Variable.name == var) ).first(): try: + value = os.environ[var] + if isinstance(value, str): + value = value.strip() self.create_variable( user_id=user_id, name=var, - value=os.environ[var], + value=value, default_fields=[], _type="Credential", session=session, diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index a36ad1a2b..54b3145e0 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -1357,13 +1357,13 @@ source = ["Cython (>=3.0.10)"] [[package]] name = "mako" -version = "1.3.3" +version = "1.3.5" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" files = [ - {file = "Mako-1.3.3-py3-none-any.whl", hash = "sha256:5324b88089a8978bf76d1629774fcc2f1c07b82acdf00f4c5dd8ceadfffc4b40"}, - {file = "Mako-1.3.3.tar.gz", hash = "sha256:e16c01d9ab9c11f7290eef1cfefc093fb5a45ee4a3da09e2fec2e4d1bae54e73"}, + {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, + {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, ] [package.dependencies] diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index b71200be7..de4935508 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.43" +version = "0.0.44" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index c40c11439..0b08aaccd 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -43,6 +43,7 @@ import KeypairListComponent from "../keypairListComponent"; import ShadTooltip from "../shadTooltipComponent"; import { Label } from "../ui/label"; import { Switch } from "../ui/switch"; +import ExportModal from "../../modals/exportModal"; export default function CodeTabsComponent({ flow, @@ -167,6 +168,12 @@ export default function CodeTabsComponent({ Tweaks

+ +
+ + Export Flow +
+
{Number(activeTab) < 4 && ( <> From d42925c16c5ebf5c19120981775e59a16187d5bb Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Wed, 15 May 2024 13:59:50 +0200 Subject: [PATCH 28/55] Fixed Undo bug adding Skip Snapshot to function that resets inputs when disabled --- .../src/components/codeAreaComponent/index.tsx | 4 ++-- .../src/components/floatComponent/index.tsx | 2 +- .../src/components/inputComponent/index.tsx | 2 +- .../src/components/inputFileComponent/index.tsx | 6 +++--- .../src/components/inputGlobalComponent/index.tsx | 14 +++++++------- src/frontend/src/components/intComponent/index.tsx | 2 +- .../src/components/promptComponent/index.tsx | 2 +- .../src/components/textAreaComponent/index.tsx | 2 +- .../components/parameterComponent/index.tsx | 3 ++- src/frontend/src/types/components/index.ts | 14 +++++++------- 10 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/frontend/src/components/codeAreaComponent/index.tsx b/src/frontend/src/components/codeAreaComponent/index.tsx index af599e1d8..cd8a0f77d 100644 --- a/src/frontend/src/components/codeAreaComponent/index.tsx +++ b/src/frontend/src/components/codeAreaComponent/index.tsx @@ -18,12 +18,12 @@ export default function CodeAreaComponent({ setOpen, }: CodeAreaComponentType) { const [myValue, setMyValue] = useState( - typeof value == "string" ? value : JSON.stringify(value) + typeof value == "string" ? value : JSON.stringify(value), ); useEffect(() => { if (disabled && myValue !== "") { setMyValue(""); - onChange(""); + onChange("", true); } }, [disabled]); diff --git a/src/frontend/src/components/floatComponent/index.tsx b/src/frontend/src/components/floatComponent/index.tsx index a4ebf1ae9..8db5b823a 100644 --- a/src/frontend/src/components/floatComponent/index.tsx +++ b/src/frontend/src/components/floatComponent/index.tsx @@ -16,7 +16,7 @@ export default function FloatComponent({ // Clear component state useEffect(() => { if (disabled && value !== "") { - onChange(""); + onChange("", true); } }, [disabled]); diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index b1b4b9ef9..b285a1874 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -48,7 +48,7 @@ export default function InputComponent({ // Clear component state useEffect(() => { if (disabled && value && onChange && value !== "") { - onChange(""); + onChange("", true); } }, [disabled]); diff --git a/src/frontend/src/components/inputFileComponent/index.tsx b/src/frontend/src/components/inputFileComponent/index.tsx index 688ea8d97..fb83b18fb 100644 --- a/src/frontend/src/components/inputFileComponent/index.tsx +++ b/src/frontend/src/components/inputFileComponent/index.tsx @@ -27,7 +27,7 @@ export default function InputFileComponent({ useEffect(() => { if (disabled && value !== "") { setMyValue(""); - onChange(""); + onChange("", true); onFileChange(""); } }, [disabled, onChange]); @@ -106,8 +106,8 @@ export default function InputFileComponent({ editNode ? "input-edit-node input-dialog text-muted-foreground" : disabled - ? "input-disable input-dialog primary-input" - : "input-dialog primary-input text-muted-foreground" + ? "input-disable input-dialog primary-input" + : "input-dialog primary-input text-muted-foreground" } > {myValue !== "" ? myValue : "No file"} diff --git a/src/frontend/src/components/inputGlobalComponent/index.tsx b/src/frontend/src/components/inputGlobalComponent/index.tsx index 3e6b340cb..2ca1aed22 100644 --- a/src/frontend/src/components/inputGlobalComponent/index.tsx +++ b/src/frontend/src/components/inputGlobalComponent/index.tsx @@ -19,15 +19,15 @@ export default function InputGlobalComponent({ editNode = false, }: InputGlobalComponentType): JSX.Element { const globalVariablesEntries = useGlobalVariablesStore( - (state) => state.globalVariablesEntries + (state) => state.globalVariablesEntries, ); const getVariableId = useGlobalVariablesStore((state) => state.getVariableId); const unavaliableFields = useGlobalVariablesStore( - (state) => state.unavaliableFields + (state) => state.unavaliableFields, ); const removeGlobalVariable = useGlobalVariablesStore( - (state) => state.removeGlobalVariable + (state) => state.removeGlobalVariable, ); const setErrorData = useAlertStore((state) => state.setErrorData); @@ -38,7 +38,7 @@ export default function InputGlobalComponent({ data.node?.template[name].load_from_db ) { setTimeout(() => { - onChange(""); + onChange("", true); setDb(false); }, 100); } @@ -129,7 +129,7 @@ export default function InputGlobalComponent({
diff --git a/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx b/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx index dbcb1e3dc..c87c97741 100644 --- a/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx @@ -1,5 +1,5 @@ import { cloneDeep } from "lodash"; -import React, { ReactNode, useEffect, useRef, useState } from "react"; +import { ReactNode, useEffect, useRef, useState } from "react"; import { Handle, Position, useUpdateNodeInternals } from "reactflow"; import CodeAreaComponent from "../../../../components/codeAreaComponent"; import DictComponent from "../../../../components/dictComponent"; @@ -18,20 +18,15 @@ import ToggleShadComponent from "../../../../components/toggleShadComponent"; import { Button } from "../../../../components/ui/button"; import { RefreshButton } from "../../../../components/ui/refreshButton"; import { - INPUT_HANDLER_HOVER, LANGFLOW_SUPPORTED_TYPES, - OUTPUT_HANDLER_HOVER, TOOLTIP_EMPTY, } from "../../../../constants/constants"; +import { Case } from "../../../../shared/components/caseComponent"; import useAlertStore from "../../../../stores/alertStore"; import useFlowStore from "../../../../stores/flowStore"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; import { useTypesStore } from "../../../../stores/typesStore"; -import { - APIClassType, - ResponseErrorDetailAPI, - ResponseErrorTypeAPI, -} from "../../../../types/api"; +import { APIClassType } from "../../../../types/api"; import { ParameterComponentType } from "../../../../types/components"; import { debouncedHandleUpdateValues, @@ -44,12 +39,13 @@ import { isValidConnection, scapedJSONStringfy, } from "../../../../utils/reactflowUtils"; -import { - nodeColors, - nodeIconsLucide, - nodeNames, -} from "../../../../utils/styleUtils"; +import { nodeColors } from "../../../../utils/styleUtils"; import { classNames, groupByFamily } from "../../../../utils/utils"; +import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount"; +import useHandleOnNewValue from "../../../hooks/use-handle-new-value"; +import useHandleNodeClass from "../../../hooks/use-handle-node-class"; +import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-buttons"; +import TooltipRenderComponent from "../tooltipRenderComponent"; export default function ParameterComponent({ left, @@ -75,175 +71,69 @@ export default function ParameterComponent({ const nodes = useFlowStore((state) => state.nodes); const edges = useFlowStore((state) => state.edges); const setNode = useFlowStore((state) => state.setNode); - + const myData = useTypesStore((state) => state.data); + const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const [isLoading, setIsLoading] = useState(false); + const updateNodeInternals = useUpdateNodeInternals(); + const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); const flow = currentFlow?.data?.nodes ?? null; - const groupedEdge = useRef(null); - const setFilterEdge = useFlowStore((state) => state.setFilterEdge); + const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue( + data, + name, + takeSnapshot, + handleUpdateValues, + debouncedHandleUpdateValues, + setNode, + renderTooltips, + isLoading, + setIsLoading, + ); + + const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass( + data, + name, + takeSnapshot, + setNode, + updateNodeInternals, + renderTooltips, + ); + + const { handleRefreshButtonPress: handleRefreshButtonPressHook } = + useHandleRefreshButtonPress(setIsLoading, setNode, renderTooltips); + let disabled = edges.some( (edge) => edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id), ) ?? false; - const myData = useTypesStore((state) => state.data); - - const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); - const handleRefreshButtonPress = async (name, data) => { - setIsLoading(true); - try { - let newTemplate = await handleUpdateValues(name, data); - - if (newTemplate) { - setNode(data.id, (oldNode) => { - let newNode = cloneDeep(oldNode); - newNode.data = { - ...newNode.data, - }; - newNode.data.node.template = newTemplate; - return newNode; - }); - } - } catch (error) { - let responseError = error as ResponseErrorDetailAPI; - - setErrorData({ - title: "Error while updating the Component", - list: [responseError.response.data.detail ?? "Unknown error"], - }); - } - setIsLoading(false); - renderTooltips(); + handleRefreshButtonPressHook(name, data); }; - useEffect(() => { - async function fetchData() { - if ( - (data.node?.template[name]?.real_time_refresh || - data.node?.template[name]?.refresh_button) && - // options can be undefined but not an empty array - (data.node?.template[name]?.options?.length ?? 0) === 0 - ) { - setIsLoading(true); - try { - let newTemplate = await handleUpdateValues(name, data); - - if (newTemplate) { - setNode(data.id, (oldNode) => { - let newNode = cloneDeep(oldNode); - newNode.data = { - ...newNode.data, - }; - newNode.data.node.template = newTemplate; - return newNode; - }); - } - } catch (error) { - let responseError = error as ResponseErrorDetailAPI; - - setErrorData({ - title: "Error while updating the Component", - list: [responseError.response.data.detail ?? "Unknown error"], - }); - } - setIsLoading(false); - renderTooltips(); - } - } - fetchData(); - }, []); + useFetchDataOnMount( + data, + name, + handleUpdateValues, + setNode, + renderTooltips, + setIsLoading, + ); const handleOnNewValue = async ( newValue: string | string[] | boolean | Object[], skipSnapshot: boolean | undefined = false, ): Promise => { - const nodeTemplate = data.node!.template[name]; - const currentValue = nodeTemplate.value; - - if (currentValue !== newValue && !skipSnapshot) { - takeSnapshot(); - } - - const shouldUpdate = - data.node?.template[name].real_time_refresh && - !data.node?.template[name].refresh_button && - currentValue !== newValue; - - const typeToDebounce = nodeTemplate.type; - - nodeTemplate.value = newValue; - - let newTemplate; - if (shouldUpdate) { - setIsLoading(true); - try { - if (["int"].includes(typeToDebounce)) { - newTemplate = await handleUpdateValues(name, data); - } else { - newTemplate = await debouncedHandleUpdateValues(name, data); - } - } catch (error) { - let responseError = error as ResponseErrorTypeAPI; - setErrorData({ - title: "Error while updating the Component", - list: [responseError.response.data.detail.error ?? "Unknown error"], - }); - } - setIsLoading(false); - } - - setNode(data.id, (oldNode) => { - const newNode = cloneDeep(oldNode); - newNode.data = { - ...newNode.data, - }; - - if (data.node?.template[name].real_time_refresh && newTemplate) { - newNode.data.node.template = newTemplate; - } else { - newNode.data.node.template[name].value = newValue; - } - - return newNode; - }); - - renderTooltips(); + handleOnNewValueHook(newValue, skipSnapshot); }; - const updateNodeInternals = useUpdateNodeInternals(); - const handleNodeClass = (newNodeClass: APIClassType, code?: string): void => { - if (!data.node) return; - if (data.node!.template[name].value !== code) { - takeSnapshot(); - } - - setNode(data.id, (oldNode) => { - let newNode = cloneDeep(oldNode); - - newNode.data = { - ...newNode.data, - node: newNodeClass, - description: newNodeClass.description ?? data.node!.description, - display_name: newNodeClass.display_name ?? data.node!.display_name, - }; - - newNode.data.node.template[name].value = code; - - return newNode; - }); - - updateNodeInternals(data.id); - - renderTooltips(); + handleNodeClassHook(newNodeClass, code); }; - const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); - useEffect(() => { // @ts-ignore infoHtml.current = ( @@ -264,88 +154,7 @@ export default function ParameterComponent({ if (groupedObj && groupedObj.length > 0) { //@ts-ignore refHtml.current = groupedObj.map((item, index) => { - const Icon: any = - nodeIconsLucide[item.family] ?? nodeIconsLucide["unknown"]; - - return ( -
- {index === 0 && ( - {left ? INPUT_HANDLER_HOVER : OUTPUT_HANDLER_HOVER} - )} - 0 ? "mt-2 flex items-center" : "mt-3 flex items-center", - )} - > -
- -
- - {nodeNames[item.family] ?? "Other"}{" "} - {item?.display_name && item?.display_name?.length > 0 ? ( - - {" "} - {item.display_name === "" ? "" : " - "} - {item.display_name.split(", ").length > 2 - ? item.display_name.split(", ").map((el, index) => ( - - - {index === - item.display_name.split(", ").length - 1 - ? el - : (el += `, `)} - - - )) - : item.display_name} - - ) : ( - - {" "} - {item.type === "" ? "" : " - "} - {item.type.split(", ").length > 2 - ? item.type.split(", ").map((el, index) => ( - - - {index === item.type.split(", ").length - 1 - ? el - : (el += `, `)} - - - )) - : item.type} - - )} - -
-
- ); + return ; }); } else { //@ts-ignore @@ -354,6 +163,7 @@ export default function ParameterComponent({ ); } } + // If optionalHandle is an empty list, then it is not an optional handle if (optionalHandle && optionalHandle.length === 0) { optionalHandle = null; @@ -362,6 +172,9 @@ export default function ParameterComponent({ useEffect(() => { renderTooltips(); }, [tooltipTitle, flow]); + + console.log(left === true && type === "dict"); + return !showNode ? ( left && LANGFLOW_SUPPORTED_TYPES.has(type ?? "") && !optionalHandle ? ( <> @@ -427,11 +240,12 @@ export default function ParameterComponent({ (left ? "" : " justify-end") } > - {!left && data.node?.frozen && ( +
- )} +
+ {proxy ? ( {proxy.id}}> @@ -477,45 +291,37 @@ export default function ParameterComponent({ }`} type={left ? "target" : "source"} position={left ? Position.Left : Position.Right} - key={ - proxy - ? scapedJSONStringfy({ ...id, proxy }) - : scapedJSONStringfy(id) - } - id={ - proxy - ? scapedJSONStringfy({ ...id, proxy }) - : scapedJSONStringfy(id) - } + key={scapedJSONStringfy(proxy ? { ...id, proxy } : id)} + id={scapedJSONStringfy(proxy ? { ...id, proxy } : id)} isValidConnection={(connection) => isValidConnection(connection, nodes, edges) } className={classNames( - left ? "-ml-0.5 " : "-mr-0.5 ", + left ? "-ml-0.5" : "-mr-0.5", "h-3 w-3 rounded-full border-2 bg-background", )} - style={{ - borderColor: color ?? nodeColors.unknown, - }} - onClick={() => { - setFilterEdge(groupedEdge.current); - }} - > + style={{ borderColor: color ?? nodeColors.unknown }} + onClick={() => setFilterEdge(groupedEdge.current)} + />
)} - {left === true && - type === "str" && - !data.node?.template[name].options ? ( +
- {data.node?.template[name].list ? ( +
@@ -523,39 +329,27 @@ export default function ParameterComponent({ componentName={name} disabled={disabled} value={ - !data.node.template[name].value || - data.node.template[name].value === "" + !data.node!.template[name]?.value || + data.node!.template[name]?.value === "" ? [""] - : data.node.template[name].value + : data.node!.template[name]?.value } onChange={handleOnNewValue} /> - {/* {data.node?.template[name].refresh_button && ( -
- -
- )} */}
- ) : data.node?.template[name].multiline ? ( +
+
- {data.node?.template[name].refresh_button && ( + {data.node?.template[name]?.refresh_button && (
)}
- ) : ( + +
- {data.node?.template[name].refresh_button && ( + {data.node?.template[name]?.refresh_button && (
)}
- )} +
- ) : left === true && type === "bool" ? ( +
+ +
- ) : left === true && type === "float" ? ( +
+ +
- ) : left === true && - type === "str" && - (data.node?.template[name].options || - data.node?.template[name]?.real_time_refresh) ? ( - // TODO: Improve CSS +
+ +
- {data.node?.template[name].refresh_button && ( + {data.node?.template[name]?.refresh_button && (
)}
- ) : left === true && type === "code" ? ( + + +
- ) : left === true && type === "file" ? ( +
+ +
{ data.node!.template[name].file_path = filePath; }} >
- ) : left === true && type === "int" ? ( +
+ +
- ) : left === true && type === "prompt" ? ( +
+ +
- ) : left === true && type === "NestedDict" ? ( +
+ +
- ) : left === true && type === "dict" ? ( +
+ +
{ const valueToNumbers = convertValuesToNumbers(newValue); setErrorDuplicateKey(hasDuplicateKeys(valueToNumbers)); - // if data.node?.template[name].list is true, then the value is an array of objects + // if data.node?.template[name]?.list is true, then the value is an array of objects // else we need to get the first object of the array - if (data.node?.template[name].list) { + if (data.node?.template[name]?.list) { handleOnNewValue(valueToNumbers); } else handleOnNewValue(valueToNumbers[0]); }} - isList={data.node?.template[name].list ?? false} + isList={data.node?.template[name]?.list ?? false} />
- ) : ( - <> - )} +
); diff --git a/src/frontend/src/customNodes/genericNode/components/tooltipRenderComponent/index.tsx b/src/frontend/src/customNodes/genericNode/components/tooltipRenderComponent/index.tsx new file mode 100644 index 000000000..ed2760161 --- /dev/null +++ b/src/frontend/src/customNodes/genericNode/components/tooltipRenderComponent/index.tsx @@ -0,0 +1,91 @@ +import React from "react"; +import { + INPUT_HANDLER_HOVER, + OUTPUT_HANDLER_HOVER, +} from "../../../../constants/constants"; +import { + nodeColors, + nodeIconsLucide, + nodeNames, +} from "../../../../utils/styleUtils"; +import { classNames } from "../../../../utils/utils"; + +const TooltipRenderComponent = ({ item, index, left }) => { + const Icon = nodeIconsLucide[item.family] ?? nodeIconsLucide["unknown"]; + + return ( +
+ {index === 0 && ( + {left ? INPUT_HANDLER_HOVER : OUTPUT_HANDLER_HOVER} + )} + 0 ? "mt-2 flex items-center" : "mt-3 flex items-center", + )} + > +
+ +
+ + {nodeNames[item.family] ?? "Other"}{" "} + {item?.display_name && item?.display_name?.length > 0 ? ( + + {" "} + {item.display_name === "" ? "" : " - "} + {item.display_name.split(", ").length > 2 + ? item.display_name.split(", ").map((el, index) => ( + + + {index === item.display_name.split(", ").length - 1 + ? el + : (el += `, `)} + + + )) + : item.display_name} + + ) : ( + + {" "} + {item.type === "" ? "" : " - "} + {item.type.split(", ").length > 2 + ? item.type.split(", ").map((el, index) => ( + + + {index === item.type.split(", ").length - 1 + ? el + : (el += `, `)} + + + )) + : item.type} + + )} + +
+
+ ); +}; + +export default TooltipRenderComponent; diff --git a/src/frontend/src/customNodes/hooks/use-fetch-data-on-mount.tsx b/src/frontend/src/customNodes/hooks/use-fetch-data-on-mount.tsx new file mode 100644 index 000000000..3fc3fbe72 --- /dev/null +++ b/src/frontend/src/customNodes/hooks/use-fetch-data-on-mount.tsx @@ -0,0 +1,54 @@ +import { cloneDeep } from "lodash"; +import { useEffect } from "react"; +import useAlertStore from "../../stores/alertStore"; +import { ResponseErrorDetailAPI } from "../../types/api"; + +const useFetchDataOnMount = ( + data, + name, + handleUpdateValues, + setNode, + renderTooltips, + setIsLoading, +) => { + const setErrorData = useAlertStore((state) => state.setErrorData); + + useEffect(() => { + async function fetchData() { + if ( + (data.node?.template[name]?.real_time_refresh || + data.node?.template[name]?.refresh_button) && + // options can be undefined but not an empty array + (data.node?.template[name]?.options?.length ?? 0) === 0 + ) { + setIsLoading(true); + try { + let newTemplate = await handleUpdateValues(name, data); + + if (newTemplate) { + setNode(data.id, (oldNode) => { + let newNode = cloneDeep(oldNode); + newNode.data = { + ...newNode.data, + }; + newNode.data.node.template = newTemplate; + return newNode; + }); + } + } catch (error) { + let responseError = error as ResponseErrorDetailAPI; + + setErrorData({ + title: "Error while updating the Component", + list: [responseError.response.data.detail ?? "Unknown error"], + }); + } + setIsLoading(false); + renderTooltips(); + } + } + fetchData(); + }, []); // Empty dependency array ensures that this effect runs only once, on mount +}; + +export default useFetchDataOnMount; diff --git a/src/frontend/src/customNodes/hooks/use-handle-new-value.tsx b/src/frontend/src/customNodes/hooks/use-handle-new-value.tsx new file mode 100644 index 000000000..7de830eda --- /dev/null +++ b/src/frontend/src/customNodes/hooks/use-handle-new-value.tsx @@ -0,0 +1,75 @@ +import { cloneDeep } from "lodash"; +import useAlertStore from "../../stores/alertStore"; +import { ResponseErrorTypeAPI } from "../../types/api"; + +const useHandleOnNewValue = ( + data, + name, + takeSnapshot, + handleUpdateValues, + debouncedHandleUpdateValues, + setNode, + renderTooltips, + isLoading, + setIsLoading, +) => { + const setErrorData = useAlertStore((state) => state.setErrorData); + + const handleOnNewValue = async (newValue, skipSnapshot = false) => { + const nodeTemplate = data.node!.template[name]; + const currentValue = nodeTemplate.value; + + if (currentValue !== newValue && !skipSnapshot) { + takeSnapshot(); + } + + const shouldUpdate = + data.node?.template[name].real_time_refresh && + !data.node?.template[name].refresh_button && + currentValue !== newValue; + + const typeToDebounce = nodeTemplate.type; + + nodeTemplate.value = newValue; + + let newTemplate; + if (shouldUpdate) { + setIsLoading(true); + try { + if (["int"].includes(typeToDebounce)) { + newTemplate = await handleUpdateValues(name, data); + } else { + newTemplate = await debouncedHandleUpdateValues(name, data); + } + } catch (error) { + let responseError = error as ResponseErrorTypeAPI; + setErrorData({ + title: "Error while updating the Component", + list: [responseError.response.data.detail.error ?? "Unknown error"], + }); + } + setIsLoading(false); + } + + setNode(data.id, (oldNode) => { + const newNode = cloneDeep(oldNode); + newNode.data = { + ...newNode.data, + }; + + if (data.node?.template[name].real_time_refresh && newTemplate) { + newNode.data.node.template = newTemplate; + } else { + newNode.data.node.template[name].value = newValue; + } + + return newNode; + }); + + renderTooltips(); + }; + + return { handleOnNewValue }; +}; + +export default useHandleOnNewValue; diff --git a/src/frontend/src/customNodes/hooks/use-handle-node-class.tsx b/src/frontend/src/customNodes/hooks/use-handle-node-class.tsx new file mode 100644 index 000000000..412658d77 --- /dev/null +++ b/src/frontend/src/customNodes/hooks/use-handle-node-class.tsx @@ -0,0 +1,40 @@ +import { cloneDeep } from "lodash"; + +const useHandleNodeClass = ( + data, + name, + takeSnapshot, + setNode, + updateNodeInternals, + renderTooltips, +) => { + const handleNodeClass = (newNodeClass, code) => { + if (!data.node) return; + if (data.node!.template[name].value !== code) { + takeSnapshot(); + } + + setNode(data.id, (oldNode) => { + let newNode = cloneDeep(oldNode); + + newNode.data = { + ...newNode.data, + node: newNodeClass, + description: newNodeClass.description ?? data.node!.description, + display_name: newNodeClass.display_name ?? data.node!.display_name, + }; + + newNode.data.node.template[name].value = code; + + return newNode; + }); + + updateNodeInternals(data.id); + + renderTooltips(); + }; + + return { handleNodeClass }; +}; + +export default useHandleNodeClass; diff --git a/src/frontend/src/customNodes/hooks/use-handle-refresh-buttons.tsx b/src/frontend/src/customNodes/hooks/use-handle-refresh-buttons.tsx new file mode 100644 index 000000000..19f2a3c29 --- /dev/null +++ b/src/frontend/src/customNodes/hooks/use-handle-refresh-buttons.tsx @@ -0,0 +1,39 @@ +import { cloneDeep } from "lodash"; +import useAlertStore from "../../stores/alertStore"; +import { ResponseErrorDetailAPI } from "../../types/api"; +import { handleUpdateValues } from "../../utils/parameterUtils"; + +const useHandleRefreshButtonPress = (setIsLoading, setNode, renderTooltips) => { + const setErrorData = useAlertStore((state) => state.setErrorData); + + const handleRefreshButtonPress = async (name, data) => { + setIsLoading(true); + try { + let newTemplate = await handleUpdateValues(name, data); + + if (newTemplate) { + setNode(data.id, (oldNode) => { + let newNode = cloneDeep(oldNode); + newNode.data = { + ...newNode.data, + }; + newNode.data.node.template = newTemplate; + return newNode; + }); + } + } catch (error) { + let responseError = error as ResponseErrorDetailAPI; + + setErrorData({ + title: "Error while updating the Component", + list: [responseError.response.data.detail ?? "Unknown error"], + }); + } + setIsLoading(false); + renderTooltips(); + }; + + return { handleRefreshButtonPress }; +}; + +export default useHandleRefreshButtonPress; diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index b853ecfab..0db4bdcf5 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -28,6 +28,7 @@ import { LANGFLOW_SUPPORTED_TYPES, limitScrollFieldsModal, } from "../../constants/constants"; +import { Case } from "../../shared/components/caseComponent"; import useFlowStore from "../../stores/flowStore"; import { NodeDataType } from "../../types/flow"; import { @@ -52,7 +53,7 @@ const EditNodeModal = forwardRef( open: boolean; setOpen: (open: boolean) => void; }, - ref + ref, ) => { const [myData, setMyData] = useState(data); @@ -84,6 +85,10 @@ const EditNodeModal = forwardRef( const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); + const type = (templateParam) => { + return myData.node?.template[templateParam].type; + }; + return ( limitScrollFieldsModal ? "overflow-scroll overflow-x-hidden custom-scroll" - : "" + : "", )} > {nodeLength > 0 && ( @@ -138,8 +143,8 @@ const EditNodeModal = forwardRef( templateParam.charAt(0) !== "_" && myData.node?.template[templateParam].show && LANGFLOW_SUPPORTED_TYPES.has( - myData.node.template[templateParam].type - ) + myData.node!.template[templateParam].type, + ), ) .map((templateParam, index) => { let id = { @@ -161,8 +166,8 @@ const EditNodeModal = forwardRef( myData.node?.template[templateParam] .proxy, } - : id - ) + : id, + ), ) ?? false; return (