@@ -93,6 +93,7 @@ def __init__(
9393 )
9494self ._store = store_manager
9595self ._exit_stack :AsyncExitStack | None = None
96+ self ._lock :asyncio .Lock = asyncio .Lock ()
9697
9798async def _run_in_context (self )-> AsyncGenerator [Self ,None ]:
9899async with AsyncExitStack ()as stack :
@@ -196,45 +197,48 @@ async def reload(
196197 Chats can be resumed after reload by using the same chat_id.
197198 """
198199# NOTE: Do Not restart MCP Servers when there is on-going query.
199- if self ._exit_stack is None :
200- raise RuntimeError ("Host not initialized" )
201-
202- # Update config
203- old_config = self ._config
204- self ._config = new_config
205-
206- try :
207- # Reload model if needed
208- if old_config .llm != new_config .llm :
209- self ._model = None
210- await self ._init_models ()
211-
212- await self ._tool_manager .reload (
213- new_configs = new_config .mcp_servers ,force = force_mcp
214- )
215-
216- # Reload checkpointer if needed
217- if old_config .checkpointer != new_config .checkpointer :
218- if self ._checkpointer is not None :
219- await self ._exit_stack .aclose ()
220- self ._checkpointer = None
221-
222- if new_config .checkpointer :
223- checkpointer = get_checkpointer (str (new_config .checkpointer .uri ))
224- self ._checkpointer = await self ._exit_stack .enter_async_context (
225- checkpointer
226- )
227- await self ._checkpointer .setup ()
228-
229- # Call the reloader function to handle service restart
230- if reloader :
231- await reloader ()
232-
233- except Exception as e :
234- # Restore old config if reload fails
235- self ._config = old_config
236- logging .error ("Failed to reload host: %s" ,e )
237- raise
200+ async with self ._lock :
201+ if self ._exit_stack is None :
202+ raise RuntimeError ("Host not initialized" )
203+
204+ # Update config
205+ old_config = self ._config
206+ self ._config = new_config
207+
208+ try :
209+ # Reload model if needed
210+ if old_config .llm != new_config .llm :
211+ self ._model = None
212+ await self ._init_models ()
213+
214+ await self ._tool_manager .reload (
215+ new_configs = new_config .mcp_servers ,force = force_mcp
216+ )
217+
218+ # Reload checkpointer if needed
219+ if old_config .checkpointer != new_config .checkpointer :
220+ if self ._checkpointer is not None :
221+ await self ._exit_stack .aclose ()
222+ self ._checkpointer = None
223+
224+ if new_config .checkpointer :
225+ checkpointer = get_checkpointer (
226+ str (new_config .checkpointer .uri )
227+ )
228+ self ._checkpointer = await self ._exit_stack .enter_async_context (
229+ checkpointer
230+ )
231+ await self ._checkpointer .setup ()
232+
233+ # Call the reloader function to handle service restart
234+ if reloader :
235+ await reloader ()
236+
237+ except Exception as e :
238+ # Restore old config if reload fails
239+ self ._config = old_config
240+ logging .error ("Failed to reload host: %s" ,e )
241+ raise
238242
239243@property
240244def config (self )-> HostConfig :