@@ -150,8 +150,16 @@ def __init__(self, loop: asyncio.AbstractEventLoop):
150150 self .cert_manager = TLSCertDomainManager (self .ca )
151151 self ._closing = False
152152 self .pipeline_factory = PipelineFactory (SecretsManager ())
153+ self .input_pipeline : Optional [CopilotPipeline ] = None
154+ self .fim_pipeline : Optional [CopilotPipeline ] = None
155+ # the context as provided by the pipeline
153156 self .context_tracking : Optional [PipelineContext ] = None
154157
158+ def _ensure_pipelines (self ):
159+ if not self .input_pipeline or not self .fim_pipeline :
160+ self .input_pipeline = CopilotChatPipeline (self .pipeline_factory )
161+ self .fim_pipeline = CopilotFimPipeline (self .pipeline_factory )
162+
155163 def _select_pipeline (self , method : str , path : str ) -> Optional [CopilotPipeline ]:
156164 if method != "POST" :
157165 logger .debug ("Not a POST request, no pipeline selected" )
@@ -161,10 +169,10 @@ def _select_pipeline(self, method: str, path: str) -> Optional[CopilotPipeline]:
161169 if path == route .path :
162170 if route .pipeline_type == PipelineType .FIM :
163171 logger .debug ("Selected FIM pipeline" )
164- return CopilotFimPipeline ( self .pipeline_factory )
172+ return self .fim_pipeline
165173 elif route .pipeline_type == PipelineType .CHAT :
166174 logger .debug ("Selected CHAT pipeline" )
167- return CopilotChatPipeline ( self .pipeline_factory )
175+ return self .input_pipeline
168176
169177 logger .debug ("No pipeline selected" )
170178 return None
@@ -181,7 +189,6 @@ async def _body_through_pipeline(
181189 # if we didn't select any strategy that would change the request
182190 # let's just pass through the body as-is
183191 return body , None
184- logger .debug (f"Processing body through pipeline: { len (body )} bytes" )
185192 return await strategy .process_body (headers , body )
186193
187194 async def _request_to_target (self , headers : list [str ], body : bytes ):
@@ -288,6 +295,9 @@ async def _forward_data_through_pipeline(self, data: bytes) -> Union[HttpRequest
288295 http_request .headers ,
289296 http_request .body ,
290297 )
298+ # TODO: it's weird that we're overwriting the context.
299+ # Should we set the context once? Maybe when
300+ # creating the pipeline instance?
291301 self .context_tracking = context
292302
293303 if context and context .shortcut_response :
@@ -442,6 +452,7 @@ def data_received(self, data: bytes) -> None:
442452 if not self .headers_parsed :
443453 self .headers_parsed = self .parse_headers ()
444454 if self .headers_parsed :
455+ self ._ensure_pipelines ()
445456 if self .request .method == "CONNECT" :
446457 self .handle_connect ()
447458 self .buffer .clear ()
@@ -756,10 +767,12 @@ def connection_made(self, transport: asyncio.Transport) -> None:
756767
757768 def _ensure_output_processor (self ) -> None :
758769 if self .proxy .context_tracking is None :
770+ logger .debug ("No context tracking, no need to process pipeline" )
759771 # No context tracking, no need to process pipeline
760772 return
761773
762774 if self .sse_processor is not None :
775+ logger .debug ("Already initialized, no need to reinitialize" )
763776 # Already initialized, no need to reinitialize
764777 return
765778
0 commit comments