langflow-base-nightly 0.5.0.dev37__py3-none-any.whl → 0.5.0.dev39__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- langflow/__main__.py +1 -1
- langflow/alembic/versions/0882f9657f22_encrypt_existing_mcp_auth_settings_.py +122 -0
- langflow/alembic/versions/4e5980a44eaa_fix_date_times_again.py +24 -30
- langflow/alembic/versions/58b28437a398_modify_nullable.py +6 -6
- langflow/alembic/versions/79e675cb6752_change_datetime_type.py +24 -30
- langflow/alembic/versions/b2fa308044b5_add_unique_constraints.py +12 -13
- langflow/api/build.py +21 -26
- langflow/api/health_check_router.py +3 -3
- langflow/api/utils.py +3 -3
- langflow/api/v1/callback.py +2 -2
- langflow/api/v1/chat.py +19 -31
- langflow/api/v1/endpoints.py +10 -10
- langflow/api/v1/flows.py +1 -1
- langflow/api/v1/knowledge_bases.py +3 -3
- langflow/api/v1/mcp.py +12 -12
- langflow/api/v1/mcp_projects.py +405 -120
- langflow/api/v1/mcp_utils.py +8 -8
- langflow/api/v1/schemas.py +2 -7
- langflow/api/v1/store.py +1 -1
- langflow/api/v1/validate.py +2 -2
- langflow/api/v1/voice_mode.py +58 -62
- langflow/api/v2/files.py +2 -2
- langflow/api/v2/mcp.py +10 -9
- langflow/base/composio/composio_base.py +21 -2
- langflow/base/data/docling_utils.py +194 -0
- langflow/base/embeddings/aiml_embeddings.py +1 -1
- langflow/base/flow_processing/utils.py +1 -2
- langflow/base/io/__init__.py +0 -1
- langflow/base/langwatch/utils.py +2 -1
- langflow/base/mcp/util.py +49 -47
- langflow/base/prompts/api_utils.py +1 -1
- langflow/base/tools/flow_tool.py +2 -2
- langflow/base/tools/run_flow.py +2 -6
- langflow/components/FAISS/__init__.py +34 -0
- langflow/components/Notion/add_content_to_page.py +2 -2
- langflow/components/Notion/list_database_properties.py +2 -2
- langflow/components/Notion/list_pages.py +2 -2
- langflow/components/Notion/page_content_viewer.py +2 -2
- langflow/components/Notion/update_page_property.py +1 -1
- langflow/components/agentql/agentql_api.py +2 -10
- langflow/components/agents/agent.py +249 -55
- langflow/components/agents/mcp_component.py +14 -14
- langflow/components/anthropic/anthropic.py +5 -4
- langflow/components/assemblyai/assemblyai_get_subtitles.py +2 -2
- langflow/components/assemblyai/assemblyai_lemur.py +2 -2
- langflow/components/assemblyai/assemblyai_list_transcripts.py +2 -2
- langflow/components/assemblyai/assemblyai_poll_transcript.py +2 -2
- langflow/components/assemblyai/assemblyai_start_transcript.py +2 -2
- langflow/components/cassandra/__init__.py +40 -0
- langflow/components/chroma/__init__.py +34 -0
- langflow/components/clickhouse/__init__.py +34 -0
- langflow/components/couchbase/__init__.py +34 -0
- langflow/components/data/file.py +575 -55
- langflow/components/data/url.py +1 -1
- langflow/components/datastax/__init__.py +3 -3
- langflow/components/datastax/astra_assistant_manager.py +3 -3
- langflow/components/datastax/create_assistant.py +1 -2
- langflow/components/deactivated/merge_data.py +1 -2
- langflow/components/deactivated/sub_flow.py +6 -7
- langflow/components/deactivated/vectara_self_query.py +3 -3
- langflow/components/docling/__init__.py +0 -198
- langflow/components/docling/docling_inline.py +1 -1
- langflow/components/elastic/__init__.py +37 -0
- langflow/components/embeddings/text_embedder.py +3 -3
- langflow/components/firecrawl/firecrawl_extract_api.py +2 -9
- langflow/components/google/gmail.py +1 -1
- langflow/components/google/google_generative_ai.py +5 -11
- langflow/components/groq/groq.py +4 -3
- langflow/components/helpers/current_date.py +2 -3
- langflow/components/helpers/memory.py +1 -1
- langflow/components/ibm/watsonx.py +1 -1
- langflow/components/ibm/watsonx_embeddings.py +1 -1
- langflow/components/langwatch/langwatch.py +3 -3
- langflow/components/logic/flow_tool.py +2 -2
- langflow/components/logic/notify.py +1 -1
- langflow/components/logic/run_flow.py +2 -3
- langflow/components/logic/sub_flow.py +4 -5
- langflow/components/mem0/mem0_chat_memory.py +2 -8
- langflow/components/milvus/__init__.py +34 -0
- langflow/components/mongodb/__init__.py +34 -0
- langflow/components/nvidia/nvidia.py +3 -3
- langflow/components/olivya/olivya.py +7 -7
- langflow/components/ollama/ollama.py +9 -6
- langflow/components/perplexity/perplexity.py +3 -13
- langflow/components/pgvector/__init__.py +34 -0
- langflow/components/pinecone/__init__.py +34 -0
- langflow/components/processing/batch_run.py +8 -8
- langflow/components/processing/data_operations.py +2 -2
- langflow/components/processing/merge_data.py +1 -2
- langflow/components/processing/message_to_data.py +2 -3
- langflow/components/processing/parse_json_data.py +1 -1
- langflow/components/prototypes/python_function.py +2 -3
- langflow/components/qdrant/__init__.py +34 -0
- langflow/components/redis/__init__.py +36 -2
- langflow/components/redis/redis.py +75 -29
- langflow/components/redis/redis_chat.py +43 -0
- langflow/components/serpapi/serp.py +1 -1
- langflow/components/supabase/__init__.py +37 -0
- langflow/components/tavily/tavily_extract.py +1 -1
- langflow/components/tavily/tavily_search.py +1 -1
- langflow/components/tools/calculator.py +2 -2
- langflow/components/tools/python_code_structured_tool.py +3 -10
- langflow/components/tools/python_repl.py +2 -2
- langflow/components/tools/searxng.py +3 -3
- langflow/components/tools/serp_api.py +2 -2
- langflow/components/tools/tavily_search_tool.py +2 -2
- langflow/components/tools/yahoo_finance.py +1 -1
- langflow/components/twelvelabs/video_embeddings.py +4 -4
- langflow/components/upstash/__init__.py +34 -0
- langflow/components/vectara/__init__.py +37 -0
- langflow/components/vectorstores/__init__.py +0 -69
- langflow/components/vectorstores/local_db.py +2 -1
- langflow/components/weaviate/__init__.py +34 -0
- langflow/components/yahoosearch/yahoo.py +1 -1
- langflow/components/youtube/trending.py +3 -4
- langflow/custom/attributes.py +2 -1
- langflow/custom/code_parser/code_parser.py +1 -1
- langflow/custom/custom_component/base_component.py +1 -1
- langflow/custom/custom_component/component.py +16 -2
- langflow/custom/dependency_analyzer.py +165 -0
- langflow/custom/directory_reader/directory_reader.py +7 -7
- langflow/custom/directory_reader/utils.py +1 -2
- langflow/custom/utils.py +63 -45
- langflow/events/event_manager.py +1 -1
- langflow/frontend/assets/{SlackIcon-CnvyOamQ.js → SlackIcon-Cr3Q15Px.js} +1 -1
- langflow/frontend/assets/{Wikipedia-nyTEXdr2.js → Wikipedia-GxM5sPdM.js} +1 -1
- langflow/frontend/assets/{Wolfram-BYMQkNSq.js → Wolfram-BN3-VOCA.js} +1 -1
- langflow/frontend/assets/{index-DZTC5pdT.js → index-28oOcafk.js} +1 -1
- langflow/frontend/assets/{index-ChXJpBz4.js → index-2wSXqBtB.js} +1 -1
- langflow/frontend/assets/{index-BB15_iOb.js → index-3wW7BClE.js} +1 -1
- langflow/frontend/assets/{index-DKHNourL.js → index-6pyH3ZJB.js} +1 -1
- langflow/frontend/assets/{index-BvwZfF2i.js → index-AWCSdofD.js} +1 -1
- langflow/frontend/assets/{index-Bvxg4_ux.js → index-B2Zgv_xv.js} +1 -1
- langflow/frontend/assets/{index-Bd6WtbKA.js → index-B2ptVQGM.js} +1 -1
- langflow/frontend/assets/{index-C7QWbnLK.js → index-B3TANVes.js} +1 -1
- langflow/frontend/assets/{index-CpvYQ0ug.js → index-B4yCvZKV.js} +1 -1
- langflow/frontend/assets/{index-Dg-63Si_.js → index-BC65VuWx.js} +1 -1
- langflow/frontend/assets/{index-C6jri9Wm.js → index-BCDSei1q.js} +1 -1
- langflow/frontend/assets/{index-OazXJdEl.js → index-BJy50PvP.js} +1 -1
- langflow/frontend/assets/{index-CWdkbVsd.js → index-BKseQQ2I.js} +1 -1
- langflow/frontend/assets/{index-CaQ_H9ww.js → index-BLTxEeTi.js} +1 -1
- langflow/frontend/assets/{index-DGRMNe9n.js → index-BRg1f4Mu.js} +1 -1
- langflow/frontend/assets/{index-D8lOi1GI.js → index-BS8Vo8nc.js} +1 -1
- langflow/frontend/assets/{index-B748uLP1.js → index-BTKOU4xC.js} +1 -1
- langflow/frontend/assets/{index-Dqd4RjYA.js → index-BVwJDmw-.js} +1 -1
- langflow/frontend/assets/{index-DbMFlnHE.js → index-BWYuQ2Sj.js} +1 -1
- langflow/frontend/assets/{index-BEMw2Np8.js → index-BWdLILDG.js} +1 -1
- langflow/frontend/assets/{index-BmX5CoED.js → index-BZcw4827.js} +1 -1
- langflow/frontend/assets/{index-CyPvTB63.js → index-Bbi87Ve4.js} +1 -1
- langflow/frontend/assets/{index-BTEW9e8P.js → index-Bf0IYKLd.js} +1 -1
- langflow/frontend/assets/{index-BZgXW854.js → index-Bg5nrMRh.js} +1 -1
- langflow/frontend/assets/{index-BBxAPk1y.js → index-BiC280Nx.js} +1 -1
- langflow/frontend/assets/{index-BR0bkVqX.js → index-BiKKN6FR.js} +1 -1
- langflow/frontend/assets/{index-CTrt1Q_j.js → index-Bief6eyJ.js} +1 -1
- langflow/frontend/assets/{index-D5_DsUJc.js → index-BkXec1Yf.js} +1 -1
- langflow/frontend/assets/{index-CZQ9rXNa.js → index-Bnl6QHtP.js} +1 -1
- langflow/frontend/assets/{index-BChjg6Az.js → index-BpxbUiZD.js} +1979 -1979
- langflow/frontend/assets/{index-BOeo01QB.js → index-BrJV8psX.js} +1 -1
- langflow/frontend/assets/{index-DysKpOuj.js → index-BwLWcUXL.js} +1 -1
- langflow/frontend/assets/{index-Bnqod3vk.js → index-Bx7dBY26.js} +1 -1
- langflow/frontend/assets/{index-D3DDfngy.js → index-C-EdnFdA.js} +1 -1
- langflow/frontend/assets/{index-Bsa0xZyL.js → index-C-Xfg4cD.js} +1 -1
- langflow/frontend/assets/{index-BTrsh9LS.js → index-C1f2wMat.js} +1 -1
- langflow/frontend/assets/index-C1xroOlH.css +1 -0
- langflow/frontend/assets/{index-B1YN7oMV.js → index-C3KequvP.js} +1 -1
- langflow/frontend/assets/{index-DzW2mfkK.js → index-C3ZjKdCD.js} +1 -1
- langflow/frontend/assets/{index-ajRge-Mg.js → index-C3l0zYn0.js} +1 -1
- langflow/frontend/assets/{index-cvZdgWHQ.js → index-C3yvArUT.js} +1 -1
- langflow/frontend/assets/{index-C-2hghRJ.js → index-C9Cxnkl8.js} +1 -1
- langflow/frontend/assets/{index-BhIOhlCH.js → index-CBc8fEAE.js} +1 -1
- langflow/frontend/assets/{index-B3Sur4Z3.js → index-CBvrGgID.js} +1 -1
- langflow/frontend/assets/{index-CCePCqkT.js → index-CD-PqGCY.js} +1 -1
- langflow/frontend/assets/{index-8yMsjVV2.js → index-CGO1CiUr.js} +1 -1
- langflow/frontend/assets/{index-DF5VwgU6.js → index-CH5UVA9b.js} +1 -1
- langflow/frontend/assets/{index-dcnYpT9N.js → index-CLJeJYjH.js} +1 -1
- langflow/frontend/assets/{index-DfxYyS3M.js → index-CMZ79X-Y.js} +1 -1
- langflow/frontend/assets/{index-ya2uXE8v.js → index-CMzfJKiW.js} +1 -1
- langflow/frontend/assets/{index-DkelbYy7.js → index-CNw1H-Wc.js} +1 -1
- langflow/frontend/assets/{index-DytJENYD.js → index-CPHEscq9.js} +1 -1
- langflow/frontend/assets/{index-Bv8h2Z-q.js → index-CRPKJZw9.js} +1 -1
- langflow/frontend/assets/{index-D-9TI74R.js → index-CRPyCfYy.js} +1 -1
- langflow/frontend/assets/{index-BLGYN-9b.js → index-CRcMqCIj.js} +1 -1
- langflow/frontend/assets/{index-tVYiABdp.js → index-CUVDws8F.js} +1 -1
- langflow/frontend/assets/{index-CpcbQZIF.js → index-CVWQfRYZ.js} +1 -1
- langflow/frontend/assets/{index-DPCzHdsC.js → index-CVl6MbaM.js} +1 -1
- langflow/frontend/assets/{index-DkXy1WFo.js → index-CVwWoX99.js} +1 -1
- langflow/frontend/assets/{index-DK1Ptcc4.js → index-CWPzZtSx.js} +1 -1
- langflow/frontend/assets/{index-DHq8TQPB.js → index-CZqRL9DE.js} +1 -1
- langflow/frontend/assets/{index-DnEGCgih.js → index-CdIf07Rw.js} +1 -1
- langflow/frontend/assets/{index-BIQQCMvz.js → index-Cewy7JZE.js} +1 -1
- langflow/frontend/assets/{index-D8GJngXa.js → index-CfwLpbMM.js} +1 -1
- langflow/frontend/assets/{index-C_TdzfAn.js → index-CiR1dxI4.js} +1 -1
- langflow/frontend/assets/{index-BzL_EoKd.js → index-CiixOzDG.js} +1 -1
- langflow/frontend/assets/{index-Boso-xEw.js → index-ClsuDmR6.js} +1 -1
- langflow/frontend/assets/{index-8WdfSTTz.js → index-CmEYYRN1.js} +1 -1
- langflow/frontend/assets/{index-FUxmznS-.js → index-Co20d-eQ.js} +1 -1
- langflow/frontend/assets/{index-C82JjCPD.js → index-CpzXS6md.js} +1 -1
- langflow/frontend/assets/{index-DIDDfmlJ.js → index-Cqpzl1J4.js} +1 -1
- langflow/frontend/assets/{index-_UcqeEjm.js → index-CtVIONP2.js} +1 -1
- langflow/frontend/assets/{index-Gkrq-vzm.js → index-CuFXdTx4.js} +1 -1
- langflow/frontend/assets/{index-WPFivmdQ.js → index-Cyd2HtHK.js} +1 -1
- langflow/frontend/assets/{index-BFp_O-c9.js → index-D-1tA8Dt.js} +1 -1
- langflow/frontend/assets/{index-BqPpO6KG.js → index-D-KY3kkq.js} +1 -1
- langflow/frontend/assets/{index-Db71w3lq.js → index-D-_B1a8v.js} +1 -1
- langflow/frontend/assets/{index-BIzTEqFh.js → index-D14EWPyZ.js} +1 -1
- langflow/frontend/assets/{index-BbJjt5m4.js → index-D2N3l-cw.js} +1 -1
- langflow/frontend/assets/{index-DCRk27Tp.js → index-D5ETnvJa.js} +1 -1
- langflow/frontend/assets/{index-CvcEzq4x.js → index-D7kquVv2.js} +1 -1
- langflow/frontend/assets/{index-Q9vDw0Xl.js → index-DA6-bvgN.js} +1 -1
- langflow/frontend/assets/{index-l7bzB8Ex.js → index-DDWBeudF.js} +1 -1
- langflow/frontend/assets/{index-BCCGvqay.js → index-DDcMAaG4.js} +1 -1
- langflow/frontend/assets/{index-pCQ_yw8m.js → index-DHgomBdh.js} +1 -1
- langflow/frontend/assets/{index-BxEuHa76.js → index-DJP-ss47.js} +1 -1
- langflow/frontend/assets/{index-BbRm7beF.js → index-DQ7VYqQc.js} +1 -1
- langflow/frontend/assets/{index-Car-zdor.js → index-DTqbvGC0.js} +1 -1
- langflow/frontend/assets/{index-BRxvproo.js → index-DUpri6zF.js} +1 -1
- langflow/frontend/assets/{index-BQ6NUdMY.js → index-DV3utZDZ.js} +1 -1
- langflow/frontend/assets/{index-DjQETUy8.js → index-DXRfN4HV.js} +1 -1
- langflow/frontend/assets/{index-DfngcQxO.js → index-Db9dYSzy.js} +1 -1
- langflow/frontend/assets/{index-rXV1G1aB.js → index-DdtMEn6I.js} +1 -1
- langflow/frontend/assets/{index-DmMDPoi0.js → index-DfDhMHgQ.js} +1 -1
- langflow/frontend/assets/{index-DJB12jIC.js → index-Dfe7qfvf.js} +1 -1
- langflow/frontend/assets/{index-C_veJlEb.js → index-DhtZ5hx8.js} +1 -1
- langflow/frontend/assets/{index-CQMoqLAu.js → index-DiB3CTo8.js} +1 -1
- langflow/frontend/assets/{index-DVlceYFD.js → index-DiGWASY5.js} +1 -1
- langflow/frontend/assets/{index-Du_18NCU.js → index-Dl5amdBz.js} +1 -1
- langflow/frontend/assets/{index-CYDAYm-i.js → index-DlD4dXlZ.js} +1 -1
- langflow/frontend/assets/{index-CLPdN-q6.js → index-DmeiHnfl.js} +1 -1
- langflow/frontend/assets/index-Dmu-X5-4.js +1 -0
- langflow/frontend/assets/{index-BzEUlaw_.js → index-DpVWih90.js} +1 -1
- langflow/frontend/assets/{index-D6PSjHxP.js → index-DrDrcajG.js} +1 -1
- langflow/frontend/assets/{index-Dq5ilsem.js → index-Du-pc0KE.js} +1 -1
- langflow/frontend/assets/{index-CYe8Ipef.js → index-DwPkMTaY.js} +1 -1
- langflow/frontend/assets/{index-BVEZDXxS.js → index-DwQEZe3C.js} +1 -1
- langflow/frontend/assets/{index-BvT7L317.js → index-DyJFTK24.js} +1 -1
- langflow/frontend/assets/{index-HK3bVMYA.js → index-J38wh62w.js} +1 -1
- langflow/frontend/assets/{index-CCxGSSTT.js → index-Kwdl-e29.js} +1 -1
- langflow/frontend/assets/{index-BOB_zsjl.js → index-OwPvCmpW.js} +1 -1
- langflow/frontend/assets/{index-Dsps-jKu.js → index-Tw3Os-DN.js} +1 -1
- langflow/frontend/assets/{index-CFDvOtKC.js → index-X0guhYF8.js} +1 -1
- langflow/frontend/assets/{index-BX5D-USa.js → index-dJWNxIRH.js} +1 -1
- langflow/frontend/assets/{index-BRYjyhAd.js → index-dcJ8-agu.js} +1 -1
- langflow/frontend/assets/{index-Ui4xUImO.js → index-eo2mAtL-.js} +1 -1
- langflow/frontend/assets/{index-CxvP91st.js → index-hG24k5xJ.js} +1 -1
- langflow/frontend/assets/{index-CVQmT7ZL.js → index-h_aSZHf3.js} +1 -1
- langflow/frontend/assets/{index-BIXaW2aY.js → index-hbndqB9B.js} +1 -1
- langflow/frontend/assets/{index-DIkNW9Cd.js → index-iJngutFo.js} +1 -1
- langflow/frontend/assets/{index-BWmPX4iQ.js → index-lTpteg8t.js} +1 -1
- langflow/frontend/assets/{index-xuIrH2Dq.js → index-lZX9AvZW.js} +1 -1
- langflow/frontend/assets/{index-yCHsaqs8.js → index-m8QA6VNM.js} +1 -1
- langflow/frontend/assets/{index-BkPYpfgw.js → index-o0D2S7xW.js} +1 -1
- langflow/frontend/assets/{index-DpClkXIV.js → index-ovFJ_0J6.js} +1 -1
- langflow/frontend/assets/{index-CmplyEaa.js → index-pYJJOcma.js} +1 -1
- langflow/frontend/assets/{index-CJo_cyWW.js → index-sI75DsdM.js} +1 -1
- langflow/frontend/assets/{index-nVwHLjuV.js → index-xvFOmxx4.js} +1 -1
- langflow/frontend/assets/{index-LbYjHKkn.js → index-z3SRY-mX.js} +1 -1
- langflow/frontend/assets/lazyIconImports-D97HEZkE.js +2 -0
- langflow/frontend/assets/{use-post-add-user-BrBYH9eR.js → use-post-add-user-C0MdTpQ5.js} +1 -1
- langflow/frontend/index.html +2 -2
- langflow/graph/edge/base.py +2 -3
- langflow/graph/graph/base.py +15 -13
- langflow/graph/graph/constants.py +3 -0
- langflow/graph/utils.py +6 -6
- langflow/graph/vertex/base.py +4 -5
- langflow/graph/vertex/param_handler.py +1 -1
- langflow/graph/vertex/vertex_types.py +2 -2
- langflow/helpers/flow.py +1 -1
- langflow/initial_setup/setup.py +32 -30
- langflow/initial_setup/starter_projects/Basic Prompt Chaining.json +26 -0
- langflow/initial_setup/starter_projects/Basic Prompting.json +26 -0
- langflow/initial_setup/starter_projects/Blog Writer.json +58 -2
- langflow/initial_setup/starter_projects/Custom Component Generator.json +37 -2
- langflow/initial_setup/starter_projects/Document Q&A.json +27 -1
- langflow/initial_setup/starter_projects/Financial Report Parser.json +43 -0
- langflow/initial_setup/starter_projects/Hybrid Search RAG.json +83 -1
- langflow/initial_setup/starter_projects/Image Sentiment Analysis.json +43 -0
- langflow/initial_setup/starter_projects/Instagram Copywriter.json +51 -3
- langflow/initial_setup/starter_projects/Invoice Summarizer.json +40 -1
- langflow/initial_setup/starter_projects/Knowledge Ingestion.json +73 -2
- langflow/initial_setup/starter_projects/Knowledge Retrieval.json +63 -0
- langflow/initial_setup/starter_projects/Market Research.json +59 -3
- langflow/initial_setup/starter_projects/Meeting Summary.json +101 -6
- langflow/initial_setup/starter_projects/Memory Chatbot.json +37 -2
- langflow/initial_setup/starter_projects/News Aggregator.json +63 -3
- langflow/initial_setup/starter_projects/Nvidia Remix.json +69 -4
- langflow/initial_setup/starter_projects/Pok/303/251dex Agent.json" +48 -1
- langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json +44 -1
- langflow/initial_setup/starter_projects/Price Deal Finder.json +57 -5
- langflow/initial_setup/starter_projects/Research Agent.json +42 -3
- langflow/initial_setup/starter_projects/Research Translation Loop.json +66 -0
- langflow/initial_setup/starter_projects/SEO Keyword Generator.json +17 -0
- langflow/initial_setup/starter_projects/SaaS Pricing.json +27 -1
- langflow/initial_setup/starter_projects/Search agent.json +40 -1
- langflow/initial_setup/starter_projects/Sequential Tasks Agents.json +76 -7
- langflow/initial_setup/starter_projects/Simple Agent.json +59 -3
- langflow/initial_setup/starter_projects/Social Media Agent.json +77 -1
- langflow/initial_setup/starter_projects/Text Sentiment Analysis.json +35 -1
- langflow/initial_setup/starter_projects/Travel Planning Agents.json +51 -3
- langflow/initial_setup/starter_projects/Twitter Thread Generator.json +80 -0
- langflow/initial_setup/starter_projects/Vector Store RAG.json +110 -3
- langflow/initial_setup/starter_projects/Youtube Analysis.json +84 -3
- langflow/initial_setup/starter_projects/vector_store_rag.py +1 -1
- langflow/interface/components.py +23 -22
- langflow/interface/initialize/loading.py +5 -5
- langflow/interface/run.py +1 -1
- langflow/interface/utils.py +1 -1
- langflow/io/__init__.py +0 -1
- langflow/langflow_launcher.py +1 -1
- langflow/load/load.py +2 -7
- langflow/logging/__init__.py +0 -1
- langflow/logging/logger.py +191 -115
- langflow/logging/setup.py +1 -1
- langflow/main.py +37 -52
- langflow/memory.py +7 -7
- langflow/middleware.py +1 -1
- langflow/processing/process.py +6 -3
- langflow/schema/artifact.py +2 -2
- langflow/schema/data.py +10 -2
- langflow/schema/dataframe.py +1 -1
- langflow/schema/message.py +1 -1
- langflow/serialization/serialization.py +1 -1
- langflow/services/auth/mcp_encryption.py +104 -0
- langflow/services/auth/utils.py +2 -2
- langflow/services/cache/disk.py +1 -1
- langflow/services/cache/service.py +3 -3
- langflow/services/database/models/flow/model.py +2 -7
- langflow/services/database/models/transactions/crud.py +2 -2
- langflow/services/database/models/user/crud.py +2 -2
- langflow/services/database/service.py +8 -8
- langflow/services/database/utils.py +6 -5
- langflow/services/deps.py +2 -3
- langflow/services/factory.py +1 -1
- langflow/services/flow/flow_runner.py +7 -12
- langflow/services/job_queue/service.py +16 -15
- langflow/services/manager.py +3 -4
- langflow/services/settings/auth.py +1 -1
- langflow/services/settings/base.py +3 -8
- langflow/services/settings/feature_flags.py +1 -1
- langflow/services/settings/manager.py +1 -1
- langflow/services/settings/utils.py +1 -1
- langflow/services/socket/__init__.py +0 -1
- langflow/services/socket/service.py +3 -3
- langflow/services/socket/utils.py +4 -4
- langflow/services/state/service.py +1 -2
- langflow/services/storage/factory.py +1 -1
- langflow/services/storage/local.py +9 -8
- langflow/services/storage/s3.py +11 -10
- langflow/services/store/service.py +3 -3
- langflow/services/store/utils.py +3 -2
- langflow/services/task/temp_flow_cleanup.py +7 -7
- langflow/services/telemetry/service.py +10 -10
- langflow/services/tracing/arize_phoenix.py +2 -2
- langflow/services/tracing/langfuse.py +1 -1
- langflow/services/tracing/langsmith.py +1 -1
- langflow/services/tracing/langwatch.py +1 -1
- langflow/services/tracing/opik.py +1 -1
- langflow/services/tracing/service.py +25 -6
- langflow/services/tracing/traceloop.py +245 -0
- langflow/services/utils.py +7 -7
- langflow/services/variable/kubernetes.py +3 -3
- langflow/services/variable/kubernetes_secrets.py +2 -1
- langflow/services/variable/service.py +5 -5
- langflow/utils/component_utils.py +9 -6
- langflow/utils/util.py +5 -5
- langflow/utils/validate.py +3 -3
- langflow/utils/voice_utils.py +2 -2
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/METADATA +2 -1
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/RECORD +393 -374
- langflow/components/vectorstores/redis.py +0 -89
- langflow/frontend/assets/index-C26RqKWL.js +0 -1
- langflow/frontend/assets/index-CqS7zir1.css +0 -1
- langflow/frontend/assets/lazyIconImports-t6wEndt1.js +0 -2
- /langflow/components/{vectorstores → FAISS}/faiss.py +0 -0
- /langflow/components/{vectorstores → cassandra}/cassandra.py +0 -0
- /langflow/components/{datastax/cassandra.py → cassandra/cassandra_chat.py} +0 -0
- /langflow/components/{vectorstores → cassandra}/cassandra_graph.py +0 -0
- /langflow/components/{vectorstores → chroma}/chroma.py +0 -0
- /langflow/components/{vectorstores → clickhouse}/clickhouse.py +0 -0
- /langflow/components/{vectorstores → couchbase}/couchbase.py +0 -0
- /langflow/components/{vectorstores → datastax}/astradb.py +0 -0
- /langflow/components/{vectorstores → datastax}/astradb_graph.py +0 -0
- /langflow/components/{vectorstores → datastax}/graph_rag.py +0 -0
- /langflow/components/{vectorstores → datastax}/hcd.py +0 -0
- /langflow/components/{vectorstores → elastic}/elasticsearch.py +0 -0
- /langflow/components/{vectorstores → elastic}/opensearch.py +0 -0
- /langflow/components/{vectorstores → milvus}/milvus.py +0 -0
- /langflow/components/{vectorstores → mongodb}/mongodb_atlas.py +0 -0
- /langflow/components/{vectorstores → pgvector}/pgvector.py +0 -0
- /langflow/components/{vectorstores → pinecone}/pinecone.py +0 -0
- /langflow/components/{vectorstores → qdrant}/qdrant.py +0 -0
- /langflow/components/{vectorstores → supabase}/supabase.py +0 -0
- /langflow/components/{vectorstores → upstash}/upstash.py +0 -0
- /langflow/components/{vectorstores → vectara}/vectara.py +0 -0
- /langflow/components/{vectorstores → vectara}/vectara_rag.py +0 -0
- /langflow/components/{vectorstores → weaviate}/weaviate.py +0 -0
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/WHEEL +0 -0
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/entry_points.txt +0 -0
|
@@ -6,8 +6,8 @@ from uuid import UUID
|
|
|
6
6
|
|
|
7
7
|
import httpx
|
|
8
8
|
from httpx import HTTPError, HTTPStatusError
|
|
9
|
-
from loguru import logger
|
|
10
9
|
|
|
10
|
+
from langflow.logging.logger import logger
|
|
11
11
|
from langflow.services.base import Service
|
|
12
12
|
from langflow.services.store.exceptions import APIKeyError, FilterError, ForbiddenError
|
|
13
13
|
from langflow.services.store.schema import (
|
|
@@ -162,7 +162,7 @@ class StoreService(Service):
|
|
|
162
162
|
except HTTPError:
|
|
163
163
|
raise
|
|
164
164
|
except Exception: # noqa: BLE001
|
|
165
|
-
logger.
|
|
165
|
+
logger.debug("Webhook failed", exc_info=True)
|
|
166
166
|
|
|
167
167
|
@staticmethod
|
|
168
168
|
def build_tags_filter(tags: list[str]):
|
|
@@ -594,7 +594,7 @@ class StoreService(Service):
|
|
|
594
594
|
authorized = True
|
|
595
595
|
result = updated_result
|
|
596
596
|
except Exception: # noqa: BLE001
|
|
597
|
-
logger.
|
|
597
|
+
logger.debug("Error updating components with user data", exc_info=True)
|
|
598
598
|
# If we get an error here, it means the user is not authorized
|
|
599
599
|
authorized = False
|
|
600
600
|
return ListComponentResponseModel(results=result, authorized=authorized, count=comp_count)
|
langflow/services/store/utils.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
import httpx
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
from langflow.logging.logger import logger
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from langflow.services.store.schema import ListComponentResponse
|
|
@@ -49,7 +50,7 @@ async def get_lf_version_from_pypi():
|
|
|
49
50
|
return None
|
|
50
51
|
return response.json()["info"]["version"]
|
|
51
52
|
except Exception: # noqa: BLE001
|
|
52
|
-
logger.
|
|
53
|
+
logger.debug("Error getting the latest version of langflow from PyPI", exc_info=True)
|
|
53
54
|
return None
|
|
54
55
|
|
|
55
56
|
|
|
@@ -4,9 +4,9 @@ import asyncio
|
|
|
4
4
|
import contextlib
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from loguru import logger
|
|
8
7
|
from sqlmodel import col, delete, select
|
|
9
8
|
|
|
9
|
+
from langflow.logging.logger import logger
|
|
10
10
|
from langflow.services.database.models.message.model import MessageTable
|
|
11
11
|
from langflow.services.database.models.transactions.model import TransactionTable
|
|
12
12
|
from langflow.services.database.models.vertex_builds.model import VertexBuildTable
|
|
@@ -79,23 +79,23 @@ class CleanupWorker:
|
|
|
79
79
|
async def start(self):
|
|
80
80
|
"""Start the cleanup worker."""
|
|
81
81
|
if self._task is not None:
|
|
82
|
-
logger.
|
|
82
|
+
await logger.awarning("Cleanup worker is already running")
|
|
83
83
|
return
|
|
84
84
|
|
|
85
85
|
self._task = asyncio.create_task(self._run())
|
|
86
|
-
logger.
|
|
86
|
+
await logger.adebug("Started database cleanup worker")
|
|
87
87
|
|
|
88
88
|
async def stop(self):
|
|
89
89
|
"""Stop the cleanup worker gracefully."""
|
|
90
90
|
if self._task is None:
|
|
91
|
-
logger.
|
|
91
|
+
await logger.awarning("Cleanup worker is not running")
|
|
92
92
|
return
|
|
93
93
|
|
|
94
|
-
logger.
|
|
94
|
+
await logger.adebug("Stopping database cleanup worker...")
|
|
95
95
|
self._stop_event.set()
|
|
96
96
|
await self._task
|
|
97
97
|
self._task = None
|
|
98
|
-
logger.
|
|
98
|
+
await logger.adebug("Database cleanup worker stopped")
|
|
99
99
|
|
|
100
100
|
async def _run(self):
|
|
101
101
|
"""Run the cleanup worker until stopped."""
|
|
@@ -105,7 +105,7 @@ class CleanupWorker:
|
|
|
105
105
|
# Clean up any orphaned records
|
|
106
106
|
await cleanup_orphaned_records()
|
|
107
107
|
except Exception as exc: # noqa: BLE001
|
|
108
|
-
logger.
|
|
108
|
+
await logger.aerror(f"Error in cleanup worker: {exc!s}")
|
|
109
109
|
|
|
110
110
|
try:
|
|
111
111
|
# Create a task for the timeout
|
|
@@ -9,8 +9,8 @@ from datetime import datetime, timezone
|
|
|
9
9
|
from typing import TYPE_CHECKING
|
|
10
10
|
|
|
11
11
|
import httpx
|
|
12
|
-
from loguru import logger
|
|
13
12
|
|
|
13
|
+
from langflow.logging.logger import logger
|
|
14
14
|
from langflow.services.base import Service
|
|
15
15
|
from langflow.services.telemetry.opentelemetry import OpenTelemetry
|
|
16
16
|
from langflow.services.telemetry.schema import (
|
|
@@ -56,13 +56,13 @@ class TelemetryService(Service):
|
|
|
56
56
|
try:
|
|
57
57
|
await func(payload, path)
|
|
58
58
|
except Exception: # noqa: BLE001
|
|
59
|
-
logger.
|
|
59
|
+
await logger.aerror("Error sending telemetry data")
|
|
60
60
|
finally:
|
|
61
61
|
self.telemetry_queue.task_done()
|
|
62
62
|
|
|
63
63
|
async def send_telemetry_data(self, payload: BaseModel, path: str | None = None) -> None:
|
|
64
64
|
if self.do_not_track:
|
|
65
|
-
logger.
|
|
65
|
+
await logger.adebug("Telemetry tracking is disabled.")
|
|
66
66
|
return
|
|
67
67
|
|
|
68
68
|
url = f"{self.base_url}"
|
|
@@ -73,15 +73,15 @@ class TelemetryService(Service):
|
|
|
73
73
|
payload_dict = payload.model_dump(by_alias=True, exclude_none=True, exclude_unset=True)
|
|
74
74
|
response = await self.client.get(url, params=payload_dict)
|
|
75
75
|
if response.status_code != httpx.codes.OK:
|
|
76
|
-
logger.
|
|
76
|
+
await logger.aerror(f"Failed to send telemetry data: {response.status_code} {response.text}")
|
|
77
77
|
else:
|
|
78
|
-
logger.
|
|
78
|
+
await logger.adebug("Telemetry data sent successfully.")
|
|
79
79
|
except httpx.HTTPStatusError:
|
|
80
|
-
logger.
|
|
80
|
+
await logger.aerror("HTTP error occurred")
|
|
81
81
|
except httpx.RequestError:
|
|
82
|
-
logger.
|
|
82
|
+
await logger.aerror("Request error occurred")
|
|
83
83
|
except Exception: # noqa: BLE001
|
|
84
|
-
logger.
|
|
84
|
+
await logger.aerror("Unexpected error occurred")
|
|
85
85
|
|
|
86
86
|
async def log_package_run(self, payload: RunPayload) -> None:
|
|
87
87
|
await self._queue_event((self.send_telemetry_data, payload, "run"))
|
|
@@ -161,7 +161,7 @@ class TelemetryService(Service):
|
|
|
161
161
|
try:
|
|
162
162
|
await self.telemetry_queue.join()
|
|
163
163
|
except Exception: # noqa: BLE001
|
|
164
|
-
logger.
|
|
164
|
+
await logger.aexception("Error flushing logs")
|
|
165
165
|
|
|
166
166
|
@staticmethod
|
|
167
167
|
async def _cancel_task(task: asyncio.Task, cancel_msg: str) -> None:
|
|
@@ -186,7 +186,7 @@ class TelemetryService(Service):
|
|
|
186
186
|
await self._cancel_task(self.log_package_version_task, "Cancel telemetry log package version task")
|
|
187
187
|
await self.client.aclose()
|
|
188
188
|
except Exception: # noqa: BLE001
|
|
189
|
-
logger.
|
|
189
|
+
await logger.aexception("Error stopping tracing service")
|
|
190
190
|
|
|
191
191
|
async def teardown(self) -> None:
|
|
192
192
|
await self.stop()
|
|
@@ -10,13 +10,13 @@ from typing import TYPE_CHECKING, Any
|
|
|
10
10
|
|
|
11
11
|
from langchain_core.documents import Document
|
|
12
12
|
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
|
|
13
|
-
from loguru import logger
|
|
14
13
|
from openinference.semconv.trace import OpenInferenceMimeTypeValues, SpanAttributes
|
|
15
14
|
from opentelemetry.semconv.trace import SpanAttributes as OTELSpanAttributes
|
|
16
15
|
from opentelemetry.trace import Span, Status, StatusCode, use_span
|
|
17
16
|
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
|
18
17
|
from typing_extensions import override
|
|
19
18
|
|
|
19
|
+
from langflow.logging.logger import logger
|
|
20
20
|
from langflow.schema.data import Data
|
|
21
21
|
from langflow.schema.message import Message
|
|
22
22
|
from langflow.services.tracing.base import BaseTracer
|
|
@@ -78,7 +78,7 @@ class ArizePhoenixTracer(BaseTracer):
|
|
|
78
78
|
self.child_spans: dict[str, Span] = {}
|
|
79
79
|
|
|
80
80
|
except Exception: # noqa: BLE001
|
|
81
|
-
logger.
|
|
81
|
+
logger.debug("Error setting up Arize/Phoenix tracer", exc_info=True)
|
|
82
82
|
self._ready = False
|
|
83
83
|
|
|
84
84
|
@property
|
|
@@ -5,9 +5,9 @@ from collections import OrderedDict
|
|
|
5
5
|
from datetime import datetime, timezone
|
|
6
6
|
from typing import TYPE_CHECKING, Any
|
|
7
7
|
|
|
8
|
-
from loguru import logger
|
|
9
8
|
from typing_extensions import override
|
|
10
9
|
|
|
10
|
+
from langflow.logging.logger import logger
|
|
11
11
|
from langflow.serialization.serialization import serialize
|
|
12
12
|
from langflow.services.tracing.base import BaseTracer
|
|
13
13
|
|
|
@@ -6,9 +6,9 @@ import types
|
|
|
6
6
|
from datetime import datetime, timezone
|
|
7
7
|
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
|
-
from loguru import logger
|
|
10
9
|
from typing_extensions import override
|
|
11
10
|
|
|
11
|
+
from langflow.logging.logger import logger
|
|
12
12
|
from langflow.schema.data import Data
|
|
13
13
|
from langflow.serialization.serialization import serialize
|
|
14
14
|
from langflow.services.tracing.base import BaseTracer
|
|
@@ -4,9 +4,9 @@ import os
|
|
|
4
4
|
from typing import TYPE_CHECKING, Any, cast
|
|
5
5
|
|
|
6
6
|
import nanoid
|
|
7
|
-
from loguru import logger
|
|
8
7
|
from typing_extensions import override
|
|
9
8
|
|
|
9
|
+
from langflow.logging.logger import logger
|
|
10
10
|
from langflow.schema.data import Data
|
|
11
11
|
from langflow.services.tracing.base import BaseTracer
|
|
12
12
|
|
|
@@ -6,9 +6,9 @@ from typing import TYPE_CHECKING, Any
|
|
|
6
6
|
|
|
7
7
|
from langchain_core.documents import Document
|
|
8
8
|
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
|
|
9
|
-
from loguru import logger
|
|
10
9
|
from typing_extensions import override
|
|
11
10
|
|
|
11
|
+
from langflow.logging.logger import logger
|
|
12
12
|
from langflow.schema.data import Data
|
|
13
13
|
from langflow.schema.message import Message
|
|
14
14
|
from langflow.services.tracing.base import BaseTracer
|
|
@@ -7,8 +7,7 @@ from contextlib import asynccontextmanager
|
|
|
7
7
|
from contextvars import ContextVar
|
|
8
8
|
from typing import TYPE_CHECKING, Any
|
|
9
9
|
|
|
10
|
-
from
|
|
11
|
-
|
|
10
|
+
from langflow.logging.logger import logger
|
|
12
11
|
from langflow.services.base import Service
|
|
13
12
|
|
|
14
13
|
if TYPE_CHECKING:
|
|
@@ -53,6 +52,12 @@ def _get_opik_tracer():
|
|
|
53
52
|
return OpikTracer
|
|
54
53
|
|
|
55
54
|
|
|
55
|
+
def _get_traceloop_tracer():
|
|
56
|
+
from langflow.services.tracing.traceloop import TraceloopTracer
|
|
57
|
+
|
|
58
|
+
return TraceloopTracer
|
|
59
|
+
|
|
60
|
+
|
|
56
61
|
trace_context_var: ContextVar[TraceContext | None] = ContextVar("trace_context", default=None)
|
|
57
62
|
component_context_var: ContextVar[ComponentTraceContext | None] = ContextVar("component_trace_context", default=None)
|
|
58
63
|
|
|
@@ -127,7 +132,7 @@ class TracingService(Service):
|
|
|
127
132
|
try:
|
|
128
133
|
trace_func(*args)
|
|
129
134
|
except Exception: # noqa: BLE001
|
|
130
|
-
logger.
|
|
135
|
+
await logger.aexception("Error processing trace_func")
|
|
131
136
|
finally:
|
|
132
137
|
trace_context.traces_queue.task_done()
|
|
133
138
|
|
|
@@ -138,7 +143,7 @@ class TracingService(Service):
|
|
|
138
143
|
trace_context.running = True
|
|
139
144
|
trace_context.worker_task = asyncio.create_task(self._trace_worker(trace_context))
|
|
140
145
|
except Exception: # noqa: BLE001
|
|
141
|
-
logger.
|
|
146
|
+
await logger.aexception("Error starting tracing service")
|
|
142
147
|
|
|
143
148
|
def _initialize_langsmith_tracer(self, trace_context: TraceContext) -> None:
|
|
144
149
|
langsmith_tracer = _get_langsmith_tracer()
|
|
@@ -201,6 +206,19 @@ class TracingService(Service):
|
|
|
201
206
|
session_id=trace_context.session_id,
|
|
202
207
|
)
|
|
203
208
|
|
|
209
|
+
def _initialize_traceloop_tracer(self, trace_context: TraceContext) -> None:
|
|
210
|
+
if self.deactivated:
|
|
211
|
+
return
|
|
212
|
+
traceloop_tracer = _get_traceloop_tracer()
|
|
213
|
+
trace_context.tracers["traceloop"] = traceloop_tracer(
|
|
214
|
+
trace_name=trace_context.run_name,
|
|
215
|
+
trace_type="chain",
|
|
216
|
+
project_name=trace_context.project_name,
|
|
217
|
+
trace_id=trace_context.run_id,
|
|
218
|
+
user_id=trace_context.user_id,
|
|
219
|
+
session_id=trace_context.session_id,
|
|
220
|
+
)
|
|
221
|
+
|
|
204
222
|
async def start_tracers(
|
|
205
223
|
self,
|
|
206
224
|
run_id: UUID,
|
|
@@ -227,8 +245,9 @@ class TracingService(Service):
|
|
|
227
245
|
self._initialize_langfuse_tracer(trace_context)
|
|
228
246
|
self._initialize_arize_phoenix_tracer(trace_context)
|
|
229
247
|
self._initialize_opik_tracer(trace_context)
|
|
248
|
+
self._initialize_traceloop_tracer(trace_context)
|
|
230
249
|
except Exception as e: # noqa: BLE001
|
|
231
|
-
logger.
|
|
250
|
+
await logger.adebug(f"Error initializing tracers: {e}")
|
|
232
251
|
|
|
233
252
|
async def _stop(self, trace_context: TraceContext) -> None:
|
|
234
253
|
try:
|
|
@@ -241,7 +260,7 @@ class TracingService(Service):
|
|
|
241
260
|
trace_context.worker_task = None
|
|
242
261
|
|
|
243
262
|
except Exception: # noqa: BLE001
|
|
244
|
-
logger.
|
|
263
|
+
await logger.aexception("Error stopping tracing service")
|
|
245
264
|
|
|
246
265
|
def _end_all_tracers(self, trace_context: TraceContext, outputs: dict, error: Exception | None = None) -> None:
|
|
247
266
|
for tracer in trace_context.tracers.values():
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import math
|
|
5
|
+
import os
|
|
6
|
+
import types
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
|
|
11
|
+
from loguru import logger
|
|
12
|
+
from opentelemetry import trace
|
|
13
|
+
from opentelemetry.trace import Span, use_span
|
|
14
|
+
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
|
15
|
+
from traceloop.sdk import Traceloop
|
|
16
|
+
from traceloop.sdk.instruments import Instruments
|
|
17
|
+
from typing_extensions import override
|
|
18
|
+
|
|
19
|
+
from langflow.services.tracing.base import BaseTracer
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from collections.abc import Sequence
|
|
23
|
+
from uuid import UUID
|
|
24
|
+
|
|
25
|
+
from langchain.callbacks.base import BaseCallbackHandler
|
|
26
|
+
from opentelemetry.propagators.textmap import CarrierT
|
|
27
|
+
from opentelemetry.trace import Span
|
|
28
|
+
|
|
29
|
+
from langflow.graph.vertex.base import Vertex
|
|
30
|
+
from langflow.services.tracing.schema import Log
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TraceloopTracer(BaseTracer):
|
|
34
|
+
"""Traceloop tracer for Langflow."""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
trace_name: str,
|
|
39
|
+
trace_type: str,
|
|
40
|
+
project_name: str,
|
|
41
|
+
trace_id: UUID,
|
|
42
|
+
user_id: str | None = None,
|
|
43
|
+
session_id: str | None = None,
|
|
44
|
+
):
|
|
45
|
+
self.trace_id = trace_id
|
|
46
|
+
self.trace_name = trace_name
|
|
47
|
+
self.trace_type = trace_type
|
|
48
|
+
self.project_name = project_name
|
|
49
|
+
self.user_id = user_id
|
|
50
|
+
self.session_id = session_id
|
|
51
|
+
self.child_spans: dict[str, Span] = {}
|
|
52
|
+
|
|
53
|
+
if not self._validate_configuration():
|
|
54
|
+
self._ready = False
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
api_key = os.getenv("TRACELOOP_API_KEY", "").strip()
|
|
58
|
+
try:
|
|
59
|
+
Traceloop.init(
|
|
60
|
+
block_instruments={Instruments.PYMYSQL},
|
|
61
|
+
app_name=project_name,
|
|
62
|
+
disable_batch=True,
|
|
63
|
+
api_key=api_key,
|
|
64
|
+
api_endpoint=os.getenv("TRACELOOP_BASE_URL", "https://api.traceloop.com"),
|
|
65
|
+
)
|
|
66
|
+
self._ready = True
|
|
67
|
+
self._tracer = trace.get_tracer("langflow")
|
|
68
|
+
self.propagator = TraceContextTextMapPropagator()
|
|
69
|
+
self.carrier: CarrierT = {}
|
|
70
|
+
|
|
71
|
+
self.root_span = self._tracer.start_span(
|
|
72
|
+
name=trace_name,
|
|
73
|
+
start_time=self._get_current_timestamp(),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
with use_span(self.root_span, end_on_exit=False):
|
|
77
|
+
self.propagator.inject(carrier=self.carrier)
|
|
78
|
+
|
|
79
|
+
except Exception: # noqa: BLE001
|
|
80
|
+
logger.opt(exception=True).debug("Error setting up Traceloop tracer")
|
|
81
|
+
self._ready = False
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def ready(self) -> bool:
|
|
85
|
+
return self._ready
|
|
86
|
+
|
|
87
|
+
def _validate_configuration(self) -> bool:
|
|
88
|
+
api_key = os.getenv("TRACELOOP_API_KEY", "").strip()
|
|
89
|
+
if not api_key:
|
|
90
|
+
logger.warning("TRACELOOP_API_KEY not set or empty.")
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
base_url = os.getenv("TRACELOOP_BASE_URL", "https://api.traceloop.com")
|
|
94
|
+
parsed = urlparse(base_url)
|
|
95
|
+
if not parsed.netloc:
|
|
96
|
+
logger.error(f"Invalid TRACELOOP_BASE_URL: {base_url}")
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
def _convert_to_traceloop_type(self, value):
|
|
102
|
+
"""Recursively converts a value to a Traceloop compatible type."""
|
|
103
|
+
from langchain.schema import BaseMessage, Document, HumanMessage, SystemMessage
|
|
104
|
+
|
|
105
|
+
from langflow.schema.message import Message
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
if isinstance(value, dict):
|
|
109
|
+
value = {key: self._convert_to_traceloop_type(val) for key, val in value.items()}
|
|
110
|
+
|
|
111
|
+
elif isinstance(value, list):
|
|
112
|
+
value = [self._convert_to_traceloop_type(v) for v in value]
|
|
113
|
+
|
|
114
|
+
elif isinstance(value, Message):
|
|
115
|
+
value = value.text
|
|
116
|
+
|
|
117
|
+
elif isinstance(value, (BaseMessage | HumanMessage | SystemMessage)):
|
|
118
|
+
value = str(value.content) if value.content is not None else ""
|
|
119
|
+
|
|
120
|
+
elif isinstance(value, Document):
|
|
121
|
+
value = value.page_content
|
|
122
|
+
|
|
123
|
+
elif isinstance(value, (types.GeneratorType | types.NoneType)):
|
|
124
|
+
value = str(value)
|
|
125
|
+
|
|
126
|
+
elif isinstance(value, float) and not math.isfinite(value):
|
|
127
|
+
value = "NaN"
|
|
128
|
+
|
|
129
|
+
except (TypeError, ValueError) as e:
|
|
130
|
+
logger.warning(f"Failed to convert value {value!r} to traceloop type: {e}")
|
|
131
|
+
return str(value)
|
|
132
|
+
else:
|
|
133
|
+
return value
|
|
134
|
+
|
|
135
|
+
def _convert_to_traceloop_dict(self, io_dict: Any) -> dict[str, Any]:
|
|
136
|
+
"""Ensure values are OTel-compatible. Dicts stay dicts, lists get JSON-serialized."""
|
|
137
|
+
if isinstance(io_dict, dict):
|
|
138
|
+
return {str(k): self._convert_to_traceloop_type(v) for k, v in io_dict.items()}
|
|
139
|
+
if isinstance(io_dict, list):
|
|
140
|
+
return {"list": json.dumps([self._convert_to_traceloop_type(v) for v in io_dict], default=str)}
|
|
141
|
+
|
|
142
|
+
return {"value": self._convert_to_traceloop_type(io_dict)}
|
|
143
|
+
|
|
144
|
+
@override
|
|
145
|
+
def add_trace(
|
|
146
|
+
self,
|
|
147
|
+
trace_id: str,
|
|
148
|
+
trace_name: str,
|
|
149
|
+
trace_type: str,
|
|
150
|
+
inputs: dict[str, Any],
|
|
151
|
+
metadata: dict[str, Any] | None = None,
|
|
152
|
+
vertex: Vertex | None = None,
|
|
153
|
+
) -> None:
|
|
154
|
+
if not self.ready:
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
span_context = self.propagator.extract(carrier=self.carrier)
|
|
158
|
+
child_span = self._tracer.start_span(
|
|
159
|
+
name=trace_name,
|
|
160
|
+
context=span_context,
|
|
161
|
+
start_time=self._get_current_timestamp(),
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
attributes = {
|
|
165
|
+
"trace_id": trace_id,
|
|
166
|
+
"trace_name": trace_name,
|
|
167
|
+
"trace_type": trace_type,
|
|
168
|
+
"inputs": json.dumps(self._convert_to_traceloop_dict(inputs), default=str),
|
|
169
|
+
**self._convert_to_traceloop_dict(metadata or {}),
|
|
170
|
+
}
|
|
171
|
+
if vertex and vertex.id is not None:
|
|
172
|
+
attributes["vertex_id"] = vertex.id
|
|
173
|
+
|
|
174
|
+
child_span.set_attributes(attributes)
|
|
175
|
+
|
|
176
|
+
self.child_spans[trace_id] = child_span
|
|
177
|
+
|
|
178
|
+
@override
|
|
179
|
+
def end_trace(
|
|
180
|
+
self,
|
|
181
|
+
trace_id: str,
|
|
182
|
+
trace_name: str,
|
|
183
|
+
outputs: dict[str, Any] | None = None,
|
|
184
|
+
error: Exception | None = None,
|
|
185
|
+
logs: Sequence[Log | dict] = (),
|
|
186
|
+
) -> None:
|
|
187
|
+
if not self._ready or trace_id not in self.child_spans:
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
child_span = self.child_spans.pop(trace_id)
|
|
191
|
+
|
|
192
|
+
if outputs:
|
|
193
|
+
child_span.set_attribute("outputs", json.dumps(self._convert_to_traceloop_dict(outputs), default=str))
|
|
194
|
+
if logs:
|
|
195
|
+
child_span.set_attribute("logs", json.dumps(self._convert_to_traceloop_dict(list(logs)), default=str))
|
|
196
|
+
if error:
|
|
197
|
+
child_span.record_exception(error)
|
|
198
|
+
|
|
199
|
+
child_span.end()
|
|
200
|
+
|
|
201
|
+
@override
|
|
202
|
+
def end(
|
|
203
|
+
self,
|
|
204
|
+
inputs: dict[str, Any],
|
|
205
|
+
outputs: dict[str, Any],
|
|
206
|
+
error: Exception | None = None,
|
|
207
|
+
metadata: dict[str, Any] | None = None,
|
|
208
|
+
) -> None:
|
|
209
|
+
if not self.ready:
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
safe_outputs = self._convert_to_traceloop_dict(outputs)
|
|
213
|
+
safe_metadata = self._convert_to_traceloop_dict(metadata or {})
|
|
214
|
+
|
|
215
|
+
self.root_span.set_attributes(
|
|
216
|
+
{
|
|
217
|
+
"workflow_name": self.trace_name,
|
|
218
|
+
"workflow_id": str(self.trace_id),
|
|
219
|
+
"outputs": json.dumps(safe_outputs, default=str),
|
|
220
|
+
**safe_metadata,
|
|
221
|
+
}
|
|
222
|
+
)
|
|
223
|
+
if error:
|
|
224
|
+
self.root_span.record_exception(error)
|
|
225
|
+
|
|
226
|
+
self.root_span.end()
|
|
227
|
+
|
|
228
|
+
@staticmethod
|
|
229
|
+
def _get_current_timestamp() -> int:
|
|
230
|
+
return int(datetime.now(timezone.utc).timestamp() * 1_000_000_000)
|
|
231
|
+
|
|
232
|
+
@override
|
|
233
|
+
def get_langchain_callback(self) -> BaseCallbackHandler | None:
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
def close(self):
|
|
237
|
+
try:
|
|
238
|
+
provider = trace.get_tracer_provider()
|
|
239
|
+
if hasattr(provider, "force_flush"):
|
|
240
|
+
provider.force_flush(timeout_millis=3000)
|
|
241
|
+
except (ValueError, RuntimeError, OSError) as e:
|
|
242
|
+
logger.warning(f"Error flushing spans: {e}")
|
|
243
|
+
|
|
244
|
+
def __del__(self):
|
|
245
|
+
self.close()
|
langflow/services/utils.py
CHANGED
|
@@ -3,11 +3,11 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
|
-
from loguru import logger
|
|
7
6
|
from sqlalchemy import delete
|
|
8
7
|
from sqlalchemy import exc as sqlalchemy_exc
|
|
9
8
|
from sqlmodel import col, select
|
|
10
9
|
|
|
10
|
+
from langflow.logging.logger import logger
|
|
11
11
|
from langflow.services.auth.utils import create_super_user, verify_password
|
|
12
12
|
from langflow.services.cache.base import ExternalAsyncBaseCacheService
|
|
13
13
|
from langflow.services.cache.factory import CacheServiceFactory
|
|
@@ -45,7 +45,7 @@ async def get_or_create_super_user(session: AsyncSession, username, password, is
|
|
|
45
45
|
# This means that the user has already created
|
|
46
46
|
# a superuser and changed the password in the UI
|
|
47
47
|
# so we don't need to do anything.
|
|
48
|
-
logger.
|
|
48
|
+
await logger.adebug(
|
|
49
49
|
"Superuser exists but password is incorrect. "
|
|
50
50
|
"This means that the user has changed the "
|
|
51
51
|
"base superuser credentials."
|
|
@@ -70,7 +70,7 @@ async def get_or_create_super_user(session: AsyncSession, username, password, is
|
|
|
70
70
|
|
|
71
71
|
async def setup_superuser(settings_service: SettingsService, session: AsyncSession) -> None:
|
|
72
72
|
if settings_service.auth_settings.AUTO_LOGIN:
|
|
73
|
-
logger.
|
|
73
|
+
await logger.adebug("AUTO_LOGIN is set to True. Creating default superuser.")
|
|
74
74
|
username = DEFAULT_SUPERUSER
|
|
75
75
|
password = DEFAULT_SUPERUSER_PASSWORD
|
|
76
76
|
else:
|
|
@@ -90,7 +90,7 @@ async def setup_superuser(settings_service: SettingsService, session: AsyncSessi
|
|
|
90
90
|
session=session, username=username, password=password, is_default=is_default
|
|
91
91
|
)
|
|
92
92
|
if user is not None:
|
|
93
|
-
logger.
|
|
93
|
+
await logger.adebug("Superuser created successfully.")
|
|
94
94
|
except Exception as exc:
|
|
95
95
|
logger.exception(exc)
|
|
96
96
|
msg = "Could not create superuser. Please create a superuser manually."
|
|
@@ -106,7 +106,7 @@ async def teardown_superuser(settings_service, session: AsyncSession) -> None:
|
|
|
106
106
|
|
|
107
107
|
if not settings_service.auth_settings.AUTO_LOGIN:
|
|
108
108
|
try:
|
|
109
|
-
logger.
|
|
109
|
+
await logger.adebug("AUTO_LOGIN is set to False. Removing default superuser if exists.")
|
|
110
110
|
username = DEFAULT_SUPERUSER
|
|
111
111
|
from langflow.services.database.models.user.model import User
|
|
112
112
|
|
|
@@ -118,7 +118,7 @@ async def teardown_superuser(settings_service, session: AsyncSession) -> None:
|
|
|
118
118
|
if user and user.is_superuser is True and not user.last_login_at:
|
|
119
119
|
await session.delete(user)
|
|
120
120
|
await session.commit()
|
|
121
|
-
logger.
|
|
121
|
+
await logger.adebug("Default superuser removed successfully.")
|
|
122
122
|
|
|
123
123
|
except Exception as exc:
|
|
124
124
|
logger.exception(exc)
|
|
@@ -238,6 +238,6 @@ async def initialize_services(*, fix_migration: bool = False) -> None:
|
|
|
238
238
|
try:
|
|
239
239
|
await get_db_service().assign_orphaned_flows_to_superuser()
|
|
240
240
|
except sqlalchemy_exc.IntegrityError as exc:
|
|
241
|
-
logger.
|
|
241
|
+
await logger.awarning(f"Error assigning orphaned flows to the superuser: {exc!s}")
|
|
242
242
|
await clean_transactions(settings_service, session)
|
|
243
243
|
await clean_vertex_builds(settings_service, session)
|
|
@@ -4,9 +4,9 @@ import asyncio
|
|
|
4
4
|
import os
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from loguru import logger
|
|
8
7
|
from typing_extensions import override
|
|
9
8
|
|
|
9
|
+
from langflow.logging.logger import logger
|
|
10
10
|
from langflow.services.auth import utils as auth_utils
|
|
11
11
|
from langflow.services.base import Service
|
|
12
12
|
from langflow.services.database.models.variable.model import Variable, VariableCreate, VariableRead
|
|
@@ -33,12 +33,12 @@ class KubernetesSecretService(VariableService, Service):
|
|
|
33
33
|
async def initialize_user_variables(self, user_id: UUID | str, session: AsyncSession) -> None:
|
|
34
34
|
# Check for environment variables that should be stored in the database
|
|
35
35
|
should_or_should_not = "Should" if self.settings_service.settings.store_environment_variables else "Should not"
|
|
36
|
-
logger.
|
|
36
|
+
await logger.ainfo(f"{should_or_should_not} store environment variables in the kubernetes.")
|
|
37
37
|
if self.settings_service.settings.store_environment_variables:
|
|
38
38
|
variables = {}
|
|
39
39
|
for var in self.settings_service.settings.variables_to_get_from_environment:
|
|
40
40
|
if var in os.environ:
|
|
41
|
-
logger.
|
|
41
|
+
await logger.adebug(f"Creating {var} variable from environment.")
|
|
42
42
|
value = os.environ[var]
|
|
43
43
|
if isinstance(value, str):
|
|
44
44
|
value = value.strip()
|