{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "# File Converters\n",
    "\n",
    "File converters transform text into file outputs such as PDFs. These converters are useful for packaging prompts into distributable formats.\n",
    "\n",
    "## Overview\n",
    "\n",
    "This notebook covers:\n",
    "\n",
    "- **PDFConverter**: Convert text to PDF documents with templates or direct generation\n",
    "- **WordDocConverter**: Convert text to Word (.docx) documents with optional placeholder injection"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "## PDFConverter\n",
    "\n",
    "The `PDFConverter` generates PDF documents from text in multiple modes:\n",
    "\n",
    "1. **Template-Based PDF Generation**: Use YAML templates to render dynamic content into PDFs\n",
    "2. **Direct Prompt PDF Generation**: Convert plain text strings into PDFs without templates\n",
    "3. **Modify Existing PDFs**: Inject text into existing PDF documents"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "### Template-Based PDF Generation\n",
    "\n",
    "This mode populates placeholders in a YAML-based template and converts the rendered content into a PDF."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found default environment files: ['./.pyrit/.env', './.pyrit/.env.local']\n",
      "Loaded environment file: ./.pyrit/.env\n",
      "Loaded environment file: ./.pyrit/.env.local\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "No new upgrade operations detected.\n",
      "TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779402999644083.pdf\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\u001b[1m\u001b[33m                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   \u001b[0m\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Attack Summary \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m  📋 Basic Information\u001b[0m\n",
      "\u001b[36m    • Objective: {'hiring_manager_name': 'Jane Doe', 'current_role': 'AI Engineer', 'company': 'CyberDefense Inc.', 'red_teaming_reason': 'to creatively identify security vulnerabilities while enjoying free coffee', 'applicant_name': 'John Smith'}\u001b[0m\n",
      "\u001b[36m    • Attack Type: PromptSendingAttack\u001b[0m\n",
      "\u001b[36m    • Conversation ID: 9edbd5d0-2bde-4432-b4a7-91b9688f4377\u001b[0m\n",
      "\n",
      "\u001b[1m  ⚡ Execution Metrics\u001b[0m\n",
      "\u001b[32m    • Turns Executed: 1\u001b[0m\n",
      "\u001b[32m    • Execution Time: 45ms\u001b[0m\n",
      "\n",
      "\u001b[1m  🎯 Outcome\u001b[0m\n",
      "\u001b[33m    • Status: ❓ UNDETERMINED\u001b[0m\n",
      "\u001b[37m    • Reason: No objective scorer configured\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Conversation History with Objective Target \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\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  {'hiring_manager_name': 'Jane Doe', 'current_role': 'AI Engineer', 'company': 'CyberDefense Inc.',\u001b[0m\n",
      "\u001b[37m      'red_teaming_reason': 'to creatively identify security vulnerabilities while enjoying free\u001b[0m\n",
      "\u001b[37m      coffee', 'applicant_name': 'John Smith'}\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  ./dbdata/prompt-\u001b[0m\n",
      "\u001b[37m      memory-entries\\binaries\\1779402999644083.pdf\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\n",
      "\u001b[2m\u001b[37m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[2m\u001b[37m                            Report generated at: 2026-05-21 22:36:39 UTC                            \u001b[0m\n"
     ]
    }
   ],
   "source": [
    "import pathlib\n",
    "\n",
    "from pyrit.common.path import CONVERTER_SEED_PROMPT_PATH\n",
    "from pyrit.converter import PDFConverter\n",
    "from pyrit.executor.attack import (\n",
    "    AttackConverterConfig,\n",
    "    PromptSendingAttack,\n",
    ")\n",
    "from pyrit.models import SeedPrompt\n",
    "from pyrit.output import output_attack_async\n",
    "from pyrit.prompt_normalizer import ConverterConfiguration\n",
    "from pyrit.prompt_target import TextTarget\n",
    "from pyrit.setup import IN_MEMORY, initialize_pyrit_async\n",
    "\n",
    "await initialize_pyrit_async(memory_db_type=IN_MEMORY)  # type: ignore\n",
    "\n",
    "prompt_data = {\n",
    "    \"hiring_manager_name\": \"Jane Doe\",\n",
    "    \"current_role\": \"AI Engineer\",\n",
    "    \"company\": \"CyberDefense Inc.\",\n",
    "    \"red_teaming_reason\": \"to creatively identify security vulnerabilities while enjoying free coffee\",\n",
    "    \"applicant_name\": \"John Smith\",\n",
    "}\n",
    "\n",
    "# Load the YAML template for the PDF generation\n",
    "template_path = pathlib.Path(CONVERTER_SEED_PROMPT_PATH) / \"pdf_converters\" / \"red_teaming_application_template.yaml\"\n",
    "if not template_path.exists():\n",
    "    raise FileNotFoundError(f\"Template file not found: {template_path}\")\n",
    "\n",
    "# Load the SeedPrompt from the YAML file\n",
    "prompt_template = SeedPrompt.from_yaml_file(template_path)\n",
    "\n",
    "# Initialize target\n",
    "prompt_target = TextTarget()\n",
    "\n",
    "# Initialize the PDFConverter\n",
    "pdf_converter = ConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        PDFConverter(\n",
    "            prompt_template=prompt_template,\n",
    "            font_type=\"Arial\",\n",
    "            font_size=12,\n",
    "            page_width=210,\n",
    "            page_height=297,\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=pdf_converter,\n",
    ")\n",
    "\n",
    "# Define prompt for the attack\n",
    "prompt = str(prompt_data)\n",
    "\n",
    "# Initialize the attack\n",
    "attack = PromptSendingAttack(\n",
    "    objective_target=prompt_target,\n",
    "    attack_converter_config=converter_config,\n",
    ")\n",
    "\n",
    "result = await attack.execute_async(objective=prompt)  # type: ignore\n",
    "await output_attack_async(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4",
   "metadata": {},
   "source": [
    "### Direct Prompt PDF Generation (No Template)\n",
    "\n",
    "This mode converts plain text strings directly into PDFs without using templates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779402999698469.pdf\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\u001b[1m\u001b[33m                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   \u001b[0m\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Attack Summary \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m  📋 Basic Information\u001b[0m\n",
      "\u001b[36m    • Objective: This is a simple test string for PDF generation. No templates here!\u001b[0m\n",
      "\u001b[36m    • Attack Type: PromptSendingAttack\u001b[0m\n",
      "\u001b[36m    • Conversation ID: 3d86d651-30f2-4d2d-8585-a130ba3dc077\u001b[0m\n",
      "\n",
      "\u001b[1m  ⚡ Execution Metrics\u001b[0m\n",
      "\u001b[32m    • Turns Executed: 1\u001b[0m\n",
      "\u001b[32m    • Execution Time: 23ms\u001b[0m\n",
      "\n",
      "\u001b[1m  🎯 Outcome\u001b[0m\n",
      "\u001b[33m    • Status: ❓ UNDETERMINED\u001b[0m\n",
      "\u001b[37m    • Reason: No objective scorer configured\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Conversation History with Objective Target \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\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  This is a simple test string for PDF generation. No templates here!\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  ./dbdata/prompt-\u001b[0m\n",
      "\u001b[37m      memory-entries\\binaries\\1779402999698469.pdf\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\n",
      "\u001b[2m\u001b[37m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[2m\u001b[37m                            Report generated at: 2026-05-21 22:36:39 UTC                            \u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# Define a simple string prompt (no templates)\n",
    "prompt = \"This is a simple test string for PDF generation. No templates here!\"\n",
    "\n",
    "# Initialize the PDFConverter without a template\n",
    "pdf_converter = ConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        PDFConverter(\n",
    "            prompt_template=None,  # No template provided\n",
    "            font_type=\"Arial\",\n",
    "            font_size=12,\n",
    "            page_width=210,\n",
    "            page_height=297,\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=pdf_converter,\n",
    ")\n",
    "\n",
    "# Initialize the attack\n",
    "attack = PromptSendingAttack(\n",
    "    objective_target=prompt_target,\n",
    "    attack_converter_config=converter_config,\n",
    ")\n",
    "\n",
    "result = await attack.execute_async(objective=prompt)  # type: ignore\n",
    "await output_attack_async(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6",
   "metadata": {},
   "source": [
    "### Modifying Existing PDFs with Injection Items\n",
    "\n",
    "The `PDFConverter` can also inject text into existing PDF documents at specified locations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[15:36:40][10][ai-red-team][INFO][Processing page 0 with 2 injection items.]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[15:36:40][13][ai-red-team][INFO][Processing page 1 with 2 injection items.]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[15:36:40][15][ai-red-team][INFO][Processing page 2 with 2 injection items.]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779403000017242.pdf\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\u001b[1m\u001b[33m                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   \u001b[0m\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Attack Summary \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m  📋 Basic Information\u001b[0m\n",
      "\u001b[36m    • Objective: Modify existing PDF\u001b[0m\n",
      "\u001b[36m    • Attack Type: PromptSendingAttack\u001b[0m\n",
      "\u001b[36m    • Conversation ID: 7f9101d9-93b6-49e3-88ae-1bebaf44a0af\u001b[0m\n",
      "\n",
      "\u001b[1m  ⚡ Execution Metrics\u001b[0m\n",
      "\u001b[32m    • Turns Executed: 1\u001b[0m\n",
      "\u001b[32m    • Execution Time: 31ms\u001b[0m\n",
      "\n",
      "\u001b[1m  🎯 Outcome\u001b[0m\n",
      "\u001b[33m    • Status: ❓ UNDETERMINED\u001b[0m\n",
      "\u001b[37m    • Reason: No objective scorer configured\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Conversation History with Objective Target \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\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  Modify existing PDF\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  ./dbdata/prompt-\u001b[0m\n",
      "\u001b[37m      memory-entries\\binaries\\1779403000017242.pdf\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\n",
      "\u001b[2m\u001b[37m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[2m\u001b[37m                            Report generated at: 2026-05-21 22:36:40 UTC                            \u001b[0m\n"
     ]
    }
   ],
   "source": [
    "import tempfile\n",
    "from pathlib import Path\n",
    "\n",
    "import requests\n",
    "\n",
    "# Download a sample PDF\n",
    "url = \"https://raw.githubusercontent.com/microsoft/PyRIT/main/pyrit/datasets/converters/pdf_converters/fake_CV.pdf\"\n",
    "\n",
    "with tempfile.NamedTemporaryFile(delete=False, suffix=\".pdf\") as tmp_file:\n",
    "    response = requests.get(url)\n",
    "    tmp_file.write(response.content)\n",
    "\n",
    "cv_pdf_path = Path(tmp_file.name)\n",
    "\n",
    "# Define injection items\n",
    "injection_items = [\n",
    "    {\n",
    "        \"page\": 0,\n",
    "        \"x\": 50,\n",
    "        \"y\": 700,\n",
    "        \"text\": \"Injected Text\",\n",
    "        \"font_size\": 12,\n",
    "        \"font\": \"Helvetica\",\n",
    "        \"font_color\": (255, 0, 0),\n",
    "    },  # Red text\n",
    "    {\n",
    "        \"page\": 1,\n",
    "        \"x\": 100,\n",
    "        \"y\": 600,\n",
    "        \"text\": \"Confidential\",\n",
    "        \"font_size\": 10,\n",
    "        \"font\": \"Helvetica\",\n",
    "        \"font_color\": (0, 0, 255),\n",
    "    },  # Blue text\n",
    "]\n",
    "\n",
    "# Initialize the PDFConverter with the existing PDF and injection items\n",
    "pdf_converter = ConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        PDFConverter(\n",
    "            prompt_template=None,\n",
    "            font_type=\"Arial\",\n",
    "            font_size=12,\n",
    "            page_width=210,\n",
    "            page_height=297,\n",
    "            existing_pdf=cv_pdf_path,  # Provide the existing PDF\n",
    "            injection_items=injection_items,  # Provide the injection items\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=pdf_converter,\n",
    ")\n",
    "\n",
    "# Initialize the attack\n",
    "attack = PromptSendingAttack(\n",
    "    objective_target=prompt_target,\n",
    "    attack_converter_config=converter_config,\n",
    ")\n",
    "\n",
    "result = await attack.execute_async(objective=\"Modify existing PDF\")  # type: ignore\n",
    "await output_attack_async(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8",
   "metadata": {},
   "source": [
    "## WordDocConverter\n",
    "\n",
    "The `WordDocConverter` generates Word (.docx) documents from text. It supports two main modes:\n",
    "\n",
    "1. **New Document Generation**: Convert plain text strings into Word documents\n",
    "2. **Placeholder-Based Injection**: Replace a placeholder in an existing `.docx` document with rendered content\n",
    "\n",
    "Placeholders must be fully contained within a single run in the document. If a placeholder spans\n",
    "multiple runs (e.g., due to mixed formatting), it will not be replaced."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9",
   "metadata": {},
   "source": [
    "### Direct Word Document Generation (No Template)\n",
    "\n",
    "This mode converts plain text strings directly into `.docx` files."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779403000064406.docx\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\u001b[1m\u001b[33m                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   \u001b[0m\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Attack Summary \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m  📋 Basic Information\u001b[0m\n",
      "\u001b[36m    • Objective: This is a simple test string for Word document generation.\u001b[0m\n",
      "\u001b[36m    • Attack Type: PromptSendingAttack\u001b[0m\n",
      "\u001b[36m    • Conversation ID: 172b3107-93fa-4443-b155-3d94f41e79ea\u001b[0m\n",
      "\n",
      "\u001b[1m  ⚡ Execution Metrics\u001b[0m\n",
      "\u001b[32m    • Turns Executed: 1\u001b[0m\n",
      "\u001b[32m    • Execution Time: 38ms\u001b[0m\n",
      "\n",
      "\u001b[1m  🎯 Outcome\u001b[0m\n",
      "\u001b[33m    • Status: ❓ UNDETERMINED\u001b[0m\n",
      "\u001b[37m    • Reason: No objective scorer configured\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Conversation History with Objective Target \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\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  This is a simple test string for Word document generation.\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  ./dbdata/prompt-\u001b[0m\n",
      "\u001b[37m      memory-entries\\binaries\\1779403000064406.docx\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\n",
      "\u001b[2m\u001b[37m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[2m\u001b[37m                            Report generated at: 2026-05-21 22:36:40 UTC                            \u001b[0m\n"
     ]
    }
   ],
   "source": [
    "from pyrit.converter import WordDocConverter\n",
    "\n",
    "word_doc_converter = ConverterConfiguration.from_converters(converters=[WordDocConverter()])\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=word_doc_converter,\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=\"This is a simple test string for Word document generation.\")  # type: ignore\n",
    "await output_attack_async(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "11",
   "metadata": {},
   "source": [
    "### Placeholder-Based Injection into Existing Word Documents\n",
    "\n",
    "This mode replaces a literal placeholder string in an existing `.docx` file with the prompt content."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TextTarget: user: ./dbdata/prompt-memory-entries/binaries/1779403000154543.docx\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\u001b[1m\u001b[33m                                  ❓ ATTACK RESULT: UNDETERMINED ❓                                   \u001b[0m\n",
      "\u001b[33m════════════════════════════════════════════════════════════════════════════════════════════════════\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Attack Summary \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[1m  📋 Basic Information\u001b[0m\n",
      "\u001b[36m    • Objective: AI Red Team Engineer\u001b[0m\n",
      "\u001b[36m    • Attack Type: PromptSendingAttack\u001b[0m\n",
      "\u001b[36m    • Conversation ID: f68f05e7-bb47-4a9d-93b1-aae35b0ba497\u001b[0m\n",
      "\n",
      "\u001b[1m  ⚡ Execution Metrics\u001b[0m\n",
      "\u001b[32m    • Turns Executed: 1\u001b[0m\n",
      "\u001b[32m    • Execution Time: 54ms\u001b[0m\n",
      "\n",
      "\u001b[1m  🎯 Outcome\u001b[0m\n",
      "\u001b[33m    • Status: ❓ UNDETERMINED\u001b[0m\n",
      "\u001b[37m    • Reason: No objective scorer configured\u001b[0m\n",
      "\n",
      "\u001b[1m\u001b[44m\u001b[37m Conversation History with Objective Target \u001b[0m\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\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  AI Red Team Engineer\u001b[0m\n",
      "\n",
      "\u001b[36m   Converted:\u001b[0m\n",
      "\u001b[37m  ./dbdata/prompt-\u001b[0m\n",
      "\u001b[37m      memory-entries\\binaries\\1779403000154543.docx\u001b[0m\n",
      "\n",
      "\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\n",
      "\u001b[2m\u001b[37m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
      "\u001b[2m\u001b[37m                            Report generated at: 2026-05-21 22:36:40 UTC                            \u001b[0m\n"
     ]
    }
   ],
   "source": [
    "import tempfile\n",
    "\n",
    "from docx import Document  # type: ignore[import-untyped]\n",
    "\n",
    "# Create a sample Word document with a placeholder\n",
    "with tempfile.NamedTemporaryFile(delete=False, suffix=\".docx\") as tmp_file:\n",
    "    doc = Document()\n",
    "    doc.add_paragraph(\"Dear Hiring Manager,\")\n",
    "    doc.add_paragraph(\"I am writing to apply for the {{INJECTION_PLACEHOLDER}} position.\")\n",
    "    doc.add_paragraph(\"Sincerely, Applicant\")\n",
    "    doc.save(tmp_file.name)\n",
    "    template_docx_path = Path(tmp_file.name)\n",
    "\n",
    "word_doc_converter = ConverterConfiguration.from_converters(\n",
    "    converters=[\n",
    "        WordDocConverter(\n",
    "            existing_docx=template_docx_path,\n",
    "            placeholder=\"{{INJECTION_PLACEHOLDER}}\",\n",
    "        )\n",
    "    ]\n",
    ")\n",
    "\n",
    "converter_config = AttackConverterConfig(\n",
    "    request_converters=word_doc_converter,\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=\"AI Red Team Engineer\")  # type: ignore\n",
    "await output_attack_async(result)"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
