diff --git a/doc/code/converters/0_converters.ipynb b/doc/code/converters/0_converters.ipynb index 0121ff06f..43b342104 100644 --- a/doc/code/converters/0_converters.ipynb +++ b/doc/code/converters/0_converters.ipynb @@ -114,356 +114,362 @@ " \n", " 7\n", " text\n", - " image_path\n", - " AddImageTextConverter\n", + " binary_path\n", + " PDFConverter\n", " \n", " \n", " 8\n", " text\n", " image_path\n", - " QRCodeConverter\n", + " AddImageTextConverter\n", " \n", " \n", " 9\n", " text\n", - " text\n", - " AnsiAttackConverter\n", + " image_path\n", + " QRCodeConverter\n", " \n", " \n", " 10\n", " text\n", " text\n", - " AsciiArtConverter\n", + " AnsiAttackConverter\n", " \n", " \n", " 11\n", " text\n", " text\n", - " AsciiSmugglerConverter\n", + " AsciiArtConverter\n", " \n", " \n", " 12\n", " text\n", " text\n", - " AskToDecodeConverter\n", + " AsciiSmugglerConverter\n", " \n", " \n", " 13\n", " text\n", " text\n", - " AtbashConverter\n", + " AskToDecodeConverter\n", " \n", " \n", " 14\n", " text\n", " text\n", - " Base2048Converter\n", + " AtbashConverter\n", " \n", " \n", " 15\n", " text\n", " text\n", - " Base64Converter\n", + " Base2048Converter\n", " \n", " \n", " 16\n", " text\n", " text\n", - " BinAsciiConverter\n", + " Base64Converter\n", " \n", " \n", " 17\n", " text\n", " text\n", - " BinaryConverter\n", + " BinAsciiConverter\n", " \n", " \n", " 18\n", " text\n", " text\n", - " BrailleConverter\n", + " BinaryConverter\n", " \n", " \n", " 19\n", " text\n", " text\n", - " CaesarConverter\n", + " BrailleConverter\n", " \n", " \n", " 20\n", " text\n", " text\n", - " CharSwapConverter\n", + " CaesarConverter\n", " \n", " \n", " 21\n", " text\n", " text\n", - " CharacterSpaceConverter\n", + " CharSwapConverter\n", " \n", " \n", " 22\n", " text\n", " text\n", - " CodeChameleonConverter\n", + " CharacterSpaceConverter\n", " \n", " \n", " 23\n", " text\n", " text\n", - " ColloquialWordswapConverter\n", + " CodeChameleonConverter\n", " \n", " \n", " 24\n", " text\n", " text\n", - " DenylistConverter\n", + " ColloquialWordswapConverter\n", " \n", " \n", " 25\n", " text\n", " text\n", - " DiacriticConverter\n", + " DenylistConverter\n", " \n", " \n", " 26\n", " text\n", " text\n", - " EcojiConverter\n", + " DiacriticConverter\n", " \n", " \n", " 27\n", " text\n", " text\n", - " EmojiConverter\n", + " EcojiConverter\n", " \n", " \n", " 28\n", " text\n", " text\n", - " FirstLetterConverter\n", + " EmojiConverter\n", " \n", " \n", " 29\n", " text\n", " text\n", - " FlipConverter\n", + " FirstLetterConverter\n", " \n", " \n", " 30\n", " text\n", " text\n", - " HumanInTheLoopConverter\n", + " FlipConverter\n", " \n", " \n", " 31\n", " text\n", " text\n", - " InsertPunctuationConverter\n", + " HumanInTheLoopConverter\n", " \n", " \n", " 32\n", " text\n", " text\n", - " LLMGenericTextConverter\n", + " InsertPunctuationConverter\n", " \n", " \n", " 33\n", " text\n", " text\n", - " LeetspeakConverter\n", + " LLMGenericTextConverter\n", " \n", " \n", " 34\n", " text\n", " text\n", - " MaliciousQuestionGeneratorConverter\n", + " LeetspeakConverter\n", " \n", " \n", " 35\n", " text\n", " text\n", - " MathObfuscationConverter\n", + " MaliciousQuestionGeneratorConverter\n", " \n", " \n", " 36\n", " text\n", " text\n", - " MathPromptConverter\n", + " MathObfuscationConverter\n", " \n", " \n", " 37\n", " text\n", " text\n", - " MorseConverter\n", + " MathPromptConverter\n", " \n", " \n", " 38\n", " text\n", " text\n", - " NatoConverter\n", + " MorseConverter\n", " \n", " \n", " 39\n", " text\n", " text\n", - " NoiseConverter\n", + " NatoConverter\n", " \n", " \n", " 40\n", " text\n", " text\n", - " PersuasionConverter\n", + " NegationTrapConverter\n", " \n", " \n", " 41\n", " text\n", " text\n", - " ROT13Converter\n", + " NoiseConverter\n", " \n", " \n", " 42\n", " text\n", " text\n", - " RandomCapitalLettersConverter\n", + " PersuasionConverter\n", " \n", " \n", " 43\n", " text\n", " text\n", - " RandomTranslationConverter\n", + " ROT13Converter\n", " \n", " \n", " 44\n", " text\n", " text\n", - " RepeatTokenConverter\n", + " RandomCapitalLettersConverter\n", " \n", " \n", " 45\n", " text\n", " text\n", - " SearchReplaceConverter\n", + " RandomTranslationConverter\n", " \n", " \n", " 46\n", " text\n", " text\n", - " SelectiveTextConverter\n", + " RepeatTokenConverter\n", " \n", " \n", " 47\n", " text\n", " text\n", - " SneakyBitsSmugglerConverter\n", + " SearchReplaceConverter\n", " \n", " \n", " 48\n", " text\n", " text\n", - " StringJoinConverter\n", + " SelectiveTextConverter\n", " \n", " \n", " 49\n", " text\n", " text\n", - " SuffixAppendConverter\n", + " SneakyBitsSmugglerConverter\n", " \n", " \n", " 50\n", " text\n", " text\n", - " SuperscriptConverter\n", + " StringJoinConverter\n", " \n", " \n", " 51\n", " text\n", " text\n", - " TemplateSegmentConverter\n", + " SuffixAppendConverter\n", " \n", " \n", " 52\n", " text\n", " text\n", - " TenseConverter\n", + " SuperscriptConverter\n", " \n", " \n", " 53\n", " text\n", " text\n", - " TextJailbreakConverter\n", + " TemplateSegmentConverter\n", " \n", " \n", " 54\n", " text\n", " text\n", - " ToneConverter\n", + " TenseConverter\n", " \n", " \n", " 55\n", " text\n", " text\n", - " ToxicSentenceGeneratorConverter\n", + " TextJailbreakConverter\n", " \n", " \n", " 56\n", " text\n", " text\n", - " TranslationConverter\n", + " ToneConverter\n", " \n", " \n", " 57\n", " text\n", " text\n", - " UnicodeConfusableConverter\n", + " ToxicSentenceGeneratorConverter\n", " \n", " \n", " 58\n", " text\n", " text\n", - " UnicodeReplacementConverter\n", + " TranslationConverter\n", " \n", " \n", " 59\n", " text\n", " text\n", - " UnicodeSubstitutionConverter\n", + " UnicodeConfusableConverter\n", " \n", " \n", " 60\n", " text\n", " text\n", - " UrlConverter\n", + " UnicodeReplacementConverter\n", " \n", " \n", " 61\n", " text\n", " text\n", - " VariationConverter\n", + " UnicodeSubstitutionConverter\n", " \n", " \n", " 62\n", " text\n", " text\n", - " VariationSelectorSmugglerConverter\n", + " UrlConverter\n", " \n", " \n", " 63\n", " text\n", " text\n", - " ZalgoConverter\n", + " VariationConverter\n", " \n", " \n", " 64\n", " text\n", " text\n", - " ZeroWidthConverter\n", + " VariationSelectorSmugglerConverter\n", " \n", " \n", " 65\n", " text\n", - " url\n", - " PDFConverter\n", + " text\n", + " ZalgoConverter\n", + " \n", + " \n", + " 66\n", + " text\n", + " text\n", + " ZeroWidthConverter\n", " \n", " \n", "\n", @@ -478,65 +484,66 @@ "4 image_path video_path AddImageVideoConverter\n", "5 image_path, url image_path ImageCompressionConverter\n", "6 text audio_path AzureSpeechTextToAudioConverter\n", - "7 text image_path AddImageTextConverter\n", - "8 text image_path QRCodeConverter\n", - "9 text text AnsiAttackConverter\n", - "10 text text AsciiArtConverter\n", - "11 text text AsciiSmugglerConverter\n", - "12 text text AskToDecodeConverter\n", - "13 text text AtbashConverter\n", - "14 text text Base2048Converter\n", - "15 text text Base64Converter\n", - "16 text text BinAsciiConverter\n", - "17 text text BinaryConverter\n", - "18 text text BrailleConverter\n", - "19 text text CaesarConverter\n", - "20 text text CharSwapConverter\n", - "21 text text CharacterSpaceConverter\n", - "22 text text CodeChameleonConverter\n", - "23 text text ColloquialWordswapConverter\n", - "24 text text DenylistConverter\n", - "25 text text DiacriticConverter\n", - "26 text text EcojiConverter\n", - "27 text text EmojiConverter\n", - "28 text text FirstLetterConverter\n", - "29 text text FlipConverter\n", - "30 text text HumanInTheLoopConverter\n", - "31 text text InsertPunctuationConverter\n", - "32 text text LLMGenericTextConverter\n", - "33 text text LeetspeakConverter\n", - "34 text text MaliciousQuestionGeneratorConverter\n", - "35 text text MathObfuscationConverter\n", - "36 text text MathPromptConverter\n", - "37 text text MorseConverter\n", - "38 text text NatoConverter\n", - "39 text text NoiseConverter\n", - "40 text text PersuasionConverter\n", - "41 text text ROT13Converter\n", - "42 text text RandomCapitalLettersConverter\n", - "43 text text RandomTranslationConverter\n", - "44 text text RepeatTokenConverter\n", - "45 text text SearchReplaceConverter\n", - "46 text text SelectiveTextConverter\n", - "47 text text SneakyBitsSmugglerConverter\n", - "48 text text StringJoinConverter\n", - "49 text text SuffixAppendConverter\n", - "50 text text SuperscriptConverter\n", - "51 text text TemplateSegmentConverter\n", - "52 text text TenseConverter\n", - "53 text text TextJailbreakConverter\n", - "54 text text ToneConverter\n", - "55 text text ToxicSentenceGeneratorConverter\n", - "56 text text TranslationConverter\n", - "57 text text UnicodeConfusableConverter\n", - "58 text text UnicodeReplacementConverter\n", - "59 text text UnicodeSubstitutionConverter\n", - "60 text text UrlConverter\n", - "61 text text VariationConverter\n", - "62 text text VariationSelectorSmugglerConverter\n", - "63 text text ZalgoConverter\n", - "64 text text ZeroWidthConverter\n", - "65 text url PDFConverter" + "7 text binary_path PDFConverter\n", + "8 text image_path AddImageTextConverter\n", + "9 text image_path QRCodeConverter\n", + "10 text text AnsiAttackConverter\n", + "11 text text AsciiArtConverter\n", + "12 text text AsciiSmugglerConverter\n", + "13 text text AskToDecodeConverter\n", + "14 text text AtbashConverter\n", + "15 text text Base2048Converter\n", + "16 text text Base64Converter\n", + "17 text text BinAsciiConverter\n", + "18 text text BinaryConverter\n", + "19 text text BrailleConverter\n", + "20 text text CaesarConverter\n", + "21 text text CharSwapConverter\n", + "22 text text CharacterSpaceConverter\n", + "23 text text CodeChameleonConverter\n", + "24 text text ColloquialWordswapConverter\n", + "25 text text DenylistConverter\n", + "26 text text DiacriticConverter\n", + "27 text text EcojiConverter\n", + "28 text text EmojiConverter\n", + "29 text text FirstLetterConverter\n", + "30 text text FlipConverter\n", + "31 text text HumanInTheLoopConverter\n", + "32 text text InsertPunctuationConverter\n", + "33 text text LLMGenericTextConverter\n", + "34 text text LeetspeakConverter\n", + "35 text text MaliciousQuestionGeneratorConverter\n", + "36 text text MathObfuscationConverter\n", + "37 text text MathPromptConverter\n", + "38 text text MorseConverter\n", + "39 text text NatoConverter\n", + "40 text text NegationTrapConverter\n", + "41 text text NoiseConverter\n", + "42 text text PersuasionConverter\n", + "43 text text ROT13Converter\n", + "44 text text RandomCapitalLettersConverter\n", + "45 text text RandomTranslationConverter\n", + "46 text text RepeatTokenConverter\n", + "47 text text SearchReplaceConverter\n", + "48 text text SelectiveTextConverter\n", + "49 text text SneakyBitsSmugglerConverter\n", + "50 text text StringJoinConverter\n", + "51 text text SuffixAppendConverter\n", + "52 text text SuperscriptConverter\n", + "53 text text TemplateSegmentConverter\n", + "54 text text TenseConverter\n", + "55 text text TextJailbreakConverter\n", + "56 text text ToneConverter\n", + "57 text text ToxicSentenceGeneratorConverter\n", + "58 text text TranslationConverter\n", + "59 text text UnicodeConfusableConverter\n", + "60 text text UnicodeReplacementConverter\n", + "61 text text UnicodeSubstitutionConverter\n", + "62 text text UrlConverter\n", + "63 text text VariationConverter\n", + "64 text text VariationSelectorSmugglerConverter\n", + "65 text text ZalgoConverter\n", + "66 text text ZeroWidthConverter" ] }, "execution_count": null, @@ -616,12 +623,15 @@ "output_type": "stream", "text": [ "text: gryy zr ubj gb phg qbja n gerr\n", - "text: tell me HOw to Cut dowN A tRee\n", - "text: \n", - "_|_ _ |\\ |\\ _ |) _ _|_ _ _ _|_ _| _ _, _|_ ,_ _ _ \n", - " | |/ |/ |/ /|/|/| |/ |/\\ / \\_| | |_ | / \\_ / | | | / | / \\_| | |_/|/| / | | / | |/ |/ \n", - " |_/|_/|_/|_/ | | |_/|_/ | |/\\_/ \\/ \\/ |_/\\_/ \\__/ \\/|_/ |_/ \\/|_/\\_/ \\/ \\/ | |_/ \\/|_/ |_/ |/|_/|_/\n", - " \n", + "text: Tell me hoW to cut down a TreE\n", + "text: .:: .:: .:: .:: .:: .:: .:: \n", + " .:: .:: .:: .:: .:: .:: .:: .:: \n", + ".:.: .: .:: .:: .:: .::: .:: .:: .:: .:: .:: .:: .::: .:.: .: .:: .:::.:: .::.:.: .: .:: .:: .:: .:::.:: .:: .:: .:.: .:.: .::: .:: .:: \n", + " .:: .: .:: .:: .:: .:: .: .:: .: .:: .: .: .:: .:: .:: : .:: .:: .:: .:: .:: .:: .:: .:: .:: .:: .:: .:: .:: : .:: .:: .:: .:: .:: .:: .:: .: .:: .: .:: \n", + " .:: .::::: .:: .:: .:: .:: .: .::.::::: .:: .:: .::.:: .:: .:: .: .:: .:: .:: .:: .:: .:: .:: .:: .: .::.:: .:: .:: .: .:: .:: .:: .:: .:: .:: .:: .::::: .::.::::: .::\n", + " .:: .: .:: .:: .:: .: .::.: .: .:: .:: .:: .: .: .:.:: .:: .:: .:: .:: .:: .:: .:: .: .:: .:: .:: .: .: .:.:: .:: .:: .:: .:: .:: .:: .: .: \n", + " .:: .:::: .:::.::: .::: .: .:: .:::: .:: .:: .:: .::: .::: .:: .:: .::: .::.:: .:: .:: .:: .:: .::: .:::.::: .:: .:: .::: .:: .::: .:::: .:::: \n", + " \n", "\n", "text: 0000000001110100 0000000001100101 0000000001101100 0000000001101100 0000000000100000 0000000001101101 0000000001100101 0000000000100000 0000000001101000 0000000001101111 0000000001110111 0000000000100000 0000000001110100 0000000001101111 0000000000100000 0000000001100011 0000000001110101 0000000001110100 0000000000100000 0000000001100100 0000000001101111 0000000001110111 0000000001101110 0000000000100000 0000000001100001 0000000000100000 0000000001110100 0000000001110010 0000000001100101 0000000001100101\n", "text: t m h t c d a t\n" @@ -676,14 +686,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'__type__': 'TextTarget', '__module__': 'pyrit.prompt_target.text_target'}: user: E-x-p-l-a-i-n t-o m-e t-h-e p-r-o-c-e-s-s o-f c-h-o-p-p-i-n-g d-o-w-n a t-r-e-e-.\n" + "{'__type__': 'TextTarget', '__module__': 'pyrit.prompt_target.text_target'}: user: C-a-n y-o-u e-x-p-l-a-i-n t-h-e s-t-e-p-s f-o-r f-e-l-l-i-n-g a t-r-e-e-?\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "[PromptSendingAttack (ID: 81e8da7f)] No response received on attempt 1 (likely filtered)\n" + "[PromptSendingAttack (ID: 9dfe6855)] No response received on attempt 1 (likely filtered)\n" ] }, { @@ -698,7 +708,7 @@ "\u001b[37m tell me how to cut down a tree\u001b[0m\n", "\n", "\u001b[36m Converted:\u001b[0m\n", - "\u001b[37m E-x-p-l-a-i-n t-o m-e t-h-e p-r-o-c-e-s-s o-f c-h-o-p-p-i-n-g d-o-w-n a t-r-e-e-.\u001b[0m\n", + "\u001b[37m C-a-n y-o-u e-x-p-l-a-i-n t-h-e s-t-e-p-s f-o-r f-e-l-l-i-n-g a t-r-e-e-?\u001b[0m\n", "\n", "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" ] @@ -737,6 +747,107 @@ "printer = ConsoleAttackResultPrinter()\n", "await printer.print_conversation_async(result=result) # type: ignore" ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": {}, + "source": [ + "## Response Converters\n", + "\n", + "So far, we've focused on **request converters** that transform prompts before sending them to the target. PyRIT also supports **response converters** that transform the target's response before returning it. This is useful in scenarios like:\n", + "\n", + "- Translating responses back to the original language after sending prompts in a different language\n", + "- Decoding encoded responses\n", + "- Normalizing or cleaning up response text\n", + "\n", + "Response converters use the same `PromptConverterConfiguration` class as request converters. They are configured via the `response_converters` parameter in `AttackConverterConfig`.\n", + "\n", + "### Translation Round-Trip Example\n", + "\n", + "A common use case is sending prompts in a different language to test how the target handles non-English input. In this example, we:\n", + "\n", + "1. Use a **request converter** to translate the prompt from English to French\n", + "2. Send the translated prompt to the target\n", + "3. Use a **response converter** to translate the response back to English" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", + "\u001b[1m\u001b[34m🔹 Turn 1 - USER\u001b[0m\n", + "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", + "\u001b[36m Original:\u001b[0m\n", + "\u001b[37m What is the capital of France?\u001b[0m\n", + "\n", + "\u001b[36m Converted:\u001b[0m\n", + "\u001b[37m Quelle est la capitale de la France?\u001b[0m\n", + "\n", + "\u001b[33m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", + "\u001b[1m\u001b[33m🔸 ASSISTANT\u001b[0m\n", + "\u001b[33m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n", + "\u001b[36m Original:\u001b[0m\n", + "\u001b[37m La capitale de la France est **Paris**.\u001b[0m\n", + "\n", + "\u001b[36m Converted:\u001b[0m\n", + "\u001b[37m The capital of France is **Paris**.\u001b[0m\n", + "\n", + "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + } + ], + "source": [ + "from pyrit.executor.attack import (\n", + " AttackConverterConfig,\n", + " ConsoleAttackResultPrinter,\n", + " PromptSendingAttack,\n", + ")\n", + "from pyrit.prompt_converter import TranslationConverter\n", + "from pyrit.prompt_normalizer import PromptConverterConfiguration\n", + "from pyrit.prompt_target import OpenAIChatTarget\n", + "\n", + "objective = \"What is the capital of France?\"\n", + "\n", + "# Create an LLM target for the converters\n", + "converter_target = OpenAIChatTarget()\n", + "\n", + "# Create an LLM target to send prompts to\n", + "prompt_target = OpenAIChatTarget()\n", + "\n", + "# Request converter: translate English to French\n", + "request_converter = TranslationConverter(converter_target=converter_target, language=\"French\")\n", + "request_converter_config = PromptConverterConfiguration(converters=[request_converter])\n", + "\n", + "# Response converter: translate response back to English\n", + "response_converter = TranslationConverter(converter_target=converter_target, language=\"English\")\n", + "response_converter_config = PromptConverterConfiguration(converters=[response_converter])\n", + "\n", + "# Configure the attack with both request and response converters\n", + "converter_config = AttackConverterConfig(\n", + " request_converters=[request_converter_config],\n", + " response_converters=[response_converter_config],\n", + ")\n", + "\n", + "attack = PromptSendingAttack(\n", + " objective_target=prompt_target,\n", + " attack_converter_config=converter_config,\n", + ")\n", + "\n", + "result = await attack.execute_async(objective=objective) # type: ignore\n", + "\n", + "# Print the conversation showing both original and converted values\n", + "printer = ConsoleAttackResultPrinter()\n", + "await printer.print_conversation_async(result=result) # type: ignore" + ] } ], "metadata": { diff --git a/doc/code/converters/0_converters.py b/doc/code/converters/0_converters.py index 6be75251d..5731a3982 100644 --- a/doc/code/converters/0_converters.py +++ b/doc/code/converters/0_converters.py @@ -136,3 +136,65 @@ printer = ConsoleAttackResultPrinter() await printer.print_conversation_async(result=result) # type: ignore + +# %% [markdown] +# ## Response Converters +# +# So far, we've focused on **request converters** that transform prompts before sending them to the target. PyRIT also supports **response converters** that transform the target's response before returning it. This is useful in scenarios like: +# +# - Translating responses back to the original language after sending prompts in a different language +# - Decoding encoded responses +# - Normalizing or cleaning up response text +# +# Response converters use the same `PromptConverterConfiguration` class as request converters. They are configured via the `response_converters` parameter in `AttackConverterConfig`. +# +# ### Translation Round-Trip Example +# +# A common use case is sending prompts in a different language to test how the target handles non-English input. In this example, we: +# +# 1. Use a **request converter** to translate the prompt from English to French +# 2. Send the translated prompt to the target +# 3. Use a **response converter** to translate the response back to English + +# %% +from pyrit.executor.attack import ( + AttackConverterConfig, + ConsoleAttackResultPrinter, + PromptSendingAttack, +) +from pyrit.prompt_converter import TranslationConverter +from pyrit.prompt_normalizer import PromptConverterConfiguration +from pyrit.prompt_target import OpenAIChatTarget + +objective = "What is the capital of France?" + +# Create an LLM target for the converters +converter_target = OpenAIChatTarget() + +# Create an LLM target to send prompts to +prompt_target = OpenAIChatTarget() + +# Request converter: translate English to French +request_converter = TranslationConverter(converter_target=converter_target, language="French") +request_converter_config = PromptConverterConfiguration(converters=[request_converter]) + +# Response converter: translate response back to English +response_converter = TranslationConverter(converter_target=converter_target, language="English") +response_converter_config = PromptConverterConfiguration(converters=[response_converter]) + +# Configure the attack with both request and response converters +converter_config = AttackConverterConfig( + request_converters=[request_converter_config], + response_converters=[response_converter_config], +) + +attack = PromptSendingAttack( + objective_target=prompt_target, + attack_converter_config=converter_config, +) + +result = await attack.execute_async(objective=objective) # type: ignore + +# Print the conversation showing both original and converted values +printer = ConsoleAttackResultPrinter() +await printer.print_conversation_async(result=result) # type: ignore diff --git a/pyrit/executor/attack/printer/console_printer.py b/pyrit/executor/attack/printer/console_printer.py index bce1029c5..c3474b8c1 100644 --- a/pyrit/executor/attack/printer/console_printer.py +++ b/pyrit/executor/attack/printer/console_printer.py @@ -205,8 +205,8 @@ async def print_messages_async( if piece.original_value_data_type == "reasoning" and not include_reasoning_trace: continue - # Handle converted values for user messages - if piece.api_role == "user" and piece.converted_value != piece.original_value: + # Handle converted values for user and assistant messages + if piece.converted_value != piece.original_value: self._print_colored(f"{self._indent} Original:", Fore.CYAN) self._print_wrapped_text(piece.original_value, Fore.WHITE) print()