Add fail-safe mode to embedding and OpenSearch components
Introduces a 'fail_safe_mode' option to the Embedding Model and OpenSearch (Multi-Model Multi-Embedding) components, allowing errors to be logged and None returned instead of raising exceptions. Refactors embedding model fetching logic for better error handling and updates component metadata, field order, and dependencies. Also adds 'className' fields and updates frontend node folder IDs for improved UI consistency.
This commit is contained in:
parent
2fa6efeaa9
commit
998d8b9195
5 changed files with 306 additions and 46 deletions
File diff suppressed because one or more lines are too long
|
|
@ -14,6 +14,7 @@ from config.settings import (
|
|||
clients,
|
||||
get_openrag_config,
|
||||
config_manager,
|
||||
is_no_auth_mode,
|
||||
)
|
||||
from api.provider_validation import validate_provider_setup
|
||||
|
||||
|
|
@ -637,6 +638,41 @@ async def update_settings(request, session_manager):
|
|||
logger.info(
|
||||
f"Set SELECTED_EMBEDDING_MODEL global variable to {current_config.knowledge.embedding_model}"
|
||||
)
|
||||
|
||||
# Update MCP servers with provider credentials
|
||||
try:
|
||||
from services.langflow_mcp_service import LangflowMCPService
|
||||
from utils.langflow_headers import build_mcp_global_vars_from_config
|
||||
|
||||
mcp_service = LangflowMCPService()
|
||||
|
||||
# Build global vars using utility function
|
||||
mcp_global_vars = build_mcp_global_vars_from_config(current_config)
|
||||
|
||||
# In no-auth mode, add the anonymous JWT token and user details
|
||||
if is_no_auth_mode() and session_manager:
|
||||
from session_manager import AnonymousUser
|
||||
|
||||
# Create/get anonymous JWT for no-auth mode
|
||||
anonymous_jwt = session_manager.get_effective_jwt_token(None, None)
|
||||
if anonymous_jwt:
|
||||
mcp_global_vars["JWT"] = anonymous_jwt
|
||||
|
||||
# Add anonymous user details
|
||||
anonymous_user = AnonymousUser()
|
||||
mcp_global_vars["OWNER"] = anonymous_user.user_id # "anonymous"
|
||||
mcp_global_vars["OWNER_NAME"] = f'"{anonymous_user.name}"' # "Anonymous User" (quoted)
|
||||
mcp_global_vars["OWNER_EMAIL"] = anonymous_user.email # "anonymous@localhost"
|
||||
|
||||
logger.debug("Added anonymous JWT and user details to MCP servers for no-auth mode")
|
||||
|
||||
if mcp_global_vars:
|
||||
result = await mcp_service.update_mcp_servers_with_global_vars(mcp_global_vars)
|
||||
logger.info("Updated MCP servers with provider credentials after settings change", **result)
|
||||
|
||||
except Exception as mcp_error:
|
||||
logger.warning(f"Failed to update MCP servers after settings change: {str(mcp_error)}")
|
||||
# Don't fail the entire settings update if MCP update fails
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update Langflow settings: {str(e)}")
|
||||
|
|
@ -655,7 +691,7 @@ async def update_settings(request, session_manager):
|
|||
)
|
||||
|
||||
|
||||
async def onboarding(request, flows_service):
|
||||
async def onboarding(request, flows_service, session_manager=None):
|
||||
"""Handle onboarding configuration setup"""
|
||||
try:
|
||||
# Get current configuration
|
||||
|
|
@ -943,6 +979,41 @@ async def onboarding(request, flows_service):
|
|||
logger.info(
|
||||
f"Set SELECTED_EMBEDDING_MODEL global variable to {current_config.knowledge.embedding_model}"
|
||||
)
|
||||
|
||||
# Update MCP servers with provider credentials during onboarding
|
||||
try:
|
||||
from services.langflow_mcp_service import LangflowMCPService
|
||||
from utils.langflow_headers import build_mcp_global_vars_from_config
|
||||
|
||||
mcp_service = LangflowMCPService()
|
||||
|
||||
# Build global vars using utility function
|
||||
mcp_global_vars = build_mcp_global_vars_from_config(current_config)
|
||||
|
||||
# In no-auth mode, add the anonymous JWT token and user details
|
||||
if is_no_auth_mode() and session_manager:
|
||||
from session_manager import AnonymousUser
|
||||
|
||||
# Create/get anonymous JWT for no-auth mode
|
||||
anonymous_jwt = session_manager.get_effective_jwt_token(None, None)
|
||||
if anonymous_jwt:
|
||||
mcp_global_vars["JWT"] = anonymous_jwt
|
||||
|
||||
# Add anonymous user details
|
||||
anonymous_user = AnonymousUser()
|
||||
mcp_global_vars["OWNER"] = anonymous_user.user_id # "anonymous"
|
||||
mcp_global_vars["OWNER_NAME"] = f'"{anonymous_user.name}"' # "Anonymous User" (quoted)
|
||||
mcp_global_vars["OWNER_EMAIL"] = anonymous_user.email # "anonymous@localhost"
|
||||
|
||||
logger.debug("Added anonymous JWT and user details to MCP servers for no-auth mode during onboarding")
|
||||
|
||||
if mcp_global_vars:
|
||||
result = await mcp_service.update_mcp_servers_with_global_vars(mcp_global_vars)
|
||||
logger.info("Updated MCP servers with provider credentials during onboarding", **result)
|
||||
|
||||
except Exception as mcp_error:
|
||||
logger.warning(f"Failed to update MCP servers during onboarding: {str(mcp_error)}")
|
||||
# Don't fail onboarding if MCP update fails
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
|
|
|
|||
58
src/main.py
58
src/main.py
|
|
@ -433,6 +433,55 @@ async def _ingest_default_documents_openrag(services, file_paths):
|
|||
)
|
||||
|
||||
|
||||
async def _update_mcp_servers_with_provider_credentials(services):
|
||||
"""Update MCP servers with provider credentials at startup.
|
||||
|
||||
This is especially important for no-auth mode where users don't go through
|
||||
the OAuth login flow that would normally set these credentials.
|
||||
"""
|
||||
try:
|
||||
auth_service = services.get("auth_service")
|
||||
session_manager = services.get("session_manager")
|
||||
|
||||
if not auth_service or not auth_service.langflow_mcp_service:
|
||||
logger.debug("MCP service not available, skipping credential update")
|
||||
return
|
||||
|
||||
config = get_openrag_config()
|
||||
|
||||
# Build global vars with provider credentials using utility function
|
||||
from utils.langflow_headers import build_mcp_global_vars_from_config
|
||||
|
||||
global_vars = build_mcp_global_vars_from_config(config)
|
||||
|
||||
# In no-auth mode, add the anonymous JWT token and user details
|
||||
if is_no_auth_mode() and session_manager:
|
||||
from session_manager import AnonymousUser
|
||||
|
||||
# Create/get anonymous JWT for no-auth mode
|
||||
anonymous_jwt = session_manager.get_effective_jwt_token(None, None)
|
||||
if anonymous_jwt:
|
||||
global_vars["JWT"] = anonymous_jwt
|
||||
|
||||
# Add anonymous user details
|
||||
anonymous_user = AnonymousUser()
|
||||
global_vars["OWNER"] = anonymous_user.user_id # "anonymous"
|
||||
global_vars["OWNER_NAME"] = f'"{anonymous_user.name}"' # "Anonymous User" (quoted for spaces)
|
||||
global_vars["OWNER_EMAIL"] = anonymous_user.email # "anonymous@localhost"
|
||||
|
||||
logger.info("Added anonymous JWT and user details to MCP servers for no-auth mode")
|
||||
|
||||
if global_vars:
|
||||
result = await auth_service.langflow_mcp_service.update_mcp_servers_with_global_vars(global_vars)
|
||||
logger.info("Updated MCP servers with provider credentials at startup", **result)
|
||||
else:
|
||||
logger.debug("No provider credentials configured, skipping MCP server update")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning("Failed to update MCP servers with provider credentials at startup", error=str(e))
|
||||
# Don't fail startup if MCP update fails
|
||||
|
||||
|
||||
async def startup_tasks(services):
|
||||
"""Startup tasks"""
|
||||
logger.info("Starting startup tasks")
|
||||
|
|
@ -445,6 +494,9 @@ async def startup_tasks(services):
|
|||
|
||||
# Configure alerting security
|
||||
await configure_alerting_security()
|
||||
|
||||
# Update MCP servers with provider credentials (especially important for no-auth mode)
|
||||
await _update_mcp_servers_with_provider_credentials(services)
|
||||
|
||||
|
||||
async def initialize_services():
|
||||
|
|
@ -1052,7 +1104,11 @@ async def create_app():
|
|||
Route(
|
||||
"/onboarding",
|
||||
require_auth(services["session_manager"])(
|
||||
partial(settings.onboarding, flows_service=services["flows_service"])
|
||||
partial(
|
||||
settings.onboarding,
|
||||
flows_service=services["flows_service"],
|
||||
session_manager=services["session_manager"]
|
||||
)
|
||||
),
|
||||
methods=["POST"],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -308,6 +308,16 @@ class AuthService:
|
|||
global_vars["OWNER_NAME"] = str(f"\"{owner_name}\"")
|
||||
if user_info.get("email"):
|
||||
global_vars["OWNER_EMAIL"] = user_info.get("email")
|
||||
|
||||
# Add provider credentials to MCP servers using utility function
|
||||
from config.settings import get_openrag_config
|
||||
from utils.langflow_headers import build_mcp_global_vars_from_config
|
||||
|
||||
config = get_openrag_config()
|
||||
provider_vars = build_mcp_global_vars_from_config(config)
|
||||
|
||||
# Merge provider credentials with user info
|
||||
global_vars.update(provider_vars)
|
||||
|
||||
# Run in background to avoid delaying login flow
|
||||
task = asyncio.create_task(
|
||||
|
|
|
|||
|
|
@ -31,3 +31,41 @@ def add_provider_credentials_to_headers(headers: Dict[str, str], config) -> None
|
|||
ollama_endpoint = transform_localhost_url(config.providers.ollama.endpoint)
|
||||
headers["X-LANGFLOW-GLOBAL-VAR-OLLAMA_BASE_URL"] = str(ollama_endpoint)
|
||||
|
||||
|
||||
def build_mcp_global_vars_from_config(config) -> Dict[str, str]:
|
||||
"""Build MCP global variables dictionary from OpenRAG configuration.
|
||||
|
||||
Args:
|
||||
config: OpenRAGConfig object containing provider configurations
|
||||
|
||||
Returns:
|
||||
Dictionary of global variables for MCP servers (without X-Langflow-Global-Var prefix)
|
||||
"""
|
||||
global_vars = {}
|
||||
|
||||
# Add OpenAI credentials
|
||||
if config.providers.openai.api_key:
|
||||
global_vars["OPENAI_API_KEY"] = config.providers.openai.api_key
|
||||
|
||||
# Add Anthropic credentials
|
||||
if config.providers.anthropic.api_key:
|
||||
global_vars["ANTHROPIC_API_KEY"] = config.providers.anthropic.api_key
|
||||
|
||||
# Add WatsonX credentials
|
||||
if config.providers.watsonx.api_key:
|
||||
global_vars["WATSONX_API_KEY"] = config.providers.watsonx.api_key
|
||||
|
||||
if config.providers.watsonx.project_id:
|
||||
global_vars["WATSONX_PROJECT_ID"] = config.providers.watsonx.project_id
|
||||
|
||||
# Add Ollama endpoint (with localhost transformation)
|
||||
if config.providers.ollama.endpoint:
|
||||
ollama_endpoint = transform_localhost_url(config.providers.ollama.endpoint)
|
||||
global_vars["OLLAMA_BASE_URL"] = ollama_endpoint
|
||||
|
||||
# Add selected embedding model
|
||||
if config.knowledge.embedding_model:
|
||||
global_vars["SELECTED_EMBEDDING_MODEL"] = config.knowledge.embedding_model
|
||||
|
||||
return global_vars
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue