11from __future__ import annotations
2+ from typing import TYPE_CHECKING
23import time
34from jupyter_events import EventLogger
45from jupyter_server .extension .application import ExtensionApp
1516 "https://events.jupyter.org/jupyter_collaboration"
1617 )
1718
19+ # Define `JSD_PRESENT` to indicate whether `jupyter_server_documents` is
20+ # installed in the current environment.
1821JSD_PRESENT = False
1922try :
2023 import jupyter_server_documents
2124 JSD_PRESENT = True
2225except ImportError :
2326 pass
2427
28+ if TYPE_CHECKING :
29+ from jupyterlab_chat .ychat import YChat
30+
2531
2632class RouterExtension (ExtensionApp ):
2733 """
@@ -33,6 +39,8 @@ class RouterExtension(ExtensionApp):
3339 (r"jupyter-ai-router/health/?" , RouteHandler ),
3440 ]
3541
42+ router : MessageRouter
43+
3644 def initialize_settings (self ):
3745 """Initialize router settings and event listeners."""
3846 start = time .time ()
@@ -79,8 +87,24 @@ async def _on_chat_event(
7987 # Connect chat to router
8088 self .router .connect_chat (room_id , ychat )
8189
82- async def _get_chat (self , room_id : str ):
83- """Get YChat instance for a room ID."""
90+ async def _get_chat (self , room_id : str ) -> YChat | None :
91+ """
92+ Get YChat instance for a room ID.
93+
94+ Dispatches to either `_get_chat_jcollab()` or `_get_chat_jsd()` based on
95+ whether `jupyter_server_documents` is installed.
96+ """
97+
98+ if JSD_PRESENT :
99+ return await self ._get_chat_jsd (room_id )
100+ else :
101+ return await self ._get_chat_jcollab (room_id )
102+
103+ async def _get_chat_jcollab (self , room_id : str ) -> YChat | None :
104+ """
105+ Method used to retrieve the `YChat` instance for a given room when
106+ `jupyter_server_documents` **is not** installed.
107+ """
84108 if not self .serverapp :
85109 return None
86110
@@ -91,6 +115,33 @@ async def _get_chat(self, room_id: str):
91115 except Exception as e :
92116 self .log .error (f"Error getting chat document for { room_id } : { e } " )
93117 return None
118+
119+ async def _get_chat_jsd (self , room_id : str ) -> YChat | None :
120+ """
121+ Method used to retrieve the `YChat` instance for a given room when
122+ `jupyter_server_documents` **is** installed.
123+
124+ This method uniquely attaches a callback which is fired whenever the
125+ `YChat` is reset.
126+ """
127+ if not self .serverapp :
128+ return None
129+
130+ try :
131+ jcollab_api = self .serverapp .web_app .settings ["jupyter_server_ydoc" ]
132+ yroom_manager = jcollab_api .yroom_manager
133+ yroom = yroom_manager .get_room (room_id )
134+
135+ def _on_ychat_reset (new_ychat : YChat ):
136+ self .router ._on_chat_reset (room_id , new_ychat )
137+
138+ ychat = await yroom .get_jupyter_ydoc (on_reset = _on_ychat_reset )
139+ return ychat
140+ except Exception as e :
141+ self .log .error (f"Error getting chat document for { room_id } : { e } " )
142+ return None
143+
144+
94145
95146 async def stop_extension (self ):
96147 """Clean up router when extension stops."""
0 commit comments