From c0624c4ad3e47b409e7b880a40541fa7de713500 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 24 Jun 2024 10:51:43 -0300 Subject: [PATCH 01/22] chore: update linting workflows to include dev branch in merge_group --- .github/workflows/lint-js.yml | 2 ++ .github/workflows/lint-py.yml | 2 ++ .github/workflows/python_test.yml | 20 +++++++++++++++++++- .github/workflows/style-check-py.yml | 2 ++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index d381a467fa0..11156c8b87b 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -4,6 +4,8 @@ on: pull_request: paths: - "src/frontend/**" + merge_group: + branches: [dev] env: NODE_VERSION: "21" diff --git a/.github/workflows/lint-py.yml b/.github/workflows/lint-py.yml index 95fbb15e6e5..9dab54eb8f0 100644 --- a/.github/workflows/lint-py.yml +++ b/.github/workflows/lint-py.yml @@ -7,6 +7,8 @@ on: - "pyproject.toml" - "src/backend/**" - "tests/**" + merge_group: + branches: [dev] env: POETRY_VERSION: "1.8.2" diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml index 9a8ef15c82d..c3c320aadf7 100644 --- a/.github/workflows/python_test.yml +++ b/.github/workflows/python_test.yml @@ -1,4 +1,4 @@ -name: test +name: Python tests on: push: @@ -13,6 +13,8 @@ on: - "poetry.lock" - "pyproject.toml" - "src/backend/**" + merge_group: + branches: [dev] env: POETRY_VERSION: "1.8.2" @@ -43,3 +45,19 @@ jobs: - name: Run unit tests run: | make unit_tests args="-n auto" + - name: Test CLI + run: | + poetry run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only & + SERVER_PID=$! + # Wait for the server to start + timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) + # Terminate the server + kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) + sleep 10 # give the server some time to terminate + # Check if the server is still running + if kill -0 $SERVER_PID 2>/dev/null; then + echo "Failed to terminate the server" + exit 1 + else + echo "Server terminated successfully" + fi diff --git a/.github/workflows/style-check-py.yml b/.github/workflows/style-check-py.yml index 3255aa31d0d..bd7b9dc0e3b 100644 --- a/.github/workflows/style-check-py.yml +++ b/.github/workflows/style-check-py.yml @@ -7,6 +7,8 @@ on: - "pyproject.toml" - "src/backend/**" - "tests/**" + merge_group: + branches: [dev] env: POETRY_VERSION: "1.8.2" From 71a9ee549b26e1c533df4e4a34cf36c6e18348c0 Mon Sep 17 00:00:00 2001 From: Rodrigo Nader Date: Mon, 24 Jun 2024 11:16:32 -0300 Subject: [PATCH 02/22] Update README.md Add 1.0 banner --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 765835b2504..a427e974e7a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +
+

Langflow 1.0 is OUT! 🎉

+

Read all about it here!

+
+ + +https://astra.datastax.com/signup?type=langflow # [![Langflow](./docs/static/img/hero.png)](https://www.langflow.org) From 73373016d908b07a2b13c71ccdfd1c962a7d8846 Mon Sep 17 00:00:00 2001 From: Rodrigo Nader Date: Mon, 24 Jun 2024 11:16:46 -0300 Subject: [PATCH 03/22] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index a427e974e7a..9ba12ae7b5e 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@

Read all about it here!

- -https://astra.datastax.com/signup?type=langflow # [![Langflow](./docs/static/img/hero.png)](https://www.langflow.org) From 546f856708f128a8e20b6994af014e18b9ae62d0 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 24 Jun 2024 11:39:17 -0300 Subject: [PATCH 04/22] chore: update package versions in pyproject.toml files --- pyproject.toml | 2 +- src/backend/base/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d42e6bb9ab9..9fd1d3e04e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0" +version = "1.0.1" 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 66d4cadccba..232bdd0aa76 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.76" +version = "0.0.77" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From 59cadd6ba383bd71b744ddb707ccd13f4e2092d0 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 24 Jun 2024 19:56:25 -0300 Subject: [PATCH 05/22] Added db value to every onChange on parameters --- .../components/parameterComponent/index.tsx | 13 ++----------- .../CustomNodes/hooks/use-handle-new-value.tsx | 6 +++++- .../src/components/codeAreaComponent/index.tsx | 2 +- .../src/components/floatComponent/index.tsx | 2 +- .../src/components/inputFileComponent/index.tsx | 2 +- .../src/components/intComponent/index.tsx | 2 +- .../src/components/promptComponent/index.tsx | 2 +- .../src/components/textAreaComponent/index.tsx | 2 +- .../editNodeModal/hooks/use-column-defs.tsx | 4 +--- src/frontend/src/modals/editNodeModal/index.tsx | 10 ++++------ src/frontend/src/types/components/index.ts | 15 +++++++-------- 11 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index afb15b8ebc9..f71613a6bd6 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -174,9 +174,10 @@ export default function ParameterComponent({ const handleOnNewValue = async ( newValue: string | string[] | boolean | Object[], + dbValue?: boolean, skipSnapshot: boolean | undefined = false, ): Promise => { - handleOnNewValueHook(newValue, skipSnapshot); + handleOnNewValueHook(newValue, dbValue, skipSnapshot); }; const handleNodeClass = (newNodeClass: APIClassType, code?: string): void => { @@ -468,16 +469,6 @@ export default function ParameterComponent({ { - setNode(data.id, (oldNode) => { - let newNode = cloneDeep(oldNode); - newNode.data = { - ...newNode.data, - }; - newNode.data.node.template[name].load_from_db = value; - return newNode; - }); - }} name={name} data={data.node?.template[name]!} /> diff --git a/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx b/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx index b9690e27001..b1cb5d0b7af 100644 --- a/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx @@ -17,7 +17,7 @@ const useHandleOnNewValue = ( ) => { const setErrorData = useAlertStore((state) => state.setErrorData); - const handleOnNewValue = async (newValue, skipSnapshot = false) => { + const handleOnNewValue = async (newValue, dbValue, skipSnapshot = false) => { const nodeTemplate = data.node!.template[name]; const currentValue = nodeTemplate.value; @@ -62,6 +62,10 @@ const useHandleOnNewValue = ( ...newNode.data, }; + if (dbValue) { + newNode.data.node.template[name].load_from_db = dbValue; + } + if (data.node?.template[name].real_time_refresh && newTemplate) { newNode.data.node.template = newTemplate; } else { diff --git a/src/frontend/src/components/codeAreaComponent/index.tsx b/src/frontend/src/components/codeAreaComponent/index.tsx index 00721137fa3..ad8cfaf6f4a 100644 --- a/src/frontend/src/components/codeAreaComponent/index.tsx +++ b/src/frontend/src/components/codeAreaComponent/index.tsx @@ -23,7 +23,7 @@ export default function CodeAreaComponent({ useEffect(() => { if (disabled && myValue !== "") { setMyValue(""); - onChange("", true); + onChange("", undefined, true); } }, [disabled]); diff --git a/src/frontend/src/components/floatComponent/index.tsx b/src/frontend/src/components/floatComponent/index.tsx index 8db5b823a58..07de1fbb253 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("", true); + onChange("", undefined, true); } }, [disabled]); diff --git a/src/frontend/src/components/inputFileComponent/index.tsx b/src/frontend/src/components/inputFileComponent/index.tsx index 9710f7f6131..f8dd9725f2b 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("", true); + onChange("", undefined, true); onFileChange(""); } }, [disabled, onChange]); diff --git a/src/frontend/src/components/intComponent/index.tsx b/src/frontend/src/components/intComponent/index.tsx index f0d67a4021a..7621d67322c 100644 --- a/src/frontend/src/components/intComponent/index.tsx +++ b/src/frontend/src/components/intComponent/index.tsx @@ -19,7 +19,7 @@ export default function IntComponent({ // Clear component state useEffect(() => { if (disabled && value !== "") { - onChange("", true); + onChange("", undefined, true); } }, [disabled, onChange]); diff --git a/src/frontend/src/components/promptComponent/index.tsx b/src/frontend/src/components/promptComponent/index.tsx index 0dcec3dbf7f..c2e721baf14 100644 --- a/src/frontend/src/components/promptComponent/index.tsx +++ b/src/frontend/src/components/promptComponent/index.tsx @@ -19,7 +19,7 @@ export default function PromptAreaComponent({ }: PromptAreaComponentType): JSX.Element { useEffect(() => { if (disabled && value !== "") { - onChange("", true); + onChange("", undefined, true); } }, [disabled]); diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx index ce42437d7c0..2f9302a715c 100644 --- a/src/frontend/src/components/textAreaComponent/index.tsx +++ b/src/frontend/src/components/textAreaComponent/index.tsx @@ -17,7 +17,7 @@ export default function TextAreaComponent({ // Clear text area useEffect(() => { if (disabled && value !== "") { - onChange("", true); + onChange("", undefined, true); } }, [disabled]); diff --git a/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx b/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx index 14263a9c60d..9ffbdbe251e 100644 --- a/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx +++ b/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx @@ -5,8 +5,7 @@ import TableToggleCellRender from "../../../components/tableComponent/components const useColumnDefs = ( myData: any, - handleOnNewValue: (newValue: any, name: string) => void, - handleOnChangeDb: (value: boolean, key: string) => void, + handleOnNewValue: (newValue: any, name: string, setDb?: boolean) => void, changeAdvanced: (n: string) => void, open: boolean, ) => { @@ -48,7 +47,6 @@ const useColumnDefs = ( value: params.data.value, nodeClass: myData.node, handleOnNewValue: handleOnNewValue, - handleOnChangeDb: handleOnChangeDb, }; }, minWidth: 340, diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index cb6f82f5960..f7f4b615fd1 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -38,12 +38,11 @@ const EditNodeModal = forwardRef( !myData.current.node!.template[n]?.advanced; } - const handleOnNewValue = (newValue: any, key: string) => { + const handleOnNewValue = (newValue: any, key: string, setDb?: boolean) => { myData.current.node!.template[key].value = newValue; - }; - - const handleOnChangeDb = (newValue: boolean, key: string) => { - myData.current.node!.template[key].load_from_db = newValue; + if(setDb){ + myData.current.node!.template[key].load_from_db = newValue; + } }; const rowData = useRowData(data, open); @@ -51,7 +50,6 @@ const EditNodeModal = forwardRef( const columnDefs: ColDef[] = useColumnDefs( data, handleOnNewValue, - handleOnChangeDb, changeAdvanced, open, ); diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 992c012bd16..c418e87cf0a 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -91,8 +91,7 @@ export type InputListComponentType = { export type InputGlobalComponentType = { disabled: boolean; - onChange: (value: string, snapshot?: boolean) => void; - setDb: (value: boolean) => void; + onChange: (value: string, dbValue: boolean, snapshot?: boolean) => void; name: string; data: InputFieldType; editNode?: boolean; @@ -124,7 +123,7 @@ export type TextAreaComponentType = { nodeClass?: APIClassType; setNodeClass?: (value: APIClassType) => void; disabled: boolean; - onChange: (value: string[] | string, skipSnapshot?: boolean) => void; + onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; value: string; editNode?: boolean; id?: string; @@ -146,7 +145,7 @@ export type PromptAreaComponentType = { nodeClass?: APIClassType; setNodeClass?: (value: APIClassType, code?: string) => void; disabled: boolean; - onChange: (value: string[] | string, skipSnapshot?: boolean) => void; + onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; value: string; readonly?: boolean; editNode?: boolean; @@ -156,7 +155,7 @@ export type PromptAreaComponentType = { export type CodeAreaComponentType = { setOpenModal?: (bool: boolean) => void; disabled: boolean; - onChange: (value: string[] | string, skipSnapshot?: boolean) => void; + onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; value: string; editNode?: boolean; nodeClass?: APIClassType; @@ -171,7 +170,7 @@ export type CodeAreaComponentType = { export type FileComponentType = { IOInputProps?; disabled: boolean; - onChange: (value: string[] | string, skipSnapshot?: boolean) => void; + onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; value: string; fileTypes: Array; onFileChange: (value: string) => void; @@ -204,7 +203,7 @@ export type IntComponentType = { value: string; disabled?: boolean; rangeSpec: RangeSpecType; - onChange: (value: string, skipSnapshot?: boolean) => void; + onChange: (value: string, dbValue?: boolean, skipSnapshot?: boolean) => void; editNode?: boolean; id?: string; }; @@ -212,7 +211,7 @@ export type IntComponentType = { export type FloatComponentType = { value: string; disabled?: boolean; - onChange: (value: string, skipSnapshot?: boolean) => void; + onChange: (value: string, dbValue?: boolean, skipSnapshot?: boolean) => void; rangeSpec: RangeSpecType; editNode?: boolean; id?: string; From 44c34b9c6eb701a25b16f6626ecfd11b07f4cf09 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 24 Jun 2024 19:57:18 -0300 Subject: [PATCH 06/22] Refactored global variables to find variables on the first render, and to execute just one onChange to update both values and db --- .../components/inputGlobalComponent/index.tsx | 44 +++++++------------ .../components/tableNodeCellRender/index.tsx | 30 ++++--------- .../globalVariablesStore/globalVariables.ts | 10 ++--- .../types/zustand/globalVariables/index.ts | 2 +- 4 files changed, 30 insertions(+), 56 deletions(-) diff --git a/src/frontend/src/components/inputGlobalComponent/index.tsx b/src/frontend/src/components/inputGlobalComponent/index.tsx index 4d20e813238..43924fffbb5 100644 --- a/src/frontend/src/components/inputGlobalComponent/index.tsx +++ b/src/frontend/src/components/inputGlobalComponent/index.tsx @@ -1,4 +1,5 @@ import { useEffect } from "react"; +import { Controller } from "react-hook-form"; import { deleteGlobalVariable } from "../../controllers/API"; import DeleteConfirmationModal from "../../modals/deleteConfirmationModal"; import useAlertStore from "../../stores/alertStore"; @@ -13,7 +14,6 @@ import { CommandItem } from "../ui/command"; export default function InputGlobalComponent({ disabled, onChange, - setDb, name, data, editNode = false, @@ -32,30 +32,19 @@ export default function InputGlobalComponent({ const setErrorData = useAlertStore((state) => state.setErrorData); useEffect(() => { - if (data) - if ( - ((globalVariablesEntries && - !globalVariablesEntries.includes(data.value)) || - !globalVariablesEntries) && - data.load_from_db + if (data && globalVariablesEntries && unavaliableFields) + if (data.load_from_db && !globalVariablesEntries.includes(data.value)) { + onChange("", false, true); + } else if ( + !data.load_from_db && + (!data.value || data.value === "") && + unavaliableFields[data.display_name!] && + !disabled && + data.display_name ) { - setTimeout(() => { - onChange("", true); - setDb(false); - }, 100); + onChange(unavaliableFields[data.display_name!], true, true); } - }, [globalVariablesEntries, data]); - - useEffect(() => { - if (!data.value && data.display_name) { - if (unavaliableFields[data.display_name!] && !disabled) { - setTimeout(() => { - setDb(true); - onChange(unavaliableFields[data.display_name!]); - }, 100); - } - } - }, [unavaliableFields]); + }, [globalVariablesEntries, unavaliableFields, data, disabled]); async function handleDelete(key: string) { const id = getVariableId(key); @@ -64,8 +53,7 @@ export default function InputGlobalComponent({ .then(() => { removeGlobalVariable(key); if (data?.value === key && data?.load_from_db) { - onChange(""); - setDb(false); + onChange("", false); } }) .catch(() => { @@ -137,12 +125,10 @@ export default function InputGlobalComponent({ : "" } setSelectedOption={(value) => { - onChange(value); - setDb(value !== "" ? true : false); + onChange(value, value !== "" ? true : false); }} onChange={(value, skipSnapshot) => { - onChange(value, skipSnapshot); - setDb(false); + onChange(value, false, skipSnapshot); }} /> ); diff --git a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx index b5578813476..980e2a106cc 100644 --- a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx +++ b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx @@ -24,32 +24,21 @@ import ToggleShadComponent from "../../../toggleShadComponent"; export default function TableNodeCellRender({ node: { data }, - value: { - value, - nodeClass, - handleOnNewValue: handleOnNewValueNode, - handleOnChangeDb: handleOnChangeDbNode, - }, + value: { value, nodeClass, handleOnNewValue: handleOnNewValueNode }, }: CustomCellRendererProps) { - const handleOnNewValue = (newValue: any, name: string) => { - handleOnNewValueNode(newValue, name); + const handleOnNewValue = (newValue: any, name: string, dbValue?: boolean) => { + handleOnNewValueNode(newValue, name, dbValue); setTemplateData((old) => { let newData = cloneDeep(old); newData.value = newValue; + if (dbValue) { + newData.load_from_db = newValue; + } return newData; }); setTemplateValue(newValue); }; - const handleOnChangeDb = (newValue: boolean, name: string) => { - handleOnChangeDbNode(newValue, name); - setTemplateData((old) => { - let newData = cloneDeep(old); - newData.load_from_db = newValue; - return newData; - }); - }; - const [templateValue, setTemplateValue] = useState(value); const [templateData, setTemplateData] = useState(data); @@ -106,10 +95,9 @@ export default function TableNodeCellRender({ handleOnNewValue(value, templateData.key)} - setDb={(value) => { - handleOnChangeDb(value, templateData.key); - }} + onChange={(value, dbValue, snapshot) => + handleOnNewValue(value, templateData.key, dbValue) + } name={templateData.key} data={templateData} /> diff --git a/src/frontend/src/stores/globalVariablesStore/globalVariables.ts b/src/frontend/src/stores/globalVariablesStore/globalVariables.ts index 708f7ec09fa..4f80559f5d2 100644 --- a/src/frontend/src/stores/globalVariablesStore/globalVariables.ts +++ b/src/frontend/src/stores/globalVariablesStore/globalVariables.ts @@ -4,12 +4,12 @@ import getUnavailableFields from "./utils/get-unavailable-fields"; export const useGlobalVariablesStore = create( (set, get) => ({ - unavaliableFields: {}, + unavaliableFields: undefined, setUnavaliableFields: (fields) => { set({ unavaliableFields: fields }); }, removeUnavaliableField: (field) => { - const newFields = get().unavaliableFields; + const newFields = get().unavaliableFields || {}; delete newFields[field]; set({ unavaliableFields: newFields }); }, @@ -18,7 +18,7 @@ export const useGlobalVariablesStore = create( setGlobalVariables: (variables) => { set({ globalVariables: variables, - globalVariablesEntries: Object.keys(variables), + globalVariablesEntries: Object.keys(variables) || [], unavaliableFields: getUnavailableFields(variables), }); }, @@ -27,7 +27,7 @@ export const useGlobalVariablesStore = create( const newVariables = { ...get().globalVariables, [name]: data }; set({ globalVariables: newVariables, - globalVariablesEntries: Object.keys(newVariables), + globalVariablesEntries: Object.keys(newVariables) || [], unavaliableFields: getUnavailableFields(newVariables), }); }, @@ -38,7 +38,7 @@ export const useGlobalVariablesStore = create( delete newVariables[name]; set({ globalVariables: newVariables, - globalVariablesEntries: Object.keys(newVariables), + globalVariablesEntries: Object.keys(newVariables) || [], unavaliableFields: getUnavailableFields(newVariables), }); }, diff --git a/src/frontend/src/types/zustand/globalVariables/index.ts b/src/frontend/src/types/zustand/globalVariables/index.ts index 4b178088c84..e4749ee8fb8 100644 --- a/src/frontend/src/types/zustand/globalVariables/index.ts +++ b/src/frontend/src/types/zustand/globalVariables/index.ts @@ -25,7 +25,7 @@ export type GlobalVariablesStore = { ) => void; removeGlobalVariable: (name: string) => Promise; getVariableId: (name: string) => string | undefined; - unavaliableFields: { [name: string]: string }; + unavaliableFields: { [name: string]: string } | undefined; setUnavaliableFields: (fields: { [name: string]: string }) => void; removeUnavaliableField: (field: string) => void; }; From ee4b25dbcd9cbf83709f8c993a8352a3f1904901 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:06:58 -0300 Subject: [PATCH 07/22] Changed group recursion function to include check for global variables already applied or outdated --- src/frontend/src/utils/reactflowUtils.ts | 58 +++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 9b62b2624f6..8e0f5186845 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -1475,11 +1475,30 @@ export function isOutputType(type: string): boolean { return OUTPUT_TYPES.has(type); } -export function updateGroupRecursion(groupNode: NodeType, edges: Edge[]) { +export function updateGroupRecursion( + groupNode: NodeType, + edges: Edge[], + unavailableFields: + | { + [name: string]: string; + } + | undefined, + globalVariablesEntries: string[] | undefined, +) { + updateGlobalVariables( + groupNode.data.node, + unavailableFields, + globalVariablesEntries, + ); if (groupNode.data.node?.flow) { groupNode.data.node.flow.data!.nodes.forEach((node) => { if (node.data.node?.flow) { - updateGroupRecursion(node, node.data.node.flow.data!.edges); + updateGroupRecursion( + node, + node.data.node.flow.data!.edges, + unavailableFields, + globalVariablesEntries, + ); } }); let newFlow = groupNode.data.node!.flow; @@ -1490,6 +1509,41 @@ export function updateGroupRecursion(groupNode: NodeType, edges: Edge[]) { } } +export function updateGlobalVariables( + node: APIClassType | undefined, + unavailableFields: + | { + [name: string]: string; + } + | undefined, + globalVariablesEntries: string[] | undefined, +) { + if (node && node.template) { + Object.keys(node.template).forEach((field) => { + if ( + globalVariablesEntries && + node!.template[field].load_from_db && + !globalVariablesEntries.includes(node!.template[field].value) + ) { + node!.template[field].value = ""; + node!.template[field].load_from_db = false; + } + if ( + !node!.template[field].load_from_db && + node!.template[field].value === "" && + unavailableFields && + Object.keys(unavailableFields).includes( + node!.template[field].display_name ?? "", + ) + ) { + node!.template[field].value = + unavailableFields[node!.template[field].display_name ?? ""]; + node!.template[field].load_from_db = true; + } + }); + } +} + export function getGroupOutputNodeId( flow: FlowType, p_name: string, From d939e4f2c7d1057d3922868e4ee14ae70f3d7968 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:07:56 -0300 Subject: [PATCH 08/22] Removed already inserted component check for default fields on global variables --- .../src/components/inputGlobalComponent/index.tsx | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/frontend/src/components/inputGlobalComponent/index.tsx b/src/frontend/src/components/inputGlobalComponent/index.tsx index 43924fffbb5..0c109030e33 100644 --- a/src/frontend/src/components/inputGlobalComponent/index.tsx +++ b/src/frontend/src/components/inputGlobalComponent/index.tsx @@ -23,28 +23,17 @@ export default function InputGlobalComponent({ ); const getVariableId = useGlobalVariablesStore((state) => state.getVariableId); - const unavaliableFields = useGlobalVariablesStore( - (state) => state.unavaliableFields, - ); const removeGlobalVariable = useGlobalVariablesStore( (state) => state.removeGlobalVariable, ); const setErrorData = useAlertStore((state) => state.setErrorData); useEffect(() => { - if (data && globalVariablesEntries && unavaliableFields) + if (data && globalVariablesEntries) if (data.load_from_db && !globalVariablesEntries.includes(data.value)) { onChange("", false, true); - } else if ( - !data.load_from_db && - (!data.value || data.value === "") && - unavaliableFields[data.display_name!] && - !disabled && - data.display_name - ) { - onChange(unavaliableFields[data.display_name!], true, true); } - }, [globalVariablesEntries, unavaliableFields, data, disabled]); + }, [globalVariablesEntries, data, disabled]); async function handleDelete(key: string) { const id = getVariableId(key); From 3471162ff8d2d4518f12424fa7374a8692d30648 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:08:05 -0300 Subject: [PATCH 09/22] Fixed import error --- src/frontend/src/stores/flowsManagerStore.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/stores/flowsManagerStore.ts b/src/frontend/src/stores/flowsManagerStore.ts index a804710ac00..7fad6e410bc 100644 --- a/src/frontend/src/stores/flowsManagerStore.ts +++ b/src/frontend/src/stores/flowsManagerStore.ts @@ -29,6 +29,7 @@ import { useDarkStore } from "./darkStore"; import useFlowStore from "./flowStore"; import { useFolderStore } from "./foldersStore"; import { useTypesStore } from "./typesStore"; +import { AxiosError } from "axios"; let saveTimeoutId: NodeJS.Timeout | null = null; From 7e0679596119cfb6f82adb173db63c0579cc49e5 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:08:31 -0300 Subject: [PATCH 10/22] Added required parameters to update node on drop --- src/frontend/src/stores/flowStore.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index df12c944c31..0b67dd88fc5 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -40,6 +40,7 @@ import { getInputsAndOutputs } from "../utils/storeUtils"; import useAlertStore from "./alertStore"; import { useDarkStore } from "./darkStore"; import useFlowsManagerStore from "./flowsManagerStore"; +import { useGlobalVariablesStore } from "./globalVariablesStore/globalVariables"; // 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) => ({ @@ -288,7 +289,12 @@ const useFlowStore = create((set, get) => ({ id: newId, }, }; - updateGroupRecursion(newNode, selection.edges); + updateGroupRecursion( + newNode, + selection.edges, + useGlobalVariablesStore.getState().unavaliableFields, + useGlobalVariablesStore.getState().globalVariablesEntries, + ); // Add the new node to the list of nodes in state newNodes = newNodes From 5780ba3d4cb2af8b13684bf1392830fc48194f78 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:15:42 -0300 Subject: [PATCH 11/22] Removed check for unused hardcoded name --- src/frontend/src/modals/newFlowModal/index.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/frontend/src/modals/newFlowModal/index.tsx b/src/frontend/src/modals/newFlowModal/index.tsx index 37a6afeeb91..295ecd3957d 100644 --- a/src/frontend/src/modals/newFlowModal/index.tsx +++ b/src/frontend/src/modals/newFlowModal/index.tsx @@ -10,12 +10,6 @@ export default function NewFlowModal({ }: newFlowModalPropsType): JSX.Element { const examples = useFlowsManagerStore((state) => state.examples); - examples?.forEach((example) => { - if (example.name === "Blog Writter") { - example.name = "Blog Writer"; - } - }); - return ( From 1e26cab3f2515c80609e89cfd9b3f48f47ac5f0a Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:34:20 -0300 Subject: [PATCH 12/22] Added global variables handling on nodes when adding a flow --- src/frontend/src/stores/flowsManagerStore.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/stores/flowsManagerStore.ts b/src/frontend/src/stores/flowsManagerStore.ts index 7fad6e410bc..a99916107a3 100644 --- a/src/frontend/src/stores/flowsManagerStore.ts +++ b/src/frontend/src/stores/flowsManagerStore.ts @@ -1,3 +1,4 @@ +import { AxiosError } from "axios"; import { cloneDeep } from "lodash"; import pDebounce from "p-debounce"; import { Edge, Node, Viewport, XYPosition } from "reactflow"; @@ -23,13 +24,14 @@ import { extractFieldsFromComponenents, processDataFromFlow, processFlows, + updateGroupRecursion, } from "../utils/reactflowUtils"; import useAlertStore from "./alertStore"; import { useDarkStore } from "./darkStore"; import useFlowStore from "./flowStore"; import { useFolderStore } from "./foldersStore"; +import { useGlobalVariablesStore } from "./globalVariablesStore/globalVariables"; import { useTypesStore } from "./typesStore"; -import { AxiosError } from "axios"; let saveTimeoutId: NodeJS.Timeout | null = null; @@ -203,6 +205,14 @@ const useFlowsManagerStore = create((set, get) => ({ let flowData = flow ? processDataFromFlow(flow) : { nodes: [], edges: [], viewport: { zoom: 1, x: 0, y: 0 } }; + flowData?.nodes.forEach((node) => { + updateGroupRecursion( + node, + flowData?.edges, + useGlobalVariablesStore.getState().unavaliableFields, + useGlobalVariablesStore.getState().globalVariablesEntries, + ); + }); if (newProject) { // Create a new flow with a default name if no flow is provided. const folder_id = useFolderStore.getState().folderUrl; From b792621daa25f3a1a7efc7f92be6a96e2621a40a Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:38:36 -0300 Subject: [PATCH 13/22] Fixed maximum update depth when deleting used global variable --- src/frontend/src/components/inputGlobalComponent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/inputGlobalComponent/index.tsx b/src/frontend/src/components/inputGlobalComponent/index.tsx index 0c109030e33..1d3cf4f6089 100644 --- a/src/frontend/src/components/inputGlobalComponent/index.tsx +++ b/src/frontend/src/components/inputGlobalComponent/index.tsx @@ -33,7 +33,7 @@ export default function InputGlobalComponent({ if (data.load_from_db && !globalVariablesEntries.includes(data.value)) { onChange("", false, true); } - }, [globalVariablesEntries, data, disabled]); + }, [globalVariablesEntries]); async function handleDelete(key: string) { const id = getVariableId(key); From 123b2bf97dceeb4233cf8acede3379eeae572904 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 01:41:37 -0300 Subject: [PATCH 14/22] Fixed type error on addNewVariableButton modal --- .../addNewVariableButtonComponent/addNewVariableButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx index 415cd92d78c..81ab1655636 100644 --- a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx +++ b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx @@ -29,7 +29,7 @@ export default function AddNewVariableButton({ const setErrorData = useAlertStore((state) => state.setErrorData); const componentFields = useTypesStore((state) => state.ComponentFields); const unavaliableFields = new Set( - Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields)), + Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields) ?? {}), ); const availableFields = () => { From 22eb3106c27e54a74980fbab6f4a72cd30526ad6 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 10:56:35 -0300 Subject: [PATCH 15/22] Fixed openai api key on starter flows --- .../Basic Prompting (Hello, World).json | 4 ++-- .../initial_setup/starter_projects/Blog Writer.json | 4 ++-- .../initial_setup/starter_projects/Document QA.json | 4 ++-- .../initial_setup/starter_projects/Memory Chatbot.json | 4 ++-- .../starter_projects/Vector Store RAG.json | 10 +++++----- 5 files changed, 13 insertions(+), 13 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 163384b2c2c..6e74f5c62f9 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 @@ -572,7 +572,7 @@ "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "openai_api_key", "password": true, "placeholder": "", @@ -580,7 +580,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "output_schema": { "advanced": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index ec4a19aac11..ac218236c14 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -773,7 +773,7 @@ "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "openai_api_key", "password": true, "placeholder": "", @@ -781,7 +781,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "output_schema": { "advanced": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json index d66c6b22bba..e5fd85db0d0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json @@ -906,7 +906,7 @@ "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "openai_api_key", "password": true, "placeholder": "", @@ -914,7 +914,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "output_schema": { "advanced": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index c3396f03e74..e56670301a4 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -827,7 +827,7 @@ "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "openai_api_key", "password": true, "placeholder": "", @@ -835,7 +835,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "output_schema": { "advanced": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index ae6115c674d..9118c915df1 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -1119,9 +1119,9 @@ "advanced": false, "display_name": "OpenAI API Key", "dynamic": false, - "info": "", + "info": "The OpenAI API Key to use for the OpenAI model.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "openai_api_key", "password": true, "placeholder": "", @@ -1129,7 +1129,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "openai_api_type": { "advanced": true, @@ -1758,7 +1758,7 @@ "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "openai_api_key", "password": true, "placeholder": "", @@ -1766,7 +1766,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "output_schema": { "advanced": true, From a6c87f6c6ee8dd294ed0e029dc7bf53d65c36709 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 11:12:45 -0300 Subject: [PATCH 16/22] Fixed values to get the .env values by default on the starter projects --- .../components/embeddings/OpenAIEmbeddings.py | 2 +- .../Basic Prompting (Hello, World).json | 869 +---- .../starter_projects/Blog Writer.json | 1070 +----- .../starter_projects/Document QA.json | 1203 +------ .../starter_projects/Memory Chatbot.json | 1124 +----- .../starter_projects/Vector Store RAG.json | 3176 +---------------- 6 files changed, 6 insertions(+), 7438 deletions(-) diff --git a/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py b/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py index 039caea245b..7f56874be21 100644 --- a/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py +++ b/src/backend/base/langflow/components/embeddings/OpenAIEmbeddings.py @@ -40,7 +40,7 @@ class OpenAIEmbeddingsComponent(LCEmbeddingsModel): ), DictInput(name="model_kwargs", display_name="Model Kwargs", advanced=True), SecretStrInput(name="openai_api_base", display_name="OpenAI API Base", advanced=True), - SecretStrInput(name="openai_api_key", display_name="OpenAI API Key"), + SecretStrInput(name="openai_api_key", display_name="OpenAI API Key", value="OPENAI_API_KEY"), SecretStrInput(name="openai_api_type", display_name="OpenAI API Type", advanced=True), MessageTextInput(name="openai_api_version", display_name="OpenAI API Version", advanced=True), MessageTextInput( 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 6e74f5c62f9..f965913a06f 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 @@ -1,868 +1 @@ -{ - "data": { - "edges": [ - { - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-pxptT", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "user_input", - "id": "Prompt-1S5SU", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-pxptT{œdataTypeœ:œChatInputœ,œidœ:œChatInput-pxptTœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-1S5SU{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-1S5SUœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ChatInput-pxptT", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-pxptTœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-1S5SU", - "targetHandle": "{œfieldNameœ: œuser_inputœ, œidœ: œPrompt-1S5SUœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-1S5SU", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-nJXWj", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-1S5SU{œdataTypeœ:œPromptœ,œidœ:œPrompt-1S5SUœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-nJXWj{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-nJXWjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-1S5SU", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-1S5SUœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-nJXWj", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-nJXWjœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-nJXWj", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-XP4bj", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-nJXWj{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-nJXWjœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-XP4bj{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-XP4bjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-nJXWj", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-nJXWjœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-XP4bj", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-XP4bjœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - } - ], - "nodes": [ - { - "data": { - "id": "ChatInput-pxptT", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Get chat inputs from the Playground.", - "display_name": "Chat Input", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "files" - ], - "frozen": false, - "icon": "ChatInput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "hidden": false, - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "files": { - "advanced": true, - "display_name": "Files", - "dynamic": false, - "fileTypes": [ - "txt", - "md", - "mdx", - "csv", - "json", - "yaml", - "yml", - "xml", - "html", - "htm", - "pdf", - "docx", - "py", - "sh", - "sql", - "js", - "ts", - "tsx", - "jpg", - "jpeg", - "png", - "bmp", - "image" - ], - "file_path": "", - "info": "Files to be sent with the message.", - "list": true, - "name": "files", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "file", - "value": "" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as input.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatInput" - }, - "dragging": false, - "height": 308, - "id": "ChatInput-pxptT", - "position": { - "x": -493.6459512396177, - "y": 1083.200545525551 - }, - "positionAbsolute": { - "x": -493.6459512396177, - "y": 1083.200545525551 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-1S5SU", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": { - "template": [ - "user_input" - ] - }, - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "documentation": "", - "edited": false, - "error": null, - "field_order": [ - "template" - ], - "frozen": false, - "full_path": null, - "icon": "prompts", - "is_composition": null, - "is_input": null, - "is_output": null, - "name": "", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Prompt Message", - "hidden": false, - "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "", - "list": false, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "prompt", - "value": "Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: " - }, - "user_input": { - "advanced": false, - "display_name": "user_input", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "user_input", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - } - } - }, - "type": "Prompt" - }, - "dragging": false, - "height": 422, - "id": "Prompt-1S5SU", - "position": { - "x": 56.354011530798516, - "y": 1157.2005405164796 - }, - "positionAbsolute": { - "x": 56.354011530798516, - "y": 1157.2005405164796 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-nJXWj", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "max_tokens", - "model_kwargs", - "output_schema", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "stream", - "system_message", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "text_response", - "name": "text_output", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Language Model", - "method": "build_model", - "name": "model_output", - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict)\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "name": "max_tokens", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "output_schema": { - "advanced": true, - "display_name": "Schema", - "dynamic": false, - "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", - "list": true, - "name": "output_schema", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "seed": { - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "name": "stream", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "list": false, - "load_from_db": false, - "name": "system_message", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "list": false, - "name": "temperature", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": 0.1 - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 621, - "id": "OpenAIModel-nJXWj", - "position": { - "x": 624.3539730827923, - "y": 1053.2005475562555 - }, - "positionAbsolute": { - "x": 624.3539730827923, - "y": 1053.2005475562555 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatOutput-XP4bj", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "data_template" - ], - "frozen": false, - "icon": "ChatOutput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "data_template": { - "advanced": true, - "display_name": "Data Template", - "dynamic": false, - "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "data_template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as output.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 308, - "id": "ChatOutput-XP4bj", - "position": { - "x": 1219.477374823274, - "y": 1200.950216973985 - }, - "positionAbsolute": { - "x": 1219.477374823274, - "y": 1200.950216973985 - }, - "selected": false, - "type": "genericNode", - "width": 384 - } - ], - "viewport": { - "x": 392.1085223509972, - "y": -327.49805229761307, - "zoom": 0.5000000676901589 - } - }, - "description": "This flow will get you experimenting with the basics of the UI, the Chat and the Prompt component. \n\nTry changing the Template in it to see how the model behaves. \nYou can change it to this and a Text Input into the `type_of_person` variable : \"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: \" ", - "endpoint_name": null, - "id": "f652abdc-7ef2-4e52-a00b-847b7aa32cee", - "is_component": false, - "last_tested_version": "1.0.0rc1", - "name": "Basic Prompting (Hello, World)" -} \ No newline at end of file +{"id":"e533253b-818b-4b5a-9793-55ab83fffb07","data":{"nodes":[{"data":{"id":"ChatInput-Y6mi1","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-Y6mi1","position":{"x":-493.6459512396177,"y":1083.200545525551},"positionAbsolute":{"x":-493.6459512396177,"y":1083.200545525551},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-Z4WYI","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["user_input"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: "},"user_input":{"advanced":false,"display_name":"user_input","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"user_input","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"Prompt"},"dragging":false,"height":422,"id":"Prompt-Z4WYI","position":{"x":56.354011530798516,"y":1157.2005405164796},"positionAbsolute":{"x":56.354011530798516,"y":1157.2005405164796},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-26Eve","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-26Eve","position":{"x":624.3539730827923,"y":1053.2005475562555},"positionAbsolute":{"x":624.3539730827923,"y":1053.2005475562555},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-cQnVI","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-cQnVI","position":{"x":1219.477374823274,"y":1200.950216973985},"positionAbsolute":{"x":1219.477374823274,"y":1200.950216973985},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-Y6mi1","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"user_input","id":"Prompt-Z4WYI","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-Y6mi1{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Y6mi1œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-Z4WYI{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-Z4WYIœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-Y6mi1","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Y6mi1œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-Z4WYI","targetHandle":"{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-Z4WYIœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-Z4WYI","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-26Eve","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-Z4WYI{œdataTypeœ:œPromptœ,œidœ:œPrompt-Z4WYIœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-26Eve{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-26Eveœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-Z4WYI","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-Z4WYIœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-26Eve","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-26Eveœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-26Eve","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-26Eveœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-cQnVI","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cQnVIœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-cQnVI","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-26Eve","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-26Eve{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-26Eveœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-cQnVI{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cQnVIœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":366.93776265249005,"y":-343.56726676261223,"zoom":0.5000000676901587}},"description":"This flow will get you experimenting with the basics of the UI, the Chat and the Prompt component. \n\nTry changing the Template in it to see how the model behaves. \nYou can change it to this and a Text Input into the `type_of_person` variable : \"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: \" ","name":"Basic Prompting (Hello, World)","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index ac218236c14..09378592eb7 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -1,1069 +1 @@ -{ - "data": { - "edges": [ - { - "data": { - "sourceHandle": { - "dataType": "URL", - "id": "URL-k9NkE", - "name": "data", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "data", - "id": "ParseData-EwWXd", - "inputTypes": [ - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-URL-k9NkE{œdataTypeœ:œURLœ,œidœ:œURL-k9NkEœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-EwWXd{œfieldNameœ:œdataœ,œidœ:œParseData-EwWXdœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", - "source": "URL-k9NkE", - "sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-k9NkEœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}", - "target": "ParseData-EwWXd", - "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-EwWXdœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "ParseData", - "id": "ParseData-EwWXd", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "references", - "id": "Prompt-B9Mq6", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ParseData-EwWXd{œdataTypeœ:œParseDataœ,œidœ:œParseData-EwWXdœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-B9Mq6{œfieldNameœ:œreferencesœ,œidœ:œPrompt-B9Mq6œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ParseData-EwWXd", - "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-EwWXdœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-B9Mq6", - "targetHandle": "{œfieldNameœ: œreferencesœ, œidœ: œPrompt-B9Mq6œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "TextInput", - "id": "TextInput-uf6ij", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "instructions", - "id": "Prompt-B9Mq6", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-TextInput-uf6ij{œdataTypeœ:œTextInputœ,œidœ:œTextInput-uf6ijœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-B9Mq6{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-B9Mq6œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "TextInput-uf6ij", - "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-uf6ijœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-B9Mq6", - "targetHandle": "{œfieldNameœ: œinstructionsœ, œidœ: œPrompt-B9Mq6œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-B9Mq6", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-X9ukk", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-B9Mq6{œdataTypeœ:œPromptœ,œidœ:œPrompt-B9Mq6œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-X9ukk{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-X9ukkœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-B9Mq6", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-B9Mq6œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-X9ukk", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-X9ukkœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-X9ukk", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-5r5Iw", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-X9ukk{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-X9ukkœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-5r5Iw{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-5r5Iwœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-X9ukk", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-X9ukkœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-5r5Iw", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-5r5Iwœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - } - ], - "nodes": [ - { - "data": { - "id": "URL-k9NkE", - "node": { - "base_classes": [ - "Data" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Fetch content from one or more URLs.", - "display_name": "URL", - "documentation": "", - "edited": false, - "field_order": [ - "urls" - ], - "frozen": false, - "icon": "layout-template", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Data", - "hidden": false, - "method": "fetch_content", - "name": "data", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "import re\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema import Data\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n" - }, - "urls": { - "advanced": false, - "display_name": "URLs", - "dynamic": false, - "info": "Enter one or more URLs, separated by commas.", - "input_types": [ - "Message" - ], - "list": true, - "load_from_db": false, - "name": "urls", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": [ - "langflow.org/", - "docs.langflow.org/" - ] - } - } - }, - "type": "URL" - }, - "dragging": false, - "height": 358, - "id": "URL-k9NkE", - "position": { - "x": 220.79156431407534, - "y": 498.8186168722667 - }, - "positionAbsolute": { - "x": 220.79156431407534, - "y": 498.8186168722667 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ParseData-EwWXd", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Convert Data into plain text following a specified template.", - "display_name": "Parse Data", - "documentation": "", - "edited": false, - "field_order": [ - "data", - "template", - "sep" - ], - "frozen": false, - "icon": "braces", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "parse_data", - "name": "text", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n" - }, - "data": { - "advanced": false, - "display_name": "Data", - "dynamic": false, - "info": "The data to convert to text.", - "input_types": [ - "Data" - ], - "list": false, - "name": "data", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "sep": { - "advanced": true, - "display_name": "Separator", - "dynamic": false, - "info": "", - "list": false, - "load_from_db": false, - "name": "sep", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "\n" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - } - } - }, - "type": "ParseData" - }, - "dragging": false, - "height": 384, - "id": "ParseData-EwWXd", - "position": { - "x": 754.3607306709101, - "y": 736.8516961537598 - }, - "positionAbsolute": { - "x": 754.3607306709101, - "y": 736.8516961537598 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-B9Mq6", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": { - "template": [ - "references", - "instructions" - ] - }, - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "documentation": "", - "edited": false, - "error": null, - "field_order": [ - "template" - ], - "frozen": false, - "full_path": null, - "icon": "prompts", - "is_composition": null, - "is_input": null, - "is_output": null, - "name": "", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Prompt Message", - "hidden": false, - "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" - }, - "instructions": { - "advanced": false, - "display_name": "instructions", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "instructions", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "references": { - "advanced": false, - "display_name": "references", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "references", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "", - "list": false, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "prompt", - "value": "Reference 1:\n\n{references}\n\n---\n\n{instructions}\n\nBlog: \n\n" - } - } - }, - "type": "Prompt" - }, - "dragging": false, - "height": 515, - "id": "Prompt-B9Mq6", - "position": { - "x": 1368.0633591447076, - "y": 467.19448061224284 - }, - "positionAbsolute": { - "x": 1368.0633591447076, - "y": 467.19448061224284 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "TextInput-uf6ij", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Get text inputs from the Playground.", - "display_name": "Instructions", - "documentation": "", - "edited": false, - "field_order": [ - "input_value" - ], - "frozen": false, - "icon": "type", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "text_response", - "name": "text", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.io.text import TextComponent\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n message = Message(\n text=self.input_value,\n )\n return message\n" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Text to be passed as input.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "Use the references above for style to write a new blog/tutorial about Langflow and AI. Suggest non-covered topics." - } - } - }, - "type": "TextInput" - }, - "dragging": false, - "height": 308, - "id": "TextInput-uf6ij", - "position": { - "x": 743.7338453293725, - "y": 301.58775454952183 - }, - "positionAbsolute": { - "x": 743.7338453293725, - "y": 301.58775454952183 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-X9ukk", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "max_tokens", - "model_kwargs", - "output_schema", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "stream", - "system_message", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "text_response", - "name": "text_output", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Language Model", - "method": "build_model", - "name": "model_output", - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict)\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "name": "max_tokens", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "output_schema": { - "advanced": true, - "display_name": "Schema", - "dynamic": false, - "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", - "list": true, - "name": "output_schema", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "seed": { - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "name": "stream", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "list": false, - "load_from_db": false, - "name": "system_message", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "list": false, - "name": "temperature", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": 0.1 - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 621, - "id": "OpenAIModel-X9ukk", - "position": { - "x": 1899.407626221589, - "y": 395.9013619556682 - }, - "positionAbsolute": { - "x": 1899.407626221589, - "y": 395.9013619556682 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatOutput-5r5Iw", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "data_template" - ], - "frozen": false, - "icon": "ChatOutput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "data_template": { - "advanced": true, - "display_name": "Data Template", - "dynamic": false, - "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "data_template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as output.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 308, - "id": "ChatOutput-5r5Iw", - "position": { - "x": 2449.3489426461606, - "y": 571.2449700910389 - }, - "positionAbsolute": { - "x": 2449.3489426461606, - "y": 571.2449700910389 - }, - "selected": false, - "type": "genericNode", - "width": 384 - } - ], - "viewport": { - "x": -63.94787944982488, - "y": -16.004163894553585, - "zoom": 0.47423908935061165 - } - }, - "description": "This flow can be used to create a blog post following instructions from the user, using two other blogs as reference.", - "endpoint_name": null, - "id": "13da3150-95b9-4d81-9ad2-f635dcdce7ab", - "is_component": false, - "last_tested_version": "1.0.0rc1", - "name": "Blog Writer" -} \ No newline at end of file +{"id":"da9999f8-9013-4bd9-8adb-653c94ebf08c","data":{"nodes":[{"data":{"id":"URL-rETJU","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Fetch content from one or more URLs.","display_name":"URL","documentation":"","edited":false,"field_order":["urls"],"frozen":false,"icon":"layout-template","output_types":[],"outputs":[{"cache":true,"display_name":"Data","hidden":false,"method":"fetch_content","name":"data","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"import re\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema import Data\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"},"urls":{"advanced":false,"display_name":"URLs","dynamic":false,"info":"Enter one or more URLs, separated by commas.","input_types":["Message"],"list":true,"load_from_db":false,"name":"urls","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":["langflow.org/","docs.langflow.org/"]}}},"type":"URL"},"dragging":false,"height":358,"id":"URL-rETJU","position":{"x":220.79156431407534,"y":498.8186168722667},"positionAbsolute":{"x":220.79156431407534,"y":498.8186168722667},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ParseData-AqSfN","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Convert Data into plain text following a specified template.","display_name":"Parse Data","documentation":"","edited":false,"field_order":["data","template","sep"],"frozen":false,"icon":"braces","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"parse_data","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n"},"data":{"advanced":false,"display_name":"Data","dynamic":false,"info":"The data to convert to text.","input_types":["Data"],"list":false,"name":"data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"sep":{"advanced":true,"display_name":"Separator","dynamic":false,"info":"","list":false,"load_from_db":false,"name":"sep","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"}}},"type":"ParseData"},"dragging":false,"height":384,"id":"ParseData-AqSfN","position":{"x":754.3607306709101,"y":736.8516961537598},"positionAbsolute":{"x":754.3607306709101,"y":736.8516961537598},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-rizUK","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["references","instructions"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"instructions":{"advanced":false,"display_name":"instructions","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"instructions","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"references":{"advanced":false,"display_name":"references","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"references","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"Reference 1:\n\n{references}\n\n---\n\n{instructions}\n\nBlog: \n\n"}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-rizUK","position":{"x":1368.0633591447076,"y":467.19448061224284},"positionAbsolute":{"x":1368.0633591447076,"y":467.19448061224284},"selected":false,"type":"genericNode","width":384},{"data":{"id":"TextInput-OffFR","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get text inputs from the Playground.","display_name":"Instructions","documentation":"","edited":false,"field_order":["input_value"],"frozen":false,"icon":"type","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"text_response","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.text import TextComponent\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n message = Message(\n text=self.input_value,\n )\n return message\n"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Text to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"Use the references above for style to write a new blog/tutorial about Langflow and AI. Suggest non-covered topics."}}},"type":"TextInput"},"dragging":false,"height":308,"id":"TextInput-OffFR","position":{"x":743.7338453293725,"y":301.58775454952183},"positionAbsolute":{"x":743.7338453293725,"y":301.58775454952183},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-qmhKV","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-qmhKV","position":{"x":1899.407626221589,"y":395.9013619556682},"positionAbsolute":{"x":1899.407626221589,"y":395.9013619556682},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-W684s","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-W684s","position":{"x":2449.3489426461606,"y":571.2449700910389},"positionAbsolute":{"x":2449.3489426461606,"y":571.2449700910389},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"URL","id":"URL-rETJU","name":"data","output_types":["Data"]},"targetHandle":{"fieldName":"data","id":"ParseData-AqSfN","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-URL-rETJU{œdataTypeœ:œURLœ,œidœ:œURL-rETJUœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-AqSfN{œfieldNameœ:œdataœ,œidœ:œParseData-AqSfNœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"URL-rETJU","sourceHandle":"{œdataTypeœ:œURLœ,œidœ:œURL-rETJUœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}","target":"ParseData-AqSfN","targetHandle":"{œfieldNameœ:œdataœ,œidœ:œParseData-AqSfNœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"ParseData","id":"ParseData-AqSfN","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"references","id":"Prompt-rizUK","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ParseData-AqSfN{œdataTypeœ:œParseDataœ,œidœ:œParseData-AqSfNœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-rizUK{œfieldNameœ:œreferencesœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ParseData-AqSfN","sourceHandle":"{œdataTypeœ:œParseDataœ,œidœ:œParseData-AqSfNœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-rizUK","targetHandle":"{œfieldNameœ:œreferencesœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"TextInput","id":"TextInput-OffFR","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"instructions","id":"Prompt-rizUK","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-TextInput-OffFR{œdataTypeœ:œTextInputœ,œidœ:œTextInput-OffFRœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-rizUK{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"TextInput-OffFR","sourceHandle":"{œdataTypeœ:œTextInputœ,œidœ:œTextInput-OffFRœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-rizUK","targetHandle":"{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-rizUK","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-qmhKV","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-rizUK{œdataTypeœ:œPromptœ,œidœ:œPrompt-rizUKœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-qmhKV{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-qmhKVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-rizUK","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-rizUKœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-qmhKV","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-qmhKVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-qmhKV","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-qmhKVœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-W684s","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-W684sœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-W684s","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-qmhKV","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-qmhKV{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-qmhKVœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-W684s{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-W684sœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":-63.94787944982488,"y":-16.004163894553585,"zoom":0.47423908935061165}},"description":"This flow can be used to create a blog post following instructions from the user, using two other blogs as reference.","name":"Blog Writer","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json index e5fd85db0d0..577e02a930b 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json @@ -1,1202 +1 @@ -{ - "data": { - "edges": [ - { - "data": { - "sourceHandle": { - "dataType": "File", - "id": "File-h46aK", - "name": "data", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "data", - "id": "ParseData-sqVr1", - "inputTypes": [ - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-File-h46aK{œdataTypeœ:œFileœ,œidœ:œFile-h46aKœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-sqVr1{œfieldNameœ:œdataœ,œidœ:œParseData-sqVr1œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", - "source": "File-h46aK", - "sourceHandle": "{œdataTypeœ: œFileœ, œidœ: œFile-h46aKœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}", - "target": "ParseData-sqVr1", - "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-sqVr1œ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "ParseData", - "id": "ParseData-sqVr1", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "Document", - "id": "Prompt-mQ7w2", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ParseData-sqVr1{œdataTypeœ:œParseDataœ,œidœ:œParseData-sqVr1œ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-mQ7w2{œfieldNameœ:œDocumentœ,œidœ:œPrompt-mQ7w2œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ParseData-sqVr1", - "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-sqVr1œ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-mQ7w2", - "targetHandle": "{œfieldNameœ: œDocumentœ, œidœ: œPrompt-mQ7w2œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-cMXe0", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "Question", - "id": "Prompt-mQ7w2", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-cMXe0{œdataTypeœ:œChatInputœ,œidœ:œChatInput-cMXe0œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-mQ7w2{œfieldNameœ:œQuestionœ,œidœ:œPrompt-mQ7w2œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ChatInput-cMXe0", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-cMXe0œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-mQ7w2", - "targetHandle": "{œfieldNameœ: œQuestionœ, œidœ: œPrompt-mQ7w2œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-mQ7w2", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-O0AGC", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-mQ7w2{œdataTypeœ:œPromptœ,œidœ:œPrompt-mQ7w2œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-O0AGC{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-O0AGCœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-mQ7w2", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-mQ7w2œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-O0AGC", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-O0AGCœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-O0AGC", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-efggd", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-O0AGC{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-O0AGCœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-efggd{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-efggdœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-O0AGC", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-O0AGCœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-efggd", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-efggdœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - } - ], - "nodes": [ - { - "data": { - "id": "File-h46aK", - "node": { - "base_classes": [ - "Data" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "A generic file loader.", - "display_name": "File", - "documentation": "", - "edited": false, - "field_order": [ - "path", - "silent_errors" - ], - "frozen": false, - "icon": "file-text", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Data", - "hidden": false, - "method": "load_file", - "name": "data", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n" - }, - "path": { - "advanced": false, - "display_name": "Path", - "dynamic": false, - "fileTypes": [ - "txt", - "md", - "mdx", - "csv", - "json", - "yaml", - "yml", - "xml", - "html", - "htm", - "pdf", - "docx", - "py", - "sh", - "sql", - "js", - "ts", - "tsx" - ], - "file_path": "", - "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx", - "list": false, - "name": "path", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "file", - "value": "" - }, - "silent_errors": { - "advanced": true, - "display_name": "Silent Errors", - "dynamic": false, - "info": "If true, errors will not raise an exception.", - "list": false, - "name": "silent_errors", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - } - } - }, - "type": "File" - }, - "dragging": false, - "height": 300, - "id": "File-h46aK", - "position": { - "x": -449.0807503257012, - "y": -253.5304920926106 - }, - "positionAbsolute": { - "x": -449.0807503257012, - "y": -253.5304920926106 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ParseData-sqVr1", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Convert Data into plain text following a specified template.", - "display_name": "Parse Data", - "documentation": "", - "edited": false, - "field_order": [ - "data", - "template", - "sep" - ], - "frozen": false, - "icon": "braces", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "parse_data", - "name": "text", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n" - }, - "data": { - "advanced": false, - "display_name": "Data", - "dynamic": false, - "info": "The data to convert to text.", - "input_types": [ - "Data" - ], - "list": false, - "name": "data", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "sep": { - "advanced": true, - "display_name": "Separator", - "dynamic": false, - "info": "", - "list": false, - "load_from_db": false, - "name": "sep", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "\n" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - } - } - }, - "type": "ParseData" - }, - "dragging": false, - "height": 384, - "id": "ParseData-sqVr1", - "position": { - "x": 73.79471204296345, - "y": -186.9430114986888 - }, - "positionAbsolute": { - "x": 73.79471204296345, - "y": -186.9430114986888 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-mQ7w2", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": { - "template": [ - "Document", - "Question" - ] - }, - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "documentation": "", - "edited": false, - "error": null, - "field_order": [ - "template" - ], - "frozen": false, - "full_path": null, - "icon": "prompts", - "is_composition": null, - "is_input": null, - "is_output": null, - "name": "", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Prompt Message", - "hidden": false, - "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "Document": { - "advanced": false, - "display_name": "Document", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "Document", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "Question": { - "advanced": false, - "display_name": "Question", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "Question", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "", - "list": false, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "prompt", - "value": "Answer user's questions based on the document below:\n\n---\n\n{Document}\n\n---\n\nQuestion:\n{Question}\n\nAnswer:\n" - } - } - }, - "type": "Prompt" - }, - "dragging": false, - "height": 515, - "id": "Prompt-mQ7w2", - "position": { - "x": 637.3518652087848, - "y": 47.191730368560215 - }, - "positionAbsolute": { - "x": 637.3518652087848, - "y": 47.191730368560215 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatInput-cMXe0", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Get chat inputs from the Playground.", - "display_name": "Chat Input", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "files" - ], - "frozen": false, - "icon": "ChatInput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "hidden": false, - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "files": { - "advanced": true, - "display_name": "Files", - "dynamic": false, - "fileTypes": [ - "txt", - "md", - "mdx", - "csv", - "json", - "yaml", - "yml", - "xml", - "html", - "htm", - "pdf", - "docx", - "py", - "sh", - "sql", - "js", - "ts", - "tsx", - "jpg", - "jpeg", - "png", - "bmp", - "image" - ], - "file_path": "", - "info": "Files to be sent with the message.", - "list": true, - "name": "files", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "file", - "value": "" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as input.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatInput" - }, - "dragging": false, - "height": 308, - "id": "ChatInput-cMXe0", - "position": { - "x": 50.08709924122684, - "y": 320.88186720121615 - }, - "positionAbsolute": { - "x": 50.08709924122684, - "y": 320.88186720121615 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-O0AGC", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "max_tokens", - "model_kwargs", - "output_schema", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "stream", - "system_message", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "text_response", - "name": "text_output", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Language Model", - "method": "build_model", - "name": "model_output", - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict)\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "name": "max_tokens", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "output_schema": { - "advanced": true, - "display_name": "Schema", - "dynamic": false, - "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", - "list": true, - "name": "output_schema", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "seed": { - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "name": "stream", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "list": false, - "load_from_db": false, - "name": "system_message", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "list": false, - "name": "temperature", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": 0.1 - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 621, - "id": "OpenAIModel-O0AGC", - "position": { - "x": 1227.3672858178775, - "y": 11.61201090144857 - }, - "positionAbsolute": { - "x": 1227.3672858178775, - "y": 11.61201090144857 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatOutput-efggd", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "data_template" - ], - "frozen": false, - "icon": "ChatOutput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "data_template": { - "advanced": true, - "display_name": "Data Template", - "dynamic": false, - "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "data_template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as output.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 308, - "id": "ChatOutput-efggd", - "position": { - "x": 1831.1359796346408, - "y": 139.5174517327903 - }, - "positionAbsolute": { - "x": 1831.1359796346408, - "y": 139.5174517327903 - }, - "selected": false, - "type": "genericNode", - "width": 384 - } - ], - "viewport": { - "x": 249.03047748371796, - "y": 251.71203687916693, - "zoom": 0.4580440916596844 - } - }, - "description": "This flow integrates PDF reading with a language model to answer document-specific questions. Ideal for small-scale texts, it facilitates direct queries with immediate insights.", - "endpoint_name": null, - "id": "4b4cbf9e-34fe-4613-a460-3b7af89b7788", - "is_component": false, - "last_tested_version": "1.0.0rc1", - "name": "Document QA" -} \ No newline at end of file +{"id":"483d5200-b59b-4afa-a71f-52fcfcde8fca","data":{"nodes":[{"data":{"id":"File-Q3Xrb","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"A generic file loader.","display_name":"File","documentation":"","edited":false,"field_order":["path","silent_errors"],"frozen":false,"icon":"file-text","output_types":[],"outputs":[{"cache":true,"display_name":"Data","hidden":false,"method":"load_file","name":"data","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n"},"path":{"advanced":false,"display_name":"Path","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx"],"file_path":"","info":"Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx","list":false,"name":"path","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"silent_errors":{"advanced":true,"display_name":"Silent Errors","dynamic":false,"info":"If true, errors will not raise an exception.","list":false,"name":"silent_errors","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false}}},"type":"File"},"dragging":false,"height":300,"id":"File-Q3Xrb","position":{"x":-449.0807503257012,"y":-253.5304920926106},"positionAbsolute":{"x":-449.0807503257012,"y":-253.5304920926106},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ParseData-1Y5jJ","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Convert Data into plain text following a specified template.","display_name":"Parse Data","documentation":"","edited":false,"field_order":["data","template","sep"],"frozen":false,"icon":"braces","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"parse_data","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n"},"data":{"advanced":false,"display_name":"Data","dynamic":false,"info":"The data to convert to text.","input_types":["Data"],"list":false,"name":"data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"sep":{"advanced":true,"display_name":"Separator","dynamic":false,"info":"","list":false,"load_from_db":false,"name":"sep","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"}}},"type":"ParseData"},"dragging":false,"height":384,"id":"ParseData-1Y5jJ","position":{"x":73.79471204296345,"y":-186.9430114986888},"positionAbsolute":{"x":73.79471204296345,"y":-186.9430114986888},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-CMJEB","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["Document","Question"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"Document":{"advanced":false,"display_name":"Document","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"Document","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"Question":{"advanced":false,"display_name":"Question","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"Question","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"Answer user's questions based on the document below:\n\n---\n\n{Document}\n\n---\n\nQuestion:\n{Question}\n\nAnswer:\n"}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-CMJEB","position":{"x":637.3518652087848,"y":47.191730368560215},"positionAbsolute":{"x":637.3518652087848,"y":47.191730368560215},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatInput-mc7sJ","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-mc7sJ","position":{"x":50.08709924122684,"y":320.88186720121615},"positionAbsolute":{"x":50.08709924122684,"y":320.88186720121615},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-U2g5u","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-U2g5u","position":{"x":1249.1992451905348,"y":2.8792271523856243},"positionAbsolute":{"x":1249.1992451905348,"y":2.8792271523856243},"selected":true,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-yZjPO","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-yZjPO","position":{"x":1831.1359796346408,"y":139.5174517327903},"positionAbsolute":{"x":1831.1359796346408,"y":139.5174517327903},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"File","id":"File-Q3Xrb","name":"data","output_types":["Data"]},"targetHandle":{"fieldName":"data","id":"ParseData-1Y5jJ","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-File-Q3Xrb{œdataTypeœ:œFileœ,œidœ:œFile-Q3Xrbœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-1Y5jJ{œfieldNameœ:œdataœ,œidœ:œParseData-1Y5jJœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"File-Q3Xrb","sourceHandle":"{œdataTypeœ:œFileœ,œidœ:œFile-Q3Xrbœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}","target":"ParseData-1Y5jJ","targetHandle":"{œfieldNameœ:œdataœ,œidœ:œParseData-1Y5jJœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"ParseData","id":"ParseData-1Y5jJ","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"Document","id":"Prompt-CMJEB","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ParseData-1Y5jJ{œdataTypeœ:œParseDataœ,œidœ:œParseData-1Y5jJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-CMJEB{œfieldNameœ:œDocumentœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ParseData-1Y5jJ","sourceHandle":"{œdataTypeœ:œParseDataœ,œidœ:œParseData-1Y5jJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-CMJEB","targetHandle":"{œfieldNameœ:œDocumentœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-mc7sJ","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"Question","id":"Prompt-CMJEB","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-mc7sJ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-mc7sJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-CMJEB{œfieldNameœ:œQuestionœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-mc7sJ","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-mc7sJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-CMJEB","targetHandle":"{œfieldNameœ:œQuestionœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-CMJEB","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-U2g5u","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-CMJEB{œdataTypeœ:œPromptœ,œidœ:œPrompt-CMJEBœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-U2g5u{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-U2g5uœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-CMJEB","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-CMJEBœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-U2g5u","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-U2g5uœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-U2g5u","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-U2g5uœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-yZjPO","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-yZjPOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-yZjPO","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-U2g5u","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-U2g5u{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-U2g5uœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-yZjPO{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-yZjPOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":252.03047748371796,"y":253.71203687916693,"zoom":0.4580440916596844}},"description":"This flow integrates PDF reading with a language model to answer document-specific questions. Ideal for small-scale texts, it facilitates direct queries with immediate insights.","name":"Document QA","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index e56670301a4..a695f3fb4a0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -1,1123 +1 @@ -{ - "data": { - "edges": [ - { - "data": { - "sourceHandle": { - "dataType": "Memory", - "id": "Memory-uy2TA", - "name": "messages_text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "context", - "id": "Prompt-m9rUs", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Memory-uy2TA{œdataTypeœ:œMemoryœ,œidœ:œMemory-uy2TAœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-m9rUs{œfieldNameœ:œcontextœ,œidœ:œPrompt-m9rUsœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Memory-uy2TA", - "sourceHandle": "{œdataTypeœ: œMemoryœ, œidœ: œMemory-uy2TAœ, œnameœ: œmessages_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-m9rUs", - "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-m9rUsœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-hSTqh", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "user_message", - "id": "Prompt-m9rUs", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-hSTqh{œdataTypeœ:œChatInputœ,œidœ:œChatInput-hSTqhœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-m9rUs{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-m9rUsœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ChatInput-hSTqh", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-hSTqhœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-m9rUs", - "targetHandle": "{œfieldNameœ: œuser_messageœ, œidœ: œPrompt-m9rUsœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-m9rUs", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-WmUtU", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-m9rUs{œdataTypeœ:œPromptœ,œidœ:œPrompt-m9rUsœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-WmUtU{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-WmUtUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-m9rUs", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-m9rUsœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-WmUtU", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-WmUtUœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-WmUtU", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-LIvGN", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-WmUtU{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-WmUtUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-LIvGN{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-LIvGNœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-WmUtU", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-WmUtUœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-LIvGN", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-LIvGNœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - } - ], - "nodes": [ - { - "data": { - "id": "Memory-uy2TA", - "node": { - "base_classes": [ - "Data", - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Retrieves stored chat messages.", - "display_name": "Chat Memory", - "documentation": "", - "edited": false, - "field_order": [ - "sender", - "sender_name", - "n_messages", - "session_id", - "order", - "template" - ], - "frozen": false, - "icon": "message-square-more", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Chat History", - "method": "retrieve_messages", - "name": "messages", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Messages (Text)", - "hidden": false, - "method": "retrieve_messages_as_text", - "name": "messages_text", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages.\"\n icon = \"message-square-more\"\n\n inputs = [\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\", \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"Session ID of the chat history.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chat History\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Messages (Text)\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n messages = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = messages\n return messages\n\n def retrieve_messages_as_text(self) -> Message:\n messages_text = data_to_text(self.template, self.retrieve_messages())\n self.status = messages_text\n return Message(text=messages_text)\n" - }, - "n_messages": { - "advanced": true, - "display_name": "Number of Messages", - "dynamic": false, - "info": "Number of messages to retrieve.", - "list": false, - "name": "n_messages", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 100 - }, - "order": { - "advanced": true, - "display_name": "Order", - "dynamic": false, - "info": "Order of the messages.", - "name": "order", - "options": [ - "Ascending", - "Descending" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Ascending" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Machine and User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID of the chat history.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "template": { - "advanced": true, - "display_name": "Template", - "dynamic": false, - "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{sender_name}: {text}" - } - } - }, - "type": "Memory" - }, - "dragging": false, - "height": 266, - "id": "Memory-uy2TA", - "position": { - "x": 1264.7588980556088, - "y": 506.6868269980502 - }, - "positionAbsolute": { - "x": 1264.7588980556088, - "y": 506.6868269980502 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-m9rUs", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": { - "template": [ - "context", - "user_message" - ] - }, - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "documentation": "", - "edited": false, - "error": null, - "field_order": [ - "template" - ], - "frozen": false, - "full_path": null, - "icon": "prompts", - "is_composition": null, - "is_input": null, - "is_output": null, - "name": "", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Prompt Message", - "hidden": false, - "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" - }, - "context": { - "advanced": false, - "display_name": "context", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "context", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "", - "list": false, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "prompt", - "value": "{context}\n\nUser: {user_message}\nAI: " - }, - "user_message": { - "advanced": false, - "display_name": "user_message", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "user_message", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - } - } - }, - "type": "Prompt" - }, - "dragging": false, - "height": 515, - "id": "Prompt-m9rUs", - "position": { - "x": 1880.8227904110583, - "y": 625.8049209882275 - }, - "positionAbsolute": { - "x": 1880.8227904110583, - "y": 625.8049209882275 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatInput-hSTqh", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Get chat inputs from the Playground.", - "display_name": "Chat Input", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "files" - ], - "frozen": false, - "icon": "ChatInput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "hidden": false, - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "files": { - "advanced": true, - "display_name": "Files", - "dynamic": false, - "fileTypes": [ - "txt", - "md", - "mdx", - "csv", - "json", - "yaml", - "yml", - "xml", - "html", - "htm", - "pdf", - "docx", - "py", - "sh", - "sql", - "js", - "ts", - "tsx", - "jpg", - "jpeg", - "png", - "bmp", - "image" - ], - "file_path": "", - "info": "Files to be sent with the message.", - "list": true, - "name": "files", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "file", - "value": "" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as input.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatInput" - }, - "dragging": false, - "height": 308, - "id": "ChatInput-hSTqh", - "position": { - "x": 1275.9262193671882, - "y": 836.1228056896347 - }, - "positionAbsolute": { - "x": 1275.9262193671882, - "y": 836.1228056896347 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-WmUtU", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "max_tokens", - "model_kwargs", - "output_schema", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "stream", - "system_message", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "text_response", - "name": "text_output", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Language Model", - "method": "build_model", - "name": "model_output", - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict)\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "name": "max_tokens", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "output_schema": { - "advanced": true, - "display_name": "Schema", - "dynamic": false, - "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", - "list": true, - "name": "output_schema", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "seed": { - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "name": "stream", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "list": false, - "load_from_db": false, - "name": "system_message", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "list": false, - "name": "temperature", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": 0.1 - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 621, - "id": "OpenAIModel-WmUtU", - "position": { - "x": 2428.0215346784357, - "y": 569.9683144303319 - }, - "positionAbsolute": { - "x": 2428.0215346784357, - "y": 569.9683144303319 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatOutput-LIvGN", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "data_template" - ], - "frozen": false, - "icon": "ChatOutput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "data_template": { - "advanced": true, - "display_name": "Data Template", - "dynamic": false, - "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "data_template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as output.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 308, - "id": "ChatOutput-LIvGN", - "position": { - "x": 2988.248820475989, - "y": 705.837390387878 - }, - "positionAbsolute": { - "x": 2988.248820475989, - "y": 705.837390387878 - }, - "selected": false, - "type": "genericNode", - "width": 384 - } - ], - "viewport": { - "x": -586.5321077101332, - "y": -103.32118023592653, - "zoom": 0.5372819347267049 - } - }, - "description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.", - "endpoint_name": null, - "id": "2a47bc35-69ca-4d8b-9895-2a7fab222b9f", - "is_component": false, - "last_tested_version": "1.0.0rc1", - "name": "Memory Chatbot" -} \ No newline at end of file +{"id":"16c029a0-0d89-4c36-8a8c-e5410206df38","data":{"nodes":[{"data":{"id":"Memory-VIq7F","node":{"base_classes":["Data","Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Retrieves stored chat messages.","display_name":"Chat Memory","documentation":"","edited":false,"field_order":["sender","sender_name","n_messages","session_id","order","template"],"frozen":false,"icon":"message-square-more","output_types":[],"outputs":[{"cache":true,"display_name":"Chat History","method":"retrieve_messages","name":"messages","selected":"Data","types":["Data"],"value":"__UNDEFINED__"},{"cache":true,"display_name":"Messages (Text)","hidden":false,"method":"retrieve_messages_as_text","name":"messages_text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages.\"\n icon = \"message-square-more\"\n\n inputs = [\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\", \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"Session ID of the chat history.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chat History\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Messages (Text)\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n messages = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = messages\n return messages\n\n def retrieve_messages_as_text(self) -> Message:\n messages_text = data_to_text(self.template, self.retrieve_messages())\n self.status = messages_text\n return Message(text=messages_text)\n"},"n_messages":{"advanced":true,"display_name":"Number of Messages","dynamic":false,"info":"Number of messages to retrieve.","list":false,"name":"n_messages","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":100},"order":{"advanced":true,"display_name":"Order","dynamic":false,"info":"Order of the messages.","name":"order","options":["Ascending","Descending"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Ascending"},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User","Machine and User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine and User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID of the chat history.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"template":{"advanced":true,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{sender_name}: {text}"}}},"type":"Memory"},"dragging":false,"height":266,"id":"Memory-VIq7F","position":{"x":1264.7588980556088,"y":506.6868269980502},"positionAbsolute":{"x":1264.7588980556088,"y":506.6868269980502},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-gEaWL","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["context","user_message"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"context":{"advanced":false,"display_name":"context","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"context","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"{context}\n\nUser: {user_message}\nAI: "},"user_message":{"advanced":false,"display_name":"user_message","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"user_message","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-gEaWL","position":{"x":1880.8227904110583,"y":625.8049209882275},"positionAbsolute":{"x":1880.8227904110583,"y":625.8049209882275},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatInput-gIy9N","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-gIy9N","position":{"x":1275.9262193671882,"y":836.1228056896347},"positionAbsolute":{"x":1275.9262193671882,"y":836.1228056896347},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-uNcAU","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-uNcAU","position":{"x":2428.0215346784357,"y":569.9683144303319},"positionAbsolute":{"x":2428.0215346784357,"y":569.9683144303319},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-KtSB9","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-KtSB9","position":{"x":2988.248820475989,"y":705.837390387878},"positionAbsolute":{"x":2988.248820475989,"y":705.837390387878},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"Memory","id":"Memory-VIq7F","name":"messages_text","output_types":["Message"]},"targetHandle":{"fieldName":"context","id":"Prompt-gEaWL","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-Memory-VIq7F{œdataTypeœ:œMemoryœ,œidœ:œMemory-VIq7Fœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-gEaWL{œfieldNameœ:œcontextœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"Memory-VIq7F","sourceHandle":"{œdataTypeœ:œMemoryœ,œidœ:œMemory-VIq7Fœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-gEaWL","targetHandle":"{œfieldNameœ:œcontextœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-gIy9N","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"user_message","id":"Prompt-gEaWL","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-gIy9N{œdataTypeœ:œChatInputœ,œidœ:œChatInput-gIy9Nœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-gEaWL{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-gIy9N","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-gIy9Nœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-gEaWL","targetHandle":"{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-gEaWL","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-uNcAU","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-gEaWL{œdataTypeœ:œPromptœ,œidœ:œPrompt-gEaWLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-uNcAU{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-uNcAUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-gEaWL","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-gEaWLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-uNcAU","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-uNcAUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-uNcAU","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-uNcAUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-KtSB9","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-KtSB9œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-KtSB9","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-uNcAU","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-uNcAU{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-uNcAUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-KtSB9{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-KtSB9œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":-586.5321077101332,"y":-103.32118023592653,"zoom":0.5372819347267049}},"description":"This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.","name":"Memory Chatbot","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index 9118c915df1..1dba89d86ca 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -1,3175 +1 @@ -{ - "data": { - "edges": [ - { - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-c4xn9", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "search_input", - "id": "AstraDB-7nAHJ", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-c4xn9{œdataTypeœ:œChatInputœ,œidœ:œChatInput-c4xn9œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-7nAHJ{œfieldNameœ:œsearch_inputœ,œidœ:œAstraDB-7nAHJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-c4xn9", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-c4xn9œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "AstraDB-7nAHJ", - "targetHandle": "{œfieldNameœ: œsearch_inputœ, œidœ: œAstraDB-7nAHJœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIEmbeddings", - "id": "OpenAIEmbeddings-BKXc6", - "name": "embeddings", - "output_types": [ - "Embeddings" - ] - }, - "targetHandle": { - "fieldName": "embedding", - "id": "AstraDB-7nAHJ", - "inputTypes": [ - "Embeddings", - "dict" - ], - "type": "other" - } - }, - "id": "reactflow__edge-OpenAIEmbeddings-BKXc6{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-BKXc6œ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-7nAHJ{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-7nAHJœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}", - "source": "OpenAIEmbeddings-BKXc6", - "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-BKXc6œ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", - "target": "AstraDB-7nAHJ", - "targetHandle": "{œfieldNameœ: œembeddingœ, œidœ: œAstraDB-7nAHJœ, œinputTypesœ: [œEmbeddingsœ, œdictœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "AstraDB", - "id": "AstraDB-7nAHJ", - "name": "search_results", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "data", - "id": "ParseData-d61Q0", - "inputTypes": [ - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-AstraDB-7nAHJ{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-7nAHJœ,œnameœ:œsearch_resultsœ,œoutput_typesœ:[œDataœ]}-ParseData-d61Q0{œfieldNameœ:œdataœ,œidœ:œParseData-d61Q0œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", - "source": "AstraDB-7nAHJ", - "sourceHandle": "{œdataTypeœ: œAstraDBœ, œidœ: œAstraDB-7nAHJœ, œnameœ: œsearch_resultsœ, œoutput_typesœ: [œDataœ]}", - "target": "ParseData-d61Q0", - "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-d61Q0œ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "ParseData", - "id": "ParseData-d61Q0", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "context", - "id": "Prompt-vqAlG", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ParseData-d61Q0{œdataTypeœ:œParseDataœ,œidœ:œParseData-d61Q0œ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-vqAlG{œfieldNameœ:œcontextœ,œidœ:œPrompt-vqAlGœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ParseData-d61Q0", - "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-d61Q0œ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-vqAlG", - "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-vqAlGœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-c4xn9", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "question", - "id": "Prompt-vqAlG", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-c4xn9{œdataTypeœ:œChatInputœ,œidœ:œChatInput-c4xn9œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-vqAlG{œfieldNameœ:œquestionœ,œidœ:œPrompt-vqAlGœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "ChatInput-c4xn9", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-c4xn9œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-vqAlG", - "targetHandle": "{œfieldNameœ: œquestionœ, œidœ: œPrompt-vqAlGœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-vqAlG", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-ybL3k", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-vqAlG{œdataTypeœ:œPromptœ,œidœ:œPrompt-vqAlGœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-ybL3k{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-ybL3kœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-vqAlG", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-vqAlGœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-ybL3k", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-ybL3kœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-ybL3k", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-BpzuD", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-ybL3k{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-ybL3kœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-BpzuD{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-BpzuDœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-ybL3k", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-ybL3kœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-BpzuD", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-BpzuDœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "File", - "id": "File-bf6wn", - "name": "data", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "data_inputs", - "id": "SplitText-52wBo", - "inputTypes": [ - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-File-bf6wn{œdataTypeœ:œFileœ,œidœ:œFile-bf6wnœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-SplitText-52wBo{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-52wBoœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", - "source": "File-bf6wn", - "sourceHandle": "{œdataTypeœ: œFileœ, œidœ: œFile-bf6wnœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}", - "target": "SplitText-52wBo", - "targetHandle": "{œfieldNameœ: œdata_inputsœ, œidœ: œSplitText-52wBoœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "SplitText", - "id": "SplitText-52wBo", - "name": "chunks", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "ingest_data", - "id": "AstraDB-vyd5U", - "inputTypes": [ - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-SplitText-52wBo{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-52wBoœ,œnameœ:œchunksœ,œoutput_typesœ:[œDataœ]}-AstraDB-vyd5U{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-vyd5Uœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", - "source": "SplitText-52wBo", - "sourceHandle": "{œdataTypeœ: œSplitTextœ, œidœ: œSplitText-52wBoœ, œnameœ: œchunksœ, œoutput_typesœ: [œDataœ]}", - "target": "AstraDB-vyd5U", - "targetHandle": "{œfieldNameœ: œingest_dataœ, œidœ: œAstraDB-vyd5Uœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "OpenAIEmbeddings", - "id": "OpenAIEmbeddings-sRZMc", - "name": "embeddings", - "output_types": [ - "Embeddings" - ] - }, - "targetHandle": { - "fieldName": "embedding", - "id": "AstraDB-vyd5U", - "inputTypes": [ - "Embeddings", - "dict" - ], - "type": "other" - } - }, - "id": "reactflow__edge-OpenAIEmbeddings-sRZMc{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-sRZMcœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-vyd5U{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-vyd5Uœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}", - "source": "OpenAIEmbeddings-sRZMc", - "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-sRZMcœ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", - "target": "AstraDB-vyd5U", - "targetHandle": "{œfieldNameœ: œembeddingœ, œidœ: œAstraDB-vyd5Uœ, œinputTypesœ: [œEmbeddingsœ, œdictœ], œtypeœ: œotherœ}" - } - ], - "nodes": [ - { - "data": { - "id": "ChatInput-c4xn9", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Get chat inputs from the Playground.", - "display_name": "Chat Input", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "files" - ], - "frozen": false, - "icon": "ChatInput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "hidden": false, - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "files": { - "advanced": true, - "display_name": "Files", - "dynamic": false, - "fileTypes": [ - "txt", - "md", - "mdx", - "csv", - "json", - "yaml", - "yml", - "xml", - "html", - "htm", - "pdf", - "docx", - "py", - "sh", - "sql", - "js", - "ts", - "tsx", - "jpg", - "jpeg", - "png", - "bmp", - "image" - ], - "file_path": "", - "info": "Files to be sent with the message.", - "list": true, - "name": "files", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "file", - "value": "" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as input.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "User" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatInput" - }, - "dragging": false, - "height": 308, - "id": "ChatInput-c4xn9", - "position": { - "x": 642.3545710150049, - "y": 220.22556606238678 - }, - "positionAbsolute": { - "x": 642.3545710150049, - "y": 220.22556606238678 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "AstraDB-7nAHJ", - "node": { - "base_classes": [ - "Data", - "Retriever" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Implementation of Vector Store using Astra DB with search capabilities", - "display_name": "Astra DB", - "documentation": "https://python.langchain.com/docs/integrations/vectorstores/astradb", - "edited": false, - "field_order": [ - "collection_name", - "token", - "api_endpoint", - "search_input", - "ingest_data", - "namespace", - "metric", - "batch_size", - "bulk_insert_batch_concurrency", - "bulk_insert_overwrite_concurrency", - "bulk_delete_concurrency", - "setup_mode", - "pre_delete_collection", - "metadata_indexing_include", - "embedding", - "metadata_indexing_exclude", - "collection_indexing_policy", - "search_type", - "number_of_results" - ], - "frozen": false, - "icon": "AstraDB", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Retriever", - "method": "build_base_retriever", - "name": "base_retriever", - "selected": "Retriever", - "types": [ - "Retriever" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Search Results", - "hidden": false, - "method": "search_documents", - "name": "search_results", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "api_endpoint": { - "advanced": false, - "display_name": "API Endpoint", - "dynamic": false, - "info": "API endpoint URL for the Astra DB service.", - "input_types": [], - "load_from_db": false, - "name": "api_endpoint", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "batch_size": { - "advanced": true, - "display_name": "Batch Size", - "dynamic": false, - "info": "Optional number of data to process in a single batch.", - "list": false, - "name": "batch_size", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "bulk_delete_concurrency": { - "advanced": true, - "display_name": "Bulk Delete Concurrency", - "dynamic": false, - "info": "Optional concurrency level for bulk delete operations.", - "list": false, - "name": "bulk_delete_concurrency", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "bulk_insert_batch_concurrency": { - "advanced": true, - "display_name": "Bulk Insert Batch Concurrency", - "dynamic": false, - "info": "Optional concurrency level for bulk insert operations.", - "list": false, - "name": "bulk_insert_batch_concurrency", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "bulk_insert_overwrite_concurrency": { - "advanced": true, - "display_name": "Bulk Insert Overwrite Concurrency", - "dynamic": false, - "info": "Optional concurrency level for bulk insert operations that overwrite existing data.", - "list": false, - "name": "bulk_insert_overwrite_concurrency", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n" - }, - "collection_indexing_policy": { - "advanced": true, - "display_name": "Collection Indexing Policy", - "dynamic": false, - "info": "Optional dictionary defining the indexing policy for the collection.", - "list": false, - "load_from_db": false, - "name": "collection_indexing_policy", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "collection_name": { - "advanced": false, - "display_name": "Collection Name", - "dynamic": false, - "info": "The name of the collection within Astra DB where the vectors will be stored.", - "list": false, - "load_from_db": false, - "name": "collection_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "langflow" - }, - "embedding": { - "advanced": false, - "display_name": "Embedding or Astra Vectorize", - "dynamic": false, - "info": "", - "input_types": [ - "Embeddings", - "dict" - ], - "list": false, - "name": "embedding", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "ingest_data": { - "advanced": false, - "display_name": "Ingest Data", - "dynamic": false, - "info": "", - "input_types": [ - "Data" - ], - "list": true, - "name": "ingest_data", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "metadata_indexing_exclude": { - "advanced": true, - "display_name": "Metadata Indexing Exclude", - "dynamic": false, - "info": "Optional list of metadata fields to exclude from the indexing.", - "list": false, - "load_from_db": false, - "name": "metadata_indexing_exclude", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "metadata_indexing_include": { - "advanced": true, - "display_name": "Metadata Indexing Include", - "dynamic": false, - "info": "Optional list of metadata fields to include in the indexing.", - "list": false, - "load_from_db": false, - "name": "metadata_indexing_include", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "metric": { - "advanced": true, - "display_name": "Metric", - "dynamic": false, - "info": "Optional distance metric for vector comparisons in the vector store.", - "name": "metric", - "options": [ - "cosine", - "dot_product", - "euclidean" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "namespace": { - "advanced": true, - "display_name": "Namespace", - "dynamic": false, - "info": "Optional namespace within Astra DB to use for the collection.", - "list": false, - "load_from_db": false, - "name": "namespace", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "number_of_results": { - "advanced": true, - "display_name": "Number of Results", - "dynamic": false, - "info": "Number of results to return.", - "list": false, - "name": "number_of_results", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 4 - }, - "pre_delete_collection": { - "advanced": true, - "display_name": "Pre Delete Collection", - "dynamic": false, - "info": "Boolean flag to determine whether to delete the collection before creating a new one.", - "list": false, - "name": "pre_delete_collection", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "search_input": { - "advanced": false, - "display_name": "Search Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "search_input", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "search_type": { - "advanced": true, - "display_name": "Search Type", - "dynamic": false, - "info": "", - "name": "search_type", - "options": [ - "Similarity", - "MMR" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Similarity" - }, - "setup_mode": { - "advanced": true, - "display_name": "Setup Mode", - "dynamic": false, - "info": "Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.", - "name": "setup_mode", - "options": [ - "Sync", - "Async", - "Off" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Sync" - }, - "token": { - "advanced": false, - "display_name": "Astra DB Application Token", - "dynamic": false, - "info": "Authentication token for accessing Astra DB.", - "input_types": [], - "load_from_db": false, - "name": "token", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - } - } - }, - "type": "AstraDB" - }, - "dragging": false, - "height": 753, - "id": "AstraDB-7nAHJ", - "position": { - "x": 1246.0381406498648, - "y": 333.25157075413966 - }, - "positionAbsolute": { - "x": 1246.0381406498648, - "y": 333.25157075413966 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIEmbeddings-BKXc6", - "node": { - "base_classes": [ - "Embeddings" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generate embeddings using OpenAI models.", - "display_name": "OpenAI Embeddings", - "documentation": "", - "edited": false, - "field_order": [ - "default_headers", - "default_query", - "chunk_size", - "client", - "deployment", - "embedding_ctx_length", - "max_retries", - "model", - "model_kwargs", - "openai_api_base", - "openai_api_key", - "openai_api_type", - "openai_api_version", - "openai_organization", - "openai_proxy", - "request_timeout", - "show_progress_bar", - "skip_empty", - "tiktoken_model_name", - "tiktoken_enable" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Embeddings", - "hidden": false, - "method": "build_embeddings", - "name": "embeddings", - "selected": "Embeddings", - "types": [ - "Embeddings" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "chunk_size": { - "advanced": true, - "display_name": "Chunk Size", - "dynamic": false, - "info": "", - "list": false, - "name": "chunk_size", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1000 - }, - "client": { - "advanced": true, - "display_name": "Client", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "client", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n" - }, - "default_headers": { - "advanced": true, - "display_name": "Default Headers", - "dynamic": false, - "info": "Default headers to use for the API request.", - "list": false, - "name": "default_headers", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "default_query": { - "advanced": true, - "display_name": "Default Query", - "dynamic": false, - "info": "Default query parameters to use for the API request.", - "list": false, - "name": "default_query", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "deployment": { - "advanced": true, - "display_name": "Deployment", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "deployment", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "embedding_ctx_length": { - "advanced": true, - "display_name": "Embedding Context Length", - "dynamic": false, - "info": "", - "list": false, - "name": "embedding_ctx_length", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1536 - }, - "max_retries": { - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "", - "list": false, - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 3 - }, - "model": { - "advanced": false, - "display_name": "Model", - "dynamic": false, - "info": "", - "name": "model", - "options": [ - "text-embedding-3-small", - "text-embedding-3-large", - "text-embedding-ada-002" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "text-embedding-3-small" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "", - "input_types": [], - "load_from_db": true, - "name": "openai_api_base", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "openai_api_type": { - "advanced": true, - "display_name": "OpenAI API Type", - "dynamic": false, - "info": "", - "input_types": [], - "load_from_db": true, - "name": "openai_api_type", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "openai_api_version": { - "advanced": true, - "display_name": "OpenAI API Version", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "openai_api_version", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_organization": { - "advanced": true, - "display_name": "OpenAI Organization", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "openai_organization", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_proxy": { - "advanced": true, - "display_name": "OpenAI Proxy", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "openai_proxy", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "request_timeout": { - "advanced": true, - "display_name": "Request Timeout", - "dynamic": false, - "info": "", - "list": false, - "name": "request_timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": "" - }, - "show_progress_bar": { - "advanced": true, - "display_name": "Show Progress Bar", - "dynamic": false, - "info": "", - "list": false, - "name": "show_progress_bar", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "skip_empty": { - "advanced": true, - "display_name": "Skip Empty", - "dynamic": false, - "info": "", - "list": false, - "name": "skip_empty", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "tiktoken_enable": { - "advanced": true, - "display_name": "TikToken Enable", - "dynamic": false, - "info": "If False, you must have transformers installed.", - "list": false, - "name": "tiktoken_enable", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": true - }, - "tiktoken_model_name": { - "advanced": true, - "display_name": "TikToken Model Name", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "tiktoken_model_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "OpenAIEmbeddings" - }, - "dragging": false, - "height": 394, - "id": "OpenAIEmbeddings-BKXc6", - "position": { - "x": 603.2488770584523, - "y": 661.6162066128852 - }, - "positionAbsolute": { - "x": 603.2488770584523, - "y": 661.6162066128852 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ParseData-d61Q0", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Convert Data into plain text following a specified template.", - "display_name": "Parse Data", - "documentation": "", - "edited": false, - "field_order": [ - "data", - "template", - "sep" - ], - "frozen": false, - "icon": "braces", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "parse_data", - "name": "text", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n" - }, - "data": { - "advanced": false, - "display_name": "Data", - "dynamic": false, - "info": "The data to convert to text.", - "input_types": [ - "Data" - ], - "list": false, - "name": "data", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "sep": { - "advanced": true, - "display_name": "Separator", - "dynamic": false, - "info": "", - "list": false, - "load_from_db": false, - "name": "sep", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "\n" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - } - } - }, - "type": "ParseData" - }, - "dragging": false, - "height": 384, - "id": "ParseData-d61Q0", - "position": { - "x": 1854.1518317915907, - "y": 459.3386924128532 - }, - "positionAbsolute": { - "x": 1854.1518317915907, - "y": 459.3386924128532 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-vqAlG", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": { - "template": [ - "context", - "question" - ] - }, - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "documentation": "", - "edited": false, - "error": null, - "field_order": [ - "template" - ], - "frozen": false, - "full_path": null, - "icon": "prompts", - "is_composition": null, - "is_input": null, - "is_output": null, - "name": "", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Prompt Message", - "hidden": false, - "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" - }, - "context": { - "advanced": false, - "display_name": "context", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "context", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "question": { - "advanced": false, - "display_name": "question", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Message", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "question", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "info": "", - "list": false, - "name": "template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "prompt", - "value": "{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: " - } - } - }, - "type": "Prompt" - }, - "dragging": false, - "height": 515, - "id": "Prompt-vqAlG", - "position": { - "x": 2486.0988668404975, - "y": 496.5120474157301 - }, - "positionAbsolute": { - "x": 2486.0988668404975, - "y": 496.5120474157301 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-ybL3k", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "max_tokens", - "model_kwargs", - "output_schema", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "stream", - "system_message", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Text", - "hidden": false, - "method": "text_response", - "name": "text_output", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Language Model", - "method": "build_model", - "name": "model_output", - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict)\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "name": "max_tokens", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "output_schema": { - "advanced": true, - "display_name": "Schema", - "dynamic": false, - "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", - "list": true, - "name": "output_schema", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "seed": { - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "name": "stream", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "list": false, - "load_from_db": false, - "name": "system_message", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "list": false, - "name": "temperature", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": 0.1 - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 621, - "id": "OpenAIModel-ybL3k", - "position": { - "x": 3145.6693008609222, - "y": 374.23955005474204 - }, - "positionAbsolute": { - "x": 3145.6693008609222, - "y": 374.23955005474204 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatOutput-BpzuD", - "node": { - "base_classes": [ - "Message" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "sender", - "sender_name", - "session_id", - "data_template" - ], - "frozen": false, - "icon": "ChatOutput", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" - }, - "data_template": { - "advanced": true, - "display_name": "Data Template", - "dynamic": false, - "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "data_template", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "{text}" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "info": "Message to be passed as output.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "info": "Type of sender.", - "name": "sender", - "options": [ - "Machine", - "User" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "info": "Name of the sender.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "sender_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": true, - "display_name": "Session ID", - "dynamic": false, - "info": "Session ID for the message.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "session_id", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 308, - "id": "ChatOutput-BpzuD", - "position": { - "x": 3769.242086248817, - "y": 585.3403837062634 - }, - "positionAbsolute": { - "x": 3769.242086248817, - "y": 585.3403837062634 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "SplitText-52wBo", - "node": { - "base_classes": [ - "Data" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Split text into chunks based on specified criteria.", - "display_name": "Split Text", - "documentation": "", - "edited": false, - "field_order": [ - "data_inputs", - "chunk_overlap", - "chunk_size", - "separator" - ], - "frozen": false, - "icon": "scissors-line-dashed", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Chunks", - "hidden": false, - "method": "split_text", - "name": "chunks", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "chunk_overlap": { - "advanced": false, - "display_name": "Chunk Overlap", - "dynamic": false, - "info": "Number of characters to overlap between chunks.", - "list": false, - "name": "chunk_overlap", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 200 - }, - "chunk_size": { - "advanced": false, - "display_name": "Chunk Size", - "dynamic": false, - "info": "The maximum number of characters in each chunk.", - "list": false, - "name": "chunk_size", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1000 - }, - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import List\n\nfrom langchain_text_splitters import CharacterTextSplitter\n\nfrom langflow.custom import Component\nfrom langflow.io import HandleInput, IntInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.utils.util import unescape_string\n\n\nclass SplitTextComponent(Component):\n display_name: str = \"Split Text\"\n description: str = \"Split text into chunks based on specified criteria.\"\n icon = \"scissors-line-dashed\"\n\n inputs = [\n HandleInput(\n name=\"data_inputs\",\n display_name=\"Data Inputs\",\n info=\"The data to split.\",\n input_types=[\"Data\"],\n is_list=True,\n ),\n IntInput(\n name=\"chunk_overlap\",\n display_name=\"Chunk Overlap\",\n info=\"Number of characters to overlap between chunks.\",\n value=200,\n ),\n IntInput(\n name=\"chunk_size\",\n display_name=\"Chunk Size\",\n info=\"The maximum number of characters in each chunk.\",\n value=1000,\n ),\n MessageTextInput(\n name=\"separator\",\n display_name=\"Separator\",\n info=\"The character to split on. Defaults to newline.\",\n value=\"\\n\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chunks\", name=\"chunks\", method=\"split_text\"),\n ]\n\n def _docs_to_data(self, docs):\n data = []\n for doc in docs:\n data.append(Data(text=doc.page_content, data=doc.metadata))\n return data\n\n def split_text(self) -> List[Data]:\n separator = unescape_string(self.separator)\n\n documents = []\n for _input in self.data_inputs:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n\n splitter = CharacterTextSplitter(\n chunk_overlap=self.chunk_overlap,\n chunk_size=self.chunk_size,\n separator=separator,\n )\n docs = splitter.split_documents(documents)\n data = self._docs_to_data(docs)\n self.status = data\n return data\n" - }, - "data_inputs": { - "advanced": false, - "display_name": "Data Inputs", - "dynamic": false, - "info": "The data to split.", - "input_types": [ - "Data" - ], - "list": true, - "name": "data_inputs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "separator": { - "advanced": false, - "display_name": "Separator", - "dynamic": false, - "info": "The character to split on. Defaults to newline.", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "separator", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "\n" - } - } - }, - "type": "SplitText" - }, - "dragging": false, - "height": 527, - "id": "SplitText-52wBo", - "position": { - "x": 2044.2799160989089, - "y": 1185.3130355818519 - }, - "positionAbsolute": { - "x": 2044.2799160989089, - "y": 1185.3130355818519 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "File-bf6wn", - "node": { - "base_classes": [ - "Data" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "A generic file loader.", - "display_name": "File", - "documentation": "", - "edited": false, - "field_order": [ - "path", - "silent_errors" - ], - "frozen": false, - "icon": "file-text", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Data", - "hidden": false, - "method": "load_file", - "name": "data", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n" - }, - "path": { - "advanced": false, - "display_name": "Path", - "dynamic": false, - "fileTypes": [ - "txt", - "md", - "mdx", - "csv", - "json", - "yaml", - "yml", - "xml", - "html", - "htm", - "pdf", - "docx", - "py", - "sh", - "sql", - "js", - "ts", - "tsx" - ], - "file_path": "", - "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx", - "list": false, - "name": "path", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "file", - "value": "" - }, - "silent_errors": { - "advanced": true, - "display_name": "Silent Errors", - "dynamic": false, - "info": "If true, errors will not raise an exception.", - "list": false, - "name": "silent_errors", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - } - } - }, - "type": "File" - }, - "dragging": false, - "height": 300, - "id": "File-bf6wn", - "position": { - "x": 1418.981990122179, - "y": 1539.3825691184466 - }, - "positionAbsolute": { - "x": 1418.981990122179, - "y": 1539.3825691184466 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "AstraDB-vyd5U", - "node": { - "base_classes": [ - "Data", - "Retriever" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Implementation of Vector Store using Astra DB with search capabilities", - "display_name": "Astra DB", - "documentation": "https://python.langchain.com/docs/integrations/vectorstores/astradb", - "edited": false, - "field_order": [ - "collection_name", - "token", - "api_endpoint", - "search_input", - "ingest_data", - "namespace", - "metric", - "batch_size", - "bulk_insert_batch_concurrency", - "bulk_insert_overwrite_concurrency", - "bulk_delete_concurrency", - "setup_mode", - "pre_delete_collection", - "metadata_indexing_include", - "embedding", - "metadata_indexing_exclude", - "collection_indexing_policy", - "search_type", - "number_of_results" - ], - "frozen": false, - "icon": "AstraDB", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Retriever", - "method": "build_base_retriever", - "name": "base_retriever", - "selected": "Retriever", - "types": [ - "Retriever" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Search Results", - "method": "search_documents", - "name": "search_results", - "selected": "Data", - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "api_endpoint": { - "advanced": false, - "display_name": "API Endpoint", - "dynamic": false, - "info": "API endpoint URL for the Astra DB service.", - "input_types": [], - "load_from_db": false, - "name": "api_endpoint", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "batch_size": { - "advanced": true, - "display_name": "Batch Size", - "dynamic": false, - "info": "Optional number of data to process in a single batch.", - "list": false, - "name": "batch_size", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "bulk_delete_concurrency": { - "advanced": true, - "display_name": "Bulk Delete Concurrency", - "dynamic": false, - "info": "Optional concurrency level for bulk delete operations.", - "list": false, - "name": "bulk_delete_concurrency", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "bulk_insert_batch_concurrency": { - "advanced": true, - "display_name": "Bulk Insert Batch Concurrency", - "dynamic": false, - "info": "Optional concurrency level for bulk insert operations.", - "list": false, - "name": "bulk_insert_batch_concurrency", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "bulk_insert_overwrite_concurrency": { - "advanced": true, - "display_name": "Bulk Insert Overwrite Concurrency", - "dynamic": false, - "info": "Optional concurrency level for bulk insert operations that overwrite existing data.", - "list": false, - "name": "bulk_insert_overwrite_concurrency", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n" - }, - "collection_indexing_policy": { - "advanced": true, - "display_name": "Collection Indexing Policy", - "dynamic": false, - "info": "Optional dictionary defining the indexing policy for the collection.", - "list": false, - "load_from_db": false, - "name": "collection_indexing_policy", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "collection_name": { - "advanced": false, - "display_name": "Collection Name", - "dynamic": false, - "info": "The name of the collection within Astra DB where the vectors will be stored.", - "list": false, - "load_from_db": false, - "name": "collection_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "langflow" - }, - "embedding": { - "advanced": false, - "display_name": "Embedding or Astra Vectorize", - "dynamic": false, - "info": "", - "input_types": [ - "Embeddings", - "dict" - ], - "list": false, - "name": "embedding", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "ingest_data": { - "advanced": false, - "display_name": "Ingest Data", - "dynamic": false, - "info": "", - "input_types": [ - "Data" - ], - "list": true, - "name": "ingest_data", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "metadata_indexing_exclude": { - "advanced": true, - "display_name": "Metadata Indexing Exclude", - "dynamic": false, - "info": "Optional list of metadata fields to exclude from the indexing.", - "list": false, - "load_from_db": false, - "name": "metadata_indexing_exclude", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "metadata_indexing_include": { - "advanced": true, - "display_name": "Metadata Indexing Include", - "dynamic": false, - "info": "Optional list of metadata fields to include in the indexing.", - "list": false, - "load_from_db": false, - "name": "metadata_indexing_include", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "metric": { - "advanced": true, - "display_name": "Metric", - "dynamic": false, - "info": "Optional distance metric for vector comparisons in the vector store.", - "name": "metric", - "options": [ - "cosine", - "dot_product", - "euclidean" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "namespace": { - "advanced": true, - "display_name": "Namespace", - "dynamic": false, - "info": "Optional namespace within Astra DB to use for the collection.", - "list": false, - "load_from_db": false, - "name": "namespace", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "number_of_results": { - "advanced": true, - "display_name": "Number of Results", - "dynamic": false, - "info": "Number of results to return.", - "list": false, - "name": "number_of_results", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 4 - }, - "pre_delete_collection": { - "advanced": true, - "display_name": "Pre Delete Collection", - "dynamic": false, - "info": "Boolean flag to determine whether to delete the collection before creating a new one.", - "list": false, - "name": "pre_delete_collection", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "search_input": { - "advanced": false, - "display_name": "Search Input", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "search_input", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "search_type": { - "advanced": true, - "display_name": "Search Type", - "dynamic": false, - "info": "", - "name": "search_type", - "options": [ - "Similarity", - "MMR" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Similarity" - }, - "setup_mode": { - "advanced": true, - "display_name": "Setup Mode", - "dynamic": false, - "info": "Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.", - "name": "setup_mode", - "options": [ - "Sync", - "Async", - "Off" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "Sync" - }, - "token": { - "advanced": false, - "display_name": "Astra DB Application Token", - "dynamic": false, - "info": "Authentication token for accessing Astra DB.", - "input_types": [], - "load_from_db": false, - "name": "token", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - } - } - }, - "type": "AstraDB" - }, - "dragging": false, - "height": 753, - "id": "AstraDB-vyd5U", - "position": { - "x": 2676.4816074350247, - "y": 1269.304067004569 - }, - "positionAbsolute": { - "x": 2676.4816074350247, - "y": 1269.304067004569 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIEmbeddings-sRZMc", - "node": { - "base_classes": [ - "Embeddings" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Generate embeddings using OpenAI models.", - "display_name": "OpenAI Embeddings", - "documentation": "", - "edited": false, - "field_order": [ - "default_headers", - "default_query", - "chunk_size", - "client", - "deployment", - "embedding_ctx_length", - "max_retries", - "model", - "model_kwargs", - "openai_api_base", - "openai_api_key", - "openai_api_type", - "openai_api_version", - "openai_organization", - "openai_proxy", - "request_timeout", - "show_progress_bar", - "skip_empty", - "tiktoken_model_name", - "tiktoken_enable" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [], - "outputs": [ - { - "cache": true, - "display_name": "Embeddings", - "hidden": false, - "method": "build_embeddings", - "name": "embeddings", - "selected": "Embeddings", - "types": [ - "Embeddings" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "chunk_size": { - "advanced": true, - "display_name": "Chunk Size", - "dynamic": false, - "info": "", - "list": false, - "name": "chunk_size", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1000 - }, - "client": { - "advanced": true, - "display_name": "Client", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "client", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n" - }, - "default_headers": { - "advanced": true, - "display_name": "Default Headers", - "dynamic": false, - "info": "Default headers to use for the API request.", - "list": false, - "name": "default_headers", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "default_query": { - "advanced": true, - "display_name": "Default Query", - "dynamic": false, - "info": "Default query parameters to use for the API request.", - "list": false, - "name": "default_query", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "deployment": { - "advanced": true, - "display_name": "Deployment", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "deployment", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "embedding_ctx_length": { - "advanced": true, - "display_name": "Embedding Context Length", - "dynamic": false, - "info": "", - "list": false, - "name": "embedding_ctx_length", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 1536 - }, - "max_retries": { - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "", - "list": false, - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "value": 3 - }, - "model": { - "advanced": false, - "display_name": "Model", - "dynamic": false, - "info": "", - "name": "model", - "options": [ - "text-embedding-3-small", - "text-embedding-3-large", - "text-embedding-ada-002" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "str", - "value": "text-embedding-3-small" - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "", - "list": false, - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "", - "input_types": [], - "load_from_db": true, - "name": "openai_api_base", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "", - "input_types": [], - "load_from_db": false, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "openai_api_type": { - "advanced": true, - "display_name": "OpenAI API Type", - "dynamic": false, - "info": "", - "input_types": [], - "load_from_db": true, - "name": "openai_api_type", - "password": true, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "openai_api_version": { - "advanced": true, - "display_name": "OpenAI API Version", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "openai_api_version", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_organization": { - "advanced": true, - "display_name": "OpenAI Organization", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "openai_organization", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "openai_proxy": { - "advanced": true, - "display_name": "OpenAI Proxy", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "openai_proxy", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "request_timeout": { - "advanced": true, - "display_name": "Request Timeout", - "dynamic": false, - "info": "", - "list": false, - "name": "request_timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "float", - "value": "" - }, - "show_progress_bar": { - "advanced": true, - "display_name": "Show Progress Bar", - "dynamic": false, - "info": "", - "list": false, - "name": "show_progress_bar", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "skip_empty": { - "advanced": true, - "display_name": "Skip Empty", - "dynamic": false, - "info": "", - "list": false, - "name": "skip_empty", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "tiktoken_enable": { - "advanced": true, - "display_name": "TikToken Enable", - "dynamic": false, - "info": "If False, you must have transformers installed.", - "list": false, - "name": "tiktoken_enable", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "bool", - "value": true - }, - "tiktoken_model_name": { - "advanced": true, - "display_name": "TikToken Model Name", - "dynamic": false, - "info": "", - "input_types": [ - "Message" - ], - "list": false, - "load_from_db": false, - "name": "tiktoken_model_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - }, - "type": "OpenAIEmbeddings" - }, - "dragging": false, - "height": 394, - "id": "OpenAIEmbeddings-sRZMc", - "position": { - "x": 2050.0569098721217, - "y": 1823.5240486490072 - }, - "positionAbsolute": { - "x": 2050.0569098721217, - "y": 1823.5240486490072 - }, - "selected": false, - "type": "genericNode", - "width": 384 - } - ], - "viewport": { - "x": -108.04801490857153, - "y": -44.38043074355511, - "zoom": 0.32281188532359256 - } - }, - "description": "Visit https://docs.langflow.org/tutorials/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", - "endpoint_name": null, - "id": "7804e4a4-8e16-45e0-88ab-ed6248daa0eb", - "is_component": false, - "last_tested_version": "1.0.0rc1", - "name": "Vector Store RAG" -} \ No newline at end of file +{"id":"f1a53ec2-49e2-4029-b8a8-1a73079f9653","data":{"nodes":[{"data":{"id":"ChatInput-tuEeg","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-tuEeg","position":{"x":642.3545710150049,"y":220.22556606238678},"positionAbsolute":{"x":642.3545710150049,"y":220.22556606238678},"selected":false,"type":"genericNode","width":384},{"data":{"id":"AstraDB-xVF1f","node":{"base_classes":["Data","Retriever"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Implementation of Vector Store using Astra DB with search capabilities","display_name":"Astra DB","documentation":"https://python.langchain.com/docs/integrations/vectorstores/astradb","edited":false,"field_order":["collection_name","token","api_endpoint","search_input","ingest_data","namespace","metric","batch_size","bulk_insert_batch_concurrency","bulk_insert_overwrite_concurrency","bulk_delete_concurrency","setup_mode","pre_delete_collection","metadata_indexing_include","embedding","metadata_indexing_exclude","collection_indexing_policy","search_type","number_of_results"],"frozen":false,"icon":"AstraDB","output_types":[],"outputs":[{"cache":true,"display_name":"Retriever","method":"build_base_retriever","name":"base_retriever","selected":"Retriever","types":["Retriever"],"value":"__UNDEFINED__"},{"cache":true,"display_name":"Search Results","hidden":false,"method":"search_documents","name":"search_results","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","api_endpoint":{"advanced":false,"display_name":"API Endpoint","dynamic":false,"info":"API endpoint URL for the Astra DB service.","input_types":[],"load_from_db":false,"name":"api_endpoint","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"batch_size":{"advanced":true,"display_name":"Batch Size","dynamic":false,"info":"Optional number of data to process in a single batch.","list":false,"name":"batch_size","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_delete_concurrency":{"advanced":true,"display_name":"Bulk Delete Concurrency","dynamic":false,"info":"Optional concurrency level for bulk delete operations.","list":false,"name":"bulk_delete_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_batch_concurrency":{"advanced":true,"display_name":"Bulk Insert Batch Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations.","list":false,"name":"bulk_insert_batch_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_overwrite_concurrency":{"advanced":true,"display_name":"Bulk Insert Overwrite Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations that overwrite existing data.","list":false,"name":"bulk_insert_overwrite_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n"},"collection_indexing_policy":{"advanced":true,"display_name":"Collection Indexing Policy","dynamic":false,"info":"Optional dictionary defining the indexing policy for the collection.","list":false,"load_from_db":false,"name":"collection_indexing_policy","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"collection_name":{"advanced":false,"display_name":"Collection Name","dynamic":false,"info":"The name of the collection within Astra DB where the vectors will be stored.","list":false,"load_from_db":false,"name":"collection_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"langflow"},"embedding":{"advanced":false,"display_name":"Embedding or Astra Vectorize","dynamic":false,"info":"","input_types":["Embeddings","dict"],"list":false,"name":"embedding","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"other","value":""},"ingest_data":{"advanced":false,"display_name":"Ingest Data","dynamic":false,"info":"","input_types":["Data"],"list":true,"name":"ingest_data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"metadata_indexing_exclude":{"advanced":true,"display_name":"Metadata Indexing Exclude","dynamic":false,"info":"Optional list of metadata fields to exclude from the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_exclude","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metadata_indexing_include":{"advanced":true,"display_name":"Metadata Indexing Include","dynamic":false,"info":"Optional list of metadata fields to include in the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_include","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metric":{"advanced":true,"display_name":"Metric","dynamic":false,"info":"Optional distance metric for vector comparisons in the vector store.","name":"metric","options":["cosine","dot_product","euclidean"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"namespace":{"advanced":true,"display_name":"Namespace","dynamic":false,"info":"Optional namespace within Astra DB to use for the collection.","list":false,"load_from_db":false,"name":"namespace","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"number_of_results":{"advanced":true,"display_name":"Number of Results","dynamic":false,"info":"Number of results to return.","list":false,"name":"number_of_results","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":4},"pre_delete_collection":{"advanced":true,"display_name":"Pre Delete Collection","dynamic":false,"info":"Boolean flag to determine whether to delete the collection before creating a new one.","list":false,"name":"pre_delete_collection","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false},"search_input":{"advanced":false,"display_name":"Search Input","dynamic":false,"info":"","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"search_input","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"search_type":{"advanced":true,"display_name":"Search Type","dynamic":false,"info":"","name":"search_type","options":["Similarity","MMR"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Similarity"},"setup_mode":{"advanced":true,"display_name":"Setup Mode","dynamic":false,"info":"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.","name":"setup_mode","options":["Sync","Async","Off"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Sync"},"token":{"advanced":false,"display_name":"Astra DB Application Token","dynamic":false,"info":"Authentication token for accessing Astra DB.","input_types":[],"load_from_db":false,"name":"token","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"AstraDB"},"dragging":false,"height":753,"id":"AstraDB-xVF1f","position":{"x":1246.0381406498648,"y":333.25157075413966},"positionAbsolute":{"x":1246.0381406498648,"y":333.25157075413966},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ParseData-ZG3Aa","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Convert Data into plain text following a specified template.","display_name":"Parse Data","documentation":"","edited":false,"field_order":["data","template","sep"],"frozen":false,"icon":"braces","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"parse_data","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n"},"data":{"advanced":false,"display_name":"Data","dynamic":false,"info":"The data to convert to text.","input_types":["Data"],"list":false,"name":"data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"sep":{"advanced":true,"display_name":"Separator","dynamic":false,"info":"","list":false,"load_from_db":false,"name":"sep","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"}}},"type":"ParseData"},"dragging":false,"height":384,"id":"ParseData-ZG3Aa","position":{"x":1854.1518317915907,"y":459.3386924128532},"positionAbsolute":{"x":1854.1518317915907,"y":459.3386924128532},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-0Hp9v","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["context","question"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"context":{"advanced":false,"display_name":"context","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"context","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"question":{"advanced":false,"display_name":"question","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"question","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: "}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-0Hp9v","position":{"x":2486.0988668404975,"y":496.5120474157301},"positionAbsolute":{"x":2486.0988668404975,"y":496.5120474157301},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-BQXFs","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-BQXFs","position":{"x":3145.6693008609222,"y":374.23955005474204},"positionAbsolute":{"x":3145.6693008609222,"y":374.23955005474204},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-fDyGT","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-fDyGT","position":{"x":3769.242086248817,"y":585.3403837062634},"positionAbsolute":{"x":3769.242086248817,"y":585.3403837062634},"selected":false,"type":"genericNode","width":384},{"data":{"id":"SplitText-RkdZ3","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Split text into chunks based on specified criteria.","display_name":"Split Text","documentation":"","edited":false,"field_order":["data_inputs","chunk_overlap","chunk_size","separator"],"frozen":false,"icon":"scissors-line-dashed","output_types":[],"outputs":[{"cache":true,"display_name":"Chunks","hidden":false,"method":"split_text","name":"chunks","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","chunk_overlap":{"advanced":false,"display_name":"Chunk Overlap","dynamic":false,"info":"Number of characters to overlap between chunks.","list":false,"name":"chunk_overlap","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":200},"chunk_size":{"advanced":false,"display_name":"Chunk Size","dynamic":false,"info":"The maximum number of characters in each chunk.","list":false,"name":"chunk_size","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":1000},"code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from typing import List\n\nfrom langchain_text_splitters import CharacterTextSplitter\n\nfrom langflow.custom import Component\nfrom langflow.io import HandleInput, IntInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.utils.util import unescape_string\n\n\nclass SplitTextComponent(Component):\n display_name: str = \"Split Text\"\n description: str = \"Split text into chunks based on specified criteria.\"\n icon = \"scissors-line-dashed\"\n\n inputs = [\n HandleInput(\n name=\"data_inputs\",\n display_name=\"Data Inputs\",\n info=\"The data to split.\",\n input_types=[\"Data\"],\n is_list=True,\n ),\n IntInput(\n name=\"chunk_overlap\",\n display_name=\"Chunk Overlap\",\n info=\"Number of characters to overlap between chunks.\",\n value=200,\n ),\n IntInput(\n name=\"chunk_size\",\n display_name=\"Chunk Size\",\n info=\"The maximum number of characters in each chunk.\",\n value=1000,\n ),\n MessageTextInput(\n name=\"separator\",\n display_name=\"Separator\",\n info=\"The character to split on. Defaults to newline.\",\n value=\"\\n\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chunks\", name=\"chunks\", method=\"split_text\"),\n ]\n\n def _docs_to_data(self, docs):\n data = []\n for doc in docs:\n data.append(Data(text=doc.page_content, data=doc.metadata))\n return data\n\n def split_text(self) -> List[Data]:\n separator = unescape_string(self.separator)\n\n documents = []\n for _input in self.data_inputs:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n\n splitter = CharacterTextSplitter(\n chunk_overlap=self.chunk_overlap,\n chunk_size=self.chunk_size,\n separator=separator,\n )\n docs = splitter.split_documents(documents)\n data = self._docs_to_data(docs)\n self.status = data\n return data\n"},"data_inputs":{"advanced":false,"display_name":"Data Inputs","dynamic":false,"info":"The data to split.","input_types":["Data"],"list":true,"name":"data_inputs","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"other","value":""},"separator":{"advanced":false,"display_name":"Separator","dynamic":false,"info":"The character to split on. Defaults to newline.","input_types":["Message"],"list":false,"load_from_db":false,"name":"separator","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"\n"}}},"type":"SplitText"},"dragging":false,"height":527,"id":"SplitText-RkdZ3","position":{"x":2044.2799160989089,"y":1185.3130355818519},"positionAbsolute":{"x":2044.2799160989089,"y":1185.3130355818519},"selected":false,"type":"genericNode","width":384},{"data":{"id":"File-BTJVJ","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"A generic file loader.","display_name":"File","documentation":"","edited":false,"field_order":["path","silent_errors"],"frozen":false,"icon":"file-text","output_types":[],"outputs":[{"cache":true,"display_name":"Data","hidden":false,"method":"load_file","name":"data","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n"},"path":{"advanced":false,"display_name":"Path","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx"],"file_path":"","info":"Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx","list":false,"name":"path","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"silent_errors":{"advanced":true,"display_name":"Silent Errors","dynamic":false,"info":"If true, errors will not raise an exception.","list":false,"name":"silent_errors","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false}}},"type":"File"},"dragging":false,"height":300,"id":"File-BTJVJ","position":{"x":1418.981990122179,"y":1539.3825691184466},"positionAbsolute":{"x":1418.981990122179,"y":1539.3825691184466},"selected":false,"type":"genericNode","width":384},{"data":{"id":"AstraDB-XXizY","node":{"base_classes":["Data","Retriever"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Implementation of Vector Store using Astra DB with search capabilities","display_name":"Astra DB","documentation":"https://python.langchain.com/docs/integrations/vectorstores/astradb","edited":false,"field_order":["collection_name","token","api_endpoint","search_input","ingest_data","namespace","metric","batch_size","bulk_insert_batch_concurrency","bulk_insert_overwrite_concurrency","bulk_delete_concurrency","setup_mode","pre_delete_collection","metadata_indexing_include","embedding","metadata_indexing_exclude","collection_indexing_policy","search_type","number_of_results"],"frozen":false,"icon":"AstraDB","output_types":[],"outputs":[{"cache":true,"display_name":"Retriever","method":"build_base_retriever","name":"base_retriever","selected":"Retriever","types":["Retriever"],"value":"__UNDEFINED__"},{"cache":true,"display_name":"Search Results","method":"search_documents","name":"search_results","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","api_endpoint":{"advanced":false,"display_name":"API Endpoint","dynamic":false,"info":"API endpoint URL for the Astra DB service.","input_types":[],"load_from_db":false,"name":"api_endpoint","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"batch_size":{"advanced":true,"display_name":"Batch Size","dynamic":false,"info":"Optional number of data to process in a single batch.","list":false,"name":"batch_size","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_delete_concurrency":{"advanced":true,"display_name":"Bulk Delete Concurrency","dynamic":false,"info":"Optional concurrency level for bulk delete operations.","list":false,"name":"bulk_delete_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_batch_concurrency":{"advanced":true,"display_name":"Bulk Insert Batch Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations.","list":false,"name":"bulk_insert_batch_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_overwrite_concurrency":{"advanced":true,"display_name":"Bulk Insert Overwrite Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations that overwrite existing data.","list":false,"name":"bulk_insert_overwrite_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n"},"collection_indexing_policy":{"advanced":true,"display_name":"Collection Indexing Policy","dynamic":false,"info":"Optional dictionary defining the indexing policy for the collection.","list":false,"load_from_db":false,"name":"collection_indexing_policy","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"collection_name":{"advanced":false,"display_name":"Collection Name","dynamic":false,"info":"The name of the collection within Astra DB where the vectors will be stored.","list":false,"load_from_db":false,"name":"collection_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"langflow"},"embedding":{"advanced":false,"display_name":"Embedding or Astra Vectorize","dynamic":false,"info":"","input_types":["Embeddings","dict"],"list":false,"name":"embedding","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"other","value":""},"ingest_data":{"advanced":false,"display_name":"Ingest Data","dynamic":false,"info":"","input_types":["Data"],"list":true,"name":"ingest_data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"metadata_indexing_exclude":{"advanced":true,"display_name":"Metadata Indexing Exclude","dynamic":false,"info":"Optional list of metadata fields to exclude from the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_exclude","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metadata_indexing_include":{"advanced":true,"display_name":"Metadata Indexing Include","dynamic":false,"info":"Optional list of metadata fields to include in the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_include","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metric":{"advanced":true,"display_name":"Metric","dynamic":false,"info":"Optional distance metric for vector comparisons in the vector store.","name":"metric","options":["cosine","dot_product","euclidean"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"namespace":{"advanced":true,"display_name":"Namespace","dynamic":false,"info":"Optional namespace within Astra DB to use for the collection.","list":false,"load_from_db":false,"name":"namespace","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"number_of_results":{"advanced":true,"display_name":"Number of Results","dynamic":false,"info":"Number of results to return.","list":false,"name":"number_of_results","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":4},"pre_delete_collection":{"advanced":true,"display_name":"Pre Delete Collection","dynamic":false,"info":"Boolean flag to determine whether to delete the collection before creating a new one.","list":false,"name":"pre_delete_collection","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false},"search_input":{"advanced":false,"display_name":"Search Input","dynamic":false,"info":"","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"search_input","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"search_type":{"advanced":true,"display_name":"Search Type","dynamic":false,"info":"","name":"search_type","options":["Similarity","MMR"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Similarity"},"setup_mode":{"advanced":true,"display_name":"Setup Mode","dynamic":false,"info":"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.","name":"setup_mode","options":["Sync","Async","Off"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Sync"},"token":{"advanced":false,"display_name":"Astra DB Application Token","dynamic":false,"info":"Authentication token for accessing Astra DB.","input_types":[],"load_from_db":false,"name":"token","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"AstraDB"},"dragging":false,"height":753,"id":"AstraDB-XXizY","position":{"x":2676.4816074350247,"y":1269.304067004569},"positionAbsolute":{"x":2676.4816074350247,"y":1269.304067004569},"selected":false,"type":"genericNode","width":384},{"id":"OpenAIEmbeddings-fpOKp","type":"genericNode","position":{"x":2044.683126356786,"y":1785.2283494456522},"data":{"type":"OpenAIEmbeddings","node":{"template":{"_type":"Component","chunk_size":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1000,"name":"chunk_size","display_name":"Chunk Size","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"client":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"client","display_name":"Client","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\", value=\"OPENAI_API_KEY\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"default_headers":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_headers","display_name":"Default Headers","advanced":true,"dynamic":false,"info":"Default headers to use for the API request.","title_case":false,"type":"dict"},"default_query":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_query","display_name":"Default Query","advanced":true,"dynamic":false,"info":"Default query parameters to use for the API request.","title_case":false,"type":"dict"},"deployment":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"deployment","display_name":"Deployment","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"embedding_ctx_length":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1536,"name":"embedding_ctx_length","display_name":"Embedding Context Length","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"max_retries":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":3,"name":"max_retries","display_name":"Max Retries","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"model":{"trace_as_metadata":true,"options":["text-embedding-3-small","text-embedding-3-large","text-embedding-ada-002"],"required":false,"placeholder":"","show":true,"value":"text-embedding-3-small","name":"model","display_name":"Model","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"openai_api_base":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_type":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_type","display_name":"OpenAI API Type","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_version":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_version","display_name":"OpenAI API Version","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_organization":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_organization","display_name":"OpenAI Organization","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_proxy":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_proxy","display_name":"OpenAI Proxy","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"request_timeout":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"request_timeout","display_name":"Request Timeout","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"float"},"show_progress_bar":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"show_progress_bar","display_name":"Show Progress Bar","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"skip_empty":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"skip_empty","display_name":"Skip Empty","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"tiktoken_enable":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":true,"name":"tiktoken_enable","display_name":"TikToken Enable","advanced":true,"dynamic":false,"info":"If False, you must have transformers installed.","title_case":false,"type":"bool"},"tiktoken_model_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"tiktoken_model_name","display_name":"TikToken Model Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"}},"description":"Generate embeddings using OpenAI models.","icon":"OpenAI","base_classes":["Embeddings"],"display_name":"OpenAI Embeddings","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Embeddings"],"selected":"Embeddings","name":"embeddings","display_name":"Embeddings","method":"build_embeddings","value":"__UNDEFINED__","cache":true,"hidden":false}],"field_order":["default_headers","default_query","chunk_size","client","deployment","embedding_ctx_length","max_retries","model","model_kwargs","openai_api_base","openai_api_key","openai_api_type","openai_api_version","openai_organization","openai_proxy","request_timeout","show_progress_bar","skip_empty","tiktoken_model_name","tiktoken_enable"],"beta":false,"edited":false},"id":"OpenAIEmbeddings-fpOKp"},"selected":false,"width":384,"height":394,"dragging":false,"positionAbsolute":{"x":2044.683126356786,"y":1785.2283494456522}},{"id":"OpenAIEmbeddings-lCQlU","type":"genericNode","position":{"x":628.9252513328779,"y":648.6750537749285},"data":{"type":"OpenAIEmbeddings","node":{"template":{"_type":"Component","chunk_size":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1000,"name":"chunk_size","display_name":"Chunk Size","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"client":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"client","display_name":"Client","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\", value=\"OPENAI_API_KEY\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"default_headers":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_headers","display_name":"Default Headers","advanced":true,"dynamic":false,"info":"Default headers to use for the API request.","title_case":false,"type":"dict"},"default_query":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_query","display_name":"Default Query","advanced":true,"dynamic":false,"info":"Default query parameters to use for the API request.","title_case":false,"type":"dict"},"deployment":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"deployment","display_name":"Deployment","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"embedding_ctx_length":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1536,"name":"embedding_ctx_length","display_name":"Embedding Context Length","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"max_retries":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":3,"name":"max_retries","display_name":"Max Retries","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"model":{"trace_as_metadata":true,"options":["text-embedding-3-small","text-embedding-3-large","text-embedding-ada-002"],"required":false,"placeholder":"","show":true,"value":"text-embedding-3-small","name":"model","display_name":"Model","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"openai_api_base":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_type":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_type","display_name":"OpenAI API Type","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_version":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_version","display_name":"OpenAI API Version","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_organization":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_organization","display_name":"OpenAI Organization","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_proxy":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_proxy","display_name":"OpenAI Proxy","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"request_timeout":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"request_timeout","display_name":"Request Timeout","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"float"},"show_progress_bar":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"show_progress_bar","display_name":"Show Progress Bar","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"skip_empty":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"skip_empty","display_name":"Skip Empty","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"tiktoken_enable":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":true,"name":"tiktoken_enable","display_name":"TikToken Enable","advanced":true,"dynamic":false,"info":"If False, you must have transformers installed.","title_case":false,"type":"bool"},"tiktoken_model_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"tiktoken_model_name","display_name":"TikToken Model Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"}},"description":"Generate embeddings using OpenAI models.","icon":"OpenAI","base_classes":["Embeddings"],"display_name":"OpenAI Embeddings","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Embeddings"],"selected":"Embeddings","name":"embeddings","display_name":"Embeddings","method":"build_embeddings","value":"__UNDEFINED__","cache":true,"hidden":false}],"field_order":["default_headers","default_query","chunk_size","client","deployment","embedding_ctx_length","max_retries","model","model_kwargs","openai_api_base","openai_api_key","openai_api_type","openai_api_version","openai_organization","openai_proxy","request_timeout","show_progress_bar","skip_empty","tiktoken_model_name","tiktoken_enable"],"beta":false,"edited":false},"id":"OpenAIEmbeddings-lCQlU"},"selected":false,"width":384,"height":394,"positionAbsolute":{"x":628.9252513328779,"y":648.6750537749285},"dragging":false}],"edges":[{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-tuEeg","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"search_input","id":"AstraDB-xVF1f","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-ChatInput-tuEeg{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-xVF1f{œfieldNameœ:œsearch_inputœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"ChatInput-tuEeg","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"AstraDB-xVF1f","targetHandle":"{œfieldNameœ:œsearch_inputœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"AstraDB","id":"AstraDB-xVF1f","name":"search_results","output_types":["Data"]},"targetHandle":{"fieldName":"data","id":"ParseData-ZG3Aa","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-AstraDB-xVF1f{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-xVF1fœ,œnameœ:œsearch_resultsœ,œoutput_typesœ:[œDataœ]}-ParseData-ZG3Aa{œfieldNameœ:œdataœ,œidœ:œParseData-ZG3Aaœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"AstraDB-xVF1f","sourceHandle":"{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-xVF1fœ,œnameœ:œsearch_resultsœ,œoutput_typesœ:[œDataœ]}","target":"ParseData-ZG3Aa","targetHandle":"{œfieldNameœ:œdataœ,œidœ:œParseData-ZG3Aaœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"ParseData","id":"ParseData-ZG3Aa","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"context","id":"Prompt-0Hp9v","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ParseData-ZG3Aa{œdataTypeœ:œParseDataœ,œidœ:œParseData-ZG3Aaœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-0Hp9v{œfieldNameœ:œcontextœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ParseData-ZG3Aa","sourceHandle":"{œdataTypeœ:œParseDataœ,œidœ:œParseData-ZG3Aaœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-0Hp9v","targetHandle":"{œfieldNameœ:œcontextœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-tuEeg","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"question","id":"Prompt-0Hp9v","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-tuEeg{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-0Hp9v{œfieldNameœ:œquestionœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-tuEeg","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-0Hp9v","targetHandle":"{œfieldNameœ:œquestionœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-0Hp9v","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-BQXFs","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-0Hp9v{œdataTypeœ:œPromptœ,œidœ:œPrompt-0Hp9vœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-BQXFs{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BQXFsœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-0Hp9v","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-0Hp9vœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-BQXFs","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BQXFsœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"File","id":"File-BTJVJ","name":"data","output_types":["Data"]},"targetHandle":{"fieldName":"data_inputs","id":"SplitText-RkdZ3","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-File-BTJVJ{œdataTypeœ:œFileœ,œidœ:œFile-BTJVJœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-SplitText-RkdZ3{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-RkdZ3œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"File-BTJVJ","sourceHandle":"{œdataTypeœ:œFileœ,œidœ:œFile-BTJVJœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}","target":"SplitText-RkdZ3","targetHandle":"{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-RkdZ3œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"SplitText","id":"SplitText-RkdZ3","name":"chunks","output_types":["Data"]},"targetHandle":{"fieldName":"ingest_data","id":"AstraDB-XXizY","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-SplitText-RkdZ3{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-RkdZ3œ,œnameœ:œchunksœ,œoutput_typesœ:[œDataœ]}-AstraDB-XXizY{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"SplitText-RkdZ3","sourceHandle":"{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-RkdZ3œ,œnameœ:œchunksœ,œoutput_typesœ:[œDataœ]}","target":"AstraDB-XXizY","targetHandle":"{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"source":"OpenAIModel-BQXFs","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-BQXFsœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-fDyGT","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-fDyGTœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-fDyGT","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-BQXFs","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-BQXFs{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-BQXFsœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-fDyGT{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-fDyGTœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"},{"source":"OpenAIEmbeddings-fpOKp","sourceHandle":"{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-fpOKpœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}","target":"AstraDB-XXizY","targetHandle":"{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}","data":{"targetHandle":{"fieldName":"embedding","id":"AstraDB-XXizY","inputTypes":["Embeddings","dict"],"type":"other"},"sourceHandle":{"dataType":"OpenAIEmbeddings","id":"OpenAIEmbeddings-fpOKp","name":"embeddings","output_types":["Embeddings"]}},"id":"reactflow__edge-OpenAIEmbeddings-fpOKp{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-fpOKpœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-XXizY{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}"},{"source":"OpenAIEmbeddings-lCQlU","sourceHandle":"{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-lCQlUœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}","target":"AstraDB-xVF1f","targetHandle":"{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}","data":{"targetHandle":{"fieldName":"embedding","id":"AstraDB-xVF1f","inputTypes":["Embeddings","dict"],"type":"other"},"sourceHandle":{"dataType":"OpenAIEmbeddings","id":"OpenAIEmbeddings-lCQlU","name":"embeddings","output_types":["Embeddings"]}},"id":"reactflow__edge-OpenAIEmbeddings-lCQlU{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-lCQlUœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-xVF1f{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}"}],"viewport":{"x":-110.08684771034166,"y":-46.27017080984389,"zoom":0.3228119071747796}},"description":"Visit https://docs.langflow.org/tutorials/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.","name":"Vector Store RAG","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file From dad60d0a11f99cf2115ccc09c767d92131c6b573 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Fri, 28 Jun 2024 11:47:54 -0300 Subject: [PATCH 17/22] Formatted flows --- .../Basic Prompting (Hello, World).json | 890 ++++- .../starter_projects/Blog Writer.json | 1093 +++++- .../starter_projects/Document QA.json | 1226 ++++++- .../starter_projects/Memory Chatbot.json | 1146 +++++- .../starter_projects/Vector Store RAG.json | 3202 ++++++++++++++++- 5 files changed, 7552 insertions(+), 5 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 f965913a06f..50f9385acb1 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 @@ -1 +1,889 @@ -{"id":"e533253b-818b-4b5a-9793-55ab83fffb07","data":{"nodes":[{"data":{"id":"ChatInput-Y6mi1","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-Y6mi1","position":{"x":-493.6459512396177,"y":1083.200545525551},"positionAbsolute":{"x":-493.6459512396177,"y":1083.200545525551},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-Z4WYI","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["user_input"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: "},"user_input":{"advanced":false,"display_name":"user_input","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"user_input","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"Prompt"},"dragging":false,"height":422,"id":"Prompt-Z4WYI","position":{"x":56.354011530798516,"y":1157.2005405164796},"positionAbsolute":{"x":56.354011530798516,"y":1157.2005405164796},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-26Eve","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-26Eve","position":{"x":624.3539730827923,"y":1053.2005475562555},"positionAbsolute":{"x":624.3539730827923,"y":1053.2005475562555},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-cQnVI","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-cQnVI","position":{"x":1219.477374823274,"y":1200.950216973985},"positionAbsolute":{"x":1219.477374823274,"y":1200.950216973985},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-Y6mi1","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"user_input","id":"Prompt-Z4WYI","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-Y6mi1{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Y6mi1œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-Z4WYI{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-Z4WYIœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-Y6mi1","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Y6mi1œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-Z4WYI","targetHandle":"{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-Z4WYIœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-Z4WYI","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-26Eve","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-Z4WYI{œdataTypeœ:œPromptœ,œidœ:œPrompt-Z4WYIœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-26Eve{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-26Eveœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-Z4WYI","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-Z4WYIœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-26Eve","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-26Eveœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-26Eve","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-26Eveœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-cQnVI","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cQnVIœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-cQnVI","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-26Eve","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-26Eve{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-26Eveœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-cQnVI{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cQnVIœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":366.93776265249005,"y":-343.56726676261223,"zoom":0.5000000676901587}},"description":"This flow will get you experimenting with the basics of the UI, the Chat and the Prompt component. \n\nTry changing the Template in it to see how the model behaves. \nYou can change it to this and a Text Input into the `type_of_person` variable : \"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: \" ","name":"Basic Prompting (Hello, World)","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file +{ + "data": { + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-Y6mi1", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "user_input", + "id": "Prompt-Z4WYI", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-Y6mi1{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Y6mi1œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-Z4WYI{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-Z4WYIœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ChatInput-Y6mi1", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-Y6mi1œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-Z4WYI", + "targetHandle": "{œfieldNameœ: œuser_inputœ, œidœ: œPrompt-Z4WYIœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-Z4WYI", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-26Eve", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-Z4WYI{œdataTypeœ:œPromptœ,œidœ:œPrompt-Z4WYIœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-26Eve{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-26Eveœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-Z4WYI", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Z4WYIœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-26Eve", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-26Eveœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIModelComponent", + "id": "OpenAIModel-26Eve", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-cQnVI", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-26Eve{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-26Eveœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-cQnVI{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cQnVIœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-26Eve", + "sourceHandle": "{œdataTypeœ: œOpenAIModelComponentœ, œidœ: œOpenAIModel-26Eveœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-cQnVI", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-cQnVIœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], + "nodes": [ + { + "data": { + "id": "ChatInput-Y6mi1", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Get chat inputs from the Playground.", + "display_name": "Chat Input", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "files" + ], + "frozen": false, + "icon": "ChatInput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "hidden": false, + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "files": { + "advanced": true, + "display_name": "Files", + "dynamic": false, + "fileTypes": [ + "txt", + "md", + "mdx", + "csv", + "json", + "yaml", + "yml", + "xml", + "html", + "htm", + "pdf", + "docx", + "py", + "sh", + "sql", + "js", + "ts", + "tsx", + "jpg", + "jpeg", + "png", + "bmp", + "image" + ], + "file_path": "", + "info": "Files to be sent with the message.", + "list": true, + "name": "files", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "file", + "value": "" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as input.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatInput" + }, + "dragging": false, + "height": 308, + "id": "ChatInput-Y6mi1", + "position": { + "x": -493.6459512396177, + "y": 1083.200545525551 + }, + "positionAbsolute": { + "x": -493.6459512396177, + "y": 1083.200545525551 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-Z4WYI", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": { + "template": [ + "user_input" + ] + }, + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "documentation": "", + "edited": false, + "error": null, + "field_order": [ + "template" + ], + "frozen": false, + "full_path": null, + "icon": "prompts", + "is_composition": null, + "is_input": null, + "is_output": null, + "name": "", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Prompt Message", + "hidden": false, + "method": "build_prompt", + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "", + "list": false, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "prompt", + "value": "Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: " + }, + "user_input": { + "advanced": false, + "display_name": "user_input", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "user_input", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + } + } + }, + "type": "Prompt" + }, + "dragging": false, + "height": 422, + "id": "Prompt-Z4WYI", + "position": { + "x": 56.354011530798516, + "y": 1157.2005405164796 + }, + "positionAbsolute": { + "x": 56.354011530798516, + "y": 1157.2005405164796 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "edited": false, + "id": "OpenAIModel-26Eve", + "node": { + "base_classes": [ + "LanguageModel", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "edited": true, + "field_order": [ + "input_value", + "max_tokens", + "model_kwargs", + "json_mode", + "output_schema", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "stream", + "system_message", + "seed" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "text_response", + "name": "text_output", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Language Model", + "method": "build_model", + "name": "model_output", + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "json_mode": { + "advanced": true, + "display_name": "JSON Mode", + "dynamic": false, + "info": "If True, it will output JSON regardless of passing a schema.", + "list": false, + "name": "json_mode", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "name": "max_tokens", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "info": "", + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "gpt-4-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", + "list": false, + "load_from_db": false, + "name": "openai_api_base", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "output_schema": { + "advanced": true, + "display_name": "Schema", + "dynamic": false, + "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", + "list": true, + "name": "output_schema", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "seed": { + "advanced": true, + "display_name": "Seed", + "dynamic": false, + "info": "The seed controls the reproducibility of the job.", + "list": false, + "name": "seed", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1 + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "name": "stream", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "info": "System message to pass to the model.", + "list": false, + "load_from_db": false, + "name": "system_message", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "info": "", + "list": false, + "name": "temperature", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": 0.1 + } + } + }, + "type": "OpenAIModelComponent" + }, + "dragging": false, + "height": 621, + "id": "OpenAIModel-26Eve", + "position": { + "x": 624.3539730827923, + "y": 1053.2005475562555 + }, + "positionAbsolute": { + "x": 624.3539730827923, + "y": 1053.2005475562555 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatOutput-cQnVI", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "data_template" + ], + "frozen": false, + "icon": "ChatOutput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "data_template": { + "advanced": true, + "display_name": "Data Template", + "dynamic": false, + "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "data_template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as output.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 308, + "id": "ChatOutput-cQnVI", + "position": { + "x": 1219.477374823274, + "y": 1200.950216973985 + }, + "positionAbsolute": { + "x": 1219.477374823274, + "y": 1200.950216973985 + }, + "selected": false, + "type": "genericNode", + "width": 384 + } + ], + "viewport": { + "x": 366.93776265249005, + "y": -343.56726676261223, + "zoom": 0.5000000676901587 + } + }, + "description": "This flow will get you experimenting with the basics of the UI, the Chat and the Prompt component. \n\nTry changing the Template in it to see how the model behaves. \nYou can change it to this and a Text Input into the `type_of_person` variable : \"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: \" ", + "endpoint_name": null, + "id": "e533253b-818b-4b5a-9793-55ab83fffb07", + "is_component": false, + "last_tested_version": "1.0.5", + "name": "Basic Prompting (Hello, World)" +} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index 09378592eb7..7828ac5854d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -1 +1,1092 @@ -{"id":"da9999f8-9013-4bd9-8adb-653c94ebf08c","data":{"nodes":[{"data":{"id":"URL-rETJU","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Fetch content from one or more URLs.","display_name":"URL","documentation":"","edited":false,"field_order":["urls"],"frozen":false,"icon":"layout-template","output_types":[],"outputs":[{"cache":true,"display_name":"Data","hidden":false,"method":"fetch_content","name":"data","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"import re\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema import Data\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"},"urls":{"advanced":false,"display_name":"URLs","dynamic":false,"info":"Enter one or more URLs, separated by commas.","input_types":["Message"],"list":true,"load_from_db":false,"name":"urls","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":["langflow.org/","docs.langflow.org/"]}}},"type":"URL"},"dragging":false,"height":358,"id":"URL-rETJU","position":{"x":220.79156431407534,"y":498.8186168722667},"positionAbsolute":{"x":220.79156431407534,"y":498.8186168722667},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ParseData-AqSfN","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Convert Data into plain text following a specified template.","display_name":"Parse Data","documentation":"","edited":false,"field_order":["data","template","sep"],"frozen":false,"icon":"braces","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"parse_data","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n"},"data":{"advanced":false,"display_name":"Data","dynamic":false,"info":"The data to convert to text.","input_types":["Data"],"list":false,"name":"data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"sep":{"advanced":true,"display_name":"Separator","dynamic":false,"info":"","list":false,"load_from_db":false,"name":"sep","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"}}},"type":"ParseData"},"dragging":false,"height":384,"id":"ParseData-AqSfN","position":{"x":754.3607306709101,"y":736.8516961537598},"positionAbsolute":{"x":754.3607306709101,"y":736.8516961537598},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-rizUK","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["references","instructions"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"instructions":{"advanced":false,"display_name":"instructions","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"instructions","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"references":{"advanced":false,"display_name":"references","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"references","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"Reference 1:\n\n{references}\n\n---\n\n{instructions}\n\nBlog: \n\n"}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-rizUK","position":{"x":1368.0633591447076,"y":467.19448061224284},"positionAbsolute":{"x":1368.0633591447076,"y":467.19448061224284},"selected":false,"type":"genericNode","width":384},{"data":{"id":"TextInput-OffFR","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get text inputs from the Playground.","display_name":"Instructions","documentation":"","edited":false,"field_order":["input_value"],"frozen":false,"icon":"type","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"text_response","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.text import TextComponent\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n message = Message(\n text=self.input_value,\n )\n return message\n"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Text to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"Use the references above for style to write a new blog/tutorial about Langflow and AI. Suggest non-covered topics."}}},"type":"TextInput"},"dragging":false,"height":308,"id":"TextInput-OffFR","position":{"x":743.7338453293725,"y":301.58775454952183},"positionAbsolute":{"x":743.7338453293725,"y":301.58775454952183},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-qmhKV","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-qmhKV","position":{"x":1899.407626221589,"y":395.9013619556682},"positionAbsolute":{"x":1899.407626221589,"y":395.9013619556682},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-W684s","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-W684s","position":{"x":2449.3489426461606,"y":571.2449700910389},"positionAbsolute":{"x":2449.3489426461606,"y":571.2449700910389},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"URL","id":"URL-rETJU","name":"data","output_types":["Data"]},"targetHandle":{"fieldName":"data","id":"ParseData-AqSfN","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-URL-rETJU{œdataTypeœ:œURLœ,œidœ:œURL-rETJUœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-AqSfN{œfieldNameœ:œdataœ,œidœ:œParseData-AqSfNœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"URL-rETJU","sourceHandle":"{œdataTypeœ:œURLœ,œidœ:œURL-rETJUœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}","target":"ParseData-AqSfN","targetHandle":"{œfieldNameœ:œdataœ,œidœ:œParseData-AqSfNœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"ParseData","id":"ParseData-AqSfN","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"references","id":"Prompt-rizUK","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ParseData-AqSfN{œdataTypeœ:œParseDataœ,œidœ:œParseData-AqSfNœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-rizUK{œfieldNameœ:œreferencesœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ParseData-AqSfN","sourceHandle":"{œdataTypeœ:œParseDataœ,œidœ:œParseData-AqSfNœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-rizUK","targetHandle":"{œfieldNameœ:œreferencesœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"TextInput","id":"TextInput-OffFR","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"instructions","id":"Prompt-rizUK","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-TextInput-OffFR{œdataTypeœ:œTextInputœ,œidœ:œTextInput-OffFRœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-rizUK{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"TextInput-OffFR","sourceHandle":"{œdataTypeœ:œTextInputœ,œidœ:œTextInput-OffFRœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-rizUK","targetHandle":"{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-rizUK","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-qmhKV","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-rizUK{œdataTypeœ:œPromptœ,œidœ:œPrompt-rizUKœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-qmhKV{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-qmhKVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-rizUK","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-rizUKœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-qmhKV","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-qmhKVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-qmhKV","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-qmhKVœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-W684s","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-W684sœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-W684s","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-qmhKV","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-qmhKV{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-qmhKVœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-W684s{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-W684sœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":-63.94787944982488,"y":-16.004163894553585,"zoom":0.47423908935061165}},"description":"This flow can be used to create a blog post following instructions from the user, using two other blogs as reference.","name":"Blog Writer","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file +{ + "data": { + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "URL", + "id": "URL-rETJU", + "name": "data", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "data", + "id": "ParseData-AqSfN", + "inputTypes": [ + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-URL-rETJU{œdataTypeœ:œURLœ,œidœ:œURL-rETJUœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-AqSfN{œfieldNameœ:œdataœ,œidœ:œParseData-AqSfNœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", + "source": "URL-rETJU", + "sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-rETJUœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}", + "target": "ParseData-AqSfN", + "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-AqSfNœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ParseData", + "id": "ParseData-AqSfN", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "references", + "id": "Prompt-rizUK", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ParseData-AqSfN{œdataTypeœ:œParseDataœ,œidœ:œParseData-AqSfNœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-rizUK{œfieldNameœ:œreferencesœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ParseData-AqSfN", + "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-AqSfNœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-rizUK", + "targetHandle": "{œfieldNameœ: œreferencesœ, œidœ: œPrompt-rizUKœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "TextInput", + "id": "TextInput-OffFR", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "instructions", + "id": "Prompt-rizUK", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-TextInput-OffFR{œdataTypeœ:œTextInputœ,œidœ:œTextInput-OffFRœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-rizUK{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-rizUKœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "TextInput-OffFR", + "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-OffFRœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-rizUK", + "targetHandle": "{œfieldNameœ: œinstructionsœ, œidœ: œPrompt-rizUKœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-rizUK", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-qmhKV", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-rizUK{œdataTypeœ:œPromptœ,œidœ:œPrompt-rizUKœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-qmhKV{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-qmhKVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-rizUK", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-rizUKœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-qmhKV", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-qmhKVœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIModelComponent", + "id": "OpenAIModel-qmhKV", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-W684s", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-qmhKV{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-qmhKVœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-W684s{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-W684sœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-qmhKV", + "sourceHandle": "{œdataTypeœ: œOpenAIModelComponentœ, œidœ: œOpenAIModel-qmhKVœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-W684s", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-W684sœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], + "nodes": [ + { + "data": { + "id": "URL-rETJU", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Fetch content from one or more URLs.", + "display_name": "URL", + "documentation": "", + "edited": false, + "field_order": [ + "urls" + ], + "frozen": false, + "icon": "layout-template", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "hidden": false, + "method": "fetch_content", + "name": "data", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import re\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema import Data\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n" + }, + "urls": { + "advanced": false, + "display_name": "URLs", + "dynamic": false, + "info": "Enter one or more URLs, separated by commas.", + "input_types": [ + "Message" + ], + "list": true, + "load_from_db": false, + "name": "urls", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": [ + "langflow.org/", + "docs.langflow.org/" + ] + } + } + }, + "type": "URL" + }, + "dragging": false, + "height": 358, + "id": "URL-rETJU", + "position": { + "x": 220.79156431407534, + "y": 498.8186168722667 + }, + "positionAbsolute": { + "x": 220.79156431407534, + "y": 498.8186168722667 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ParseData-AqSfN", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Convert Data into plain text following a specified template.", + "display_name": "Parse Data", + "documentation": "", + "edited": false, + "field_order": [ + "data", + "template", + "sep" + ], + "frozen": false, + "icon": "braces", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "parse_data", + "name": "text", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n" + }, + "data": { + "advanced": false, + "display_name": "Data", + "dynamic": false, + "info": "The data to convert to text.", + "input_types": [ + "Data" + ], + "list": false, + "name": "data", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "sep": { + "advanced": true, + "display_name": "Separator", + "dynamic": false, + "info": "", + "list": false, + "load_from_db": false, + "name": "sep", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + } + } + }, + "type": "ParseData" + }, + "dragging": false, + "height": 384, + "id": "ParseData-AqSfN", + "position": { + "x": 754.3607306709101, + "y": 736.8516961537598 + }, + "positionAbsolute": { + "x": 754.3607306709101, + "y": 736.8516961537598 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-rizUK", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": { + "template": [ + "references", + "instructions" + ] + }, + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "documentation": "", + "edited": false, + "error": null, + "field_order": [ + "template" + ], + "frozen": false, + "full_path": null, + "icon": "prompts", + "is_composition": null, + "is_input": null, + "is_output": null, + "name": "", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Prompt Message", + "hidden": false, + "method": "build_prompt", + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" + }, + "instructions": { + "advanced": false, + "display_name": "instructions", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "instructions", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "references": { + "advanced": false, + "display_name": "references", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "references", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "", + "list": false, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "prompt", + "value": "Reference 1:\n\n{references}\n\n---\n\n{instructions}\n\nBlog: \n\n" + } + } + }, + "type": "Prompt" + }, + "dragging": false, + "height": 515, + "id": "Prompt-rizUK", + "position": { + "x": 1368.0633591447076, + "y": 467.19448061224284 + }, + "positionAbsolute": { + "x": 1368.0633591447076, + "y": 467.19448061224284 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "TextInput-OffFR", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Get text inputs from the Playground.", + "display_name": "Instructions", + "documentation": "", + "edited": false, + "field_order": [ + "input_value" + ], + "frozen": false, + "icon": "type", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "text_response", + "name": "text", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.text import TextComponent\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n message = Message(\n text=self.input_value,\n )\n return message\n" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Text to be passed as input.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "Use the references above for style to write a new blog/tutorial about Langflow and AI. Suggest non-covered topics." + } + } + }, + "type": "TextInput" + }, + "dragging": false, + "height": 308, + "id": "TextInput-OffFR", + "position": { + "x": 743.7338453293725, + "y": 301.58775454952183 + }, + "positionAbsolute": { + "x": 743.7338453293725, + "y": 301.58775454952183 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "edited": false, + "id": "OpenAIModel-qmhKV", + "node": { + "base_classes": [ + "LanguageModel", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "edited": true, + "field_order": [ + "input_value", + "max_tokens", + "model_kwargs", + "json_mode", + "output_schema", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "stream", + "system_message", + "seed" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "text_response", + "name": "text_output", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Language Model", + "method": "build_model", + "name": "model_output", + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "json_mode": { + "advanced": true, + "display_name": "JSON Mode", + "dynamic": false, + "info": "If True, it will output JSON regardless of passing a schema.", + "list": false, + "name": "json_mode", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "name": "max_tokens", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "info": "", + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "gpt-4-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", + "list": false, + "load_from_db": false, + "name": "openai_api_base", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "output_schema": { + "advanced": true, + "display_name": "Schema", + "dynamic": false, + "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", + "list": true, + "name": "output_schema", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "seed": { + "advanced": true, + "display_name": "Seed", + "dynamic": false, + "info": "The seed controls the reproducibility of the job.", + "list": false, + "name": "seed", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1 + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "name": "stream", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "info": "System message to pass to the model.", + "list": false, + "load_from_db": false, + "name": "system_message", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "info": "", + "list": false, + "name": "temperature", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": 0.1 + } + } + }, + "type": "OpenAIModelComponent" + }, + "dragging": false, + "height": 621, + "id": "OpenAIModel-qmhKV", + "position": { + "x": 1899.407626221589, + "y": 395.9013619556682 + }, + "positionAbsolute": { + "x": 1899.407626221589, + "y": 395.9013619556682 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatOutput-W684s", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "data_template" + ], + "frozen": false, + "icon": "ChatOutput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "data_template": { + "advanced": true, + "display_name": "Data Template", + "dynamic": false, + "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "data_template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as output.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 308, + "id": "ChatOutput-W684s", + "position": { + "x": 2449.3489426461606, + "y": 571.2449700910389 + }, + "positionAbsolute": { + "x": 2449.3489426461606, + "y": 571.2449700910389 + }, + "selected": false, + "type": "genericNode", + "width": 384 + } + ], + "viewport": { + "x": -63.94787944982488, + "y": -16.004163894553585, + "zoom": 0.47423908935061165 + } + }, + "description": "This flow can be used to create a blog post following instructions from the user, using two other blogs as reference.", + "endpoint_name": null, + "id": "da9999f8-9013-4bd9-8adb-653c94ebf08c", + "is_component": false, + "last_tested_version": "1.0.5", + "name": "Blog Writer" +} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json index 577e02a930b..d0e7c53b045 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json @@ -1 +1,1225 @@ -{"id":"483d5200-b59b-4afa-a71f-52fcfcde8fca","data":{"nodes":[{"data":{"id":"File-Q3Xrb","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"A generic file loader.","display_name":"File","documentation":"","edited":false,"field_order":["path","silent_errors"],"frozen":false,"icon":"file-text","output_types":[],"outputs":[{"cache":true,"display_name":"Data","hidden":false,"method":"load_file","name":"data","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n"},"path":{"advanced":false,"display_name":"Path","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx"],"file_path":"","info":"Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx","list":false,"name":"path","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"silent_errors":{"advanced":true,"display_name":"Silent Errors","dynamic":false,"info":"If true, errors will not raise an exception.","list":false,"name":"silent_errors","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false}}},"type":"File"},"dragging":false,"height":300,"id":"File-Q3Xrb","position":{"x":-449.0807503257012,"y":-253.5304920926106},"positionAbsolute":{"x":-449.0807503257012,"y":-253.5304920926106},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ParseData-1Y5jJ","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Convert Data into plain text following a specified template.","display_name":"Parse Data","documentation":"","edited":false,"field_order":["data","template","sep"],"frozen":false,"icon":"braces","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"parse_data","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n"},"data":{"advanced":false,"display_name":"Data","dynamic":false,"info":"The data to convert to text.","input_types":["Data"],"list":false,"name":"data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"sep":{"advanced":true,"display_name":"Separator","dynamic":false,"info":"","list":false,"load_from_db":false,"name":"sep","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"}}},"type":"ParseData"},"dragging":false,"height":384,"id":"ParseData-1Y5jJ","position":{"x":73.79471204296345,"y":-186.9430114986888},"positionAbsolute":{"x":73.79471204296345,"y":-186.9430114986888},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-CMJEB","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["Document","Question"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"Document":{"advanced":false,"display_name":"Document","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"Document","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"Question":{"advanced":false,"display_name":"Question","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"Question","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"Answer user's questions based on the document below:\n\n---\n\n{Document}\n\n---\n\nQuestion:\n{Question}\n\nAnswer:\n"}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-CMJEB","position":{"x":637.3518652087848,"y":47.191730368560215},"positionAbsolute":{"x":637.3518652087848,"y":47.191730368560215},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatInput-mc7sJ","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-mc7sJ","position":{"x":50.08709924122684,"y":320.88186720121615},"positionAbsolute":{"x":50.08709924122684,"y":320.88186720121615},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-U2g5u","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-U2g5u","position":{"x":1249.1992451905348,"y":2.8792271523856243},"positionAbsolute":{"x":1249.1992451905348,"y":2.8792271523856243},"selected":true,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-yZjPO","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-yZjPO","position":{"x":1831.1359796346408,"y":139.5174517327903},"positionAbsolute":{"x":1831.1359796346408,"y":139.5174517327903},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"File","id":"File-Q3Xrb","name":"data","output_types":["Data"]},"targetHandle":{"fieldName":"data","id":"ParseData-1Y5jJ","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-File-Q3Xrb{œdataTypeœ:œFileœ,œidœ:œFile-Q3Xrbœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-1Y5jJ{œfieldNameœ:œdataœ,œidœ:œParseData-1Y5jJœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"File-Q3Xrb","sourceHandle":"{œdataTypeœ:œFileœ,œidœ:œFile-Q3Xrbœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}","target":"ParseData-1Y5jJ","targetHandle":"{œfieldNameœ:œdataœ,œidœ:œParseData-1Y5jJœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"ParseData","id":"ParseData-1Y5jJ","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"Document","id":"Prompt-CMJEB","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ParseData-1Y5jJ{œdataTypeœ:œParseDataœ,œidœ:œParseData-1Y5jJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-CMJEB{œfieldNameœ:œDocumentœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ParseData-1Y5jJ","sourceHandle":"{œdataTypeœ:œParseDataœ,œidœ:œParseData-1Y5jJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-CMJEB","targetHandle":"{œfieldNameœ:œDocumentœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-mc7sJ","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"Question","id":"Prompt-CMJEB","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-mc7sJ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-mc7sJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-CMJEB{œfieldNameœ:œQuestionœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-mc7sJ","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-mc7sJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-CMJEB","targetHandle":"{œfieldNameœ:œQuestionœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-CMJEB","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-U2g5u","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-CMJEB{œdataTypeœ:œPromptœ,œidœ:œPrompt-CMJEBœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-U2g5u{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-U2g5uœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-CMJEB","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-CMJEBœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-U2g5u","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-U2g5uœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-U2g5u","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-U2g5uœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-yZjPO","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-yZjPOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-yZjPO","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-U2g5u","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-U2g5u{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-U2g5uœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-yZjPO{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-yZjPOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":252.03047748371796,"y":253.71203687916693,"zoom":0.4580440916596844}},"description":"This flow integrates PDF reading with a language model to answer document-specific questions. Ideal for small-scale texts, it facilitates direct queries with immediate insights.","name":"Document QA","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file +{ + "data": { + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "File", + "id": "File-Q3Xrb", + "name": "data", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "data", + "id": "ParseData-1Y5jJ", + "inputTypes": [ + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-File-Q3Xrb{œdataTypeœ:œFileœ,œidœ:œFile-Q3Xrbœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-ParseData-1Y5jJ{œfieldNameœ:œdataœ,œidœ:œParseData-1Y5jJœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", + "source": "File-Q3Xrb", + "sourceHandle": "{œdataTypeœ: œFileœ, œidœ: œFile-Q3Xrbœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}", + "target": "ParseData-1Y5jJ", + "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-1Y5jJœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ParseData", + "id": "ParseData-1Y5jJ", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "Document", + "id": "Prompt-CMJEB", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ParseData-1Y5jJ{œdataTypeœ:œParseDataœ,œidœ:œParseData-1Y5jJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-CMJEB{œfieldNameœ:œDocumentœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ParseData-1Y5jJ", + "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-1Y5jJœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-CMJEB", + "targetHandle": "{œfieldNameœ: œDocumentœ, œidœ: œPrompt-CMJEBœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-mc7sJ", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "Question", + "id": "Prompt-CMJEB", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-mc7sJ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-mc7sJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-CMJEB{œfieldNameœ:œQuestionœ,œidœ:œPrompt-CMJEBœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ChatInput-mc7sJ", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-mc7sJœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-CMJEB", + "targetHandle": "{œfieldNameœ: œQuestionœ, œidœ: œPrompt-CMJEBœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-CMJEB", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-U2g5u", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-CMJEB{œdataTypeœ:œPromptœ,œidœ:œPrompt-CMJEBœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-U2g5u{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-U2g5uœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-CMJEB", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-CMJEBœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-U2g5u", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-U2g5uœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIModelComponent", + "id": "OpenAIModel-U2g5u", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-yZjPO", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-U2g5u{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-U2g5uœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-yZjPO{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-yZjPOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-U2g5u", + "sourceHandle": "{œdataTypeœ: œOpenAIModelComponentœ, œidœ: œOpenAIModel-U2g5uœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-yZjPO", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-yZjPOœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], + "nodes": [ + { + "data": { + "id": "File-Q3Xrb", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "A generic file loader.", + "display_name": "File", + "documentation": "", + "edited": false, + "field_order": [ + "path", + "silent_errors" + ], + "frozen": false, + "icon": "file-text", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "hidden": false, + "method": "load_file", + "name": "data", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n" + }, + "path": { + "advanced": false, + "display_name": "Path", + "dynamic": false, + "fileTypes": [ + "txt", + "md", + "mdx", + "csv", + "json", + "yaml", + "yml", + "xml", + "html", + "htm", + "pdf", + "docx", + "py", + "sh", + "sql", + "js", + "ts", + "tsx" + ], + "file_path": "", + "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx", + "list": false, + "name": "path", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "file", + "value": "" + }, + "silent_errors": { + "advanced": true, + "display_name": "Silent Errors", + "dynamic": false, + "info": "If true, errors will not raise an exception.", + "list": false, + "name": "silent_errors", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + } + } + }, + "type": "File" + }, + "dragging": false, + "height": 300, + "id": "File-Q3Xrb", + "position": { + "x": -449.0807503257012, + "y": -253.5304920926106 + }, + "positionAbsolute": { + "x": -449.0807503257012, + "y": -253.5304920926106 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ParseData-1Y5jJ", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Convert Data into plain text following a specified template.", + "display_name": "Parse Data", + "documentation": "", + "edited": false, + "field_order": [ + "data", + "template", + "sep" + ], + "frozen": false, + "icon": "braces", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "parse_data", + "name": "text", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n" + }, + "data": { + "advanced": false, + "display_name": "Data", + "dynamic": false, + "info": "The data to convert to text.", + "input_types": [ + "Data" + ], + "list": false, + "name": "data", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "sep": { + "advanced": true, + "display_name": "Separator", + "dynamic": false, + "info": "", + "list": false, + "load_from_db": false, + "name": "sep", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + } + } + }, + "type": "ParseData" + }, + "dragging": false, + "height": 384, + "id": "ParseData-1Y5jJ", + "position": { + "x": 73.79471204296345, + "y": -186.9430114986888 + }, + "positionAbsolute": { + "x": 73.79471204296345, + "y": -186.9430114986888 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-CMJEB", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": { + "template": [ + "Document", + "Question" + ] + }, + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "documentation": "", + "edited": false, + "error": null, + "field_order": [ + "template" + ], + "frozen": false, + "full_path": null, + "icon": "prompts", + "is_composition": null, + "is_input": null, + "is_output": null, + "name": "", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Prompt Message", + "hidden": false, + "method": "build_prompt", + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "Document": { + "advanced": false, + "display_name": "Document", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "Document", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "Question": { + "advanced": false, + "display_name": "Question", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "Question", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "", + "list": false, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "prompt", + "value": "Answer user's questions based on the document below:\n\n---\n\n{Document}\n\n---\n\nQuestion:\n{Question}\n\nAnswer:\n" + } + } + }, + "type": "Prompt" + }, + "dragging": false, + "height": 515, + "id": "Prompt-CMJEB", + "position": { + "x": 637.3518652087848, + "y": 47.191730368560215 + }, + "positionAbsolute": { + "x": 637.3518652087848, + "y": 47.191730368560215 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatInput-mc7sJ", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Get chat inputs from the Playground.", + "display_name": "Chat Input", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "files" + ], + "frozen": false, + "icon": "ChatInput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "hidden": false, + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "files": { + "advanced": true, + "display_name": "Files", + "dynamic": false, + "fileTypes": [ + "txt", + "md", + "mdx", + "csv", + "json", + "yaml", + "yml", + "xml", + "html", + "htm", + "pdf", + "docx", + "py", + "sh", + "sql", + "js", + "ts", + "tsx", + "jpg", + "jpeg", + "png", + "bmp", + "image" + ], + "file_path": "", + "info": "Files to be sent with the message.", + "list": true, + "name": "files", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "file", + "value": "" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as input.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatInput" + }, + "dragging": false, + "height": 308, + "id": "ChatInput-mc7sJ", + "position": { + "x": 50.08709924122684, + "y": 320.88186720121615 + }, + "positionAbsolute": { + "x": 50.08709924122684, + "y": 320.88186720121615 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "edited": false, + "id": "OpenAIModel-U2g5u", + "node": { + "base_classes": [ + "LanguageModel", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "edited": true, + "field_order": [ + "input_value", + "max_tokens", + "model_kwargs", + "json_mode", + "output_schema", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "stream", + "system_message", + "seed" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "text_response", + "name": "text_output", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Language Model", + "method": "build_model", + "name": "model_output", + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "json_mode": { + "advanced": true, + "display_name": "JSON Mode", + "dynamic": false, + "info": "If True, it will output JSON regardless of passing a schema.", + "list": false, + "name": "json_mode", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "name": "max_tokens", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "info": "", + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "gpt-4-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", + "list": false, + "load_from_db": false, + "name": "openai_api_base", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "output_schema": { + "advanced": true, + "display_name": "Schema", + "dynamic": false, + "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", + "list": true, + "name": "output_schema", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "seed": { + "advanced": true, + "display_name": "Seed", + "dynamic": false, + "info": "The seed controls the reproducibility of the job.", + "list": false, + "name": "seed", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1 + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "name": "stream", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "info": "System message to pass to the model.", + "list": false, + "load_from_db": false, + "name": "system_message", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "info": "", + "list": false, + "name": "temperature", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": 0.1 + } + } + }, + "type": "OpenAIModelComponent" + }, + "dragging": false, + "height": 621, + "id": "OpenAIModel-U2g5u", + "position": { + "x": 1249.1992451905348, + "y": 2.8792271523856243 + }, + "positionAbsolute": { + "x": 1249.1992451905348, + "y": 2.8792271523856243 + }, + "selected": true, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatOutput-yZjPO", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "data_template" + ], + "frozen": false, + "icon": "ChatOutput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "data_template": { + "advanced": true, + "display_name": "Data Template", + "dynamic": false, + "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "data_template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as output.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 308, + "id": "ChatOutput-yZjPO", + "position": { + "x": 1831.1359796346408, + "y": 139.5174517327903 + }, + "positionAbsolute": { + "x": 1831.1359796346408, + "y": 139.5174517327903 + }, + "selected": false, + "type": "genericNode", + "width": 384 + } + ], + "viewport": { + "x": 252.03047748371796, + "y": 253.71203687916693, + "zoom": 0.4580440916596844 + } + }, + "description": "This flow integrates PDF reading with a language model to answer document-specific questions. Ideal for small-scale texts, it facilitates direct queries with immediate insights.", + "endpoint_name": null, + "id": "483d5200-b59b-4afa-a71f-52fcfcde8fca", + "is_component": false, + "last_tested_version": "1.0.5", + "name": "Document QA" +} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index a695f3fb4a0..1edb56cd54f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -1 +1,1145 @@ -{"id":"16c029a0-0d89-4c36-8a8c-e5410206df38","data":{"nodes":[{"data":{"id":"Memory-VIq7F","node":{"base_classes":["Data","Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Retrieves stored chat messages.","display_name":"Chat Memory","documentation":"","edited":false,"field_order":["sender","sender_name","n_messages","session_id","order","template"],"frozen":false,"icon":"message-square-more","output_types":[],"outputs":[{"cache":true,"display_name":"Chat History","method":"retrieve_messages","name":"messages","selected":"Data","types":["Data"],"value":"__UNDEFINED__"},{"cache":true,"display_name":"Messages (Text)","hidden":false,"method":"retrieve_messages_as_text","name":"messages_text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages.\"\n icon = \"message-square-more\"\n\n inputs = [\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\", \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"Session ID of the chat history.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chat History\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Messages (Text)\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n messages = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = messages\n return messages\n\n def retrieve_messages_as_text(self) -> Message:\n messages_text = data_to_text(self.template, self.retrieve_messages())\n self.status = messages_text\n return Message(text=messages_text)\n"},"n_messages":{"advanced":true,"display_name":"Number of Messages","dynamic":false,"info":"Number of messages to retrieve.","list":false,"name":"n_messages","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":100},"order":{"advanced":true,"display_name":"Order","dynamic":false,"info":"Order of the messages.","name":"order","options":["Ascending","Descending"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Ascending"},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User","Machine and User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine and User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID of the chat history.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"template":{"advanced":true,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{sender_name}: {text}"}}},"type":"Memory"},"dragging":false,"height":266,"id":"Memory-VIq7F","position":{"x":1264.7588980556088,"y":506.6868269980502},"positionAbsolute":{"x":1264.7588980556088,"y":506.6868269980502},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-gEaWL","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["context","user_message"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"context":{"advanced":false,"display_name":"context","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"context","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"{context}\n\nUser: {user_message}\nAI: "},"user_message":{"advanced":false,"display_name":"user_message","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"user_message","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-gEaWL","position":{"x":1880.8227904110583,"y":625.8049209882275},"positionAbsolute":{"x":1880.8227904110583,"y":625.8049209882275},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatInput-gIy9N","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-gIy9N","position":{"x":1275.9262193671882,"y":836.1228056896347},"positionAbsolute":{"x":1275.9262193671882,"y":836.1228056896347},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-uNcAU","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-uNcAU","position":{"x":2428.0215346784357,"y":569.9683144303319},"positionAbsolute":{"x":2428.0215346784357,"y":569.9683144303319},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-KtSB9","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-KtSB9","position":{"x":2988.248820475989,"y":705.837390387878},"positionAbsolute":{"x":2988.248820475989,"y":705.837390387878},"selected":false,"type":"genericNode","width":384}],"edges":[{"data":{"sourceHandle":{"dataType":"Memory","id":"Memory-VIq7F","name":"messages_text","output_types":["Message"]},"targetHandle":{"fieldName":"context","id":"Prompt-gEaWL","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-Memory-VIq7F{œdataTypeœ:œMemoryœ,œidœ:œMemory-VIq7Fœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-gEaWL{œfieldNameœ:œcontextœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"Memory-VIq7F","sourceHandle":"{œdataTypeœ:œMemoryœ,œidœ:œMemory-VIq7Fœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-gEaWL","targetHandle":"{œfieldNameœ:œcontextœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-gIy9N","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"user_message","id":"Prompt-gEaWL","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-gIy9N{œdataTypeœ:œChatInputœ,œidœ:œChatInput-gIy9Nœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-gEaWL{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-gIy9N","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-gIy9Nœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-gEaWL","targetHandle":"{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-gEaWL","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-uNcAU","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-gEaWL{œdataTypeœ:œPromptœ,œidœ:œPrompt-gEaWLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-uNcAU{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-uNcAUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-gEaWL","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-gEaWLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-uNcAU","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-uNcAUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"source":"OpenAIModel-uNcAU","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-uNcAUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-KtSB9","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-KtSB9œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-KtSB9","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-uNcAU","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-uNcAU{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-uNcAUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-KtSB9{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-KtSB9œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"}],"viewport":{"x":-586.5321077101332,"y":-103.32118023592653,"zoom":0.5372819347267049}},"description":"This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.","name":"Memory Chatbot","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file +{ + "data": { + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "Memory", + "id": "Memory-VIq7F", + "name": "messages_text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "context", + "id": "Prompt-gEaWL", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Memory-VIq7F{œdataTypeœ:œMemoryœ,œidœ:œMemory-VIq7Fœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-gEaWL{œfieldNameœ:œcontextœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "Memory-VIq7F", + "sourceHandle": "{œdataTypeœ: œMemoryœ, œidœ: œMemory-VIq7Fœ, œnameœ: œmessages_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-gEaWL", + "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-gEaWLœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-gIy9N", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "user_message", + "id": "Prompt-gEaWL", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-gIy9N{œdataTypeœ:œChatInputœ,œidœ:œChatInput-gIy9Nœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-gEaWL{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-gEaWLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ChatInput-gIy9N", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-gIy9Nœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-gEaWL", + "targetHandle": "{œfieldNameœ: œuser_messageœ, œidœ: œPrompt-gEaWLœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-gEaWL", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-uNcAU", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-gEaWL{œdataTypeœ:œPromptœ,œidœ:œPrompt-gEaWLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-uNcAU{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-uNcAUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-gEaWL", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-gEaWLœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-uNcAU", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-uNcAUœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIModelComponent", + "id": "OpenAIModel-uNcAU", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-KtSB9", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-uNcAU{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-uNcAUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-KtSB9{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-KtSB9œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-uNcAU", + "sourceHandle": "{œdataTypeœ: œOpenAIModelComponentœ, œidœ: œOpenAIModel-uNcAUœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-KtSB9", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-KtSB9œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], + "nodes": [ + { + "data": { + "id": "Memory-VIq7F", + "node": { + "base_classes": [ + "Data", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Retrieves stored chat messages.", + "display_name": "Chat Memory", + "documentation": "", + "edited": false, + "field_order": [ + "sender", + "sender_name", + "n_messages", + "session_id", + "order", + "template" + ], + "frozen": false, + "icon": "message-square-more", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Chat History", + "method": "retrieve_messages", + "name": "messages", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Messages (Text)", + "hidden": false, + "method": "retrieve_messages_as_text", + "name": "messages_text", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages.\"\n icon = \"message-square-more\"\n\n inputs = [\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\", \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"Session ID of the chat history.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chat History\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Messages (Text)\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n messages = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = messages\n return messages\n\n def retrieve_messages_as_text(self) -> Message:\n messages_text = data_to_text(self.template, self.retrieve_messages())\n self.status = messages_text\n return Message(text=messages_text)\n" + }, + "n_messages": { + "advanced": true, + "display_name": "Number of Messages", + "dynamic": false, + "info": "Number of messages to retrieve.", + "list": false, + "name": "n_messages", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 100 + }, + "order": { + "advanced": true, + "display_name": "Order", + "dynamic": false, + "info": "Order of the messages.", + "name": "order", + "options": [ + "Ascending", + "Descending" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Ascending" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User", + "Machine and User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Machine and User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID of the chat history.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "template": { + "advanced": true, + "display_name": "Template", + "dynamic": false, + "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{sender_name}: {text}" + } + } + }, + "type": "Memory" + }, + "dragging": false, + "height": 266, + "id": "Memory-VIq7F", + "position": { + "x": 1264.7588980556088, + "y": 506.6868269980502 + }, + "positionAbsolute": { + "x": 1264.7588980556088, + "y": 506.6868269980502 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-gEaWL", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": { + "template": [ + "context", + "user_message" + ] + }, + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "documentation": "", + "edited": false, + "error": null, + "field_order": [ + "template" + ], + "frozen": false, + "full_path": null, + "icon": "prompts", + "is_composition": null, + "is_input": null, + "is_output": null, + "name": "", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Prompt Message", + "hidden": false, + "method": "build_prompt", + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" + }, + "context": { + "advanced": false, + "display_name": "context", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "context", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "", + "list": false, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "prompt", + "value": "{context}\n\nUser: {user_message}\nAI: " + }, + "user_message": { + "advanced": false, + "display_name": "user_message", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "user_message", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + } + } + }, + "type": "Prompt" + }, + "dragging": false, + "height": 515, + "id": "Prompt-gEaWL", + "position": { + "x": 1880.8227904110583, + "y": 625.8049209882275 + }, + "positionAbsolute": { + "x": 1880.8227904110583, + "y": 625.8049209882275 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatInput-gIy9N", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Get chat inputs from the Playground.", + "display_name": "Chat Input", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "files" + ], + "frozen": false, + "icon": "ChatInput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "hidden": false, + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "files": { + "advanced": true, + "display_name": "Files", + "dynamic": false, + "fileTypes": [ + "txt", + "md", + "mdx", + "csv", + "json", + "yaml", + "yml", + "xml", + "html", + "htm", + "pdf", + "docx", + "py", + "sh", + "sql", + "js", + "ts", + "tsx", + "jpg", + "jpeg", + "png", + "bmp", + "image" + ], + "file_path": "", + "info": "Files to be sent with the message.", + "list": true, + "name": "files", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "file", + "value": "" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as input.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatInput" + }, + "dragging": false, + "height": 308, + "id": "ChatInput-gIy9N", + "position": { + "x": 1275.9262193671882, + "y": 836.1228056896347 + }, + "positionAbsolute": { + "x": 1275.9262193671882, + "y": 836.1228056896347 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "edited": false, + "id": "OpenAIModel-uNcAU", + "node": { + "base_classes": [ + "LanguageModel", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "edited": true, + "field_order": [ + "input_value", + "max_tokens", + "model_kwargs", + "json_mode", + "output_schema", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "stream", + "system_message", + "seed" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "text_response", + "name": "text_output", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Language Model", + "method": "build_model", + "name": "model_output", + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "json_mode": { + "advanced": true, + "display_name": "JSON Mode", + "dynamic": false, + "info": "If True, it will output JSON regardless of passing a schema.", + "list": false, + "name": "json_mode", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "name": "max_tokens", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "info": "", + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "gpt-4-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", + "list": false, + "load_from_db": false, + "name": "openai_api_base", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "output_schema": { + "advanced": true, + "display_name": "Schema", + "dynamic": false, + "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", + "list": true, + "name": "output_schema", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "seed": { + "advanced": true, + "display_name": "Seed", + "dynamic": false, + "info": "The seed controls the reproducibility of the job.", + "list": false, + "name": "seed", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1 + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "name": "stream", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "info": "System message to pass to the model.", + "list": false, + "load_from_db": false, + "name": "system_message", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "info": "", + "list": false, + "name": "temperature", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": 0.1 + } + } + }, + "type": "OpenAIModelComponent" + }, + "dragging": false, + "height": 621, + "id": "OpenAIModel-uNcAU", + "position": { + "x": 2428.0215346784357, + "y": 569.9683144303319 + }, + "positionAbsolute": { + "x": 2428.0215346784357, + "y": 569.9683144303319 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatOutput-KtSB9", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "data_template" + ], + "frozen": false, + "icon": "ChatOutput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "data_template": { + "advanced": true, + "display_name": "Data Template", + "dynamic": false, + "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "data_template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as output.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 308, + "id": "ChatOutput-KtSB9", + "position": { + "x": 2988.248820475989, + "y": 705.837390387878 + }, + "positionAbsolute": { + "x": 2988.248820475989, + "y": 705.837390387878 + }, + "selected": false, + "type": "genericNode", + "width": 384 + } + ], + "viewport": { + "x": -586.5321077101332, + "y": -103.32118023592653, + "zoom": 0.5372819347267049 + } + }, + "description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.", + "endpoint_name": null, + "id": "16c029a0-0d89-4c36-8a8c-e5410206df38", + "is_component": false, + "last_tested_version": "1.0.5", + "name": "Memory Chatbot" +} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index 1dba89d86ca..7890fe16421 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -1 +1,3201 @@ -{"id":"f1a53ec2-49e2-4029-b8a8-1a73079f9653","data":{"nodes":[{"data":{"id":"ChatInput-tuEeg","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Get chat inputs from the Playground.","display_name":"Chat Input","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","files"],"frozen":false,"icon":"ChatInput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","hidden":false,"method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"files":{"advanced":true,"display_name":"Files","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"file_path":"","info":"Files to be sent with the message.","list":true,"name":"files","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as input.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"User"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"User"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatInput"},"dragging":false,"height":308,"id":"ChatInput-tuEeg","position":{"x":642.3545710150049,"y":220.22556606238678},"positionAbsolute":{"x":642.3545710150049,"y":220.22556606238678},"selected":false,"type":"genericNode","width":384},{"data":{"id":"AstraDB-xVF1f","node":{"base_classes":["Data","Retriever"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Implementation of Vector Store using Astra DB with search capabilities","display_name":"Astra DB","documentation":"https://python.langchain.com/docs/integrations/vectorstores/astradb","edited":false,"field_order":["collection_name","token","api_endpoint","search_input","ingest_data","namespace","metric","batch_size","bulk_insert_batch_concurrency","bulk_insert_overwrite_concurrency","bulk_delete_concurrency","setup_mode","pre_delete_collection","metadata_indexing_include","embedding","metadata_indexing_exclude","collection_indexing_policy","search_type","number_of_results"],"frozen":false,"icon":"AstraDB","output_types":[],"outputs":[{"cache":true,"display_name":"Retriever","method":"build_base_retriever","name":"base_retriever","selected":"Retriever","types":["Retriever"],"value":"__UNDEFINED__"},{"cache":true,"display_name":"Search Results","hidden":false,"method":"search_documents","name":"search_results","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","api_endpoint":{"advanced":false,"display_name":"API Endpoint","dynamic":false,"info":"API endpoint URL for the Astra DB service.","input_types":[],"load_from_db":false,"name":"api_endpoint","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"batch_size":{"advanced":true,"display_name":"Batch Size","dynamic":false,"info":"Optional number of data to process in a single batch.","list":false,"name":"batch_size","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_delete_concurrency":{"advanced":true,"display_name":"Bulk Delete Concurrency","dynamic":false,"info":"Optional concurrency level for bulk delete operations.","list":false,"name":"bulk_delete_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_batch_concurrency":{"advanced":true,"display_name":"Bulk Insert Batch Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations.","list":false,"name":"bulk_insert_batch_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_overwrite_concurrency":{"advanced":true,"display_name":"Bulk Insert Overwrite Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations that overwrite existing data.","list":false,"name":"bulk_insert_overwrite_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n"},"collection_indexing_policy":{"advanced":true,"display_name":"Collection Indexing Policy","dynamic":false,"info":"Optional dictionary defining the indexing policy for the collection.","list":false,"load_from_db":false,"name":"collection_indexing_policy","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"collection_name":{"advanced":false,"display_name":"Collection Name","dynamic":false,"info":"The name of the collection within Astra DB where the vectors will be stored.","list":false,"load_from_db":false,"name":"collection_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"langflow"},"embedding":{"advanced":false,"display_name":"Embedding or Astra Vectorize","dynamic":false,"info":"","input_types":["Embeddings","dict"],"list":false,"name":"embedding","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"other","value":""},"ingest_data":{"advanced":false,"display_name":"Ingest Data","dynamic":false,"info":"","input_types":["Data"],"list":true,"name":"ingest_data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"metadata_indexing_exclude":{"advanced":true,"display_name":"Metadata Indexing Exclude","dynamic":false,"info":"Optional list of metadata fields to exclude from the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_exclude","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metadata_indexing_include":{"advanced":true,"display_name":"Metadata Indexing Include","dynamic":false,"info":"Optional list of metadata fields to include in the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_include","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metric":{"advanced":true,"display_name":"Metric","dynamic":false,"info":"Optional distance metric for vector comparisons in the vector store.","name":"metric","options":["cosine","dot_product","euclidean"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"namespace":{"advanced":true,"display_name":"Namespace","dynamic":false,"info":"Optional namespace within Astra DB to use for the collection.","list":false,"load_from_db":false,"name":"namespace","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"number_of_results":{"advanced":true,"display_name":"Number of Results","dynamic":false,"info":"Number of results to return.","list":false,"name":"number_of_results","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":4},"pre_delete_collection":{"advanced":true,"display_name":"Pre Delete Collection","dynamic":false,"info":"Boolean flag to determine whether to delete the collection before creating a new one.","list":false,"name":"pre_delete_collection","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false},"search_input":{"advanced":false,"display_name":"Search Input","dynamic":false,"info":"","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"search_input","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"search_type":{"advanced":true,"display_name":"Search Type","dynamic":false,"info":"","name":"search_type","options":["Similarity","MMR"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Similarity"},"setup_mode":{"advanced":true,"display_name":"Setup Mode","dynamic":false,"info":"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.","name":"setup_mode","options":["Sync","Async","Off"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Sync"},"token":{"advanced":false,"display_name":"Astra DB Application Token","dynamic":false,"info":"Authentication token for accessing Astra DB.","input_types":[],"load_from_db":false,"name":"token","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"AstraDB"},"dragging":false,"height":753,"id":"AstraDB-xVF1f","position":{"x":1246.0381406498648,"y":333.25157075413966},"positionAbsolute":{"x":1246.0381406498648,"y":333.25157075413966},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ParseData-ZG3Aa","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Convert Data into plain text following a specified template.","display_name":"Parse Data","documentation":"","edited":false,"field_order":["data","template","sep"],"frozen":false,"icon":"braces","output_types":[],"outputs":[{"cache":true,"display_name":"Text","hidden":false,"method":"parse_data","name":"text","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n"},"data":{"advanced":false,"display_name":"Data","dynamic":false,"info":"The data to convert to text.","input_types":["Data"],"list":false,"name":"data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"sep":{"advanced":true,"display_name":"Separator","dynamic":false,"info":"","list":false,"load_from_db":false,"name":"sep","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"\n"},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"}}},"type":"ParseData"},"dragging":false,"height":384,"id":"ParseData-ZG3Aa","position":{"x":1854.1518317915907,"y":459.3386924128532},"positionAbsolute":{"x":1854.1518317915907,"y":459.3386924128532},"selected":false,"type":"genericNode","width":384},{"data":{"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","id":"Prompt-0Hp9v","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{"template":["context","question"]},"description":"Create a prompt template with dynamic variables.","display_name":"Prompt","documentation":"","edited":false,"error":null,"field_order":["template"],"frozen":false,"full_path":null,"icon":"prompts","is_composition":null,"is_input":null,"is_output":null,"name":"","output_types":[],"outputs":[{"cache":true,"display_name":"Prompt Message","hidden":false,"method":"build_prompt","name":"prompt","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n"},"context":{"advanced":false,"display_name":"context","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"context","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"question":{"advanced":false,"display_name":"question","dynamic":false,"field_type":"str","fileTypes":[],"file_path":"","info":"","input_types":["Message","Text"],"list":false,"load_from_db":false,"multiline":true,"name":"question","password":false,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"template":{"advanced":false,"display_name":"Template","dynamic":false,"info":"","list":false,"name":"template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"type":"prompt","value":"{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: "}}},"type":"Prompt"},"dragging":false,"height":515,"id":"Prompt-0Hp9v","position":{"x":2486.0988668404975,"y":496.5120474157301},"positionAbsolute":{"x":2486.0988668404975,"y":496.5120474157301},"selected":false,"type":"genericNode","width":384},{"data":{"id":"OpenAIModel-BQXFs","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"input_value","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"json_mode","display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool"},"max_tokens":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"max_tokens","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"required":false,"placeholder":"","show":true,"value":"gpt-4-turbo","name":"model_name","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"value":{},"name":"output_schema","display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1,"name":"seed","display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"stream","display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool"},"system_message":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"system_message","display_name":"System Message","advanced":true,"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":0.1,"name":"temperature","display_name":"Temperature","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"float"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true,"hidden":false},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","openai_api_key","temperature","stream","system_message","seed"],"beta":false,"edited":true},"type":"OpenAIModelComponent","description":"Generates text using OpenAI LLMs.","display_name":"OpenAI","edited":false},"dragging":false,"height":621,"id":"OpenAIModel-BQXFs","position":{"x":3145.6693008609222,"y":374.23955005474204},"positionAbsolute":{"x":3145.6693008609222,"y":374.23955005474204},"selected":false,"type":"genericNode","width":384},{"data":{"id":"ChatOutput-fDyGT","node":{"base_classes":["Message"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Display a chat message in the Playground.","display_name":"Chat Output","documentation":"","edited":false,"field_order":["input_value","sender","sender_name","session_id","data_template"],"frozen":false,"icon":"ChatOutput","output_types":[],"outputs":[{"cache":true,"display_name":"Message","method":"message_response","name":"message","selected":"Message","types":["Message"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n"},"data_template":{"advanced":true,"display_name":"Data Template","dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","input_types":["Message"],"list":false,"load_from_db":false,"name":"data_template","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"{text}"},"input_value":{"advanced":false,"display_name":"Text","dynamic":false,"info":"Message to be passed as output.","input_types":["Message"],"list":false,"load_from_db":false,"name":"input_value","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"sender":{"advanced":true,"display_name":"Sender Type","dynamic":false,"info":"Type of sender.","name":"sender","options":["Machine","User"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Machine"},"sender_name":{"advanced":true,"display_name":"Sender Name","dynamic":false,"info":"Name of the sender.","input_types":["Message"],"list":false,"load_from_db":false,"name":"sender_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"AI"},"session_id":{"advanced":true,"display_name":"Session ID","dynamic":false,"info":"Session ID for the message.","input_types":["Message"],"list":false,"load_from_db":false,"name":"session_id","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""}}},"type":"ChatOutput"},"dragging":false,"height":308,"id":"ChatOutput-fDyGT","position":{"x":3769.242086248817,"y":585.3403837062634},"positionAbsolute":{"x":3769.242086248817,"y":585.3403837062634},"selected":false,"type":"genericNode","width":384},{"data":{"id":"SplitText-RkdZ3","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Split text into chunks based on specified criteria.","display_name":"Split Text","documentation":"","edited":false,"field_order":["data_inputs","chunk_overlap","chunk_size","separator"],"frozen":false,"icon":"scissors-line-dashed","output_types":[],"outputs":[{"cache":true,"display_name":"Chunks","hidden":false,"method":"split_text","name":"chunks","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","chunk_overlap":{"advanced":false,"display_name":"Chunk Overlap","dynamic":false,"info":"Number of characters to overlap between chunks.","list":false,"name":"chunk_overlap","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":200},"chunk_size":{"advanced":false,"display_name":"Chunk Size","dynamic":false,"info":"The maximum number of characters in each chunk.","list":false,"name":"chunk_size","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":1000},"code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from typing import List\n\nfrom langchain_text_splitters import CharacterTextSplitter\n\nfrom langflow.custom import Component\nfrom langflow.io import HandleInput, IntInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.utils.util import unescape_string\n\n\nclass SplitTextComponent(Component):\n display_name: str = \"Split Text\"\n description: str = \"Split text into chunks based on specified criteria.\"\n icon = \"scissors-line-dashed\"\n\n inputs = [\n HandleInput(\n name=\"data_inputs\",\n display_name=\"Data Inputs\",\n info=\"The data to split.\",\n input_types=[\"Data\"],\n is_list=True,\n ),\n IntInput(\n name=\"chunk_overlap\",\n display_name=\"Chunk Overlap\",\n info=\"Number of characters to overlap between chunks.\",\n value=200,\n ),\n IntInput(\n name=\"chunk_size\",\n display_name=\"Chunk Size\",\n info=\"The maximum number of characters in each chunk.\",\n value=1000,\n ),\n MessageTextInput(\n name=\"separator\",\n display_name=\"Separator\",\n info=\"The character to split on. Defaults to newline.\",\n value=\"\\n\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chunks\", name=\"chunks\", method=\"split_text\"),\n ]\n\n def _docs_to_data(self, docs):\n data = []\n for doc in docs:\n data.append(Data(text=doc.page_content, data=doc.metadata))\n return data\n\n def split_text(self) -> List[Data]:\n separator = unescape_string(self.separator)\n\n documents = []\n for _input in self.data_inputs:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n\n splitter = CharacterTextSplitter(\n chunk_overlap=self.chunk_overlap,\n chunk_size=self.chunk_size,\n separator=separator,\n )\n docs = splitter.split_documents(documents)\n data = self._docs_to_data(docs)\n self.status = data\n return data\n"},"data_inputs":{"advanced":false,"display_name":"Data Inputs","dynamic":false,"info":"The data to split.","input_types":["Data"],"list":true,"name":"data_inputs","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"other","value":""},"separator":{"advanced":false,"display_name":"Separator","dynamic":false,"info":"The character to split on. Defaults to newline.","input_types":["Message"],"list":false,"load_from_db":false,"name":"separator","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":"\n"}}},"type":"SplitText"},"dragging":false,"height":527,"id":"SplitText-RkdZ3","position":{"x":2044.2799160989089,"y":1185.3130355818519},"positionAbsolute":{"x":2044.2799160989089,"y":1185.3130355818519},"selected":false,"type":"genericNode","width":384},{"data":{"id":"File-BTJVJ","node":{"base_classes":["Data"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"A generic file loader.","display_name":"File","documentation":"","edited":false,"field_order":["path","silent_errors"],"frozen":false,"icon":"file-text","output_types":[],"outputs":[{"cache":true,"display_name":"Data","hidden":false,"method":"load_file","name":"data","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n"},"path":{"advanced":false,"display_name":"Path","dynamic":false,"fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx"],"file_path":"","info":"Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx","list":false,"name":"path","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"file","value":""},"silent_errors":{"advanced":true,"display_name":"Silent Errors","dynamic":false,"info":"If true, errors will not raise an exception.","list":false,"name":"silent_errors","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false}}},"type":"File"},"dragging":false,"height":300,"id":"File-BTJVJ","position":{"x":1418.981990122179,"y":1539.3825691184466},"positionAbsolute":{"x":1418.981990122179,"y":1539.3825691184466},"selected":false,"type":"genericNode","width":384},{"data":{"id":"AstraDB-XXizY","node":{"base_classes":["Data","Retriever"],"beta":false,"conditional_paths":[],"custom_fields":{},"description":"Implementation of Vector Store using Astra DB with search capabilities","display_name":"Astra DB","documentation":"https://python.langchain.com/docs/integrations/vectorstores/astradb","edited":false,"field_order":["collection_name","token","api_endpoint","search_input","ingest_data","namespace","metric","batch_size","bulk_insert_batch_concurrency","bulk_insert_overwrite_concurrency","bulk_delete_concurrency","setup_mode","pre_delete_collection","metadata_indexing_include","embedding","metadata_indexing_exclude","collection_indexing_policy","search_type","number_of_results"],"frozen":false,"icon":"AstraDB","output_types":[],"outputs":[{"cache":true,"display_name":"Retriever","method":"build_base_retriever","name":"base_retriever","selected":"Retriever","types":["Retriever"],"value":"__UNDEFINED__"},{"cache":true,"display_name":"Search Results","method":"search_documents","name":"search_results","selected":"Data","types":["Data"],"value":"__UNDEFINED__"}],"pinned":false,"template":{"_type":"Component","api_endpoint":{"advanced":false,"display_name":"API Endpoint","dynamic":false,"info":"API endpoint URL for the Astra DB service.","input_types":[],"load_from_db":false,"name":"api_endpoint","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""},"batch_size":{"advanced":true,"display_name":"Batch Size","dynamic":false,"info":"Optional number of data to process in a single batch.","list":false,"name":"batch_size","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_delete_concurrency":{"advanced":true,"display_name":"Bulk Delete Concurrency","dynamic":false,"info":"Optional concurrency level for bulk delete operations.","list":false,"name":"bulk_delete_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_batch_concurrency":{"advanced":true,"display_name":"Bulk Insert Batch Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations.","list":false,"name":"bulk_insert_batch_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"bulk_insert_overwrite_concurrency":{"advanced":true,"display_name":"Bulk Insert Overwrite Concurrency","dynamic":false,"info":"Optional concurrency level for bulk insert operations that overwrite existing data.","list":false,"name":"bulk_insert_overwrite_concurrency","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":""},"code":{"advanced":true,"dynamic":true,"fileTypes":[],"file_path":"","info":"","list":false,"load_from_db":false,"multiline":true,"name":"code","password":false,"placeholder":"","required":true,"show":true,"title_case":false,"type":"code","value":"from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n"},"collection_indexing_policy":{"advanced":true,"display_name":"Collection Indexing Policy","dynamic":false,"info":"Optional dictionary defining the indexing policy for the collection.","list":false,"load_from_db":false,"name":"collection_indexing_policy","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"collection_name":{"advanced":false,"display_name":"Collection Name","dynamic":false,"info":"The name of the collection within Astra DB where the vectors will be stored.","list":false,"load_from_db":false,"name":"collection_name","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"langflow"},"embedding":{"advanced":false,"display_name":"Embedding or Astra Vectorize","dynamic":false,"info":"","input_types":["Embeddings","dict"],"list":false,"name":"embedding","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"other","value":""},"ingest_data":{"advanced":false,"display_name":"Ingest Data","dynamic":false,"info":"","input_types":["Data"],"list":true,"name":"ingest_data","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"other","value":""},"metadata_indexing_exclude":{"advanced":true,"display_name":"Metadata Indexing Exclude","dynamic":false,"info":"Optional list of metadata fields to exclude from the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_exclude","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metadata_indexing_include":{"advanced":true,"display_name":"Metadata Indexing Include","dynamic":false,"info":"Optional list of metadata fields to include in the indexing.","list":false,"load_from_db":false,"name":"metadata_indexing_include","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"metric":{"advanced":true,"display_name":"Metric","dynamic":false,"info":"Optional distance metric for vector comparisons in the vector store.","name":"metric","options":["cosine","dot_product","euclidean"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"namespace":{"advanced":true,"display_name":"Namespace","dynamic":false,"info":"Optional namespace within Astra DB to use for the collection.","list":false,"load_from_db":false,"name":"namespace","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":""},"number_of_results":{"advanced":true,"display_name":"Number of Results","dynamic":false,"info":"Number of results to return.","list":false,"name":"number_of_results","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"int","value":4},"pre_delete_collection":{"advanced":true,"display_name":"Pre Delete Collection","dynamic":false,"info":"Boolean flag to determine whether to delete the collection before creating a new one.","list":false,"name":"pre_delete_collection","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"bool","value":false},"search_input":{"advanced":false,"display_name":"Search Input","dynamic":false,"info":"","input_types":["Message"],"list":false,"load_from_db":false,"multiline":true,"name":"search_input","placeholder":"","required":false,"show":true,"title_case":false,"trace_as_input":true,"trace_as_metadata":true,"type":"str","value":""},"search_type":{"advanced":true,"display_name":"Search Type","dynamic":false,"info":"","name":"search_type","options":["Similarity","MMR"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Similarity"},"setup_mode":{"advanced":true,"display_name":"Setup Mode","dynamic":false,"info":"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.","name":"setup_mode","options":["Sync","Async","Off"],"placeholder":"","required":false,"show":true,"title_case":false,"trace_as_metadata":true,"type":"str","value":"Sync"},"token":{"advanced":false,"display_name":"Astra DB Application Token","dynamic":false,"info":"Authentication token for accessing Astra DB.","input_types":[],"load_from_db":false,"name":"token","password":true,"placeholder":"","required":false,"show":true,"title_case":false,"type":"str","value":""}}},"type":"AstraDB"},"dragging":false,"height":753,"id":"AstraDB-XXizY","position":{"x":2676.4816074350247,"y":1269.304067004569},"positionAbsolute":{"x":2676.4816074350247,"y":1269.304067004569},"selected":false,"type":"genericNode","width":384},{"id":"OpenAIEmbeddings-fpOKp","type":"genericNode","position":{"x":2044.683126356786,"y":1785.2283494456522},"data":{"type":"OpenAIEmbeddings","node":{"template":{"_type":"Component","chunk_size":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1000,"name":"chunk_size","display_name":"Chunk Size","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"client":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"client","display_name":"Client","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\", value=\"OPENAI_API_KEY\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"default_headers":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_headers","display_name":"Default Headers","advanced":true,"dynamic":false,"info":"Default headers to use for the API request.","title_case":false,"type":"dict"},"default_query":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_query","display_name":"Default Query","advanced":true,"dynamic":false,"info":"Default query parameters to use for the API request.","title_case":false,"type":"dict"},"deployment":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"deployment","display_name":"Deployment","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"embedding_ctx_length":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1536,"name":"embedding_ctx_length","display_name":"Embedding Context Length","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"max_retries":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":3,"name":"max_retries","display_name":"Max Retries","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"model":{"trace_as_metadata":true,"options":["text-embedding-3-small","text-embedding-3-large","text-embedding-ada-002"],"required":false,"placeholder":"","show":true,"value":"text-embedding-3-small","name":"model","display_name":"Model","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"openai_api_base":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_type":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_type","display_name":"OpenAI API Type","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_version":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_version","display_name":"OpenAI API Version","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_organization":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_organization","display_name":"OpenAI Organization","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_proxy":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_proxy","display_name":"OpenAI Proxy","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"request_timeout":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"request_timeout","display_name":"Request Timeout","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"float"},"show_progress_bar":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"show_progress_bar","display_name":"Show Progress Bar","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"skip_empty":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"skip_empty","display_name":"Skip Empty","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"tiktoken_enable":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":true,"name":"tiktoken_enable","display_name":"TikToken Enable","advanced":true,"dynamic":false,"info":"If False, you must have transformers installed.","title_case":false,"type":"bool"},"tiktoken_model_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"tiktoken_model_name","display_name":"TikToken Model Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"}},"description":"Generate embeddings using OpenAI models.","icon":"OpenAI","base_classes":["Embeddings"],"display_name":"OpenAI Embeddings","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Embeddings"],"selected":"Embeddings","name":"embeddings","display_name":"Embeddings","method":"build_embeddings","value":"__UNDEFINED__","cache":true,"hidden":false}],"field_order":["default_headers","default_query","chunk_size","client","deployment","embedding_ctx_length","max_retries","model","model_kwargs","openai_api_base","openai_api_key","openai_api_type","openai_api_version","openai_organization","openai_proxy","request_timeout","show_progress_bar","skip_empty","tiktoken_model_name","tiktoken_enable"],"beta":false,"edited":false},"id":"OpenAIEmbeddings-fpOKp"},"selected":false,"width":384,"height":394,"dragging":false,"positionAbsolute":{"x":2044.683126356786,"y":1785.2283494456522}},{"id":"OpenAIEmbeddings-lCQlU","type":"genericNode","position":{"x":628.9252513328779,"y":648.6750537749285},"data":{"type":"OpenAIEmbeddings","node":{"template":{"_type":"Component","chunk_size":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1000,"name":"chunk_size","display_name":"Chunk Size","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"client":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"client","display_name":"Client","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\", value=\"OPENAI_API_KEY\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"default_headers":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_headers","display_name":"Default Headers","advanced":true,"dynamic":false,"info":"Default headers to use for the API request.","title_case":false,"type":"dict"},"default_query":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"default_query","display_name":"Default Query","advanced":true,"dynamic":false,"info":"Default query parameters to use for the API request.","title_case":false,"type":"dict"},"deployment":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"deployment","display_name":"Deployment","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"embedding_ctx_length":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":1536,"name":"embedding_ctx_length","display_name":"Embedding Context Length","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"max_retries":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":3,"name":"max_retries","display_name":"Max Retries","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int"},"model":{"trace_as_metadata":true,"options":["text-embedding-3-small","text-embedding-3-large","text-embedding-ada-002"],"required":false,"placeholder":"","show":true,"value":"text-embedding-3-small","name":"model","display_name":"Model","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"value":{},"name":"model_kwargs","display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict"},"openai_api_base":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_base","display_name":"OpenAI API Base","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"value":"OPENAI_API_KEY","name":"openai_api_key","display_name":"OpenAI API Key","advanced":false,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_type":{"load_from_db":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_type","display_name":"OpenAI API Type","advanced":true,"input_types":[],"dynamic":false,"info":"","title_case":false,"password":true,"type":"str"},"openai_api_version":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_api_version","display_name":"OpenAI API Version","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_organization":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_organization","display_name":"OpenAI Organization","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"openai_proxy":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"openai_proxy","display_name":"OpenAI Proxy","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"},"request_timeout":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"request_timeout","display_name":"Request Timeout","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"float"},"show_progress_bar":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"show_progress_bar","display_name":"Show Progress Bar","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"skip_empty":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":false,"name":"skip_empty","display_name":"Skip Empty","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool"},"tiktoken_enable":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"value":true,"name":"tiktoken_enable","display_name":"TikToken Enable","advanced":true,"dynamic":false,"info":"If False, you must have transformers installed.","title_case":false,"type":"bool"},"tiktoken_model_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"value":"","name":"tiktoken_model_name","display_name":"TikToken Model Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str"}},"description":"Generate embeddings using OpenAI models.","icon":"OpenAI","base_classes":["Embeddings"],"display_name":"OpenAI Embeddings","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Embeddings"],"selected":"Embeddings","name":"embeddings","display_name":"Embeddings","method":"build_embeddings","value":"__UNDEFINED__","cache":true,"hidden":false}],"field_order":["default_headers","default_query","chunk_size","client","deployment","embedding_ctx_length","max_retries","model","model_kwargs","openai_api_base","openai_api_key","openai_api_type","openai_api_version","openai_organization","openai_proxy","request_timeout","show_progress_bar","skip_empty","tiktoken_model_name","tiktoken_enable"],"beta":false,"edited":false},"id":"OpenAIEmbeddings-lCQlU"},"selected":false,"width":384,"height":394,"positionAbsolute":{"x":628.9252513328779,"y":648.6750537749285},"dragging":false}],"edges":[{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-tuEeg","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"search_input","id":"AstraDB-xVF1f","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-ChatInput-tuEeg{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-xVF1f{œfieldNameœ:œsearch_inputœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"ChatInput-tuEeg","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"AstraDB-xVF1f","targetHandle":"{œfieldNameœ:œsearch_inputœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"AstraDB","id":"AstraDB-xVF1f","name":"search_results","output_types":["Data"]},"targetHandle":{"fieldName":"data","id":"ParseData-ZG3Aa","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-AstraDB-xVF1f{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-xVF1fœ,œnameœ:œsearch_resultsœ,œoutput_typesœ:[œDataœ]}-ParseData-ZG3Aa{œfieldNameœ:œdataœ,œidœ:œParseData-ZG3Aaœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"AstraDB-xVF1f","sourceHandle":"{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-xVF1fœ,œnameœ:œsearch_resultsœ,œoutput_typesœ:[œDataœ]}","target":"ParseData-ZG3Aa","targetHandle":"{œfieldNameœ:œdataœ,œidœ:œParseData-ZG3Aaœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"ParseData","id":"ParseData-ZG3Aa","name":"text","output_types":["Message"]},"targetHandle":{"fieldName":"context","id":"Prompt-0Hp9v","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ParseData-ZG3Aa{œdataTypeœ:œParseDataœ,œidœ:œParseData-ZG3Aaœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-0Hp9v{œfieldNameœ:œcontextœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ParseData-ZG3Aa","sourceHandle":"{œdataTypeœ:œParseDataœ,œidœ:œParseData-ZG3Aaœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-0Hp9v","targetHandle":"{œfieldNameœ:œcontextœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"ChatInput","id":"ChatInput-tuEeg","name":"message","output_types":["Message"]},"targetHandle":{"fieldName":"question","id":"Prompt-0Hp9v","inputTypes":["Message","Text"],"type":"str"}},"id":"reactflow__edge-ChatInput-tuEeg{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-0Hp9v{œfieldNameœ:œquestionœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","source":"ChatInput-tuEeg","sourceHandle":"{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}","target":"Prompt-0Hp9v","targetHandle":"{œfieldNameœ:œquestionœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"Prompt","id":"Prompt-0Hp9v","name":"prompt","output_types":["Message"]},"targetHandle":{"fieldName":"input_value","id":"OpenAIModel-BQXFs","inputTypes":["Message"],"type":"str"}},"id":"reactflow__edge-Prompt-0Hp9v{œdataTypeœ:œPromptœ,œidœ:œPrompt-0Hp9vœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-BQXFs{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BQXFsœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","source":"Prompt-0Hp9v","sourceHandle":"{œdataTypeœ:œPromptœ,œidœ:œPrompt-0Hp9vœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}","target":"OpenAIModel-BQXFs","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BQXFsœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","className":""},{"data":{"sourceHandle":{"dataType":"File","id":"File-BTJVJ","name":"data","output_types":["Data"]},"targetHandle":{"fieldName":"data_inputs","id":"SplitText-RkdZ3","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-File-BTJVJ{œdataTypeœ:œFileœ,œidœ:œFile-BTJVJœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-SplitText-RkdZ3{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-RkdZ3œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"File-BTJVJ","sourceHandle":"{œdataTypeœ:œFileœ,œidœ:œFile-BTJVJœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}","target":"SplitText-RkdZ3","targetHandle":"{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-RkdZ3œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"data":{"sourceHandle":{"dataType":"SplitText","id":"SplitText-RkdZ3","name":"chunks","output_types":["Data"]},"targetHandle":{"fieldName":"ingest_data","id":"AstraDB-XXizY","inputTypes":["Data"],"type":"other"}},"id":"reactflow__edge-SplitText-RkdZ3{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-RkdZ3œ,œnameœ:œchunksœ,œoutput_typesœ:[œDataœ]}-AstraDB-XXizY{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","source":"SplitText-RkdZ3","sourceHandle":"{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-RkdZ3œ,œnameœ:œchunksœ,œoutput_typesœ:[œDataœ]}","target":"AstraDB-XXizY","targetHandle":"{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}","className":""},{"source":"OpenAIModel-BQXFs","sourceHandle":"{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-BQXFsœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}","target":"ChatOutput-fDyGT","targetHandle":"{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-fDyGTœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}","data":{"targetHandle":{"fieldName":"input_value","id":"ChatOutput-fDyGT","inputTypes":["Message"],"type":"str"},"sourceHandle":{"dataType":"OpenAIModelComponent","id":"OpenAIModel-BQXFs","name":"text_output","output_types":["Message"]}},"id":"reactflow__edge-OpenAIModel-BQXFs{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-BQXFsœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-fDyGT{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-fDyGTœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}"},{"source":"OpenAIEmbeddings-fpOKp","sourceHandle":"{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-fpOKpœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}","target":"AstraDB-XXizY","targetHandle":"{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}","data":{"targetHandle":{"fieldName":"embedding","id":"AstraDB-XXizY","inputTypes":["Embeddings","dict"],"type":"other"},"sourceHandle":{"dataType":"OpenAIEmbeddings","id":"OpenAIEmbeddings-fpOKp","name":"embeddings","output_types":["Embeddings"]}},"id":"reactflow__edge-OpenAIEmbeddings-fpOKp{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-fpOKpœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-XXizY{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}"},{"source":"OpenAIEmbeddings-lCQlU","sourceHandle":"{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-lCQlUœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}","target":"AstraDB-xVF1f","targetHandle":"{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}","data":{"targetHandle":{"fieldName":"embedding","id":"AstraDB-xVF1f","inputTypes":["Embeddings","dict"],"type":"other"},"sourceHandle":{"dataType":"OpenAIEmbeddings","id":"OpenAIEmbeddings-lCQlU","name":"embeddings","output_types":["Embeddings"]}},"id":"reactflow__edge-OpenAIEmbeddings-lCQlU{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-lCQlUœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-xVF1f{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}"}],"viewport":{"x":-110.08684771034166,"y":-46.27017080984389,"zoom":0.3228119071747796}},"description":"Visit https://docs.langflow.org/tutorials/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.","name":"Vector Store RAG","last_tested_version":"1.0.5","endpoint_name":null,"is_component":false} \ No newline at end of file +{ + "data": { + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-tuEeg", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "search_input", + "id": "AstraDB-xVF1f", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-tuEeg{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-xVF1f{œfieldNameœ:œsearch_inputœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "ChatInput-tuEeg", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-tuEegœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "AstraDB-xVF1f", + "targetHandle": "{œfieldNameœ: œsearch_inputœ, œidœ: œAstraDB-xVF1fœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "AstraDB", + "id": "AstraDB-xVF1f", + "name": "search_results", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "data", + "id": "ParseData-ZG3Aa", + "inputTypes": [ + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-AstraDB-xVF1f{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-xVF1fœ,œnameœ:œsearch_resultsœ,œoutput_typesœ:[œDataœ]}-ParseData-ZG3Aa{œfieldNameœ:œdataœ,œidœ:œParseData-ZG3Aaœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", + "source": "AstraDB-xVF1f", + "sourceHandle": "{œdataTypeœ: œAstraDBœ, œidœ: œAstraDB-xVF1fœ, œnameœ: œsearch_resultsœ, œoutput_typesœ: [œDataœ]}", + "target": "ParseData-ZG3Aa", + "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-ZG3Aaœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ParseData", + "id": "ParseData-ZG3Aa", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "context", + "id": "Prompt-0Hp9v", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ParseData-ZG3Aa{œdataTypeœ:œParseDataœ,œidœ:œParseData-ZG3Aaœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-0Hp9v{œfieldNameœ:œcontextœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ParseData-ZG3Aa", + "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-ZG3Aaœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-0Hp9v", + "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-0Hp9vœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-tuEeg", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "question", + "id": "Prompt-0Hp9v", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-tuEeg{œdataTypeœ:œChatInputœ,œidœ:œChatInput-tuEegœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-0Hp9v{œfieldNameœ:œquestionœ,œidœ:œPrompt-0Hp9vœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "ChatInput-tuEeg", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-tuEegœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-0Hp9v", + "targetHandle": "{œfieldNameœ: œquestionœ, œidœ: œPrompt-0Hp9vœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-0Hp9v", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-BQXFs", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-0Hp9v{œdataTypeœ:œPromptœ,œidœ:œPrompt-0Hp9vœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-BQXFs{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BQXFsœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-0Hp9v", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-0Hp9vœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-BQXFs", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-BQXFsœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "File", + "id": "File-BTJVJ", + "name": "data", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "data_inputs", + "id": "SplitText-RkdZ3", + "inputTypes": [ + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-File-BTJVJ{œdataTypeœ:œFileœ,œidœ:œFile-BTJVJœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-SplitText-RkdZ3{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-RkdZ3œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", + "source": "File-BTJVJ", + "sourceHandle": "{œdataTypeœ: œFileœ, œidœ: œFile-BTJVJœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}", + "target": "SplitText-RkdZ3", + "targetHandle": "{œfieldNameœ: œdata_inputsœ, œidœ: œSplitText-RkdZ3œ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "SplitText", + "id": "SplitText-RkdZ3", + "name": "chunks", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "ingest_data", + "id": "AstraDB-XXizY", + "inputTypes": [ + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-SplitText-RkdZ3{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-RkdZ3œ,œnameœ:œchunksœ,œoutput_typesœ:[œDataœ]}-AstraDB-XXizY{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", + "source": "SplitText-RkdZ3", + "sourceHandle": "{œdataTypeœ: œSplitTextœ, œidœ: œSplitText-RkdZ3œ, œnameœ: œchunksœ, œoutput_typesœ: [œDataœ]}", + "target": "AstraDB-XXizY", + "targetHandle": "{œfieldNameœ: œingest_dataœ, œidœ: œAstraDB-XXizYœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIModelComponent", + "id": "OpenAIModel-BQXFs", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-fDyGT", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-BQXFs{œdataTypeœ:œOpenAIModelComponentœ,œidœ:œOpenAIModel-BQXFsœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-fDyGT{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-fDyGTœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-BQXFs", + "sourceHandle": "{œdataTypeœ: œOpenAIModelComponentœ, œidœ: œOpenAIModel-BQXFsœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-fDyGT", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-fDyGTœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIEmbeddings", + "id": "OpenAIEmbeddings-fpOKp", + "name": "embeddings", + "output_types": [ + "Embeddings" + ] + }, + "targetHandle": { + "fieldName": "embedding", + "id": "AstraDB-XXizY", + "inputTypes": [ + "Embeddings", + "dict" + ], + "type": "other" + } + }, + "id": "reactflow__edge-OpenAIEmbeddings-fpOKp{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-fpOKpœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-XXizY{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-XXizYœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}", + "source": "OpenAIEmbeddings-fpOKp", + "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-fpOKpœ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", + "target": "AstraDB-XXizY", + "targetHandle": "{œfieldNameœ: œembeddingœ, œidœ: œAstraDB-XXizYœ, œinputTypesœ: [œEmbeddingsœ, œdictœ], œtypeœ: œotherœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "OpenAIEmbeddings", + "id": "OpenAIEmbeddings-lCQlU", + "name": "embeddings", + "output_types": [ + "Embeddings" + ] + }, + "targetHandle": { + "fieldName": "embedding", + "id": "AstraDB-xVF1f", + "inputTypes": [ + "Embeddings", + "dict" + ], + "type": "other" + } + }, + "id": "reactflow__edge-OpenAIEmbeddings-lCQlU{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-lCQlUœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-xVF1f{œfieldNameœ:œembeddingœ,œidœ:œAstraDB-xVF1fœ,œinputTypesœ:[œEmbeddingsœ,œdictœ],œtypeœ:œotherœ}", + "source": "OpenAIEmbeddings-lCQlU", + "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-lCQlUœ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", + "target": "AstraDB-xVF1f", + "targetHandle": "{œfieldNameœ: œembeddingœ, œidœ: œAstraDB-xVF1fœ, œinputTypesœ: [œEmbeddingsœ, œdictœ], œtypeœ: œotherœ}" + } + ], + "nodes": [ + { + "data": { + "id": "ChatInput-tuEeg", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Get chat inputs from the Playground.", + "display_name": "Chat Input", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "files" + ], + "frozen": false, + "icon": "ChatInput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "hidden": false, + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "files": { + "advanced": true, + "display_name": "Files", + "dynamic": false, + "fileTypes": [ + "txt", + "md", + "mdx", + "csv", + "json", + "yaml", + "yml", + "xml", + "html", + "htm", + "pdf", + "docx", + "py", + "sh", + "sql", + "js", + "ts", + "tsx", + "jpg", + "jpeg", + "png", + "bmp", + "image" + ], + "file_path": "", + "info": "Files to be sent with the message.", + "list": true, + "name": "files", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "file", + "value": "" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as input.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "User" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatInput" + }, + "dragging": false, + "height": 308, + "id": "ChatInput-tuEeg", + "position": { + "x": 642.3545710150049, + "y": 220.22556606238678 + }, + "positionAbsolute": { + "x": 642.3545710150049, + "y": 220.22556606238678 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "AstraDB-xVF1f", + "node": { + "base_classes": [ + "Data", + "Retriever" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Implementation of Vector Store using Astra DB with search capabilities", + "display_name": "Astra DB", + "documentation": "https://python.langchain.com/docs/integrations/vectorstores/astradb", + "edited": false, + "field_order": [ + "collection_name", + "token", + "api_endpoint", + "search_input", + "ingest_data", + "namespace", + "metric", + "batch_size", + "bulk_insert_batch_concurrency", + "bulk_insert_overwrite_concurrency", + "bulk_delete_concurrency", + "setup_mode", + "pre_delete_collection", + "metadata_indexing_include", + "embedding", + "metadata_indexing_exclude", + "collection_indexing_policy", + "search_type", + "number_of_results" + ], + "frozen": false, + "icon": "AstraDB", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Retriever", + "method": "build_base_retriever", + "name": "base_retriever", + "selected": "Retriever", + "types": [ + "Retriever" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Search Results", + "hidden": false, + "method": "search_documents", + "name": "search_results", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "api_endpoint": { + "advanced": false, + "display_name": "API Endpoint", + "dynamic": false, + "info": "API endpoint URL for the Astra DB service.", + "input_types": [], + "load_from_db": false, + "name": "api_endpoint", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "batch_size": { + "advanced": true, + "display_name": "Batch Size", + "dynamic": false, + "info": "Optional number of data to process in a single batch.", + "list": false, + "name": "batch_size", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "bulk_delete_concurrency": { + "advanced": true, + "display_name": "Bulk Delete Concurrency", + "dynamic": false, + "info": "Optional concurrency level for bulk delete operations.", + "list": false, + "name": "bulk_delete_concurrency", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "bulk_insert_batch_concurrency": { + "advanced": true, + "display_name": "Bulk Insert Batch Concurrency", + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations.", + "list": false, + "name": "bulk_insert_batch_concurrency", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "bulk_insert_overwrite_concurrency": { + "advanced": true, + "display_name": "Bulk Insert Overwrite Concurrency", + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations that overwrite existing data.", + "list": false, + "name": "bulk_insert_overwrite_concurrency", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n" + }, + "collection_indexing_policy": { + "advanced": true, + "display_name": "Collection Indexing Policy", + "dynamic": false, + "info": "Optional dictionary defining the indexing policy for the collection.", + "list": false, + "load_from_db": false, + "name": "collection_indexing_policy", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "collection_name": { + "advanced": false, + "display_name": "Collection Name", + "dynamic": false, + "info": "The name of the collection within Astra DB where the vectors will be stored.", + "list": false, + "load_from_db": false, + "name": "collection_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "langflow" + }, + "embedding": { + "advanced": false, + "display_name": "Embedding or Astra Vectorize", + "dynamic": false, + "info": "", + "input_types": [ + "Embeddings", + "dict" + ], + "list": false, + "name": "embedding", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "ingest_data": { + "advanced": false, + "display_name": "Ingest Data", + "dynamic": false, + "info": "", + "input_types": [ + "Data" + ], + "list": true, + "name": "ingest_data", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "metadata_indexing_exclude": { + "advanced": true, + "display_name": "Metadata Indexing Exclude", + "dynamic": false, + "info": "Optional list of metadata fields to exclude from the indexing.", + "list": false, + "load_from_db": false, + "name": "metadata_indexing_exclude", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "metadata_indexing_include": { + "advanced": true, + "display_name": "Metadata Indexing Include", + "dynamic": false, + "info": "Optional list of metadata fields to include in the indexing.", + "list": false, + "load_from_db": false, + "name": "metadata_indexing_include", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "metric": { + "advanced": true, + "display_name": "Metric", + "dynamic": false, + "info": "Optional distance metric for vector comparisons in the vector store.", + "name": "metric", + "options": [ + "cosine", + "dot_product", + "euclidean" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "namespace": { + "advanced": true, + "display_name": "Namespace", + "dynamic": false, + "info": "Optional namespace within Astra DB to use for the collection.", + "list": false, + "load_from_db": false, + "name": "namespace", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "number_of_results": { + "advanced": true, + "display_name": "Number of Results", + "dynamic": false, + "info": "Number of results to return.", + "list": false, + "name": "number_of_results", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 4 + }, + "pre_delete_collection": { + "advanced": true, + "display_name": "Pre Delete Collection", + "dynamic": false, + "info": "Boolean flag to determine whether to delete the collection before creating a new one.", + "list": false, + "name": "pre_delete_collection", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "search_input": { + "advanced": false, + "display_name": "Search Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "search_input", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "search_type": { + "advanced": true, + "display_name": "Search Type", + "dynamic": false, + "info": "", + "name": "search_type", + "options": [ + "Similarity", + "MMR" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Similarity" + }, + "setup_mode": { + "advanced": true, + "display_name": "Setup Mode", + "dynamic": false, + "info": "Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.", + "name": "setup_mode", + "options": [ + "Sync", + "Async", + "Off" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Sync" + }, + "token": { + "advanced": false, + "display_name": "Astra DB Application Token", + "dynamic": false, + "info": "Authentication token for accessing Astra DB.", + "input_types": [], + "load_from_db": false, + "name": "token", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + } + } + }, + "type": "AstraDB" + }, + "dragging": false, + "height": 753, + "id": "AstraDB-xVF1f", + "position": { + "x": 1246.0381406498648, + "y": 333.25157075413966 + }, + "positionAbsolute": { + "x": 1246.0381406498648, + "y": 333.25157075413966 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ParseData-ZG3Aa", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Convert Data into plain text following a specified template.", + "display_name": "Parse Data", + "documentation": "", + "edited": false, + "field_order": [ + "data", + "template", + "sep" + ], + "frozen": false, + "icon": "braces", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "parse_data", + "name": "text", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DataInput, MultilineInput, Output, StrInput\nfrom langflow.schema.message import Message\n\n\nclass ParseDataComponent(Component):\n display_name = \"Parse Data\"\n description = \"Convert Data into plain text following a specified template.\"\n icon = \"braces\"\n\n inputs = [\n DataInput(name=\"data\", display_name=\"Data\", info=\"The data to convert to text.\"),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.\",\n value=\"{text}\",\n ),\n StrInput(name=\"sep\", display_name=\"Separator\", advanced=True, value=\"\\n\"),\n ]\n\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"parse_data\"),\n ]\n\n def parse_data(self) -> Message:\n data = self.data if isinstance(self.data, list) else [self.data]\n template = self.template\n\n result_string = data_to_text(template, data, sep=self.sep)\n self.status = result_string\n return Message(text=result_string)\n" + }, + "data": { + "advanced": false, + "display_name": "Data", + "dynamic": false, + "info": "The data to convert to text.", + "input_types": [ + "Data" + ], + "list": false, + "name": "data", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "sep": { + "advanced": true, + "display_name": "Separator", + "dynamic": false, + "info": "", + "list": false, + "load_from_db": false, + "name": "sep", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + } + } + }, + "type": "ParseData" + }, + "dragging": false, + "height": 384, + "id": "ParseData-ZG3Aa", + "position": { + "x": 1854.1518317915907, + "y": 459.3386924128532 + }, + "positionAbsolute": { + "x": 1854.1518317915907, + "y": 459.3386924128532 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-0Hp9v", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": { + "template": [ + "context", + "question" + ] + }, + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "documentation": "", + "edited": false, + "error": null, + "field_order": [ + "template" + ], + "frozen": false, + "full_path": null, + "icon": "prompts", + "is_composition": null, + "is_input": null, + "is_output": null, + "name": "", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Prompt Message", + "hidden": false, + "method": "build_prompt", + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = await Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def post_code_processing(self, new_build_config: dict, current_build_config: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_build_config, current_build_config)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_build_config\n # and update the frontend_node with those values\n update_template_values(frontend_template=frontend_node, raw_template=current_build_config[\"template\"])\n return frontend_node\n" + }, + "context": { + "advanced": false, + "display_name": "context", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "context", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "question": { + "advanced": false, + "display_name": "question", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Message", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "question", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "info": "", + "list": false, + "name": "template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "prompt", + "value": "{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: " + } + } + }, + "type": "Prompt" + }, + "dragging": false, + "height": 515, + "id": "Prompt-0Hp9v", + "position": { + "x": 2486.0988668404975, + "y": 496.5120474157301 + }, + "positionAbsolute": { + "x": 2486.0988668404975, + "y": 496.5120474157301 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "edited": false, + "id": "OpenAIModel-BQXFs", + "node": { + "base_classes": [ + "LanguageModel", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "edited": true, + "field_order": [ + "input_value", + "max_tokens", + "model_kwargs", + "json_mode", + "output_schema", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "stream", + "system_message", + "seed" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Text", + "hidden": false, + "method": "text_response", + "name": "text_output", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Language Model", + "method": "build_model", + "name": "model_output", + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import operator\nfrom functools import reduce\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 LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n MessageInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n MessageInput(name=\"input_value\", display_name=\"Input\"),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"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 value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n # self.output_schea is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n model_kwargs[\"seed\"] = seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "json_mode": { + "advanced": true, + "display_name": "JSON Mode", + "dynamic": false, + "info": "If True, it will output JSON regardless of passing a schema.", + "list": false, + "name": "json_mode", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "name": "max_tokens", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "info": "", + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "gpt-4-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", + "list": false, + "load_from_db": false, + "name": "openai_api_base", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "output_schema": { + "advanced": true, + "display_name": "Schema", + "dynamic": false, + "info": "The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.", + "list": true, + "name": "output_schema", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "seed": { + "advanced": true, + "display_name": "Seed", + "dynamic": false, + "info": "The seed controls the reproducibility of the job.", + "list": false, + "name": "seed", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1 + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "name": "stream", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "info": "System message to pass to the model.", + "list": false, + "load_from_db": false, + "name": "system_message", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "info": "", + "list": false, + "name": "temperature", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": 0.1 + } + } + }, + "type": "OpenAIModelComponent" + }, + "dragging": false, + "height": 621, + "id": "OpenAIModel-BQXFs", + "position": { + "x": 3145.6693008609222, + "y": 374.23955005474204 + }, + "positionAbsolute": { + "x": 3145.6693008609222, + "y": 374.23955005474204 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatOutput-fDyGT", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "edited": false, + "field_order": [ + "input_value", + "sender", + "sender_name", + "session_id", + "data_template" + ], + "frozen": false, + "icon": "ChatOutput", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Message", + "method": "message_response", + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True\n ),\n MessageTextInput(\n name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.message.value = message\n\n self.status = message\n return message\n" + }, + "data_template": { + "advanced": true, + "display_name": "Data Template", + "dynamic": false, + "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "data_template", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "{text}" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "info": "Message to be passed as output.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "info": "Type of sender.", + "name": "sender", + "options": [ + "Machine", + "User" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "info": "Name of the sender.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "sender_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": true, + "display_name": "Session ID", + "dynamic": false, + "info": "Session ID for the message.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "session_id", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 308, + "id": "ChatOutput-fDyGT", + "position": { + "x": 3769.242086248817, + "y": 585.3403837062634 + }, + "positionAbsolute": { + "x": 3769.242086248817, + "y": 585.3403837062634 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "SplitText-RkdZ3", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Split text into chunks based on specified criteria.", + "display_name": "Split Text", + "documentation": "", + "edited": false, + "field_order": [ + "data_inputs", + "chunk_overlap", + "chunk_size", + "separator" + ], + "frozen": false, + "icon": "scissors-line-dashed", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Chunks", + "hidden": false, + "method": "split_text", + "name": "chunks", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "chunk_overlap": { + "advanced": false, + "display_name": "Chunk Overlap", + "dynamic": false, + "info": "Number of characters to overlap between chunks.", + "list": false, + "name": "chunk_overlap", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 200 + }, + "chunk_size": { + "advanced": false, + "display_name": "Chunk Size", + "dynamic": false, + "info": "The maximum number of characters in each chunk.", + "list": false, + "name": "chunk_size", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1000 + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import List\n\nfrom langchain_text_splitters import CharacterTextSplitter\n\nfrom langflow.custom import Component\nfrom langflow.io import HandleInput, IntInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.utils.util import unescape_string\n\n\nclass SplitTextComponent(Component):\n display_name: str = \"Split Text\"\n description: str = \"Split text into chunks based on specified criteria.\"\n icon = \"scissors-line-dashed\"\n\n inputs = [\n HandleInput(\n name=\"data_inputs\",\n display_name=\"Data Inputs\",\n info=\"The data to split.\",\n input_types=[\"Data\"],\n is_list=True,\n ),\n IntInput(\n name=\"chunk_overlap\",\n display_name=\"Chunk Overlap\",\n info=\"Number of characters to overlap between chunks.\",\n value=200,\n ),\n IntInput(\n name=\"chunk_size\",\n display_name=\"Chunk Size\",\n info=\"The maximum number of characters in each chunk.\",\n value=1000,\n ),\n MessageTextInput(\n name=\"separator\",\n display_name=\"Separator\",\n info=\"The character to split on. Defaults to newline.\",\n value=\"\\n\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Chunks\", name=\"chunks\", method=\"split_text\"),\n ]\n\n def _docs_to_data(self, docs):\n data = []\n for doc in docs:\n data.append(Data(text=doc.page_content, data=doc.metadata))\n return data\n\n def split_text(self) -> List[Data]:\n separator = unescape_string(self.separator)\n\n documents = []\n for _input in self.data_inputs:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n\n splitter = CharacterTextSplitter(\n chunk_overlap=self.chunk_overlap,\n chunk_size=self.chunk_size,\n separator=separator,\n )\n docs = splitter.split_documents(documents)\n data = self._docs_to_data(docs)\n self.status = data\n return data\n" + }, + "data_inputs": { + "advanced": false, + "display_name": "Data Inputs", + "dynamic": false, + "info": "The data to split.", + "input_types": [ + "Data" + ], + "list": true, + "name": "data_inputs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "separator": { + "advanced": false, + "display_name": "Separator", + "dynamic": false, + "info": "The character to split on. Defaults to newline.", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "separator", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "\n" + } + } + }, + "type": "SplitText" + }, + "dragging": false, + "height": 527, + "id": "SplitText-RkdZ3", + "position": { + "x": 2044.2799160989089, + "y": 1185.3130355818519 + }, + "positionAbsolute": { + "x": 2044.2799160989089, + "y": 1185.3130355818519 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "File-BTJVJ", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "A generic file loader.", + "display_name": "File", + "documentation": "", + "edited": false, + "field_order": [ + "path", + "silent_errors" + ], + "frozen": false, + "icon": "file-text", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "hidden": false, + "method": "load_file", + "name": "data", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from pathlib import Path\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=TEXT_FILE_TYPES,\n info=f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"load_file\"),\n ]\n\n def load_file(self) -> Data:\n if not self.path:\n raise ValueError(\"Please, upload a file to use this component.\")\n resolved_path = self.resolve_path(self.path)\n silent_errors = self.silent_errors\n\n extension = Path(resolved_path).suffix[1:].lower()\n\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n\n data = parse_text_file_to_data(resolved_path, silent_errors)\n self.status = data if data else \"No data\"\n return data or Data()\n" + }, + "path": { + "advanced": false, + "display_name": "Path", + "dynamic": false, + "fileTypes": [ + "txt", + "md", + "mdx", + "csv", + "json", + "yaml", + "yml", + "xml", + "html", + "htm", + "pdf", + "docx", + "py", + "sh", + "sql", + "js", + "ts", + "tsx" + ], + "file_path": "", + "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx, py, sh, sql, js, ts, tsx", + "list": false, + "name": "path", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "file", + "value": "" + }, + "silent_errors": { + "advanced": true, + "display_name": "Silent Errors", + "dynamic": false, + "info": "If true, errors will not raise an exception.", + "list": false, + "name": "silent_errors", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + } + } + }, + "type": "File" + }, + "dragging": false, + "height": 300, + "id": "File-BTJVJ", + "position": { + "x": 1418.981990122179, + "y": 1539.3825691184466 + }, + "positionAbsolute": { + "x": 1418.981990122179, + "y": 1539.3825691184466 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "AstraDB-XXizY", + "node": { + "base_classes": [ + "Data", + "Retriever" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Implementation of Vector Store using Astra DB with search capabilities", + "display_name": "Astra DB", + "documentation": "https://python.langchain.com/docs/integrations/vectorstores/astradb", + "edited": false, + "field_order": [ + "collection_name", + "token", + "api_endpoint", + "search_input", + "ingest_data", + "namespace", + "metric", + "batch_size", + "bulk_insert_batch_concurrency", + "bulk_insert_overwrite_concurrency", + "bulk_delete_concurrency", + "setup_mode", + "pre_delete_collection", + "metadata_indexing_include", + "embedding", + "metadata_indexing_exclude", + "collection_indexing_policy", + "search_type", + "number_of_results" + ], + "frozen": false, + "icon": "AstraDB", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Retriever", + "method": "build_base_retriever", + "name": "base_retriever", + "selected": "Retriever", + "types": [ + "Retriever" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Search Results", + "method": "search_documents", + "name": "search_results", + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "api_endpoint": { + "advanced": false, + "display_name": "API Endpoint", + "dynamic": false, + "info": "API endpoint URL for the Astra DB service.", + "input_types": [], + "load_from_db": false, + "name": "api_endpoint", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "batch_size": { + "advanced": true, + "display_name": "Batch Size", + "dynamic": false, + "info": "Optional number of data to process in a single batch.", + "list": false, + "name": "batch_size", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "bulk_delete_concurrency": { + "advanced": true, + "display_name": "Bulk Delete Concurrency", + "dynamic": false, + "info": "Optional concurrency level for bulk delete operations.", + "list": false, + "name": "bulk_delete_concurrency", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "bulk_insert_batch_concurrency": { + "advanced": true, + "display_name": "Bulk Insert Batch Concurrency", + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations.", + "list": false, + "name": "bulk_insert_batch_concurrency", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "bulk_insert_overwrite_concurrency": { + "advanced": true, + "display_name": "Bulk Insert Overwrite Concurrency", + "dynamic": false, + "info": "Optional concurrency level for bulk insert operations that overwrite existing data.", + "list": false, + "name": "bulk_insert_overwrite_concurrency", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from loguru import logger\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n MultilineInput,\n SecretStrInput,\n StrInput,\n DataInput,\n)\nfrom langflow.schema import Data\n\n\nclass AstraVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Implementation of Vector Store using Astra DB with search capabilities\"\n documentation: str = \"https://python.langchain.com/docs/integrations/vectorstores/astradb\"\n icon: str = \"AstraDB\"\n\n inputs = [\n StrInput(\n name=\"collection_name\",\n display_name=\"Collection Name\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n ),\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n ),\n SecretStrInput(\n name=\"api_endpoint\",\n display_name=\"API Endpoint\",\n info=\"API endpoint URL for the Astra DB service.\",\n value=\"ASTRA_DB_API_ENDPOINT\",\n ),\n MultilineInput(\n name=\"search_input\",\n display_name=\"Search Input\",\n ),\n DataInput(\n name=\"ingest_data\",\n display_name=\"Ingest Data\",\n is_list=True,\n ),\n StrInput(\n name=\"namespace\",\n display_name=\"Namespace\",\n info=\"Optional namespace within Astra DB to use for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"metric\",\n display_name=\"Metric\",\n info=\"Optional distance metric for vector comparisons in the vector store.\",\n options=[\"cosine\", \"dot_product\", \"euclidean\"],\n advanced=True,\n ),\n IntInput(\n name=\"batch_size\",\n display_name=\"Batch Size\",\n info=\"Optional number of data to process in a single batch.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_batch_concurrency\",\n display_name=\"Bulk Insert Batch Concurrency\",\n info=\"Optional concurrency level for bulk insert operations.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_insert_overwrite_concurrency\",\n display_name=\"Bulk Insert Overwrite Concurrency\",\n info=\"Optional concurrency level for bulk insert operations that overwrite existing data.\",\n advanced=True,\n ),\n IntInput(\n name=\"bulk_delete_concurrency\",\n display_name=\"Bulk Delete Concurrency\",\n info=\"Optional concurrency level for bulk delete operations.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"setup_mode\",\n display_name=\"Setup Mode\",\n info=\"Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.\",\n options=[\"Sync\", \"Async\", \"Off\"],\n advanced=True,\n value=\"Sync\",\n ),\n BoolInput(\n name=\"pre_delete_collection\",\n display_name=\"Pre Delete Collection\",\n info=\"Boolean flag to determine whether to delete the collection before creating a new one.\",\n advanced=True,\n ),\n StrInput(\n name=\"metadata_indexing_include\",\n display_name=\"Metadata Indexing Include\",\n info=\"Optional list of metadata fields to include in the indexing.\",\n advanced=True,\n ),\n HandleInput(\n name=\"embedding\",\n display_name=\"Embedding or Astra Vectorize\",\n input_types=[\"Embeddings\", \"dict\"],\n ),\n StrInput(\n name=\"metadata_indexing_exclude\",\n display_name=\"Metadata Indexing Exclude\",\n info=\"Optional list of metadata fields to exclude from the indexing.\",\n advanced=True,\n ),\n StrInput(\n name=\"collection_indexing_policy\",\n display_name=\"Collection Indexing Policy\",\n info=\"Optional dictionary defining the indexing policy for the collection.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n options=[\"Similarity\", \"MMR\"],\n value=\"Similarity\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Results\",\n info=\"Number of results to return.\",\n advanced=True,\n value=4,\n ),\n ]\n\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n if not self.setup_mode:\n self.setup_mode = self._inputs[\"setup_mode\"].options[0]\n\n setup_mode_value = SetupMode[self.setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {self.setup_mode}\")\n\n if not isinstance(self.embedding, dict):\n embedding_dict = {\"embedding\": self.embedding}\n else:\n from astrapy.info import CollectionVectorServiceOptions\n\n dict_options = self.embedding.get(\"collection_vector_service_options\", {})\n dict_options[\"authentication\"] = {\n k: v for k, v in dict_options.get(\"authentication\", {}).items() if k and v\n }\n dict_options[\"parameters\"] = {k: v for k, v in dict_options.get(\"parameters\", {}).items() if k and v}\n embedding_dict = {\n \"collection_vector_service_options\": CollectionVectorServiceOptions.from_dict(dict_options),\n \"collection_embedding_api_key\": self.embedding.get(\"collection_embedding_api_key\"),\n }\n vector_store_kwargs = {\n **embedding_dict,\n \"collection_name\": self.collection_name,\n \"token\": self.token,\n \"api_endpoint\": self.api_endpoint,\n \"namespace\": self.namespace or None,\n \"metric\": self.metric or None,\n \"batch_size\": self.batch_size or None,\n \"bulk_insert_batch_concurrency\": self.bulk_insert_batch_concurrency or None,\n \"bulk_insert_overwrite_concurrency\": self.bulk_insert_overwrite_concurrency or None,\n \"bulk_delete_concurrency\": self.bulk_delete_concurrency or None,\n \"setup_mode\": setup_mode_value,\n \"pre_delete_collection\": self.pre_delete_collection or False,\n }\n\n if self.metadata_indexing_include:\n vector_store_kwargs[\"metadata_indexing_include\"] = self.metadata_indexing_include\n elif self.metadata_indexing_exclude:\n vector_store_kwargs[\"metadata_indexing_exclude\"] = self.metadata_indexing_exclude\n elif self.collection_indexing_policy:\n vector_store_kwargs[\"collection_indexing_policy\"] = self.collection_indexing_policy\n\n try:\n vector_store = AstraDBVectorStore(**vector_store_kwargs)\n except Exception as e:\n raise ValueError(f\"Error initializing AstraDBVectorStore: {str(e)}\") from e\n\n self.status = self._astradb_collection_to_data(vector_store.collection)\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store):\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n raise ValueError(\"Vector Store Inputs must be Data objects.\")\n\n if documents and self.embedding is not None:\n logger.debug(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n raise ValueError(f\"Error adding documents to AstraDBVectorStore: {str(e)}\") from e\n else:\n logger.debug(\"No documents to add to the Vector Store.\")\n\n def search_documents(self):\n vector_store = self.build_vector_store()\n\n logger.debug(f\"Search input: {self.search_input}\")\n logger.debug(f\"Search type: {self.search_type}\")\n logger.debug(f\"Number of results: {self.number_of_results}\")\n\n if self.search_input and isinstance(self.search_input, str) and self.search_input.strip():\n try:\n if self.search_type == \"Similarity\":\n docs = vector_store.similarity_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n elif self.search_type == \"MMR\":\n docs = vector_store.max_marginal_relevance_search(\n query=self.search_input,\n k=self.number_of_results,\n )\n else:\n raise ValueError(f\"Invalid search type: {self.search_type}\")\n except Exception as e:\n raise ValueError(f\"Error performing search in AstraDBVectorStore: {str(e)}\") from e\n\n logger.debug(f\"Retrieved documents: {len(docs)}\")\n\n data = [Data.from_document(doc) for doc in docs]\n logger.debug(f\"Converted documents to data: {len(data)}\")\n self.status = data\n return data\n else:\n logger.debug(\"No search input provided. Skipping search.\")\n return []\n\n def _astradb_collection_to_data(self, collection):\n data = []\n data_dict = collection.find()\n if data_dict and \"data\" in data_dict:\n data_dict = data_dict[\"data\"].get(\"documents\", [])\n\n for item in data_dict:\n data.append(Data(content=item[\"content\"]))\n return data\n" + }, + "collection_indexing_policy": { + "advanced": true, + "display_name": "Collection Indexing Policy", + "dynamic": false, + "info": "Optional dictionary defining the indexing policy for the collection.", + "list": false, + "load_from_db": false, + "name": "collection_indexing_policy", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "collection_name": { + "advanced": false, + "display_name": "Collection Name", + "dynamic": false, + "info": "The name of the collection within Astra DB where the vectors will be stored.", + "list": false, + "load_from_db": false, + "name": "collection_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "langflow" + }, + "embedding": { + "advanced": false, + "display_name": "Embedding or Astra Vectorize", + "dynamic": false, + "info": "", + "input_types": [ + "Embeddings", + "dict" + ], + "list": false, + "name": "embedding", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "ingest_data": { + "advanced": false, + "display_name": "Ingest Data", + "dynamic": false, + "info": "", + "input_types": [ + "Data" + ], + "list": true, + "name": "ingest_data", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "metadata_indexing_exclude": { + "advanced": true, + "display_name": "Metadata Indexing Exclude", + "dynamic": false, + "info": "Optional list of metadata fields to exclude from the indexing.", + "list": false, + "load_from_db": false, + "name": "metadata_indexing_exclude", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "metadata_indexing_include": { + "advanced": true, + "display_name": "Metadata Indexing Include", + "dynamic": false, + "info": "Optional list of metadata fields to include in the indexing.", + "list": false, + "load_from_db": false, + "name": "metadata_indexing_include", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "metric": { + "advanced": true, + "display_name": "Metric", + "dynamic": false, + "info": "Optional distance metric for vector comparisons in the vector store.", + "name": "metric", + "options": [ + "cosine", + "dot_product", + "euclidean" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "namespace": { + "advanced": true, + "display_name": "Namespace", + "dynamic": false, + "info": "Optional namespace within Astra DB to use for the collection.", + "list": false, + "load_from_db": false, + "name": "namespace", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "number_of_results": { + "advanced": true, + "display_name": "Number of Results", + "dynamic": false, + "info": "Number of results to return.", + "list": false, + "name": "number_of_results", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 4 + }, + "pre_delete_collection": { + "advanced": true, + "display_name": "Pre Delete Collection", + "dynamic": false, + "info": "Boolean flag to determine whether to delete the collection before creating a new one.", + "list": false, + "name": "pre_delete_collection", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "search_input": { + "advanced": false, + "display_name": "Search Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "search_input", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "search_type": { + "advanced": true, + "display_name": "Search Type", + "dynamic": false, + "info": "", + "name": "search_type", + "options": [ + "Similarity", + "MMR" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Similarity" + }, + "setup_mode": { + "advanced": true, + "display_name": "Setup Mode", + "dynamic": false, + "info": "Configuration mode for setting up the vector store, with options like 'Sync', 'Async', or 'Off'.", + "name": "setup_mode", + "options": [ + "Sync", + "Async", + "Off" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "Sync" + }, + "token": { + "advanced": false, + "display_name": "Astra DB Application Token", + "dynamic": false, + "info": "Authentication token for accessing Astra DB.", + "input_types": [], + "load_from_db": false, + "name": "token", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + } + } + }, + "type": "AstraDB" + }, + "dragging": false, + "height": 753, + "id": "AstraDB-XXizY", + "position": { + "x": 2676.4816074350247, + "y": 1269.304067004569 + }, + "positionAbsolute": { + "x": 2676.4816074350247, + "y": 1269.304067004569 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "OpenAIEmbeddings-fpOKp", + "node": { + "base_classes": [ + "Embeddings" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generate embeddings using OpenAI models.", + "display_name": "OpenAI Embeddings", + "documentation": "", + "edited": false, + "field_order": [ + "default_headers", + "default_query", + "chunk_size", + "client", + "deployment", + "embedding_ctx_length", + "max_retries", + "model", + "model_kwargs", + "openai_api_base", + "openai_api_key", + "openai_api_type", + "openai_api_version", + "openai_organization", + "openai_proxy", + "request_timeout", + "show_progress_bar", + "skip_empty", + "tiktoken_model_name", + "tiktoken_enable" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Embeddings", + "hidden": false, + "method": "build_embeddings", + "name": "embeddings", + "selected": "Embeddings", + "types": [ + "Embeddings" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "chunk_size": { + "advanced": true, + "display_name": "Chunk Size", + "dynamic": false, + "info": "", + "list": false, + "name": "chunk_size", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1000 + }, + "client": { + "advanced": true, + "display_name": "Client", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "client", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\", value=\"OPENAI_API_KEY\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n" + }, + "default_headers": { + "advanced": true, + "display_name": "Default Headers", + "dynamic": false, + "info": "Default headers to use for the API request.", + "list": false, + "name": "default_headers", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "default_query": { + "advanced": true, + "display_name": "Default Query", + "dynamic": false, + "info": "Default query parameters to use for the API request.", + "list": false, + "name": "default_query", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "deployment": { + "advanced": true, + "display_name": "Deployment", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "deployment", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "embedding_ctx_length": { + "advanced": true, + "display_name": "Embedding Context Length", + "dynamic": false, + "info": "", + "list": false, + "name": "embedding_ctx_length", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1536 + }, + "max_retries": { + "advanced": true, + "display_name": "Max Retries", + "dynamic": false, + "info": "", + "list": false, + "name": "max_retries", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 3 + }, + "model": { + "advanced": false, + "display_name": "Model", + "dynamic": false, + "info": "", + "name": "model", + "options": [ + "text-embedding-3-small", + "text-embedding-3-large", + "text-embedding-ada-002" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "text-embedding-3-small" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "", + "input_types": [], + "load_from_db": false, + "name": "openai_api_base", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "openai_api_type": { + "advanced": true, + "display_name": "OpenAI API Type", + "dynamic": false, + "info": "", + "input_types": [], + "load_from_db": false, + "name": "openai_api_type", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "openai_api_version": { + "advanced": true, + "display_name": "OpenAI API Version", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "openai_api_version", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_organization": { + "advanced": true, + "display_name": "OpenAI Organization", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "openai_organization", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_proxy": { + "advanced": true, + "display_name": "OpenAI Proxy", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "openai_proxy", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "request_timeout": { + "advanced": true, + "display_name": "Request Timeout", + "dynamic": false, + "info": "", + "list": false, + "name": "request_timeout", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": "" + }, + "show_progress_bar": { + "advanced": true, + "display_name": "Show Progress Bar", + "dynamic": false, + "info": "", + "list": false, + "name": "show_progress_bar", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "skip_empty": { + "advanced": true, + "display_name": "Skip Empty", + "dynamic": false, + "info": "", + "list": false, + "name": "skip_empty", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "tiktoken_enable": { + "advanced": true, + "display_name": "TikToken Enable", + "dynamic": false, + "info": "If False, you must have transformers installed.", + "list": false, + "name": "tiktoken_enable", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "tiktoken_model_name": { + "advanced": true, + "display_name": "TikToken Model Name", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "tiktoken_model_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "OpenAIEmbeddings" + }, + "dragging": false, + "height": 394, + "id": "OpenAIEmbeddings-fpOKp", + "position": { + "x": 2044.683126356786, + "y": 1785.2283494456522 + }, + "positionAbsolute": { + "x": 2044.683126356786, + "y": 1785.2283494456522 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "OpenAIEmbeddings-lCQlU", + "node": { + "base_classes": [ + "Embeddings" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Generate embeddings using OpenAI models.", + "display_name": "OpenAI Embeddings", + "documentation": "", + "edited": false, + "field_order": [ + "default_headers", + "default_query", + "chunk_size", + "client", + "deployment", + "embedding_ctx_length", + "max_retries", + "model", + "model_kwargs", + "openai_api_base", + "openai_api_key", + "openai_api_type", + "openai_api_version", + "openai_organization", + "openai_proxy", + "request_timeout", + "show_progress_bar", + "skip_empty", + "tiktoken_model_name", + "tiktoken_enable" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Embeddings", + "hidden": false, + "method": "build_embeddings", + "name": "embeddings", + "selected": "Embeddings", + "types": [ + "Embeddings" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "chunk_size": { + "advanced": true, + "display_name": "Chunk Size", + "dynamic": false, + "info": "", + "list": false, + "name": "chunk_size", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1000 + }, + "client": { + "advanced": true, + "display_name": "Client", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "client", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.base.embeddings.model import LCEmbeddingsModel\nfrom langflow.field_typing import Embeddings\nfrom langflow.io import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass OpenAIEmbeddingsComponent(LCEmbeddingsModel):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n icon = \"OpenAI\"\n inputs = [\n DictInput(\n name=\"default_headers\",\n display_name=\"Default Headers\",\n advanced=True,\n info=\"Default headers to use for the API request.\",\n ),\n DictInput(\n name=\"default_query\",\n display_name=\"Default Query\",\n advanced=True,\n info=\"Default query parameters to use for the API request.\",\n ),\n IntInput(name=\"chunk_size\", display_name=\"Chunk Size\", advanced=True, value=1000),\n MessageTextInput(name=\"client\", display_name=\"Client\", advanced=True),\n MessageTextInput(name=\"deployment\", display_name=\"Deployment\", advanced=True),\n IntInput(name=\"embedding_ctx_length\", display_name=\"Embedding Context Length\", advanced=True, value=1536),\n IntInput(name=\"max_retries\", display_name=\"Max Retries\", value=3, advanced=True),\n DropdownInput(\n name=\"model\",\n display_name=\"Model\",\n advanced=False,\n options=[\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n value=\"text-embedding-3-small\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n SecretStrInput(name=\"openai_api_base\", display_name=\"OpenAI API Base\", advanced=True),\n SecretStrInput(name=\"openai_api_key\", display_name=\"OpenAI API Key\", value=\"OPENAI_API_KEY\"),\n SecretStrInput(name=\"openai_api_type\", display_name=\"OpenAI API Type\", advanced=True),\n MessageTextInput(name=\"openai_api_version\", display_name=\"OpenAI API Version\", advanced=True),\n MessageTextInput(\n name=\"openai_organization\",\n display_name=\"OpenAI Organization\",\n advanced=True,\n ),\n MessageTextInput(name=\"openai_proxy\", display_name=\"OpenAI Proxy\", advanced=True),\n FloatInput(name=\"request_timeout\", display_name=\"Request Timeout\", advanced=True),\n BoolInput(name=\"show_progress_bar\", display_name=\"Show Progress Bar\", advanced=True),\n BoolInput(name=\"skip_empty\", display_name=\"Skip Empty\", advanced=True),\n MessageTextInput(\n name=\"tiktoken_model_name\",\n display_name=\"TikToken Model Name\",\n advanced=True,\n ),\n BoolInput(\n name=\"tiktoken_enable\",\n display_name=\"TikToken Enable\",\n advanced=True,\n value=True,\n info=\"If False, you must have transformers installed.\",\n ),\n ]\n\n def build_embeddings(self) -> Embeddings:\n return OpenAIEmbeddings(\n tiktoken_enabled=self.tiktoken_enable,\n default_headers=self.default_headers,\n default_query=self.default_query,\n allowed_special=\"all\",\n disallowed_special=\"all\",\n chunk_size=self.chunk_size,\n deployment=self.deployment,\n embedding_ctx_length=self.embedding_ctx_length,\n max_retries=self.max_retries,\n model=self.model,\n model_kwargs=self.model_kwargs,\n base_url=self.openai_api_base,\n api_key=self.openai_api_key,\n openai_api_type=self.openai_api_type,\n api_version=self.openai_api_version,\n organization=self.openai_organization,\n openai_proxy=self.openai_proxy,\n timeout=self.request_timeout or None,\n show_progress_bar=self.show_progress_bar,\n skip_empty=self.skip_empty,\n tiktoken_model_name=self.tiktoken_model_name,\n )\n" + }, + "default_headers": { + "advanced": true, + "display_name": "Default Headers", + "dynamic": false, + "info": "Default headers to use for the API request.", + "list": false, + "name": "default_headers", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "default_query": { + "advanced": true, + "display_name": "Default Query", + "dynamic": false, + "info": "Default query parameters to use for the API request.", + "list": false, + "name": "default_query", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "deployment": { + "advanced": true, + "display_name": "Deployment", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "deployment", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "embedding_ctx_length": { + "advanced": true, + "display_name": "Embedding Context Length", + "dynamic": false, + "info": "", + "list": false, + "name": "embedding_ctx_length", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 1536 + }, + "max_retries": { + "advanced": true, + "display_name": "Max Retries", + "dynamic": false, + "info": "", + "list": false, + "name": "max_retries", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "int", + "value": 3 + }, + "model": { + "advanced": false, + "display_name": "Model", + "dynamic": false, + "info": "", + "name": "model", + "options": [ + "text-embedding-3-small", + "text-embedding-3-large", + "text-embedding-ada-002" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "str", + "value": "text-embedding-3-small" + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "info": "", + "list": false, + "name": "model_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "type": "dict", + "value": {} + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "info": "", + "input_types": [], + "load_from_db": false, + "name": "openai_api_base", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "info": "", + "input_types": [], + "load_from_db": true, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "openai_api_type": { + "advanced": true, + "display_name": "OpenAI API Type", + "dynamic": false, + "info": "", + "input_types": [], + "load_from_db": false, + "name": "openai_api_type", + "password": true, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "openai_api_version": { + "advanced": true, + "display_name": "OpenAI API Version", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "openai_api_version", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_organization": { + "advanced": true, + "display_name": "OpenAI Organization", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "openai_organization", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "openai_proxy": { + "advanced": true, + "display_name": "OpenAI Proxy", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "openai_proxy", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "request_timeout": { + "advanced": true, + "display_name": "Request Timeout", + "dynamic": false, + "info": "", + "list": false, + "name": "request_timeout", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "float", + "value": "" + }, + "show_progress_bar": { + "advanced": true, + "display_name": "Show Progress Bar", + "dynamic": false, + "info": "", + "list": false, + "name": "show_progress_bar", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "skip_empty": { + "advanced": true, + "display_name": "Skip Empty", + "dynamic": false, + "info": "", + "list": false, + "name": "skip_empty", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "tiktoken_enable": { + "advanced": true, + "display_name": "TikToken Enable", + "dynamic": false, + "info": "If False, you must have transformers installed.", + "list": false, + "name": "tiktoken_enable", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "tiktoken_model_name": { + "advanced": true, + "display_name": "TikToken Model Name", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "load_from_db": false, + "name": "tiktoken_model_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + }, + "type": "OpenAIEmbeddings" + }, + "dragging": false, + "height": 394, + "id": "OpenAIEmbeddings-lCQlU", + "position": { + "x": 628.9252513328779, + "y": 648.6750537749285 + }, + "positionAbsolute": { + "x": 628.9252513328779, + "y": 648.6750537749285 + }, + "selected": false, + "type": "genericNode", + "width": 384 + } + ], + "viewport": { + "x": -110.08684771034166, + "y": -46.27017080984389, + "zoom": 0.3228119071747796 + } + }, + "description": "Visit https://docs.langflow.org/tutorials/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.", + "endpoint_name": null, + "id": "f1a53ec2-49e2-4029-b8a8-1a73079f9653", + "is_component": false, + "last_tested_version": "1.0.5", + "name": "Vector Store RAG" +} \ No newline at end of file From 9ef46af9ed216bfede4f1fd3e5622e48a2b0650a Mon Sep 17 00:00:00 2001 From: italojohnny Date: Fri, 28 Jun 2024 18:39:41 -0300 Subject: [PATCH 18/22] fix erros reported by mypy --- .../base/langflow/components/prototypes/ConditionalRouter.py | 4 ++-- src/backend/base/langflow/components/prototypes/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/base/langflow/components/prototypes/ConditionalRouter.py b/src/backend/base/langflow/components/prototypes/ConditionalRouter.py index 07c8103f00b..32f97b78087 100644 --- a/src/backend/base/langflow/components/prototypes/ConditionalRouter.py +++ b/src/backend/base/langflow/components/prototypes/ConditionalRouter.py @@ -63,7 +63,7 @@ def evaluate_condition(self, input_text: str, match_text: str, operator: str, ca return input_text.endswith(match_text) return False - def true_response(self) -> Message: + def true_response(self) -> Message | None: result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) if result: self.status = self.message @@ -72,7 +72,7 @@ def true_response(self) -> Message: self.stop("true_result") return None - def false_response(self) -> Message: + def false_response(self) -> Message | None: result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) if not result: self.status = self.message diff --git a/src/backend/base/langflow/components/prototypes/__init__.py b/src/backend/base/langflow/components/prototypes/__init__.py index 89c14f7e904..b4292185aa4 100644 --- a/src/backend/base/langflow/components/prototypes/__init__.py +++ b/src/backend/base/langflow/components/prototypes/__init__.py @@ -2,7 +2,7 @@ from .FlowTool import FlowToolComponent from .Listen import ListenComponent from .Notify import NotifyComponent -from .Pass import PassComponent +from .Pass import PassMessageComponent from .PythonFunction import PythonFunctionComponent from .RunFlow import RunFlowComponent from .RunnableExecutor import RunnableExecComponent @@ -16,7 +16,7 @@ "FlowToolComponent", "ListenComponent", "NotifyComponent", - "PassComponent", + "PassMessageComponent" "PythonFunctionComponent", "RunFlowComponent", "RunnableExecComponent", From 24787af401fb6c6cf5484563390ddd8041b80e29 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 21:43:54 +0000 Subject: [PATCH 19/22] [autofix.ci] apply automated fixes --- src/backend/base/langflow/components/prototypes/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/base/langflow/components/prototypes/__init__.py b/src/backend/base/langflow/components/prototypes/__init__.py index b4292185aa4..5157a2626e7 100644 --- a/src/backend/base/langflow/components/prototypes/__init__.py +++ b/src/backend/base/langflow/components/prototypes/__init__.py @@ -16,8 +16,7 @@ "FlowToolComponent", "ListenComponent", "NotifyComponent", - "PassMessageComponent" - "PythonFunctionComponent", + "PassMessageComponent" "PythonFunctionComponent", "RunFlowComponent", "RunnableExecComponent", "SQLExecutorComponent", From f31b712a19729824c933e77dda3bbcc9345cf305 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sun, 30 Jun 2024 11:15:08 -0300 Subject: [PATCH 20/22] =?UTF-8?q?=F0=9F=90=9B=20(prototypes/=5F=5Finit=5F?= =?UTF-8?q?=5F.py):=20fix=20missing=20comma=20in=20the=20list=20of=20impor?= =?UTF-8?q?ted=20components=20to=20prevent=20syntax=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/base/langflow/components/prototypes/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/base/langflow/components/prototypes/__init__.py b/src/backend/base/langflow/components/prototypes/__init__.py index 5157a2626e7..252d1a1c581 100644 --- a/src/backend/base/langflow/components/prototypes/__init__.py +++ b/src/backend/base/langflow/components/prototypes/__init__.py @@ -16,7 +16,8 @@ "FlowToolComponent", "ListenComponent", "NotifyComponent", - "PassMessageComponent" "PythonFunctionComponent", + "PassMessageComponent", + "PythonFunctionComponent", "RunFlowComponent", "RunnableExecComponent", "SQLExecutorComponent", From 7794b5e605ebcfe8d42f783cbe0b8ce645b59c03 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sun, 30 Jun 2024 11:15:51 -0300 Subject: [PATCH 21/22] chore: Fix type hinting in ConditionalRouterComponent --- .../langflow/components/prototypes/ConditionalRouter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/base/langflow/components/prototypes/ConditionalRouter.py b/src/backend/base/langflow/components/prototypes/ConditionalRouter.py index 32f97b78087..6d24bfa5e1e 100644 --- a/src/backend/base/langflow/components/prototypes/ConditionalRouter.py +++ b/src/backend/base/langflow/components/prototypes/ConditionalRouter.py @@ -63,20 +63,20 @@ def evaluate_condition(self, input_text: str, match_text: str, operator: str, ca return input_text.endswith(match_text) return False - def true_response(self) -> Message | None: + def true_response(self) -> Message: result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) if result: self.status = self.message return self.message else: self.stop("true_result") - return None + return None # type: ignore - def false_response(self) -> Message | None: + def false_response(self) -> Message: result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) if not result: self.status = self.message return self.message else: self.stop("false_result") - return None + return None # type: ignore From 6dd0a045957c56d0974c0d31e869650f69f99b58 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 14:19:18 +0000 Subject: [PATCH 22/22] [autofix.ci] apply automated fixes --- .../addNewVariableButton.tsx | 4 +++- .../src/modals/editNodeModal/index.tsx | 2 +- src/frontend/src/types/components/index.ts | 24 +++++++++++++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx index 81ab1655636..4dcda2deb9d 100644 --- a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx +++ b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx @@ -29,7 +29,9 @@ export default function AddNewVariableButton({ const setErrorData = useAlertStore((state) => state.setErrorData); const componentFields = useTypesStore((state) => state.ComponentFields); const unavaliableFields = new Set( - Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields) ?? {}), + Object.keys( + useGlobalVariablesStore((state) => state.unavaliableFields) ?? {}, + ), ); const availableFields = () => { diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index 34ef8613b34..dd95087be7a 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -38,7 +38,7 @@ const EditNodeModal = forwardRef( const handleOnNewValue = (newValue: any, key: string, setDb?: boolean) => { myData.current.node!.template[key].value = newValue; - if(setDb){ + if (setDb) { myData.current.node!.template[key].load_from_db = newValue; } }; diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index cc1a1cc2116..7c5c60579f0 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -123,7 +123,11 @@ export type TextAreaComponentType = { nodeClass?: APIClassType; setNodeClass?: (value: APIClassType) => void; disabled: boolean; - onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; + onChange: ( + value: string[] | string, + dbValue?: boolean, + skipSnapshot?: boolean, + ) => void; value: string; editNode?: boolean; id?: string; @@ -145,7 +149,11 @@ export type PromptAreaComponentType = { nodeClass?: APIClassType; setNodeClass?: (value: APIClassType, code?: string) => void; disabled: boolean; - onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; + onChange: ( + value: string[] | string, + dbValue?: boolean, + skipSnapshot?: boolean, + ) => void; value: string; readonly?: boolean; editNode?: boolean; @@ -155,7 +163,11 @@ export type PromptAreaComponentType = { export type CodeAreaComponentType = { setOpenModal?: (bool: boolean) => void; disabled: boolean; - onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; + onChange: ( + value: string[] | string, + dbValue?: boolean, + skipSnapshot?: boolean, + ) => void; value: string; editNode?: boolean; nodeClass?: APIClassType; @@ -170,7 +182,11 @@ export type CodeAreaComponentType = { export type FileComponentType = { IOInputProps?; disabled: boolean; - onChange: (value: string[] | string, dbValue?: boolean, skipSnapshot?: boolean) => void; + onChange: ( + value: string[] | string, + dbValue?: boolean, + skipSnapshot?: boolean, + ) => void; value: string; fileTypes: Array; onFileChange: (value: string) => void;