@@ -152,3 +152,129 @@ async def test_parallel_rails_output_fail_2():
152152        and  result .response [0 ]["content" ]
153153        ==  "I cannot express a term in the bot answer." 
154154    )
155+ 
156+ 
157+ @pytest .mark .asyncio  
158+ async  def  test_parallel_rails_input_stop_flag ():
159+     config  =  RailsConfig .from_path (os .path .join (CONFIGS_FOLDER , "parallel_rails" ))
160+     chat  =  TestChat (
161+         config ,
162+         llm_completions = [
163+             "No" ,
164+             "Hi there! How can I assist you with questions about the ABC Company today?" ,
165+             "No" ,
166+         ],
167+     )
168+ 
169+     chat  >>  "hi, this is a blocked term." 
170+     result  =  await  chat .app .generate_async (messages = chat .history , options = OPTIONS )
171+ 
172+     stopped_rails  =  [rail  for  rail  in  result .log .activated_rails  if  rail .stop ]
173+     assert  len (stopped_rails ) ==  1 , "Expected exactly one stopped rail" 
174+     assert  (
175+         "check blocked input terms"  in  stopped_rails [0 ].name 
176+     ), f"Expected 'check blocked input terms' rail to be stopped, got { stopped_rails [0 ].name }  
177+ 
178+ 
179+ @pytest .mark .asyncio  
180+ async  def  test_parallel_rails_output_stop_flag ():
181+     config  =  RailsConfig .from_path (os .path .join (CONFIGS_FOLDER , "parallel_rails" ))
182+     chat  =  TestChat (
183+         config ,
184+         llm_completions = [
185+             "No" ,
186+             "Hi there! This is a blocked term!" ,
187+             "No" ,
188+         ],
189+     )
190+ 
191+     chat  >>  "hi!" 
192+     result  =  await  chat .app .generate_async (messages = chat .history , options = OPTIONS )
193+ 
194+     stopped_rails  =  [rail  for  rail  in  result .log .activated_rails  if  rail .stop ]
195+     assert  len (stopped_rails ) ==  1 , "Expected exactly one stopped rail" 
196+     assert  (
197+         "check blocked output terms"  in  stopped_rails [0 ].name 
198+     ), f"Expected 'check blocked output terms' rail to be stopped, got { stopped_rails [0 ].name }  
199+ 
200+ 
201+ @pytest .mark .asyncio  
202+ async  def  test_parallel_rails_client_code_pattern ():
203+     config  =  RailsConfig .from_path (os .path .join (CONFIGS_FOLDER , "parallel_rails" ))
204+     chat  =  TestChat (
205+         config ,
206+         llm_completions = [
207+             "No" ,
208+             "Hi there! This is a blocked term!" ,
209+             "No" ,
210+         ],
211+     )
212+ 
213+     chat  >>  "hi!" 
214+     result  =  await  chat .app .generate_async (messages = chat .history , options = OPTIONS )
215+ 
216+     activated_rails  =  result .log .activated_rails  if  result .log  else  None 
217+     assert  activated_rails  is  not None , "Expected activated_rails to be present" 
218+ 
219+     rails_to_check  =  [
220+         "self check output" ,
221+         "check blocked output terms $duration=1.0" ,
222+     ]
223+     rails_set  =  set (rails_to_check )
224+ 
225+     stopping_rails  =  [rail  for  rail  in  activated_rails  if  rail .stop ]
226+ 
227+     assert  len (stopping_rails ) >  0 , "Expected at least one stopping rail" 
228+ 
229+     blocked_rails  =  []
230+     for  rail  in  stopping_rails :
231+         if  rail .name  in  rails_set :
232+             blocked_rails .append (rail .name )
233+ 
234+     assert  (
235+         len (blocked_rails ) ==  1 
236+     ), f"Expected exactly one blocked rail from our check list, got { len (blocked_rails )} { blocked_rails }  
237+     assert  (
238+         "check blocked output terms $duration=1.0"  in  blocked_rails 
239+     ), f"Expected 'check blocked output terms $duration=1.0' to be blocked, got { blocked_rails }  
240+ 
241+     non_stopped_rails  =  [rail  for  rail  in  activated_rails  if  not  rail .stop ]
242+     for  rail  in  non_stopped_rails :
243+         assert  (
244+             rail .stop  is  False  or  rail .stop  is  None 
245+         ), f"Non-stopped rail { rail .name }  
246+ 
247+ 
248+ @pytest .mark .asyncio  
249+ async  def  test_parallel_rails_multiple_activated_rails ():
250+     config  =  RailsConfig .from_path (os .path .join (CONFIGS_FOLDER , "parallel_rails" ))
251+     chat  =  TestChat (
252+         config ,
253+         llm_completions = [
254+             "No" ,
255+             "Hi there! This is a blocked term!" ,
256+             "No" ,
257+         ],
258+     )
259+ 
260+     chat  >>  "hi!" 
261+     result  =  await  chat .app .generate_async (messages = chat .history , options = OPTIONS )
262+ 
263+     activated_rails  =  result .log .activated_rails  if  result .log  else  None 
264+     assert  activated_rails  is  not None , "Expected activated_rails to be present" 
265+     assert  len (activated_rails ) >  1 , (
266+         f"Expected multiple activated_rails, got { len (activated_rails )}  
267+         f"{ [rail .name  for  rail  in  activated_rails ]}  
268+     )
269+ 
270+     stopped_rails  =  [rail  for  rail  in  activated_rails  if  rail .stop ]
271+     assert  len (stopped_rails ) ==  1 , (
272+         f"Expected exactly one stopped rail, got { len (stopped_rails )}  
273+         f"{ [rail .name  for  rail  in  stopped_rails ]}  
274+     )
275+ 
276+     rails_with_stop_true  =  [rail  for  rail  in  activated_rails  if  rail .stop  is  True ]
277+     assert  len (rails_with_stop_true ) ==  1 , (
278+         f"Expected exactly one rail with stop=True, got { len (rails_with_stop_true )}  
279+         f"{ [rail .name  for  rail  in  rails_with_stop_true ]}  
280+     )
0 commit comments