* new tests folders organizations * 📝 (nightly_build.yml): update tests_folder path from "tests/scheduled" to "tests/core" to reflect the correct location of the tests folder * renaming test folder * changing e2e to integrations folder * 📝 (frontend/tsconfig.json): update test file paths to reflect changes in folder structure for better organization and clarity * change assets folder * 📝 (frontend): update file paths to remove redundant 'core' directory in test assets * 📝 (Document QA.spec.ts, Vector Store.spec.ts, fileUploadComponent.spec.ts): Update file paths to correctly reference test assets in integration and unit tests. * github suggestions
217 lines
11 KiB
JSON
217 lines
11 KiB
JSON
{
|
|
"name": "Lonely Stonebraker",
|
|
"description": "Design Dialogues with Langflow.",
|
|
"data": {
|
|
"nodes": [
|
|
{
|
|
"width": 384,
|
|
"height": 461,
|
|
"id": "CustomComponent-MtJjl",
|
|
"type": "genericNode",
|
|
"position": {
|
|
"x": 534.3712097224906,
|
|
"y": -135.01908566635723
|
|
},
|
|
"data": {
|
|
"type": "CustomComponent",
|
|
"node": {
|
|
"template": {
|
|
"code": {
|
|
"type": "code",
|
|
"required": true,
|
|
"placeholder": "",
|
|
"list": false,
|
|
"show": true,
|
|
"multiline": true,
|
|
"value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Data\nfrom pathlib import Path\nfrom platformdirs import user_cache_dir\nimport os\n\nclass Component(CustomComponent):\n documentation: str = \"http://docs.langflow.org/components/custom\"\n\n def build_config(self):\n return {\"text_input\":{\"display_name\":\"Text Input\", \"input_types\":[\"str\"]},\"save_path\":{\"display_name\":\"Save Path\",\n \"info\":\"Put the full path with the file name and extension\",\"value\":Path(user_cache_dir(\"langflow\"))/\"text.t1.txt\"}}\n\n def build(self, text_input:str,save_path:str) -> str:\n try:\n # Create the directory if it doesn't exist\n os.makedirs(os.path.dirname(save_path), exist_ok=True)\n\n # Open the file in write mode and save the text\n with open(save_path, 'w') as file:\n file.write(text_input)\n except Exception as e:\n raise e\n self.status = text_input\n return text_input",
|
|
"fileTypes": [],
|
|
"file_path": "",
|
|
"password": false,
|
|
"name": "code",
|
|
"advanced": false,
|
|
"dynamic": true,
|
|
"info": ""
|
|
},
|
|
"save_path": {
|
|
"type": "str",
|
|
"required": true,
|
|
"placeholder": "",
|
|
"list": false,
|
|
"show": true,
|
|
"multiline": false,
|
|
"value": "/home/vazz/.cache/langflow/text.t1.txt",
|
|
"fileTypes": [],
|
|
"file_path": "",
|
|
"password": false,
|
|
"name": "save_path",
|
|
"display_name": "Save Path",
|
|
"advanced": false,
|
|
"dynamic": false,
|
|
"info": "Put the full path with the file name and extension"
|
|
},
|
|
"text_input": {
|
|
"type": "str",
|
|
"required": true,
|
|
"placeholder": "",
|
|
"list": false,
|
|
"show": true,
|
|
"multiline": false,
|
|
"fileTypes": [],
|
|
"file_path": "",
|
|
"password": false,
|
|
"name": "text_input",
|
|
"display_name": "Text Input",
|
|
"advanced": false,
|
|
"input_types": ["str"],
|
|
"dynamic": false,
|
|
"info": "",
|
|
"value": ""
|
|
},
|
|
"_type": "CustomComponent"
|
|
},
|
|
"base_classes": ["str"],
|
|
"display_name": "text checkpoint",
|
|
"documentation": "http://docs.langflow.org/components/custom",
|
|
"custom_fields": {
|
|
"save_path": null,
|
|
"text_input": null
|
|
},
|
|
"output_types": ["str"],
|
|
"field_formatters": {},
|
|
"beta": true
|
|
},
|
|
"id": "CustomComponent-MtJjl"
|
|
},
|
|
"selected": false,
|
|
"dragging": false,
|
|
"positionAbsolute": {
|
|
"x": 534.3712097224906,
|
|
"y": -135.01908566635723
|
|
}
|
|
},
|
|
{
|
|
"width": 384,
|
|
"height": 453,
|
|
"id": "CustomComponent-7NQoq",
|
|
"type": "genericNode",
|
|
"position": {
|
|
"x": 27.487979888011637,
|
|
"y": -414.43998171034826
|
|
},
|
|
"data": {
|
|
"type": "CustomComponent",
|
|
"node": {
|
|
"template": {
|
|
"audio": {
|
|
"type": "file",
|
|
"required": true,
|
|
"placeholder": "",
|
|
"list": false,
|
|
"show": true,
|
|
"multiline": false,
|
|
"fileTypes": [],
|
|
"file_path": "/home/vazz/.cache/langflow/1b0814b7-2964-4e09-9b4b-f7413c4fb50b/b56b043d8940daecbdec03b97ad4346488c58d7cc62016560dd333aa7a6a12ce.m4a",
|
|
"password": false,
|
|
"name": "audio",
|
|
"display_name": "audio",
|
|
"advanced": false,
|
|
"dynamic": false,
|
|
"info": "",
|
|
"value": "Audio Recording 2023-12-13 at 16.35.22.m4a"
|
|
},
|
|
"OpenAIKey": {
|
|
"type": "str",
|
|
"required": true,
|
|
"placeholder": "",
|
|
"list": false,
|
|
"show": true,
|
|
"multiline": false,
|
|
"fileTypes": [],
|
|
"file_path": "",
|
|
"password": true,
|
|
"name": "OpenAIKey",
|
|
"display_name": "OpenAIKey",
|
|
"advanced": false,
|
|
"dynamic": false,
|
|
"info": "",
|
|
"value": ""
|
|
},
|
|
"code": {
|
|
"type": "code",
|
|
"required": true,
|
|
"placeholder": "",
|
|
"list": false,
|
|
"show": true,
|
|
"multiline": true,
|
|
"value": "from langflow.custom import CustomComponent\nfrom typing import Optional, List, Dict, Union\nfrom langflow.field_typing import (\n AgentExecutor,\n BaseChatMemory,\n BaseLanguageModel,\n BaseLLM,\n BaseLoader,\n BaseMemory,\n BaseOutputParser,\n BasePromptTemplate,\n BaseRetriever,\n Callable,\n Chain,\n ChatPromptTemplate,\n Data,\n Document,\n Embeddings,\n NestedDict,\n Object,\n PromptTemplate,\n TextSplitter,\n Tool,\n VectorStore,\n)\n\nfrom openai import OpenAI\nimport os\nimport ffmpeg\n\nclass Component(CustomComponent):\n display_name: str = \"Whisper Transcriber\"\n description: str = \"Converts audio to text using OpenAI's Whisper.\"\n\n def build_config(self):\n return {\"audio\": {\"field_type\": \"file\", \"suffixes\": [\".mp3\", \".mp4\", \".m4a\"]}, \"OpenAIKey\": {\"field_type\": \"str\", \"password\": True}}\n\n def calculate_segment_duration(self, audio_path, target_chunk_size_mb=24):\n # Calculate the target chunk size in bytes\n target_chunk_size_bytes = target_chunk_size_mb * 1024 * 1024\n\n # Use ffprobe to get the audio file information\n ffprobe_output = ffmpeg.probe(audio_path)\n print(ffprobe_output)\n # Convert duration to float\n duration = float(ffprobe_output[\"format\"][\"duration\"])\n\n # Calculate the approximate bitrate\n bitrate = os.path.getsize(audio_path) / duration\n\n # Calculate the segment duration to achieve the target chunk size\n segment_duration = target_chunk_size_bytes / bitrate\n\n return segment_duration\n\n def split_audio_into_chunks(self, audio_path, target_chunk_size_mb=24):\n # Calculate the segment duration\n segment_duration = self.calculate_segment_duration(audio_path, target_chunk_size_mb)\n\n # Create a directory to store the chunks\n output_directory = f\"{os.path.splitext(audio_path)[0]}_chunks\"\n os.makedirs(output_directory, exist_ok=True)\n\n # Use ffmpeg-python to split the audio file into chunks\n (\n ffmpeg.input(audio_path)\n .output(f\"{output_directory}/%03d{os.path.splitext(audio_path)[1]}\", codec=\"copy\", f=\"segment\", segment_time=segment_duration)\n .run()\n )\n\n # Get the list of generated chunk files\n chunks = [os.path.join(output_directory, file) for file in os.listdir(output_directory)]\n\n return chunks\n\n def build(self, audio: str, OpenAIKey: str) -> str:\n # Split audio into chunks\n audio_chunks = self.split_audio_into_chunks(audio)\n\n client = OpenAI(api_key=OpenAIKey)\n transcripts = []\n\n try:\n for chunk in audio_chunks:\n with open(chunk, \"rb\") as chunk_file:\n transcript = client.audio.transcriptions.create(\n model=\"whisper-1\",\n file=chunk_file,\n response_format=\"text\"\n )\n transcripts.append(transcript)\n finally:\n # Clean up temporary chunk files\n for chunk in audio_chunks:\n os.remove(chunk)\n\n # Concatenate transcripts into the final response\n final_response = \"\\n\".join(transcripts)\n self.status = final_response\n return final_response\n",
|
|
"fileTypes": [],
|
|
"file_path": "",
|
|
"password": false,
|
|
"name": "code",
|
|
"advanced": false,
|
|
"dynamic": true,
|
|
"info": ""
|
|
},
|
|
"_type": "CustomComponent"
|
|
},
|
|
"description": "Converts audio to text using OpenAI's Whisper.",
|
|
"base_classes": ["str"],
|
|
"display_name": "Whisper Transcriber",
|
|
"documentation": "",
|
|
"custom_fields": {
|
|
"OpenAIKey": null,
|
|
"audio": null
|
|
},
|
|
"output_types": ["str"],
|
|
"field_formatters": {},
|
|
"beta": true
|
|
},
|
|
"id": "CustomComponent-7NQoq"
|
|
},
|
|
"selected": true,
|
|
"positionAbsolute": {
|
|
"x": 27.487979888011637,
|
|
"y": -414.43998171034826
|
|
},
|
|
"dragging": false
|
|
}
|
|
],
|
|
"edges": [
|
|
{
|
|
"source": "CustomComponent-7NQoq",
|
|
"sourceHandle": "{œbaseClassesœ:[œstrœ],œdataTypeœ:œCustomComponentœ,œidœ:œCustomComponent-7NQoqœ}",
|
|
"target": "CustomComponent-MtJjl",
|
|
"targetHandle": "{œfieldNameœ:œtext_inputœ,œidœ:œCustomComponent-MtJjlœ,œinputTypesœ:[œstrœ],œtypeœ:œstrœ}",
|
|
"data": {
|
|
"targetHandle": {
|
|
"fieldName": "text_input",
|
|
"id": "CustomComponent-MtJjl",
|
|
"inputTypes": ["str"],
|
|
"type": "str"
|
|
},
|
|
"sourceHandle": {
|
|
"baseClasses": ["str"],
|
|
"dataType": "CustomComponent",
|
|
"id": "CustomComponent-7NQoq"
|
|
}
|
|
},
|
|
"style": {
|
|
"stroke": "#555"
|
|
},
|
|
"className": "stroke-gray-900 stroke-connection",
|
|
"animated": false,
|
|
"id": "reactflow__edge-CustomComponent-7NQoq{œbaseClassesœ:[œstrœ],œdataTypeœ:œCustomComponentœ,œidœ:œCustomComponent-7NQoqœ}-CustomComponent-MtJjl{œfieldNameœ:œtext_inputœ,œidœ:œCustomComponent-MtJjlœ,œinputTypesœ:[œstrœ],œtypeœ:œstrœ}"
|
|
}
|
|
],
|
|
"viewport": {
|
|
"x": 119.37759169012509,
|
|
"y": 351.3082742479685,
|
|
"zoom": 1
|
|
}
|
|
},
|
|
"is_component": false,
|
|
"updated_at": "2023-12-13T23:51:56.874099",
|
|
"folder": null,
|
|
"id": "1b0814b7-2964-4e09-9b4b-f7413c4fb50b",
|
|
"user_id": "8b5cf798-f1b8-4108-88fd-d7274d08d471"
|
|
}
|