langflow-base-nightly 0.5.0.dev37__py3-none-any.whl → 0.5.0.dev38__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/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 +45 -81
- langflow/api/v1/mcp_utils.py +8 -8
- langflow/api/v1/schemas.py +1 -5
- 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/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 +3 -3
- 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/data/file.py +575 -55
- langflow/components/data/url.py +1 -1
- 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/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/nvidia/nvidia.py +3 -3
- langflow/components/olivya/olivya.py +7 -7
- langflow/components/ollama/ollama.py +8 -6
- 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/serpapi/serp.py +1 -1
- 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/vectorstores/local_db.py +1 -1
- 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/directory_reader/directory_reader.py +7 -7
- langflow/custom/directory_reader/utils.py +1 -2
- langflow/custom/utils.py +30 -30
- langflow/events/event_manager.py +1 -1
- langflow/frontend/assets/{SlackIcon-CnvyOamQ.js → SlackIcon-BhW6H3JR.js} +1 -1
- langflow/frontend/assets/{Wikipedia-nyTEXdr2.js → Wikipedia-Dx5jbiy3.js} +1 -1
- langflow/frontend/assets/{Wolfram-BYMQkNSq.js → Wolfram-CIyonzwo.js} +1 -1
- langflow/frontend/assets/{index-HK3bVMYA.js → index-0XQqYgdG.js} +1 -1
- langflow/frontend/assets/{index-BZgXW854.js → index-1Q3VBqKn.js} +1 -1
- langflow/frontend/assets/{index-BQ6NUdMY.js → index-35sspuLu.js} +1 -1
- langflow/frontend/assets/{index-DPCzHdsC.js → index-7hzXChQz.js} +1 -1
- langflow/frontend/assets/{index-CFDvOtKC.js → index-8cuhogZP.js} +1 -1
- langflow/frontend/assets/{index-CYDAYm-i.js → index-B0m53xKd.js} +1 -1
- langflow/frontend/assets/{index-Q9vDw0Xl.js → index-B1XqWJhG.js} +1 -1
- langflow/frontend/assets/{index-Gkrq-vzm.js → index-B3KCdQ91.js} +1 -1
- langflow/frontend/assets/{index-DytJENYD.js → index-B7uEuOPK.js} +1 -1
- langflow/frontend/assets/{index-DkXy1WFo.js → index-B8UR8v-Q.js} +1 -1
- langflow/frontend/assets/{index-BChjg6Az.js → index-BD7Io1hL.js} +6 -6
- langflow/frontend/assets/{index-CyPvTB63.js → index-BDQrd7Tj.js} +1 -1
- langflow/frontend/assets/{index-BbJjt5m4.js → index-BDuk0d7P.js} +1 -1
- langflow/frontend/assets/{index-BBxAPk1y.js → index-BFQ8KFK0.js} +1 -1
- langflow/frontend/assets/{index-BqPpO6KG.js → index-BFf0HTFI.js} +1 -1
- langflow/frontend/assets/{index-yCHsaqs8.js → index-BHhnpSkW.js} +1 -1
- langflow/frontend/assets/{index-Bd6WtbKA.js → index-BKKrUElc.js} +1 -1
- langflow/frontend/assets/{index-DHq8TQPB.js → index-BKeZt2hQ.js} +1 -1
- langflow/frontend/assets/{index-BCCGvqay.js → index-BKlQbl-6.js} +1 -1
- langflow/frontend/assets/{index-Boso-xEw.js → index-BLYw9MK2.js} +1 -1
- langflow/frontend/assets/{index-DmMDPoi0.js → index-BLsVo9iW.js} +1 -1
- langflow/frontend/assets/{index-Car-zdor.js → index-BNQIbda3.js} +1 -1
- langflow/frontend/assets/{index-Dg-63Si_.js → index-BPR2mEFC.js} +1 -1
- langflow/frontend/assets/{index-CTrt1Q_j.js → index-BPfdqCc_.js} +1 -1
- langflow/frontend/assets/{index-CVQmT7ZL.js → index-BQrVDjR1.js} +1 -1
- langflow/frontend/assets/{index-BB15_iOb.js → index-BRmSeoWR.js} +1 -1
- langflow/frontend/assets/{index-BX5D-USa.js → index-BUse-kxM.js} +1 -1
- langflow/frontend/assets/{index-CaQ_H9ww.js → index-BVFaF7HW.js} +1 -1
- langflow/frontend/assets/{index-C26RqKWL.js → index-BWgIWfv2.js} +1 -1
- langflow/frontend/assets/{index-DbMFlnHE.js → index-BWt5xGeA.js} +1 -1
- langflow/frontend/assets/{index-Db71w3lq.js → index-BYhcGLTV.js} +1 -1
- langflow/frontend/assets/{index-DzW2mfkK.js → index-BYjw7Gk3.js} +1 -1
- langflow/frontend/assets/{index-DJB12jIC.js → index-BZFljdMa.js} +1 -1
- langflow/frontend/assets/{index-nVwHLjuV.js → index-BcAgItH4.js} +1 -1
- langflow/frontend/assets/{index-DkelbYy7.js → index-Bct1s6__.js} +1 -1
- langflow/frontend/assets/{index-ChXJpBz4.js → index-Bhv79Zso.js} +1 -1
- langflow/frontend/assets/{index-BxEuHa76.js → index-Bj3lSwvZ.js} +1 -1
- langflow/frontend/assets/{index-BkPYpfgw.js → index-Bk4mTwnI.js} +1 -1
- langflow/frontend/assets/{index-BvT7L317.js → index-BmIx1cws.js} +1 -1
- langflow/frontend/assets/{index-DIDDfmlJ.js → index-BmYJJ5YS.js} +1 -1
- langflow/frontend/assets/{index-C7QWbnLK.js → index-BnAFhkSN.js} +1 -1
- langflow/frontend/assets/{index-CJo_cyWW.js → index-Bo-ww0Bb.js} +1 -1
- langflow/frontend/assets/{index-DjQETUy8.js → index-BpmqDOeZ.js} +1 -1
- langflow/frontend/assets/{index-ya2uXE8v.js → index-BrVhdPZb.js} +1 -1
- langflow/frontend/assets/{index-DCRk27Tp.js → index-BvGQfVBD.js} +1 -1
- langflow/frontend/assets/{index-BTrsh9LS.js → index-Bwi4flFg.js} +1 -1
- langflow/frontend/assets/{index-BRxvproo.js → index-BzoRPtTY.js} +1 -1
- langflow/frontend/assets/{index-BIQQCMvz.js → index-C--IDAyc.js} +1 -1
- langflow/frontend/assets/{index-DfngcQxO.js → index-C0E3_MIK.js} +1 -1
- langflow/frontend/assets/{index-Bvxg4_ux.js → index-C27Jj_26.js} +1 -1
- langflow/frontend/assets/{index-D8lOi1GI.js → index-C2eQmQsn.js} +1 -1
- langflow/frontend/assets/{index-rXV1G1aB.js → index-C8K0r39B.js} +1 -1
- langflow/frontend/assets/{index-B3Sur4Z3.js → index-CEJNWPhA.js} +1 -1
- langflow/frontend/assets/{index-BR0bkVqX.js → index-CFNTYfFK.js} +1 -1
- langflow/frontend/assets/{index-Bnqod3vk.js → index-CMHpjHZl.js} +1 -1
- langflow/frontend/assets/{index-BLGYN-9b.js → index-CSu8KHOi.js} +1 -1
- langflow/frontend/assets/{index-BOB_zsjl.js → index-CUKmGsI6.js} +1 -1
- langflow/frontend/assets/{index-BzEUlaw_.js → index-CWYiSeWV.js} +1 -1
- langflow/frontend/assets/{index-DVlceYFD.js → index-CY7_TBTC.js} +1 -1
- langflow/frontend/assets/{index-D3DDfngy.js → index-CbnWRlYY.js} +1 -1
- langflow/frontend/assets/{index-cvZdgWHQ.js → index-CfPBgkqg.js} +1 -1
- langflow/frontend/assets/{index-Ui4xUImO.js → index-Cg53lrYh.js} +1 -1
- langflow/frontend/assets/{index-C6jri9Wm.js → index-CgU7KF4I.js} +1 -1
- langflow/frontend/assets/{index-BVEZDXxS.js → index-CgwykVGh.js} +1 -1
- langflow/frontend/assets/{index-BOeo01QB.js → index-Ch5r0oW6.js} +1 -1
- langflow/frontend/assets/{index-D6PSjHxP.js → index-CjsommIr.js} +1 -1
- langflow/frontend/assets/{index-pCQ_yw8m.js → index-CkK25zZO.js} +1 -1
- langflow/frontend/assets/{index-BFp_O-c9.js → index-CkjwSTSM.js} +1 -1
- langflow/frontend/assets/{index-Du_18NCU.js → index-CmSFKgiD.js} +1 -1
- langflow/frontend/assets/{index-BvwZfF2i.js → index-Cr5v2ave.js} +1 -1
- langflow/frontend/assets/{index-FUxmznS-.js → index-CrAF-31Y.js} +1 -1
- langflow/frontend/assets/{index-C-2hghRJ.js → index-CsLQiWNf.js} +1 -1
- langflow/frontend/assets/{index-C_TdzfAn.js → index-CuCM7Wu7.js} +1 -1
- langflow/frontend/assets/{index-D5_DsUJc.js → index-Cxy9sEpy.js} +1 -1
- langflow/frontend/assets/{index-C_veJlEb.js → index-CyP3py8K.js} +1 -1
- langflow/frontend/assets/{index-OazXJdEl.js → index-CzHzeZuA.js} +1 -1
- langflow/frontend/assets/{index-CvcEzq4x.js → index-D1oynC8a.js} +1 -1
- langflow/frontend/assets/{index-CZQ9rXNa.js → index-D4tjMhfY.js} +1 -1
- langflow/frontend/assets/{index-B1YN7oMV.js → index-D6CSIrp1.js} +1 -1
- langflow/frontend/assets/{index-DfxYyS3M.js → index-D9kwEzPB.js} +1 -1
- langflow/frontend/assets/{index-BbRm7beF.js → index-DDXsm8tz.js} +1 -1
- langflow/frontend/assets/{index-xuIrH2Dq.js → index-DDhJVVel.js} +1 -1
- langflow/frontend/assets/{index-CmplyEaa.js → index-DH6o91_s.js} +1 -1
- langflow/frontend/assets/{index-DnEGCgih.js → index-DHngW1k8.js} +1 -1
- langflow/frontend/assets/{index-ajRge-Mg.js → index-DIKUsGLF.js} +1 -1
- langflow/frontend/assets/{index-DpClkXIV.js → index-DJESSNJi.js} +1 -1
- langflow/frontend/assets/{index-8WdfSTTz.js → index-DMCWDJOl.js} +1 -1
- langflow/frontend/assets/{index-DZTC5pdT.js → index-DOEvKC2X.js} +1 -1
- langflow/frontend/assets/{index-DysKpOuj.js → index-DOQDkSoK.js} +1 -1
- langflow/frontend/assets/{index-C82JjCPD.js → index-DXAfIEvs.js} +1 -1
- langflow/frontend/assets/{index-D8GJngXa.js → index-DZP_SaHb.js} +1 -1
- langflow/frontend/assets/{index-DIkNW9Cd.js → index-DZxUIhWh.js} +1 -1
- langflow/frontend/assets/{index-DK1Ptcc4.js → index-Dda2u_yz.js} +1 -1
- langflow/frontend/assets/{index-BWmPX4iQ.js → index-Dg8N3NSO.js} +1 -1
- langflow/frontend/assets/{index-CWdkbVsd.js → index-DkGhPNeA.js} +1 -1
- langflow/frontend/assets/{index-DF5VwgU6.js → index-Dka_Rk4-.js} +1 -1
- langflow/frontend/assets/{index-Bsa0xZyL.js → index-DljpLeCW.js} +1 -1
- langflow/frontend/assets/{index-CLPdN-q6.js → index-DnVYJtVO.js} +1 -1
- langflow/frontend/assets/{index-CxvP91st.js → index-DqbzUcI5.js} +1 -1
- langflow/frontend/assets/{index-BIzTEqFh.js → index-Dr6pVDPI.js} +1 -1
- langflow/frontend/assets/{index-tVYiABdp.js → index-DsoX2o1S.js} +1 -1
- langflow/frontend/assets/{index-CCePCqkT.js → index-DwfHWnX7.js} +1 -1
- langflow/frontend/assets/{index-BEMw2Np8.js → index-Dx-Z87KT.js} +1 -1
- langflow/frontend/assets/{index-BRYjyhAd.js → index-DyqITq51.js} +1 -1
- langflow/frontend/assets/{index-l7bzB8Ex.js → index-DzIv3RyR.js} +1 -1
- langflow/frontend/assets/{index-D-9TI74R.js → index-G4ro0MjT.js} +1 -1
- langflow/frontend/assets/{index-CCxGSSTT.js → index-H7J7w7fa.js} +1 -1
- langflow/frontend/assets/{index-_UcqeEjm.js → index-KWY77KfV.js} +1 -1
- langflow/frontend/assets/{index-Dqd4RjYA.js → index-U9GWm1eH.js} +1 -1
- langflow/frontend/assets/{index-Dq5ilsem.js → index-Un9pWxnP.js} +1 -1
- langflow/frontend/assets/{index-BzL_EoKd.js → index-Xi4TplbI.js} +1 -1
- langflow/frontend/assets/{index-LbYjHKkn.js → index-_cbGmjF4.js} +1 -1
- langflow/frontend/assets/{index-DGRMNe9n.js → index-cEXY6V06.js} +1 -1
- langflow/frontend/assets/{index-8yMsjVV2.js → index-dyXKnkMi.js} +1 -1
- langflow/frontend/assets/{index-DKHNourL.js → index-eUkS6iJM.js} +1 -1
- langflow/frontend/assets/{index-Bv8h2Z-q.js → index-ekfMOqrF.js} +1 -1
- langflow/frontend/assets/{index-B748uLP1.js → index-gdb7XMS8.js} +1 -1
- langflow/frontend/assets/{index-CpvYQ0ug.js → index-hZUcL0MZ.js} +1 -1
- langflow/frontend/assets/{index-BIXaW2aY.js → index-kkA-qHB_.js} +1 -1
- langflow/frontend/assets/{index-BhIOhlCH.js → index-mzl9ULw5.js} +1 -1
- langflow/frontend/assets/{index-CYe8Ipef.js → index-oxHBZk2v.js} +1 -1
- langflow/frontend/assets/{index-WPFivmdQ.js → index-p2kStSPe.js} +1 -1
- langflow/frontend/assets/{index-BmX5CoED.js → index-paQEWYGT.js} +1 -1
- langflow/frontend/assets/{index-CpcbQZIF.js → index-r_8gs4nL.js} +1 -1
- langflow/frontend/assets/{index-dcnYpT9N.js → index-uiKla4UR.js} +1 -1
- langflow/frontend/assets/{index-BTEW9e8P.js → index-vJOO5U8M.js} +1 -1
- langflow/frontend/assets/{index-CQMoqLAu.js → index-w72fDjpG.js} +1 -1
- langflow/frontend/assets/{index-Dsps-jKu.js → index-zV82kQ6k.js} +1 -1
- langflow/frontend/assets/lazyIconImports-DTNgvPE-.js +2 -0
- langflow/frontend/assets/{use-post-add-user-BrBYH9eR.js → use-post-add-user-CvtuazTg.js} +1 -1
- langflow/frontend/index.html +1 -1
- langflow/graph/edge/base.py +2 -3
- langflow/graph/graph/base.py +14 -12
- 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/Blog Writer.json +2 -2
- langflow/initial_setup/starter_projects/Custom Component Generator.json +2 -2
- langflow/initial_setup/starter_projects/Document Q&A.json +1 -1
- langflow/initial_setup/starter_projects/Instagram Copywriter.json +3 -3
- langflow/initial_setup/starter_projects/Invoice Summarizer.json +1 -1
- langflow/initial_setup/starter_projects/Knowledge Ingestion.json +2 -2
- langflow/initial_setup/starter_projects/Market Research.json +3 -3
- langflow/initial_setup/starter_projects/Meeting Summary.json +6 -6
- langflow/initial_setup/starter_projects/Memory Chatbot.json +2 -2
- langflow/initial_setup/starter_projects/News Aggregator.json +3 -3
- langflow/initial_setup/starter_projects/Nvidia Remix.json +3 -3
- langflow/initial_setup/starter_projects/Pok/303/251dex Agent.json" +1 -1
- langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json +1 -1
- langflow/initial_setup/starter_projects/Price Deal Finder.json +5 -5
- langflow/initial_setup/starter_projects/Research Agent.json +3 -3
- langflow/initial_setup/starter_projects/SaaS Pricing.json +1 -1
- langflow/initial_setup/starter_projects/Search agent.json +1 -1
- langflow/initial_setup/starter_projects/Sequential Tasks Agents.json +7 -7
- langflow/initial_setup/starter_projects/Simple Agent.json +3 -3
- langflow/initial_setup/starter_projects/Social Media Agent.json +1 -1
- langflow/initial_setup/starter_projects/Text Sentiment Analysis.json +1 -1
- langflow/initial_setup/starter_projects/Travel Planning Agents.json +3 -3
- langflow/initial_setup/starter_projects/Vector Store RAG.json +1 -1
- langflow/initial_setup/starter_projects/Youtube Analysis.json +3 -3
- 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 +3 -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/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/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.dev38.dist-info}/METADATA +2 -1
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev38.dist-info}/RECORD +334 -333
- langflow/frontend/assets/lazyIconImports-t6wEndt1.js +0 -2
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev38.dist-info}/WHEEL +0 -0
- {langflow_base_nightly-0.5.0.dev37.dist-info → langflow_base_nightly-0.5.0.dev38.dist-info}/entry_points.txt +0 -0
|
@@ -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()
|
|
@@ -4,10 +4,10 @@ import os
|
|
|
4
4
|
from datetime import datetime, timezone
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from loguru import logger
|
|
8
7
|
from sqlmodel import select
|
|
9
8
|
from typing_extensions import override
|
|
10
9
|
|
|
10
|
+
from langflow.logging.logger import logger
|
|
11
11
|
from langflow.services.auth import utils as auth_utils
|
|
12
12
|
from langflow.services.base import Service
|
|
13
13
|
from langflow.services.database.models.variable.model import Variable, VariableCreate, VariableRead, VariableUpdate
|
|
@@ -29,7 +29,7 @@ class DatabaseVariableService(VariableService, Service):
|
|
|
29
29
|
|
|
30
30
|
async def initialize_user_variables(self, user_id: UUID | str, session: AsyncSession) -> None:
|
|
31
31
|
if not self.settings_service.settings.store_environment_variables:
|
|
32
|
-
logger.
|
|
32
|
+
await logger.adebug("Skipping environment variable storage.")
|
|
33
33
|
return
|
|
34
34
|
|
|
35
35
|
for var_name in self.settings_service.settings.variables_to_get_from_environment:
|
|
@@ -49,9 +49,9 @@ class DatabaseVariableService(VariableService, Service):
|
|
|
49
49
|
type_=CREDENTIAL_TYPE,
|
|
50
50
|
session=session,
|
|
51
51
|
)
|
|
52
|
-
logger.
|
|
52
|
+
await logger.adebug(f"Processed {var_name} variable from environment.")
|
|
53
53
|
except Exception as e: # noqa: BLE001
|
|
54
|
-
logger.
|
|
54
|
+
await logger.aexception(f"Error processing {var_name} variable: {e!s}")
|
|
55
55
|
|
|
56
56
|
async def get_variable(
|
|
57
57
|
self,
|
|
@@ -91,7 +91,7 @@ class DatabaseVariableService(VariableService, Service):
|
|
|
91
91
|
try:
|
|
92
92
|
value = auth_utils.decrypt_api_key(variable.value, settings_service=self.settings_service)
|
|
93
93
|
except Exception as e: # noqa: BLE001
|
|
94
|
-
logger.
|
|
94
|
+
await logger.adebug(
|
|
95
95
|
f"Decryption of {variable.type} failed for variable '{variable.name}': {e}. Assuming plaintext."
|
|
96
96
|
)
|
|
97
97
|
value = variable.value
|
|
@@ -53,7 +53,7 @@ def update_input_types(build_config: dotdict) -> dotdict:
|
|
|
53
53
|
return build_config
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def set_field_display(build_config: dotdict, field: str, value: bool | None = None) -> dotdict:
|
|
56
|
+
def set_field_display(build_config: dotdict, field: str, value: bool | None = None) -> dotdict: # noqa: FBT001
|
|
57
57
|
"""Set whether a field should be displayed in the UI."""
|
|
58
58
|
if field in build_config and isinstance(build_config[field], dict) and "show" in build_config[field]:
|
|
59
59
|
build_config[field]["show"] = value
|
|
@@ -63,20 +63,21 @@ def set_field_display(build_config: dotdict, field: str, value: bool | None = No
|
|
|
63
63
|
def set_multiple_field_display(
|
|
64
64
|
build_config: dotdict,
|
|
65
65
|
fields: dict[str, bool] | None = None,
|
|
66
|
+
*,
|
|
66
67
|
value: bool | None = None,
|
|
67
68
|
field_list: list[str] | None = None,
|
|
68
69
|
) -> dotdict:
|
|
69
70
|
"""Set display property for multiple fields at once."""
|
|
70
71
|
if fields is not None:
|
|
71
72
|
for field, visibility in fields.items():
|
|
72
|
-
build_config = set_field_display(build_config, field, visibility)
|
|
73
|
+
build_config = set_field_display(build_config, field, value=visibility)
|
|
73
74
|
elif field_list is not None:
|
|
74
75
|
for field in field_list:
|
|
75
|
-
build_config = set_field_display(build_config, field, value)
|
|
76
|
+
build_config = set_field_display(build_config, field, value=value)
|
|
76
77
|
return build_config
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
def set_field_advanced(build_config: dotdict, field: str, value: bool | None = None) -> dotdict:
|
|
80
|
+
def set_field_advanced(build_config: dotdict, field: str, value: bool | None = None) -> dotdict: # noqa: FBT001
|
|
80
81
|
"""Set whether a field is considered 'advanced' in the UI."""
|
|
81
82
|
if value is None:
|
|
82
83
|
value = False
|
|
@@ -88,16 +89,17 @@ def set_field_advanced(build_config: dotdict, field: str, value: bool | None = N
|
|
|
88
89
|
def set_multiple_field_advanced(
|
|
89
90
|
build_config: dotdict,
|
|
90
91
|
fields: dict[str, bool] | None = None,
|
|
92
|
+
*,
|
|
91
93
|
value: bool | None = None,
|
|
92
94
|
field_list: list[str] | None = None,
|
|
93
95
|
) -> dotdict:
|
|
94
96
|
"""Set advanced property for multiple fields at once."""
|
|
95
97
|
if fields is not None:
|
|
96
98
|
for field, advanced in fields.items():
|
|
97
|
-
build_config = set_field_advanced(build_config, field, advanced)
|
|
99
|
+
build_config = set_field_advanced(build_config, field, value=advanced)
|
|
98
100
|
elif field_list is not None:
|
|
99
101
|
for field in field_list:
|
|
100
|
-
build_config = set_field_advanced(build_config, field, value)
|
|
102
|
+
build_config = set_field_advanced(build_config, field, value=value)
|
|
101
103
|
return build_config
|
|
102
104
|
|
|
103
105
|
|
|
@@ -120,6 +122,7 @@ def set_current_fields(
|
|
|
120
122
|
selected_action: str | None = None,
|
|
121
123
|
default_fields: list[str] = DEFAULT_FIELDS,
|
|
122
124
|
func: Callable[[dotdict, str, bool], dotdict] = set_field_display,
|
|
125
|
+
*,
|
|
123
126
|
default_value: bool | None = None,
|
|
124
127
|
) -> dotdict:
|
|
125
128
|
"""Set the current fields for a selected action."""
|