lfx-nightly 0.1.13.dev0__py3-none-any.whl → 0.2.0.dev26__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.
- lfx/_assets/component_index.json +1 -1
- lfx/base/agents/agent.py +121 -29
- lfx/base/agents/altk_base_agent.py +380 -0
- lfx/base/agents/altk_tool_wrappers.py +565 -0
- lfx/base/agents/events.py +103 -35
- lfx/base/agents/utils.py +15 -2
- lfx/base/composio/composio_base.py +183 -233
- lfx/base/data/base_file.py +88 -21
- lfx/base/data/storage_utils.py +192 -0
- lfx/base/data/utils.py +178 -14
- lfx/base/datastax/__init__.py +5 -0
- lfx/{components/vectorstores/astradb.py → base/datastax/astradb_base.py} +84 -473
- lfx/base/embeddings/embeddings_class.py +113 -0
- lfx/base/io/chat.py +5 -4
- lfx/base/mcp/util.py +101 -15
- lfx/base/models/groq_constants.py +74 -58
- lfx/base/models/groq_model_discovery.py +265 -0
- lfx/base/models/model.py +1 -1
- lfx/base/models/model_input_constants.py +74 -7
- lfx/base/models/model_utils.py +100 -0
- lfx/base/models/ollama_constants.py +3 -0
- lfx/base/models/openai_constants.py +7 -0
- lfx/base/models/watsonx_constants.py +36 -0
- lfx/base/tools/run_flow.py +601 -129
- lfx/cli/commands.py +7 -4
- lfx/cli/common.py +2 -2
- lfx/cli/run.py +1 -1
- lfx/cli/script_loader.py +53 -11
- lfx/components/Notion/create_page.py +1 -1
- lfx/components/Notion/list_database_properties.py +1 -1
- lfx/components/Notion/list_pages.py +1 -1
- lfx/components/Notion/list_users.py +1 -1
- lfx/components/Notion/page_content_viewer.py +1 -1
- lfx/components/Notion/search.py +1 -1
- lfx/components/Notion/update_page_property.py +1 -1
- lfx/components/__init__.py +19 -5
- lfx/components/altk/__init__.py +34 -0
- lfx/components/altk/altk_agent.py +193 -0
- lfx/components/amazon/amazon_bedrock_converse.py +1 -1
- lfx/components/apify/apify_actor.py +4 -4
- lfx/components/composio/__init__.py +70 -18
- lfx/components/composio/apollo_composio.py +11 -0
- lfx/components/composio/bitbucket_composio.py +11 -0
- lfx/components/composio/canva_composio.py +11 -0
- lfx/components/composio/coda_composio.py +11 -0
- lfx/components/composio/composio_api.py +10 -0
- lfx/components/composio/discord_composio.py +1 -1
- lfx/components/composio/elevenlabs_composio.py +11 -0
- lfx/components/composio/exa_composio.py +11 -0
- lfx/components/composio/firecrawl_composio.py +11 -0
- lfx/components/composio/fireflies_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +1 -1
- lfx/components/composio/googlebigquery_composio.py +11 -0
- lfx/components/composio/googlecalendar_composio.py +1 -1
- lfx/components/composio/googledocs_composio.py +1 -1
- lfx/components/composio/googlemeet_composio.py +1 -1
- lfx/components/composio/googlesheets_composio.py +1 -1
- lfx/components/composio/googletasks_composio.py +1 -1
- lfx/components/composio/heygen_composio.py +11 -0
- lfx/components/composio/mem0_composio.py +11 -0
- lfx/components/composio/peopledatalabs_composio.py +11 -0
- lfx/components/composio/perplexityai_composio.py +11 -0
- lfx/components/composio/serpapi_composio.py +11 -0
- lfx/components/composio/slack_composio.py +3 -574
- lfx/components/composio/slackbot_composio.py +1 -1
- lfx/components/composio/snowflake_composio.py +11 -0
- lfx/components/composio/tavily_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +2 -2
- lfx/components/{agents → cuga}/__init__.py +5 -7
- lfx/components/cuga/cuga_agent.py +730 -0
- lfx/components/data/__init__.py +78 -28
- lfx/components/data_source/__init__.py +58 -0
- lfx/components/{data → data_source}/api_request.py +26 -3
- lfx/components/{data → data_source}/csv_to_data.py +15 -10
- lfx/components/{data → data_source}/json_to_data.py +15 -8
- lfx/components/{data → data_source}/news_search.py +1 -1
- lfx/components/{data → data_source}/rss.py +1 -1
- lfx/components/{data → data_source}/sql_executor.py +1 -1
- lfx/components/{data → data_source}/url.py +1 -1
- lfx/components/{data → data_source}/web_search.py +1 -1
- lfx/components/datastax/__init__.py +12 -6
- lfx/components/datastax/{astra_assistant_manager.py → astradb_assistant_manager.py} +1 -0
- lfx/components/datastax/astradb_chatmemory.py +40 -0
- lfx/components/datastax/astradb_cql.py +6 -32
- lfx/components/datastax/astradb_graph.py +10 -124
- lfx/components/datastax/astradb_tool.py +13 -53
- lfx/components/datastax/astradb_vectorstore.py +134 -977
- lfx/components/datastax/create_assistant.py +1 -0
- lfx/components/datastax/create_thread.py +1 -0
- lfx/components/datastax/dotenv.py +1 -0
- lfx/components/datastax/get_assistant.py +1 -0
- lfx/components/datastax/getenvvar.py +1 -0
- lfx/components/datastax/graph_rag.py +1 -1
- lfx/components/datastax/hcd.py +1 -1
- lfx/components/datastax/list_assistants.py +1 -0
- lfx/components/datastax/run.py +1 -0
- lfx/components/deactivated/json_document_builder.py +1 -1
- lfx/components/elastic/elasticsearch.py +1 -1
- lfx/components/elastic/opensearch_multimodal.py +1575 -0
- lfx/components/files_and_knowledge/__init__.py +47 -0
- lfx/components/{data → files_and_knowledge}/directory.py +1 -1
- lfx/components/{data → files_and_knowledge}/file.py +246 -18
- lfx/components/{knowledge_bases → files_and_knowledge}/ingestion.py +17 -9
- lfx/components/{knowledge_bases → files_and_knowledge}/retrieval.py +18 -10
- lfx/components/{data → files_and_knowledge}/save_file.py +142 -22
- lfx/components/flow_controls/__init__.py +58 -0
- lfx/components/{logic → flow_controls}/conditional_router.py +1 -1
- lfx/components/{logic → flow_controls}/loop.py +47 -9
- lfx/components/flow_controls/run_flow.py +108 -0
- lfx/components/glean/glean_search_api.py +1 -1
- lfx/components/groq/groq.py +35 -28
- lfx/components/helpers/__init__.py +102 -0
- lfx/components/ibm/watsonx.py +25 -21
- lfx/components/input_output/__init__.py +3 -1
- lfx/components/input_output/chat.py +12 -3
- lfx/components/input_output/chat_output.py +12 -4
- lfx/components/input_output/text.py +1 -1
- lfx/components/input_output/text_output.py +1 -1
- lfx/components/{data → input_output}/webhook.py +1 -1
- lfx/components/knowledge_bases/__init__.py +59 -4
- lfx/components/langchain_utilities/character.py +1 -1
- lfx/components/langchain_utilities/csv_agent.py +84 -16
- lfx/components/langchain_utilities/json_agent.py +67 -12
- lfx/components/langchain_utilities/language_recursive.py +1 -1
- lfx/components/llm_operations/__init__.py +46 -0
- lfx/components/{processing → llm_operations}/batch_run.py +1 -1
- lfx/components/{processing → llm_operations}/lambda_filter.py +1 -1
- lfx/components/{logic → llm_operations}/llm_conditional_router.py +1 -1
- lfx/components/{processing/llm_router.py → llm_operations/llm_selector.py} +3 -3
- lfx/components/{processing → llm_operations}/structured_output.py +56 -18
- lfx/components/logic/__init__.py +126 -0
- lfx/components/mem0/mem0_chat_memory.py +11 -0
- lfx/components/mistral/mistral_embeddings.py +1 -1
- lfx/components/models/__init__.py +64 -9
- lfx/components/models_and_agents/__init__.py +49 -0
- lfx/components/{agents → models_and_agents}/agent.py +49 -6
- lfx/components/models_and_agents/embedding_model.py +423 -0
- lfx/components/models_and_agents/language_model.py +398 -0
- lfx/components/{agents → models_and_agents}/mcp_component.py +84 -45
- lfx/components/{helpers → models_and_agents}/memory.py +1 -1
- lfx/components/nvidia/system_assist.py +1 -1
- lfx/components/olivya/olivya.py +1 -1
- lfx/components/ollama/ollama.py +235 -14
- lfx/components/openrouter/openrouter.py +49 -147
- lfx/components/processing/__init__.py +9 -57
- lfx/components/processing/converter.py +1 -1
- lfx/components/processing/dataframe_operations.py +1 -1
- lfx/components/processing/parse_json_data.py +2 -2
- lfx/components/processing/parser.py +7 -2
- lfx/components/processing/split_text.py +1 -1
- lfx/components/qdrant/qdrant.py +1 -1
- lfx/components/redis/redis.py +1 -1
- lfx/components/twelvelabs/split_video.py +10 -0
- lfx/components/twelvelabs/video_file.py +12 -0
- lfx/components/utilities/__init__.py +43 -0
- lfx/components/{helpers → utilities}/calculator_core.py +1 -1
- lfx/components/{helpers → utilities}/current_date.py +1 -1
- lfx/components/{processing → utilities}/python_repl_core.py +1 -1
- lfx/components/vectorstores/__init__.py +0 -6
- lfx/components/vectorstores/local_db.py +9 -0
- lfx/components/youtube/youtube_transcripts.py +118 -30
- lfx/custom/custom_component/component.py +60 -3
- lfx/custom/custom_component/custom_component.py +68 -6
- lfx/field_typing/constants.py +1 -0
- lfx/graph/edge/base.py +45 -22
- lfx/graph/graph/base.py +5 -2
- lfx/graph/graph/schema.py +3 -2
- lfx/graph/state/model.py +15 -2
- lfx/graph/utils.py +6 -0
- lfx/graph/vertex/base.py +4 -1
- lfx/graph/vertex/param_handler.py +10 -7
- lfx/graph/vertex/vertex_types.py +1 -1
- lfx/helpers/__init__.py +12 -0
- lfx/helpers/flow.py +117 -0
- lfx/inputs/input_mixin.py +24 -1
- lfx/inputs/inputs.py +13 -1
- lfx/interface/components.py +161 -83
- lfx/io/schema.py +6 -0
- lfx/log/logger.py +5 -3
- lfx/schema/schema.py +5 -0
- lfx/services/database/__init__.py +5 -0
- lfx/services/database/service.py +25 -0
- lfx/services/deps.py +87 -22
- lfx/services/manager.py +19 -6
- lfx/services/mcp_composer/service.py +998 -157
- lfx/services/session.py +5 -0
- lfx/services/settings/base.py +51 -7
- lfx/services/settings/constants.py +8 -0
- lfx/services/storage/local.py +76 -46
- lfx/services/storage/service.py +152 -29
- lfx/template/field/base.py +3 -0
- lfx/utils/ssrf_protection.py +384 -0
- lfx/utils/validate_cloud.py +26 -0
- {lfx_nightly-0.1.13.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/METADATA +38 -22
- {lfx_nightly-0.1.13.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/RECORD +210 -196
- {lfx_nightly-0.1.13.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/WHEEL +1 -1
- lfx/components/agents/cuga_agent.py +0 -1013
- lfx/components/datastax/astra_db.py +0 -77
- lfx/components/datastax/cassandra.py +0 -92
- lfx/components/logic/run_flow.py +0 -71
- lfx/components/models/embedding_model.py +0 -114
- lfx/components/models/language_model.py +0 -144
- lfx/components/vectorstores/astradb_graph.py +0 -326
- lfx/components/vectorstores/cassandra.py +0 -264
- lfx/components/vectorstores/cassandra_graph.py +0 -238
- lfx/components/vectorstores/chroma.py +0 -167
- lfx/components/vectorstores/clickhouse.py +0 -135
- lfx/components/vectorstores/couchbase.py +0 -102
- lfx/components/vectorstores/elasticsearch.py +0 -267
- lfx/components/vectorstores/faiss.py +0 -111
- lfx/components/vectorstores/graph_rag.py +0 -141
- lfx/components/vectorstores/hcd.py +0 -314
- lfx/components/vectorstores/milvus.py +0 -115
- lfx/components/vectorstores/mongodb_atlas.py +0 -213
- lfx/components/vectorstores/opensearch.py +0 -243
- lfx/components/vectorstores/pgvector.py +0 -72
- lfx/components/vectorstores/pinecone.py +0 -134
- lfx/components/vectorstores/qdrant.py +0 -109
- lfx/components/vectorstores/supabase.py +0 -76
- lfx/components/vectorstores/upstash.py +0 -124
- lfx/components/vectorstores/vectara.py +0 -97
- lfx/components/vectorstores/vectara_rag.py +0 -164
- lfx/components/vectorstores/weaviate.py +0 -89
- /lfx/components/{data → data_source}/mock_data.py +0 -0
- /lfx/components/datastax/{astra_vectorize.py → astradb_vectorize.py} +0 -0
- /lfx/components/{logic → flow_controls}/data_conditional_router.py +0 -0
- /lfx/components/{logic → flow_controls}/flow_tool.py +0 -0
- /lfx/components/{logic → flow_controls}/listen.py +0 -0
- /lfx/components/{logic → flow_controls}/notify.py +0 -0
- /lfx/components/{logic → flow_controls}/pass_message.py +0 -0
- /lfx/components/{logic → flow_controls}/sub_flow.py +0 -0
- /lfx/components/{processing → models_and_agents}/prompt.py +0 -0
- /lfx/components/{helpers → processing}/create_list.py +0 -0
- /lfx/components/{helpers → processing}/output_parser.py +0 -0
- /lfx/components/{helpers → processing}/store_message.py +0 -0
- /lfx/components/{helpers → utilities}/id_generator.py +0 -0
- {lfx_nightly-0.1.13.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Extended embeddings class with available models metadata."""
|
|
2
|
+
|
|
3
|
+
from langchain_core.embeddings import Embeddings
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EmbeddingsWithModels(Embeddings):
|
|
7
|
+
"""Extended Embeddings class that includes available models with dedicated instances.
|
|
8
|
+
|
|
9
|
+
This class inherits from LangChain Embeddings and provides a mapping of model names
|
|
10
|
+
to their dedicated embedding instances, enabling multi-model support without the need
|
|
11
|
+
for dynamic model switching.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
embeddings: The primary LangChain Embeddings instance (used as fallback).
|
|
15
|
+
available_models: Dict mapping model names to their dedicated Embeddings instances.
|
|
16
|
+
Each model has its own pre-configured instance with specific parameters.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
embeddings: Embeddings,
|
|
22
|
+
available_models: dict[str, Embeddings] | None = None,
|
|
23
|
+
):
|
|
24
|
+
"""Initialize the EmbeddingsWithModels wrapper.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
embeddings: The primary LangChain Embeddings instance (used as default/fallback).
|
|
28
|
+
available_models: Dict mapping model names to dedicated Embeddings instances.
|
|
29
|
+
Each value should be a fully configured Embeddings object ready to use.
|
|
30
|
+
Defaults to empty dict if not provided.
|
|
31
|
+
"""
|
|
32
|
+
super().__init__()
|
|
33
|
+
self.embeddings = embeddings
|
|
34
|
+
self.available_models = available_models if available_models is not None else {}
|
|
35
|
+
|
|
36
|
+
def embed_documents(self, texts: list[str]) -> list[list[float]]:
|
|
37
|
+
"""Embed search docs by delegating to the underlying embeddings instance.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
texts: List of text to embed.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
List of embeddings.
|
|
44
|
+
"""
|
|
45
|
+
return self.embeddings.embed_documents(texts)
|
|
46
|
+
|
|
47
|
+
def embed_query(self, text: str) -> list[float]:
|
|
48
|
+
"""Embed query text by delegating to the underlying embeddings instance.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
text: Text to embed.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Embedding.
|
|
55
|
+
"""
|
|
56
|
+
return self.embeddings.embed_query(text)
|
|
57
|
+
|
|
58
|
+
async def aembed_documents(self, texts: list[str]) -> list[list[float]]:
|
|
59
|
+
"""Asynchronously embed search docs.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
texts: List of text to embed.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
List of embeddings.
|
|
66
|
+
"""
|
|
67
|
+
return await self.embeddings.aembed_documents(texts)
|
|
68
|
+
|
|
69
|
+
async def aembed_query(self, text: str) -> list[float]:
|
|
70
|
+
"""Asynchronously embed query text.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
text: Text to embed.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Embedding.
|
|
77
|
+
"""
|
|
78
|
+
return await self.embeddings.aembed_query(text)
|
|
79
|
+
|
|
80
|
+
def __call__(self, *args, **kwargs):
|
|
81
|
+
"""Make the class callable by delegating to the underlying embeddings instance.
|
|
82
|
+
|
|
83
|
+
This handles cases where the embeddings object is used as a callable.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
*args: Positional arguments to pass to the underlying embeddings instance.
|
|
87
|
+
**kwargs: Keyword arguments to pass to the underlying embeddings instance.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
The result of calling the underlying embeddings instance.
|
|
91
|
+
"""
|
|
92
|
+
if callable(self.embeddings):
|
|
93
|
+
return self.embeddings(*args, **kwargs)
|
|
94
|
+
msg = f"'{type(self.embeddings).__name__}' object is not callable"
|
|
95
|
+
raise TypeError(msg)
|
|
96
|
+
|
|
97
|
+
def __getattr__(self, name: str):
|
|
98
|
+
"""Delegate attribute access to the underlying embeddings instance.
|
|
99
|
+
|
|
100
|
+
This ensures full compatibility with any additional methods or attributes
|
|
101
|
+
that the underlying embeddings instance might have.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
name: The attribute name to access.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
The attribute from the underlying embeddings instance.
|
|
108
|
+
"""
|
|
109
|
+
return getattr(self.embeddings, name)
|
|
110
|
+
|
|
111
|
+
def __repr__(self) -> str:
|
|
112
|
+
"""Return string representation of the wrapper."""
|
|
113
|
+
return f"EmbeddingsWithModels(embeddings={self.embeddings!r}, available_models={self.available_models!r})"
|
lfx/base/io/chat.py
CHANGED
|
@@ -6,8 +6,9 @@ class ChatComponent(Component):
|
|
|
6
6
|
description = "Use as base for chat components."
|
|
7
7
|
|
|
8
8
|
def get_properties_from_source_component(self):
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
vertex = self.get_vertex()
|
|
10
|
+
if vertex and hasattr(vertex, "incoming_edges") and vertex.incoming_edges:
|
|
11
|
+
source_id = vertex.incoming_edges[0].source_id
|
|
11
12
|
source_vertex = self.graph.get_vertex(source_id)
|
|
12
13
|
component = source_vertex.custom_component
|
|
13
14
|
source = component.display_name
|
|
@@ -15,6 +16,6 @@ class ChatComponent(Component):
|
|
|
15
16
|
possible_attributes = ["model_name", "model_id", "model"]
|
|
16
17
|
for attribute in possible_attributes:
|
|
17
18
|
if hasattr(component, attribute) and getattr(component, attribute):
|
|
18
|
-
return getattr(component, attribute), icon, source, component.
|
|
19
|
-
return source, icon, component.display_name, component.
|
|
19
|
+
return getattr(component, attribute), icon, source, component.get_id()
|
|
20
|
+
return source, icon, component.display_name, component.get_id()
|
|
20
21
|
return None, None, None, None
|
lfx/base/mcp/util.py
CHANGED
|
@@ -35,13 +35,33 @@ HTTP_INTERNAL_SERVER_ERROR = 500
|
|
|
35
35
|
HTTP_UNAUTHORIZED = 401
|
|
36
36
|
HTTP_FORBIDDEN = 403
|
|
37
37
|
|
|
38
|
-
# MCP Session Manager constants
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
# MCP Session Manager constants - lazy loaded
|
|
39
|
+
_mcp_settings_cache: dict[str, Any] = {}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _get_mcp_setting(key: str, default: Any = None) -> Any:
|
|
43
|
+
"""Lazy load MCP settings from settings service."""
|
|
44
|
+
if key not in _mcp_settings_cache:
|
|
45
|
+
settings = get_settings_service().settings
|
|
46
|
+
_mcp_settings_cache[key] = getattr(settings, key, default)
|
|
47
|
+
return _mcp_settings_cache[key]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_max_sessions_per_server() -> int:
|
|
51
|
+
"""Get maximum number of sessions per server to prevent resource exhaustion."""
|
|
52
|
+
return _get_mcp_setting("mcp_max_sessions_per_server")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_session_idle_timeout() -> int:
|
|
56
|
+
"""Get 5 minutes idle timeout for sessions."""
|
|
57
|
+
return _get_mcp_setting("mcp_session_idle_timeout")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_session_cleanup_interval() -> int:
|
|
61
|
+
"""Get cleanup interval in seconds."""
|
|
62
|
+
return _get_mcp_setting("mcp_session_cleanup_interval")
|
|
63
|
+
|
|
64
|
+
|
|
45
65
|
# RFC 7230 compliant header name pattern: token = 1*tchar
|
|
46
66
|
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
|
|
47
67
|
# "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
|
@@ -65,6 +85,46 @@ ALLOWED_HEADERS = {
|
|
|
65
85
|
}
|
|
66
86
|
|
|
67
87
|
|
|
88
|
+
def create_mcp_http_client_with_ssl_option(
|
|
89
|
+
headers: dict[str, str] | None = None,
|
|
90
|
+
timeout: httpx.Timeout | None = None,
|
|
91
|
+
auth: httpx.Auth | None = None,
|
|
92
|
+
*,
|
|
93
|
+
verify_ssl: bool = True,
|
|
94
|
+
) -> httpx.AsyncClient:
|
|
95
|
+
"""Create an httpx AsyncClient with configurable SSL verification.
|
|
96
|
+
|
|
97
|
+
This is a custom factory that extends the standard MCP client factory
|
|
98
|
+
to support disabling SSL verification for self-signed certificates.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
headers: Optional headers to include with all requests.
|
|
102
|
+
timeout: Request timeout as httpx.Timeout object.
|
|
103
|
+
auth: Optional authentication handler.
|
|
104
|
+
verify_ssl: Whether to verify SSL certificates (default: True).
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Configured httpx.AsyncClient instance.
|
|
108
|
+
"""
|
|
109
|
+
kwargs: dict[str, Any] = {
|
|
110
|
+
"follow_redirects": True,
|
|
111
|
+
"verify": verify_ssl,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if timeout is None:
|
|
115
|
+
kwargs["timeout"] = httpx.Timeout(30.0)
|
|
116
|
+
else:
|
|
117
|
+
kwargs["timeout"] = timeout
|
|
118
|
+
|
|
119
|
+
if headers is not None:
|
|
120
|
+
kwargs["headers"] = headers
|
|
121
|
+
|
|
122
|
+
if auth is not None:
|
|
123
|
+
kwargs["auth"] = auth
|
|
124
|
+
|
|
125
|
+
return httpx.AsyncClient(**kwargs)
|
|
126
|
+
|
|
127
|
+
|
|
68
128
|
def validate_headers(headers: dict[str, str]) -> dict[str, str]:
|
|
69
129
|
"""Validate and sanitize HTTP headers according to RFC 7230.
|
|
70
130
|
|
|
@@ -432,7 +492,7 @@ class MCPSessionManager:
|
|
|
432
492
|
"""Periodically clean up idle sessions."""
|
|
433
493
|
while True:
|
|
434
494
|
try:
|
|
435
|
-
await asyncio.sleep(
|
|
495
|
+
await asyncio.sleep(get_session_cleanup_interval())
|
|
436
496
|
await self._cleanup_idle_sessions()
|
|
437
497
|
except asyncio.CancelledError:
|
|
438
498
|
break
|
|
@@ -450,7 +510,7 @@ class MCPSessionManager:
|
|
|
450
510
|
sessions_to_remove = []
|
|
451
511
|
|
|
452
512
|
for session_id, session_info in list(sessions.items()):
|
|
453
|
-
if current_time - session_info["last_used"] >
|
|
513
|
+
if current_time - session_info["last_used"] > get_session_idle_timeout():
|
|
454
514
|
sessions_to_remove.append(session_id)
|
|
455
515
|
|
|
456
516
|
# Clean up idle sessions
|
|
@@ -573,7 +633,7 @@ class MCPSessionManager:
|
|
|
573
633
|
await self._cleanup_session_by_id(server_key, session_id)
|
|
574
634
|
|
|
575
635
|
# Check if we've reached the maximum number of sessions for this server
|
|
576
|
-
if len(sessions) >=
|
|
636
|
+
if len(sessions) >= get_max_sessions_per_server():
|
|
577
637
|
# Remove the oldest session
|
|
578
638
|
oldest_session_id = min(sessions.keys(), key=lambda x: sessions[x]["last_used"])
|
|
579
639
|
await logger.ainfo(
|
|
@@ -675,7 +735,7 @@ class MCPSessionManager:
|
|
|
675
735
|
|
|
676
736
|
Args:
|
|
677
737
|
session_id: Unique identifier for this session
|
|
678
|
-
connection_params: Connection parameters including URL, headers, timeouts
|
|
738
|
+
connection_params: Connection parameters including URL, headers, timeouts, verify_ssl
|
|
679
739
|
preferred_transport: If set to "sse", skip Streamable HTTP and go directly to SSE
|
|
680
740
|
|
|
681
741
|
Returns:
|
|
@@ -691,6 +751,19 @@ class MCPSessionManager:
|
|
|
691
751
|
# Track which transport succeeded
|
|
692
752
|
used_transport: list[str] = []
|
|
693
753
|
|
|
754
|
+
# Get verify_ssl option from connection params, default to True
|
|
755
|
+
verify_ssl = connection_params.get("verify_ssl", True)
|
|
756
|
+
|
|
757
|
+
# Create custom httpx client factory with SSL verification option
|
|
758
|
+
def custom_httpx_factory(
|
|
759
|
+
headers: dict[str, str] | None = None,
|
|
760
|
+
timeout: httpx.Timeout | None = None,
|
|
761
|
+
auth: httpx.Auth | None = None,
|
|
762
|
+
) -> httpx.AsyncClient:
|
|
763
|
+
return create_mcp_http_client_with_ssl_option(
|
|
764
|
+
headers=headers, timeout=timeout, auth=auth, verify_ssl=verify_ssl
|
|
765
|
+
)
|
|
766
|
+
|
|
694
767
|
async def session_task():
|
|
695
768
|
"""Background task that keeps the session alive."""
|
|
696
769
|
streamable_error = None
|
|
@@ -705,6 +778,7 @@ class MCPSessionManager:
|
|
|
705
778
|
url=connection_params["url"],
|
|
706
779
|
headers=connection_params["headers"],
|
|
707
780
|
timeout=connection_params["timeout_seconds"],
|
|
781
|
+
httpx_client_factory=custom_httpx_factory,
|
|
708
782
|
) as (read, write, _):
|
|
709
783
|
session = ClientSession(read, write)
|
|
710
784
|
async with session:
|
|
@@ -745,6 +819,7 @@ class MCPSessionManager:
|
|
|
745
819
|
connection_params["headers"],
|
|
746
820
|
connection_params["timeout_seconds"],
|
|
747
821
|
sse_read_timeout,
|
|
822
|
+
httpx_client_factory=custom_httpx_factory,
|
|
748
823
|
) as (read, write):
|
|
749
824
|
session = ClientSession(read, write)
|
|
750
825
|
async with session:
|
|
@@ -1196,6 +1271,8 @@ class MCPStreamableHttpClient:
|
|
|
1196
1271
|
headers: dict[str, str] | None = None,
|
|
1197
1272
|
timeout_seconds: int = 30,
|
|
1198
1273
|
sse_read_timeout_seconds: int = 30,
|
|
1274
|
+
*,
|
|
1275
|
+
verify_ssl: bool = True,
|
|
1199
1276
|
) -> list[StructuredTool]:
|
|
1200
1277
|
"""Connect to MCP server using Streamable HTTP transport with SSE fallback (SDK style)."""
|
|
1201
1278
|
# Validate and sanitize headers early
|
|
@@ -1213,12 +1290,13 @@ class MCPStreamableHttpClient:
|
|
|
1213
1290
|
msg = f"Invalid Streamable HTTP or SSE URL ({url}): {error_msg}"
|
|
1214
1291
|
raise ValueError(msg)
|
|
1215
1292
|
# Store connection parameters for later use in run_tool
|
|
1216
|
-
# Include SSE read timeout for fallback
|
|
1293
|
+
# Include SSE read timeout for fallback and SSL verification option
|
|
1217
1294
|
self._connection_params = {
|
|
1218
1295
|
"url": url,
|
|
1219
1296
|
"headers": validated_headers,
|
|
1220
1297
|
"timeout_seconds": timeout_seconds,
|
|
1221
1298
|
"sse_read_timeout_seconds": sse_read_timeout_seconds,
|
|
1299
|
+
"verify_ssl": verify_ssl,
|
|
1222
1300
|
}
|
|
1223
1301
|
elif headers:
|
|
1224
1302
|
self._connection_params["headers"] = validated_headers
|
|
@@ -1238,11 +1316,18 @@ class MCPStreamableHttpClient:
|
|
|
1238
1316
|
return response.tools
|
|
1239
1317
|
|
|
1240
1318
|
async def connect_to_server(
|
|
1241
|
-
self,
|
|
1319
|
+
self,
|
|
1320
|
+
url: str,
|
|
1321
|
+
headers: dict[str, str] | None = None,
|
|
1322
|
+
sse_read_timeout_seconds: int = 30,
|
|
1323
|
+
*,
|
|
1324
|
+
verify_ssl: bool = True,
|
|
1242
1325
|
) -> list[StructuredTool]:
|
|
1243
1326
|
"""Connect to MCP server using Streamable HTTP with SSE fallback transport (SDK style)."""
|
|
1244
1327
|
return await asyncio.wait_for(
|
|
1245
|
-
self._connect_to_server(
|
|
1328
|
+
self._connect_to_server(
|
|
1329
|
+
url, headers, sse_read_timeout_seconds=sse_read_timeout_seconds, verify_ssl=verify_ssl
|
|
1330
|
+
),
|
|
1246
1331
|
timeout=get_settings_service().settings.mcp_server_timeout,
|
|
1247
1332
|
)
|
|
1248
1333
|
|
|
@@ -1473,7 +1558,8 @@ async def update_tools(
|
|
|
1473
1558
|
client = mcp_stdio_client
|
|
1474
1559
|
elif mode in ["Streamable_HTTP", "SSE"]:
|
|
1475
1560
|
# Streamable HTTP connection with SSE fallback
|
|
1476
|
-
|
|
1561
|
+
verify_ssl = server_config.get("verify_ssl", True)
|
|
1562
|
+
tools = await mcp_streamable_http_client.connect_to_server(url, headers=headers, verify_ssl=verify_ssl)
|
|
1477
1563
|
client = mcp_streamable_http_client
|
|
1478
1564
|
else:
|
|
1479
1565
|
logger.error(f"Invalid MCP server mode for '{server_name}': {mode}")
|
|
@@ -1,87 +1,91 @@
|
|
|
1
1
|
from .model_metadata import create_model_metadata
|
|
2
2
|
|
|
3
|
-
# Unified model metadata
|
|
3
|
+
# Unified model metadata
|
|
4
|
+
#
|
|
5
|
+
# NOTE: This file serves as a FALLBACK when the dynamic model discovery system
|
|
6
|
+
# (groq_model_discovery.py) cannot fetch fresh data from the Groq API.
|
|
7
|
+
#
|
|
8
|
+
# The dynamic system is the PRIMARY source and will:
|
|
9
|
+
# - Fetch available models directly from Groq API
|
|
10
|
+
# - Test each model for tool calling support automatically
|
|
11
|
+
# - Cache results for 24 hours
|
|
12
|
+
# - Always provide up-to-date model lists
|
|
13
|
+
#
|
|
14
|
+
# This fallback list should contain:
|
|
15
|
+
# - Minimal set of stable production models
|
|
16
|
+
# - Deprecated models for backwards compatibility
|
|
17
|
+
# - Non-LLM models (audio, TTS) marked as not_supported
|
|
18
|
+
#
|
|
19
|
+
# Last manually updated: 2025-01-06
|
|
20
|
+
#
|
|
4
21
|
GROQ_MODELS_DETAILED = [
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
),
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
create_model_metadata( #
|
|
13
|
-
provider="Groq", name="
|
|
14
|
-
),
|
|
15
|
-
create_model_metadata( # Meta
|
|
16
|
-
provider="Groq", name="llama-guard-3-8b", icon="Groq"
|
|
22
|
+
# ===== FALLBACK PRODUCTION MODELS =====
|
|
23
|
+
# These are stable models that are very unlikely to be removed
|
|
24
|
+
create_model_metadata(provider="Groq", name="llama-3.1-8b-instant", icon="Groq", tool_calling=True),
|
|
25
|
+
create_model_metadata(provider="Groq", name="llama-3.3-70b-versatile", icon="Groq", tool_calling=True),
|
|
26
|
+
# ===== DEPRECATED MODELS =====
|
|
27
|
+
# Keep these for backwards compatibility - users may have flows using them
|
|
28
|
+
# These will appear in the list but show as deprecated in the UI
|
|
29
|
+
create_model_metadata( # Google - Removed
|
|
30
|
+
provider="Groq", name="gemma2-9b-it", icon="Groq", deprecated=True
|
|
17
31
|
),
|
|
18
|
-
create_model_metadata( #
|
|
19
|
-
provider="Groq", name="
|
|
20
|
-
),
|
|
21
|
-
create_model_metadata( # Meta
|
|
22
|
-
provider="Groq", name="llama3-8b-8192", icon="Groq"
|
|
23
|
-
),
|
|
24
|
-
# Preview Models - For evaluation purposes only
|
|
25
|
-
create_model_metadata( # Meta
|
|
26
|
-
provider="Groq", name="meta-llama/llama-4-scout-17b-16e-instruct", icon="Groq", tool_calling=True, preview=True
|
|
32
|
+
create_model_metadata( # Google
|
|
33
|
+
provider="Groq", name="gemma-7b-it", icon="Groq", deprecated=True
|
|
27
34
|
),
|
|
28
|
-
create_model_metadata( # Meta
|
|
29
|
-
provider="Groq",
|
|
30
|
-
name="meta-llama/llama-4-maverick-17b-128e-instruct",
|
|
31
|
-
icon="Groq",
|
|
32
|
-
tool_calling=True,
|
|
33
|
-
preview=True,
|
|
35
|
+
create_model_metadata( # Meta - Removed
|
|
36
|
+
provider="Groq", name="llama3-70b-8192", icon="Groq", deprecated=True
|
|
34
37
|
),
|
|
35
|
-
create_model_metadata( #
|
|
36
|
-
provider="Groq", name="
|
|
38
|
+
create_model_metadata( # Meta - Removed
|
|
39
|
+
provider="Groq", name="llama3-8b-8192", icon="Groq", deprecated=True
|
|
37
40
|
),
|
|
38
|
-
create_model_metadata( #
|
|
39
|
-
provider="Groq", name="
|
|
41
|
+
create_model_metadata( # Meta - Removed, replaced by llama-guard-4-12b
|
|
42
|
+
provider="Groq", name="llama-guard-3-8b", icon="Groq", deprecated=True
|
|
40
43
|
),
|
|
41
|
-
create_model_metadata( #
|
|
42
|
-
provider="Groq", name="
|
|
44
|
+
create_model_metadata( # Meta - Removed
|
|
45
|
+
provider="Groq", name="llama-3.2-1b-preview", icon="Groq", deprecated=True
|
|
43
46
|
),
|
|
44
|
-
create_model_metadata( #
|
|
45
|
-
provider="Groq", name="
|
|
47
|
+
create_model_metadata( # Meta - Removed
|
|
48
|
+
provider="Groq", name="llama-3.2-3b-preview", icon="Groq", deprecated=True
|
|
46
49
|
),
|
|
47
|
-
create_model_metadata( #
|
|
48
|
-
provider="Groq", name="
|
|
50
|
+
create_model_metadata( # Meta - Removed
|
|
51
|
+
provider="Groq", name="llama-3.2-11b-vision-preview", icon="Groq", deprecated=True
|
|
49
52
|
),
|
|
50
|
-
create_model_metadata( # Meta
|
|
51
|
-
provider="Groq", name="llama-3.
|
|
53
|
+
create_model_metadata( # Meta - Removed
|
|
54
|
+
provider="Groq", name="llama-3.2-90b-vision-preview", icon="Groq", deprecated=True
|
|
52
55
|
),
|
|
53
|
-
create_model_metadata( # Meta
|
|
54
|
-
provider="Groq", name="llama-3.
|
|
56
|
+
create_model_metadata( # Meta - Removed
|
|
57
|
+
provider="Groq", name="llama-3.3-70b-specdec", icon="Groq", deprecated=True
|
|
55
58
|
),
|
|
56
|
-
create_model_metadata( #
|
|
57
|
-
provider="Groq", name="
|
|
59
|
+
create_model_metadata( # Alibaba - Removed, replaced by qwen/qwen3-32b
|
|
60
|
+
provider="Groq", name="qwen-qwq-32b", icon="Groq", deprecated=True
|
|
58
61
|
),
|
|
59
|
-
create_model_metadata( #
|
|
60
|
-
provider="Groq", name="
|
|
62
|
+
create_model_metadata( # Alibaba - Removed
|
|
63
|
+
provider="Groq", name="qwen-2.5-coder-32b", icon="Groq", deprecated=True
|
|
61
64
|
),
|
|
62
|
-
create_model_metadata( #
|
|
63
|
-
provider="Groq", name="
|
|
65
|
+
create_model_metadata( # Alibaba - Removed
|
|
66
|
+
provider="Groq", name="qwen-2.5-32b", icon="Groq", deprecated=True
|
|
64
67
|
),
|
|
65
|
-
create_model_metadata( #
|
|
66
|
-
provider="Groq", name="
|
|
68
|
+
create_model_metadata( # DeepSeek - Removed
|
|
69
|
+
provider="Groq", name="deepseek-r1-distill-qwen-32b", icon="Groq", deprecated=True
|
|
67
70
|
),
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
provider="Groq", name="gemma-7b-it", icon="Groq", tool_calling=True, deprecated=True
|
|
71
|
+
create_model_metadata( # DeepSeek - Removed
|
|
72
|
+
provider="Groq", name="deepseek-r1-distill-llama-70b", icon="Groq", deprecated=True
|
|
71
73
|
),
|
|
72
74
|
create_model_metadata( # Groq
|
|
73
|
-
provider="Groq", name="llama3-groq-70b-8192-tool-use-preview", icon="Groq",
|
|
75
|
+
provider="Groq", name="llama3-groq-70b-8192-tool-use-preview", icon="Groq", deprecated=True
|
|
74
76
|
),
|
|
75
77
|
create_model_metadata( # Groq
|
|
76
|
-
provider="Groq", name="llama3-groq-8b-8192-tool-use-preview", icon="Groq",
|
|
78
|
+
provider="Groq", name="llama3-groq-8b-8192-tool-use-preview", icon="Groq", deprecated=True
|
|
77
79
|
),
|
|
78
80
|
create_model_metadata( # Meta
|
|
79
|
-
provider="Groq", name="llama-3.1-70b-versatile", icon="Groq",
|
|
81
|
+
provider="Groq", name="llama-3.1-70b-versatile", icon="Groq", deprecated=True
|
|
80
82
|
),
|
|
81
83
|
create_model_metadata( # Mistral
|
|
82
|
-
provider="Groq", name="mixtral-8x7b-32768", icon="Groq",
|
|
84
|
+
provider="Groq", name="mixtral-8x7b-32768", icon="Groq", deprecated=True
|
|
83
85
|
),
|
|
84
|
-
#
|
|
86
|
+
# ===== UNSUPPORTED MODELS =====
|
|
87
|
+
# Audio/TTS/Guard models that should not appear in LLM model lists
|
|
88
|
+
# The dynamic system automatically filters these out
|
|
85
89
|
create_model_metadata( # Mistral
|
|
86
90
|
provider="Groq", name="mistral-saba-24b", icon="Groq", not_supported=True
|
|
87
91
|
),
|
|
@@ -100,6 +104,18 @@ GROQ_MODELS_DETAILED = [
|
|
|
100
104
|
create_model_metadata( # Hugging Face
|
|
101
105
|
provider="Groq", name="distil-whisper-large-v3-en", icon="Groq", not_supported=True
|
|
102
106
|
),
|
|
107
|
+
create_model_metadata( # Meta
|
|
108
|
+
provider="Groq", name="meta-llama/llama-guard-4-12b", icon="Groq", not_supported=True
|
|
109
|
+
),
|
|
110
|
+
create_model_metadata( # Meta
|
|
111
|
+
provider="Groq", name="meta-llama/llama-prompt-guard-2-86m", icon="Groq", not_supported=True
|
|
112
|
+
),
|
|
113
|
+
create_model_metadata( # Meta
|
|
114
|
+
provider="Groq", name="meta-llama/llama-prompt-guard-2-22m", icon="Groq", not_supported=True
|
|
115
|
+
),
|
|
116
|
+
create_model_metadata( # OpenAI
|
|
117
|
+
provider="Groq", name="openai/gpt-oss-safeguard-20b", icon="Groq", not_supported=True
|
|
118
|
+
),
|
|
103
119
|
]
|
|
104
120
|
|
|
105
121
|
# Generate backwards-compatible lists from the metadata
|