wisent 0.5.10__py3-none-any.whl → 0.5.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of wisent might be problematic. Click here for more details.

wisent/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.5.10"
1
+ __version__ = "0.5.12"
@@ -337,7 +337,7 @@ class WisentModel:
337
337
  @torch.inference_mode()
338
338
  def generate(
339
339
  self,
340
- inputs: list[list[ChatMessage]],
340
+ inputs: list[list[ChatMessage]] | str,
341
341
  max_new_tokens: int = 128,
342
342
  temperature: float = 0.7,
343
343
  top_p: float = 0.95,
@@ -346,6 +346,7 @@ class WisentModel:
346
346
  use_steering: bool = False,
347
347
  steering_plan: SteeringPlan | None = None,
348
348
  enable_thinking: bool = True,
349
+ prompt_is_formatted: bool = False,
349
350
  **gen_kwargs: Any,
350
351
  ) -> list[str]:
351
352
  """
@@ -353,7 +354,7 @@ class WisentModel:
353
354
 
354
355
  attributes:
355
356
  inputs:
356
- list of chat messages (each a list of {'role','content'} dicts).
357
+ list of chat messages (each a list of {'role','content'} dicts) OR pre-formatted string.
357
358
  max_new_tokens:
358
359
  max tokens to generate (beyond the prompt).
359
360
  temperature:
@@ -371,6 +372,8 @@ class WisentModel:
371
372
  If None, uses the internal plan.
372
373
  enable_thinking:
373
374
  If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen).
375
+ prompt_is_formatted:
376
+ If True, inputs is a pre-formatted string with chat template already applied.
374
377
  **gen_kwargs:
375
378
  additional kwargs passed to 'model.generate()'.
376
379
 
@@ -449,7 +452,23 @@ class WisentModel:
449
452
  if use_steering:
450
453
  self.apply_steering(steering_plan)
451
454
 
452
- batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
455
+ if prompt_is_formatted and isinstance(inputs, str):
456
+ # Direct tokenization of pre-formatted prompt
457
+ tokenizer_output = self.tokenizer(
458
+ inputs,
459
+ return_tensors="pt",
460
+ padding=False, # Single prompt, no padding needed
461
+ truncation=True, # Avoid errors on long inputs
462
+ max_length=self.tokenizer.model_max_length # Use model's actual limit
463
+ )
464
+ # Move tensors to the correct device (same as _batch_encode does)
465
+ batch = {
466
+ "input_ids": tokenizer_output["input_ids"].to(resolve_torch_device()),
467
+ "attention_mask": tokenizer_output["attention_mask"].to(resolve_torch_device())
468
+ }
469
+ else:
470
+ # Current behavior: apply chat template
471
+ batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
453
472
 
454
473
  gen_out = self.hf_model.generate(
455
474
  **batch,
@@ -613,7 +632,7 @@ class WisentModel:
613
632
  @torch.inference_mode()
614
633
  def generate_stream(
615
634
  self,
616
- inputs: list[list[ChatMessage]],
635
+ inputs: list[list[ChatMessage]] | str,
617
636
  max_new_tokens: int = 128,
618
637
  temperature: float = 0.7,
619
638
  top_p: float = 0.95,
@@ -623,6 +642,7 @@ class WisentModel:
623
642
  skip_prompt: bool = True,
624
643
  skip_special_tokens: bool = True,
625
644
  enable_thinking: bool = True,
645
+ prompt_is_formatted: bool = False,
626
646
  **gen_kwargs: Any,
627
647
  ) -> Iterable[str]:
628
648
  """
@@ -631,7 +651,8 @@ class WisentModel:
631
651
 
632
652
  attributes:
633
653
  inputs:
634
- list of chat messages (each a list of {'role','content'} dicts). Currently only one conversation is supported.
654
+ list of chat messages (each a list of {'role','content'} dicts) OR pre-formatted string.
655
+ Currently only one conversation is supported.
635
656
  max_new_tokens:
636
657
  max tokens to generate (beyond the prompt).
637
658
  temperature:
@@ -651,6 +672,8 @@ class WisentModel:
651
672
  if True, special tokens are removed from the yielded text.
652
673
  enable_thinking:
653
674
  If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen).
675
+ prompt_is_formatted:
676
+ If True, inputs is a pre-formatted string with chat template already applied.
654
677
  **gen_kwargs:
655
678
  additional kwargs passed to 'model.generate()'.
656
679
 
@@ -658,14 +681,30 @@ class WisentModel:
658
681
  generated text chunks (str), as they become available.
659
682
  """
660
683
 
661
- if len(inputs) != 1:
662
- raise ValueError(
663
- f"generate_stream currently supports exactly one conversation at a time (got {len(inputs)})."
664
- )
665
684
  if use_steering:
666
685
  self.apply_steering(steering_plan)
667
686
 
668
- batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
687
+ if prompt_is_formatted and isinstance(inputs, str):
688
+ # Direct tokenization of pre-formatted prompt
689
+ tokenizer_output = self.tokenizer(
690
+ inputs,
691
+ return_tensors="pt",
692
+ padding=False, # Single prompt, no padding needed
693
+ truncation=True, # Avoid errors on long inputs
694
+ max_length=self.tokenizer.model_max_length # Use model's actual limit
695
+ )
696
+ # Move tensors to the correct device (same as _batch_encode does)
697
+ batch = {
698
+ "input_ids": tokenizer_output["input_ids"].to(resolve_torch_device()),
699
+ "attention_mask": tokenizer_output["attention_mask"].to(resolve_torch_device())
700
+ }
701
+ else:
702
+ # Current behavior: apply chat template
703
+ if not isinstance(inputs, list) or len(inputs) != 1:
704
+ raise ValueError(
705
+ f"generate_stream currently supports exactly one conversation at a time (got {type(inputs)} with {len(inputs) if isinstance(inputs, list) else 'N/A'} items)."
706
+ )
707
+ batch = self._batch_encode(inputs, add_generation_prompt=True, enable_thinking=enable_thinking)
669
708
 
670
709
  streamer = TextIteratorStreamer(
671
710
  self.tokenizer,
@@ -166,17 +166,19 @@ class MultiSteering:
166
166
  max_new_tokens: int = 100,
167
167
  temperature: float = 0.7,
168
168
  top_p: float = 0.9,
169
- enable_thinking: bool = True
169
+ enable_thinking: bool = True,
170
+ prompt_is_formatted: bool = False
170
171
  ) -> Iterable[str]:
171
172
  """Apply the combined steering vector to generate text with streaming.
172
173
 
173
174
  Args:
174
175
  model: WisentModel instance to use for generation
175
- prompt: Input prompt
176
+ prompt: Input prompt (either raw text or pre-formatted with chat template)
176
177
  max_new_tokens: Maximum tokens to generate
177
178
  temperature: Sampling temperature
178
179
  top_p: Top-p sampling parameter
179
180
  enable_thinking: If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen)
181
+ prompt_is_formatted: If True, prompt already has chat template applied
180
182
 
181
183
  Yields:
182
184
  Generated text chunks
@@ -191,7 +193,8 @@ class MultiSteering:
191
193
  raise MultiSteeringError("No layer information available")
192
194
 
193
195
  print(f"\n🎯 Applying combined steering vector at layer {self.layer}")
194
- print(f"Prompt: {prompt}")
196
+ print(f"Prompt: {prompt[:100]}..." if len(prompt) > 100 else f"Prompt: {prompt}")
197
+ print(f"Prompt is formatted: {prompt_is_formatted}")
195
198
  print("=" * 50)
196
199
 
197
200
  # Create SteeringPlan from the combined vector
@@ -202,13 +205,19 @@ class MultiSteering:
202
205
  normalize=False # Already normalized in combine_vectors
203
206
  )
204
207
 
205
- # Format prompt as chat messages
206
- messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
208
+ # Handle prompt formatting
209
+ if prompt_is_formatted:
210
+ # Prompt already has chat template applied - pass as string directly
211
+ inputs = prompt
212
+ else:
213
+ # Format prompt as chat messages (current behavior)
214
+ messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
215
+ inputs = [messages]
207
216
 
208
217
  try:
209
218
  # Use WisentModel's generate_stream with steering
210
219
  yield from model.generate_stream(
211
- inputs=[messages],
220
+ inputs=inputs,
212
221
  max_new_tokens=max_new_tokens,
213
222
  temperature=temperature,
214
223
  top_p=top_p,
@@ -216,7 +225,8 @@ class MultiSteering:
216
225
  steering_plan=steering_plan,
217
226
  skip_prompt=True,
218
227
  skip_special_tokens=True,
219
- enable_thinking=enable_thinking
228
+ enable_thinking=enable_thinking,
229
+ prompt_is_formatted=prompt_is_formatted
220
230
  )
221
231
 
222
232
  except Exception as e:
@@ -231,17 +241,19 @@ class MultiSteering:
231
241
  max_new_tokens: int = 100,
232
242
  temperature: float = 0.7,
233
243
  top_p: float = 0.9,
234
- enable_thinking: bool = True
244
+ enable_thinking: bool = True,
245
+ prompt_is_formatted: bool = False
235
246
  ) -> str:
236
247
  """Apply the combined steering vector to generate text (non-streaming).
237
248
 
238
249
  Args:
239
250
  model: WisentModel instance to use for generation
240
- prompt: Input prompt
251
+ prompt: Input prompt (either raw text or pre-formatted with chat template)
241
252
  max_new_tokens: Maximum tokens to generate
242
253
  temperature: Sampling temperature
243
254
  top_p: Top-p sampling parameter
244
255
  enable_thinking: If False, disable thinking/reasoning mode (prevents <think> tags for supported models like Qwen)
256
+ prompt_is_formatted: If True, prompt already has chat template applied
245
257
 
246
258
  Returns:
247
259
  Generated text
@@ -256,7 +268,8 @@ class MultiSteering:
256
268
  raise MultiSteeringError("No layer information available")
257
269
 
258
270
  print(f"\n🎯 Applying combined steering vector at layer {self.layer}")
259
- print(f"Prompt: {prompt}")
271
+ print(f"Prompt: {prompt[:100]}..." if len(prompt) > 100 else f"Prompt: {prompt}")
272
+ print(f"Prompt is formatted: {prompt_is_formatted}")
260
273
  print("=" * 50)
261
274
 
262
275
  # Create SteeringPlan from the combined vector
@@ -267,19 +280,26 @@ class MultiSteering:
267
280
  normalize=False # Already normalized in combine_vectors
268
281
  )
269
282
 
270
- # Format prompt as chat messages
271
- messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
283
+ # Handle prompt formatting
284
+ if prompt_is_formatted:
285
+ # Prompt already has chat template applied - pass as string directly
286
+ inputs = prompt
287
+ else:
288
+ # Format prompt as chat messages (current behavior)
289
+ messages: list[ChatMessage] = [{"role": "user", "content": prompt}]
290
+ inputs = [messages]
272
291
 
273
292
  try:
274
293
  # Use WisentModel's generate with steering
275
294
  outputs = model.generate(
276
- inputs=[messages],
295
+ inputs=inputs,
277
296
  max_new_tokens=max_new_tokens,
278
297
  temperature=temperature,
279
298
  top_p=top_p,
280
299
  use_steering=True,
281
300
  steering_plan=steering_plan,
282
- enable_thinking=enable_thinking
301
+ enable_thinking=enable_thinking,
302
+ prompt_is_formatted=prompt_is_formatted
283
303
  )
284
304
 
285
305
  return outputs[0] if outputs else ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wisent
3
- Version: 0.5.10
3
+ Version: 0.5.12
4
4
  Summary: Monitor and guard against harmful content in language models
5
5
  Home-page: https://github.com/yourusername/wisent-activation-guardrails
6
6
  Author: Wisent Team
@@ -1,4 +1,4 @@
1
- wisent/__init__.py,sha256=1nlPInsRzDbcDPveZ3ghSJ6v6KveN9n6gnj-twW4DkI,23
1
+ wisent/__init__.py,sha256=LznNzk7nDbJCv7NVxCOu958-1uT_nFJ79_3vJt7WPDc,23
2
2
  wisent/benchmarks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  wisent/benchmarks/coding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  wisent/benchmarks/coding/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -64,7 +64,7 @@ wisent/core/managed_cached_benchmarks.py,sha256=JbvpZ1fgSuQQhyQVKEvqrQZRHGqfnjo9
64
64
  wisent/core/mixed_benchmark_sampler.py,sha256=tKQCHUXVuYeCyx4VZt8O1hGyB-TOY_SQ_SYi8cyApII,13585
65
65
  wisent/core/model_config_manager.py,sha256=rQAdSmk3GFlZXyHp3fSV1bORxiZWhmzIz1uo3H4JtkA,12009
66
66
  wisent/core/model_persistence.py,sha256=6_vc1Ndujd4v0O68giINSTvYhmb7-AiacWwAbqLOrls,10636
67
- wisent/core/multi_steering.py,sha256=EMaKn4dZPlAsFupEUQZlxTZGJ0-ofpLcTCKQk8HaZL8,12295
67
+ wisent/core/multi_steering.py,sha256=YhVKmf08KacVEYZWLk6t2uNWSv-Pi_zBeLdDopo3QXk,13491
68
68
  wisent/core/parser.py,sha256=_YDeSuQMx0zNknz9rX3Ls1YPT1x5eohoY8rfjeoqxV8,69091
69
69
  wisent/core/representation.py,sha256=hBl_N9qbr5Gsa7GCQ0nMWRm82RqYEfhd9cyf0PPH5LY,195
70
70
  wisent/core/sample_size_optimizer.py,sha256=6wegGXZpdGpiR4R0YJ1D2JqLr6yinMndEx2gB5FL80s,23666
@@ -134,7 +134,7 @@ wisent/core/evaluators/oracles/interactive.py,sha256=f3v2_N17fKzGyeOxONRJbrbn8i5
134
134
  wisent/core/evaluators/oracles/nlp_evaluator.py,sha256=KxbnF-I2IFbBQpoYyjQKGbYh4NErsEuhTCRYX_Tob8o,18220
135
135
  wisent/core/evaluators/oracles/user_specified.py,sha256=V1dKrNj3Oq7UC_I7DT0WGnktP7R_DSW6UAwDdrA8SnE,2360
136
136
  wisent/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
- wisent/core/models/wisent_model.py,sha256=-QJRrPxQPduDyjH0l9PDZC0cdoBzyrQQ_bgeImfGwfI,29873
137
+ wisent/core/models/wisent_model.py,sha256=4W77IrPdVpgxjhnhybLuJpIFQmdc9e7TzmwxaRPRWVc,32052
138
138
  wisent/core/models/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
139
  wisent/core/models/core/atoms.py,sha256=_Bpz0Sfiq6_VswThIltUwNGj_ukl5MhAg8RrgMKwEBM,15756
140
140
  wisent/core/optuna/__init__.py,sha256=sTfwRnrRyKrCNVsF_qCjBDFEZC0ZmUZ7m6IE0iHfTVs,1914
@@ -213,8 +213,8 @@ wisent/synthetic/generators/diversities/core/__init__.py,sha256=47DEQpj8HBSa-_TI
213
213
  wisent/synthetic/generators/diversities/core/core.py,sha256=TjSj5T7NE5kRH-ABcFqb1Hz_j3Z6F_TcV-95uHD5Xw8,2201
214
214
  wisent/synthetic/generators/diversities/methods/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
215
215
  wisent/synthetic/generators/diversities/methods/fast_diversity.py,sha256=Z2UzTbzyJFM_ToxCoXM_LQQQ1Jc6BZknrbpikTG1MRw,8522
216
- wisent-0.5.10.dist-info/licenses/LICENSE,sha256=wy0iaw8b2tyqZAfKHib3lP3PJ9o88FDCg92oUHh3sDQ,1073
217
- wisent-0.5.10.dist-info/METADATA,sha256=-CwqNc9Sz5brGHuNi1lMz34YNVqKNHRft4QVlOAjZvM,2425
218
- wisent-0.5.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
219
- wisent-0.5.10.dist-info/top_level.txt,sha256=2Ts9Iyldnb3auIN2HBBaHPknRy7nSRDm2f6RGzYgr8A,7
220
- wisent-0.5.10.dist-info/RECORD,,
216
+ wisent-0.5.12.dist-info/licenses/LICENSE,sha256=wy0iaw8b2tyqZAfKHib3lP3PJ9o88FDCg92oUHh3sDQ,1073
217
+ wisent-0.5.12.dist-info/METADATA,sha256=03T1uh1O8l6nuJQtIolh3yLGNBm-UPpwx0HNLZ2wntw,2425
218
+ wisent-0.5.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
219
+ wisent-0.5.12.dist-info/top_level.txt,sha256=2Ts9Iyldnb3auIN2HBBaHPknRy7nSRDm2f6RGzYgr8A,7
220
+ wisent-0.5.12.dist-info/RECORD,,