diff --git a/src/langbot/pkg/core/app.py b/src/langbot/pkg/core/app.py index 4b82b3efc..3c1a74402 100644 --- a/src/langbot/pkg/core/app.py +++ b/src/langbot/pkg/core/app.py @@ -304,10 +304,10 @@ class Application: async def run(self): self.event_loop_monitor.start() try: - if self.directory_projection_service is not None: - self.task_mgr.create_task( + if self.directory_projection_service is not None and getattr(self, "directory_projection_task", None) is None: + self.directory_projection_task = self.task_mgr.create_task( self.directory_projection_service.run(), - name='cloud-directory-projection', + name="cloud-directory-projection", scopes=[core_entities.LifecycleControlScope.APPLICATION], ) if self.cloud_model_catalog_service is not None: diff --git a/src/langbot/pkg/core/stages/build_app.py b/src/langbot/pkg/core/stages/build_app.py index 14d533dcc..001696d45 100644 --- a/src/langbot/pkg/core/stages/build_app.py +++ b/src/langbot/pkg/core/stages/build_app.py @@ -292,6 +292,16 @@ class BuildAppStage(stage.BootingStage): async def runtime_disconnect_callback(connector: plugin_connector.PluginRuntimeConnector) -> None: connector.schedule_reconnect() + if ap.directory_projection_service is not None: + # Keep the projection fresh while shared Runtime cold restore runs. + # BuildApp initializes the connector before Application.run() starts + # its long-lived tasks, so start the single refresh task here. + ap.directory_projection_task = ap.task_mgr.create_task( + ap.directory_projection_service.run(), + name="cloud-directory-projection", + scopes=[core_entities.LifecycleControlScope.APPLICATION], + ) + plugin_connector_inst = plugin_connector.PluginRuntimeConnector(ap, runtime_disconnect_callback) try: await plugin_connector_inst.initialize()