diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 19227b6b9e..c437365312 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -707,30 +707,34 @@ async def lifespan(app: FastAPI): # Pre-fetch tool server specs so the first request doesn't pay the latency cost if len(app.state.config.TOOL_SERVER_CONNECTIONS) > 0: + mock_request = Request( + { + 'type': 'http', + 'asgi.version': '3.0', + 'asgi.spec_version': '2.0', + 'method': 'GET', + 'path': '/internal', + 'query_string': b'', + 'headers': Headers({}).raw, + 'client': ('127.0.0.1', 12345), + 'server': ('127.0.0.1', 80), + 'scheme': 'http', + 'app': app, + } + ) + log.info('Initializing tool servers...') try: - mock_request = Request( - { - 'type': 'http', - 'asgi.version': '3.0', - 'asgi.spec_version': '2.0', - 'method': 'GET', - 'path': '/internal', - 'query_string': b'', - 'headers': Headers({}).raw, - 'client': ('127.0.0.1', 12345), - 'server': ('127.0.0.1', 80), - 'scheme': 'http', - 'app': app, - } - ) await set_tool_servers(mock_request) log.info(f'Initialized {len(app.state.TOOL_SERVERS)} tool server(s)') + except Exception as e: + log.warning(f'Failed to initialize tool servers at startup: {e}') + try: await set_terminal_servers(mock_request) log.info(f'Initialized {len(app.state.TERMINAL_SERVERS)} terminal server(s)') except Exception as e: - log.warning(f'Failed to initialize tool/terminal servers at startup: {e}') + log.warning(f'Failed to initialize terminal servers at startup: {e}') # Mark application as ready to accept traffic from a startup perspective. app.state.startup_complete = True diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index 0cd182dc84..f1b4fb1d1f 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -872,29 +872,40 @@ def convert_openapi_to_tool_payload(openapi_spec): async def set_tool_servers(request: Request): - request.app.state.TOOL_SERVERS = await get_tool_servers_data(request.app.state.config.TOOL_SERVER_CONNECTIONS) + try: + request.app.state.TOOL_SERVERS = await get_tool_servers_data(request.app.state.config.TOOL_SERVER_CONNECTIONS) + except Exception as e: + log.error(f'Error fetching tool server data: {e}') + request.app.state.TOOL_SERVERS = getattr(request.app.state, 'TOOL_SERVERS', None) or [] - if request.app.state.redis is not None: - await request.app.state.redis.set( - f'{REDIS_KEY_PREFIX}:tool_servers', json.dumps(request.app.state.TOOL_SERVERS) - ) + try: + if request.app.state.redis is not None: + await request.app.state.redis.set( + f'{REDIS_KEY_PREFIX}:tool_servers', json.dumps(request.app.state.TOOL_SERVERS) + ) + except Exception as e: + log.error(f'Error caching tool_servers to Redis: {e}') return request.app.state.TOOL_SERVERS async def get_tool_servers(request: Request): - tool_servers = [] - if request.app.state.redis is not None: - try: - tool_servers = json.loads(await request.app.state.redis.get(f'{REDIS_KEY_PREFIX}:tool_servers')) - request.app.state.TOOL_SERVERS = tool_servers - except Exception as e: - log.error(f'Error fetching tool_servers from Redis: {e}') + try: + tool_servers = [] + if request.app.state.redis is not None: + try: + tool_servers = json.loads(await request.app.state.redis.get(f'{REDIS_KEY_PREFIX}:tool_servers')) + request.app.state.TOOL_SERVERS = tool_servers + except Exception as e: + log.error(f'Error fetching tool_servers from Redis: {e}') - if not tool_servers: - tool_servers = await set_tool_servers(request) + if not tool_servers: + tool_servers = await set_tool_servers(request) - return tool_servers + return tool_servers + except Exception as e: + log.error(f'Failed to load tool servers, skipping: {e}') + return getattr(request.app.state, 'TOOL_SERVERS', None) or [] async def get_terminal_cwd(