Skip to content

Commit 28c8770

Browse files
FEAT add supports_system_prompt flag (#1563)
1 parent 7624edf commit 28c8770

8 files changed

Lines changed: 53 additions & 3 deletions

File tree

pyrit/prompt_target/azure_ml_chat_target.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ class AzureMLChatTarget(PromptChatTarget):
4242
api_key_environment_variable: str = "AZURE_ML_KEY"
4343

4444
_DEFAULT_CAPABILITIES: TargetCapabilities = TargetCapabilities(
45-
supports_multi_message_pieces=True, supports_editable_history=True, supports_multi_turn=True
45+
supports_multi_message_pieces=True,
46+
supports_editable_history=True,
47+
supports_multi_turn=True,
48+
supports_system_prompt=True,
4649
)
4750

4851
def __init__(

pyrit/prompt_target/common/prompt_chat_target.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ class PromptChatTarget(PromptTarget):
2222
"""
2323

2424
_DEFAULT_CAPABILITIES: TargetCapabilities = TargetCapabilities(
25-
supports_multi_turn=True, supports_multi_message_pieces=True
25+
supports_multi_turn=True,
26+
supports_multi_message_pieces=True,
27+
supports_system_prompt=True,
2628
)
2729

2830
def __init__(

pyrit/prompt_target/common/target_capabilities.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class attribute. Users can override individual capabilities per instance
3838
# multi-turn interactions and that the attack history is not immutable once set.
3939
supports_editable_history: bool = False
4040

41+
# Whether the target natively supports system prompts.
42+
supports_system_prompt: bool = False
43+
4144
# The input modalities supported by the target (e.g., "text", "image").
4245
input_modalities: frozenset[frozenset[PromptDataType]] = frozenset({frozenset(["text"])})
4346

@@ -76,6 +79,7 @@ def get_known_capabilities(underlying_model: str) -> "Optional[TargetCapabilitie
7679
_GPT_4O = TargetCapabilities(
7780
supports_multi_turn=True,
7881
supports_multi_message_pieces=True,
82+
supports_system_prompt=True,
7983
supports_json_output=True,
8084
input_modalities=_TEXT_IMAGE_INPUT,
8185
output_modalities=_TEXT_OUTPUT,
@@ -84,6 +88,7 @@ def get_known_capabilities(underlying_model: str) -> "Optional[TargetCapabilitie
8488
_GPT_5 = TargetCapabilities(
8589
supports_multi_turn=True,
8690
supports_multi_message_pieces=True,
91+
supports_system_prompt=True,
8792
supports_json_schema=True,
8893
supports_json_output=True,
8994
input_modalities=_TEXT_IMAGE_INPUT,

pyrit/prompt_target/hugging_face/hugging_face_chat_target.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ class HuggingFaceChatTarget(PromptChatTarget):
3333
"""
3434

3535
_DEFAULT_CAPABILITIES: TargetCapabilities = TargetCapabilities(
36-
supports_multi_turn=True, supports_editable_history=True
36+
supports_multi_turn=True,
37+
supports_editable_history=True,
38+
supports_system_prompt=True,
3739
)
3840

3941
# Class-level cache for model and tokenizer

pyrit/prompt_target/openai/openai_chat_target.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class OpenAIChatTarget(OpenAITarget, PromptChatTarget):
6969
supports_multi_turn=True,
7070
supports_json_output=True,
7171
supports_multi_message_pieces=True,
72+
supports_system_prompt=True,
7273
)
7374

7475
def __init__(

pyrit/prompt_target/openai/openai_realtime_target.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class RealtimeTarget(OpenAITarget, PromptChatTarget):
7171
_DEFAULT_CAPABILITIES: TargetCapabilities = TargetCapabilities(
7272
supports_multi_turn=True,
7373
supports_multi_message_pieces=True,
74+
supports_system_prompt=True,
7475
input_modalities=frozenset(
7576
{
7677
frozenset(["text"]),

pyrit/prompt_target/openai/openai_response_target.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class OpenAIResponseTarget(OpenAITarget, PromptChatTarget):
7272
supports_multi_turn=True,
7373
supports_json_output=True,
7474
supports_multi_message_pieces=True,
75+
supports_system_prompt=True,
7576
input_modalities=frozenset(
7677
{
7778
frozenset(["text"]),

tests/unit/target/test_target_capabilities.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ def test_hugging_face_chat_target_capabilities(self):
243243
caps = HuggingFaceChatTarget._DEFAULT_CAPABILITIES
244244
assert caps.supports_editable_history is True
245245
assert caps.supports_multi_turn is True
246+
assert caps.supports_system_prompt is True
246247

247248
def test_azure_ml_chat_target_capabilities(self):
248249
from pyrit.prompt_target import AzureMLChatTarget
@@ -253,6 +254,31 @@ def test_azure_ml_chat_target_capabilities(self):
253254
)
254255
assert target.capabilities.supports_editable_history is True
255256
assert target.capabilities.supports_multi_message_pieces is True
257+
assert target.capabilities.supports_system_prompt is True
258+
259+
@patch.dict("os.environ", _CLEAN_UNDERLYING_MODEL_ENV)
260+
def test_prompt_chat_targets_support_system_prompt(self):
261+
from pyrit.prompt_target import OpenAIChatTarget, OpenAIResponseTarget, RealtimeTarget
262+
263+
openai_chat_target = OpenAIChatTarget(
264+
model_name="test-model",
265+
endpoint="https://mock.azure.com/",
266+
api_key="mock-api-key",
267+
)
268+
openai_response_target = OpenAIResponseTarget(
269+
model_name="o1",
270+
endpoint="https://mock.azure.com/",
271+
api_key="mock-api-key",
272+
)
273+
realtime_target = RealtimeTarget(
274+
model_name="gpt-4o-realtime",
275+
endpoint="https://mock.azure.com/",
276+
api_key="mock-api-key",
277+
)
278+
279+
assert openai_chat_target.capabilities.supports_system_prompt is True
280+
assert openai_response_target.capabilities.supports_system_prompt is True
281+
assert realtime_target.capabilities.supports_system_prompt is True
256282

257283
def test_custom_capabilities_override_modalities(self):
258284
from pyrit.prompt_target import OpenAIChatTarget, TargetCapabilities
@@ -415,3 +441,12 @@ def test_recognized_model_overrides_class_default(self):
415441
cls = self._make_target_class(default_caps=minimal_caps)
416442
result = cls.get_default_capabilities("tts")
417443
assert result.output_modalities == frozenset({frozenset(["audio_path"])})
444+
445+
def test_prompt_chat_target_preserves_system_prompt_for_recognized_model(self):
446+
from pyrit.prompt_target.common.prompt_chat_target import PromptChatTarget
447+
448+
result = PromptChatTarget.get_default_capabilities("gpt-4o")
449+
450+
assert result.supports_multi_turn is True
451+
assert result.supports_multi_message_pieces is True
452+
assert result.supports_system_prompt is True

0 commit comments

Comments
 (0)